Пример #1
0
            private bool ProjectOnCircle(PlaneSphereIntersection psi, Plane[] plane)
            {
                pos = plane[4].ProjectedPoint(pos);
                Vector3 v  = pos - psi.onPlane;
                float   d2 = v.sqrMagnitude;

                if (d2 > psi.circleRadius * psi.circleRadius)
                {
                    v  /= Mathf.Sqrt(d2);
                    v  *= psi.circleRadius;
                    pos = psi.onPlane + v;
                    return(true);
                }
                return(false);
            }
Пример #2
0
            public TriangleData(List <VerticeData> vertices, Vector3 p0, Vector3 p1, Vector3 p2, string name, PlaneSphereIntersection psi)
            {
                this.vertices = vertices;
                this.name     = name;
                this.psi      = psi;
                SetVertice(0, p0);
                SetVertice(1, p1);
                SetVertice(2, p2);

                com = (p0 + p1 + p2) / 3;
                for (int i = 0; i < 3; ++i)
                {
                    neighbour[i] = null;
                    display[i]   = Vector3.Lerp(com, this[i].pos, 0.9f);
                }
            }
Пример #3
0
            public void ToSphere(Vector3 center, float radius, Plane[] plane, PlaneSphereIntersection psi, Transform camPos)
            {
                if (isVisible)
                {
                    // just project visible vertices on the sphere

                    ProjectOnSphere(center, radius, plane[4].normal);
                    return;
                }
                ProjectOnCircle(psi, plane);
                //int projCount = 0;
                //for(int i = 4; --i>=0;)
                //{
                //    if(plane[i].Distance(pos) < 0)
                //    {
                //        pos = plane[i].ProjectedPoint(pos);
                //    }
                //}

                ProjectOnSphere(center, radius, camPos.position - pos);
            }
Пример #4
0
            public TriangleData(TriangleData parent, int i0, int i1, Vector3 p2, string name)
            {
                this.name = name;
                psi       = parent.psi;
                vertices  = parent.vertices;
                p[0]      = i0;
                p[1]      = i1;
                vertices[i0].triangles.Add(this);
                vertices[i1].triangles.Add(this);
                SetVertice(2, p2);
                com = Vector3.zero;
                for (int i = 0; i < 3; ++i)
                {
                    com         += this[i].pos;
                    neighbour[i] = CheckNeighbour(p[i], p.Modulo(i + 1));
                }
                com /= 3;

                for (int i = 0; i < 3; ++i)
                {
                    display[i] = Vector3.Lerp(com, this[i].pos, 0.9f);
                }
            }
Пример #5
0
        public FrustumSphereMeshBuilder(Vector3 center, float radius, Camera cam, int triangleRatio)
        {
            this.center = center;
            this.radius = radius;
            triangles   = new List <TriangleData>();
            camPos      = cam.transform;

            Vector3[] corners = new Vector3[5];
            cam.CalculateFrustumCorners(cam.rect,
                                        cam.farClipPlane,
                                        Camera.MonoOrStereoscopicEye.Mono,
                                        corners);

            Transform camTransform = cam.transform;
            Vector3   camPosition  = cam.transform.position;

            //centerInter = new RaySphereIntersection(camPosition, center-camPosition, center, radius);
            // compute world space coordinates for frustum
            for (var index = 0; index < 4; index++)
            {
                corners[index] = camTransform.TransformPoint(corners[index]);
            }
            corners[4] = corners[0];

            Vector3 p0 = camPosition;
            Vector3 p1, p2;

            plane = new Plane[5];

            float distanceSqr = (p0 - center).sqrMagnitude;

            if (distanceSqr > radius * radius)
            {
                plane[4] = Plane.SphereBackPlaneSeenFromPosition(p0, center, radius);
                psi      = new PlaneSphereIntersection(plane[4], center, radius);
                seed     = psi.ProjectOnCircle(camPosition);
                for (int i = 0; i < 4; ++i)
                {
                    p1 = corners[i];
                    p2 = corners[i + 1];

                    Plane p = new Plane(p0, p2, p1);
                    p.SetName(Vector3.Lerp(p1, p2, 0.5f), "SidePl" + i);
                    plane[i] = p;
                    MoveToPlaneIfOnNegativeSide(ref plane[i], ref seed);
                }
            }
            else
            {
                return;
            }

            Vector3    axis      = plane[4].normal;
            Quaternion q         = Quaternion.AngleAxis(120, axis);
            Vector3    direction = Vector3.Cross(axis, camTransform.up).normalized;

            direction *= radius / triangleRatio;

            p0 = direction;

            p1    = q * p0;
            p2    = q * p1;
            p0   += seed;
            p1   += seed;
            p2   += seed;
            first = new TriangleData(new List <VerticeData>(), p0, p1, p2, "0", psi);
            first[0].isVisible = first.IsVisible(first[0].pos, plane);
            first[1].isVisible = first.IsVisible(first[1].pos, plane);
            first[2].isVisible = first.IsVisible(first[2].pos, plane);
        }
