private void ComputeAllSegments()
    {
        allSegments.Clear();
        for (int i = 0; i < 4; ++i)
        {
            circleInter[i] = GetInterWithNextCircle(i);
        }

        if (seedInter.type == RaySphereIntersection.eType.None)
        {
            return;
        }


        int firstIndex = GetFirstIntersectingPlane(-1);

        if (firstIndex == -1)
        {
            // sphere is fully visible, the backCircle is the only circle segment
            // just take the point closest to any side plane as start
            Vector3 start = backPlaneInter.ProjectOnCircle(plane[0].ProjectedPoint(center));
            allSegments.Add(new CircleSegment(backPlaneInter.onPlane, backPlane.normal, start, 360));
            return;
        }
        var lsb = new List <SegmentBuilder>();

        for (int i = 0; i < 4; ++i)
        {
            if (planeInter[i].type != PlaneSphereIntersection.eType.Circle)
            {
                continue;
            }
            Vector3 s, e;
            GetPointsForCircleIntersection(i, out s, out e);

            if (IsVisible(e) || IsVisible(s))
            {
                lsb.Add(new SegmentBuilder(i, s, e));
            }
        }

        for (var index = 0; index < lsb.Count; index++)
        {
            SegmentBuilder builder = lsb[index];
            builder.BuildSegment(this);
            if (!circleInter[builder.planeIndex].HasValue)
            {
                // that segment doesn't end on a side circle,
                // we have to make the junction with the next one
                SegmentBuilder nextBuilder = lsb[(index + 1) % lsb.Count];
                SegmentBuilder junction    = new SegmentBuilder(-1, builder.end, nextBuilder.start);
                junction.BuildSegment(this);
            }
        }
    }
    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;
        }
    }