예제 #1
0
        private bool MoveToPlaneIfOnNegativeSide(ref Plane sidePlane, ref Vector3 p0)
        {
            float distance = sidePlane.Distance(p0);

            if (distance >= 0)
            {
                return(false);
            }
            p0 -= sidePlane.normal * distance;
            return(true);
        }
예제 #2
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);
        }
예제 #3
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;
        }
    }