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); }
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); }
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; } }