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