Пример #6
0
    public void Compute()
    {
        main.CalculateFrustumCorners(main.rect,
                                     main.farClipPlane,
                                     Camera.MonoOrStereoscopicEye.Mono,
                                     corners);
        //centerInter = new RaySphereIntersection(camPosition, center-camPosition, center, radius);
        // compute world space coordinates for frustum
        for (var index = 0; index < 4; index++)
        {
            corners[index] = camTransform.TransformPoint(corners[index]);
        }
        corners[4] = corners[0];

        Vector3 p0 = camPosition;

        float distanceSqr = (p0 - center).sqrMagnitude;

        if (distanceSqr > radius * radius)
        {
            backPlane      = Plane.SphereBackPlaneSeenFromPosition(p0, center, radius);
            backPlaneInter = new PlaneSphereIntersection(backPlane, center, radius);

            seed = center;
            for (int i = 0; i < 4; ++i)
            {
                Vector3 p1 = corners[i];
                Vector3 p2 = corners[i + 1];

                Plane p = new Plane(p0, p2, p1);
                p.SetName(Vector3.Lerp(p1, p2, 0.5f), "SidePl" + i);
                plane[i]        = p;
                planeInter[i]   = new PlaneSphereIntersection(p, center, radius);
                cornersInter[i] = new RaySphereIntersection(p0, p1 - p0, center, radius);
                moved[i]        = MoveToPlaneIfOnNegativeSide(ref plane[i], ref seed);
            }

            seedInter = new RaySphereIntersection(camPosition, seed - camPosition, center, radius);
            ComputeAllSegments();
        }
        else
        {
            for (int i = 0; i < 4; ++i)
            {
                Vector3 p1 = corners[i];
                Vector3 p2 = corners[i + 1];
                Plane   p  = new Plane(p0, p1, p2);
                p.SetName(Vector3.Lerp(p1, p2, 0.5f), "SidePl" + i);
                plane[i]        = p;
                planeInter[i]   = new PlaneSphereIntersection(p, center, radius);
                cornersInter[i] = new RaySphereIntersection(p0, p1 - p0, center, radius);
            }

            allSegments.Clear();
            for (int i = 0; i < 4; ++i)
            {
                Vector3        start   = cornersInter[i].I;
                Vector3        end     = cornersInter.Modulo(i + 1).I;
                SegmentBuilder builder = new SegmentBuilder(i, start, end);
                builder.BuildSegment(this);
            }
        }

        barycenter = Vector3.zero;
        if (allSegments.Count > 0)
        {
            foreach (CircleSegment circleSegment in allSegments)
            {
                //for(float angle = 0; angle < circleSegment.angle; angle += 5)
                {
                    barycenter += circleSegment.Start;
                }
            }
            barycenter /= allSegments.Count;
            barycenter  = center + (barycenter - center).normalized * radius;
        }
    }