public bool Intersects(Line2D line, out float t0, out float t1, out float t2, out float t3) { List <LineSegment2D> segs = LineSegment2D.FromBounds(this); t0 = t1 = t2 = t3 = 0f; float unused; // horizontal float h0, h1; bool intersects = segs[0].line.Intersects(line, out unused, out h0); if (!intersects) { return(false); } intersects = segs[1].line.Intersects(line, out unused, out h1); if (!intersects) { return(false); } // vertical float v0, v1; intersects = segs[2].line.Intersects(line, out unused, out v0); if (!intersects) { return(false); } intersects = segs[3].line.Intersects(line, out unused, out v1); if (!intersects) { return(false); } float hh0 = Mathf.Min(h0, h1); float hh1 = Mathf.Max(h0, h1); float vv0 = Mathf.Min(v0, v1); float vv1 = Mathf.Max(v0, v1); if (MUtils.LessOrEqual(hh0, vv0)) { // hit h0 first t0 = hh0; t1 = vv0; t2 = Mathf.Min(hh1, vv1); t3 = Mathf.Max(hh1, vv1); return(MUtils.LessOrEqual(vv0, hh1)); } else { // hit v0 first t0 = vv0; t1 = hh0; t2 = Mathf.Min(vv1, hh1); t3 = Mathf.Max(vv1, hh1); return(MUtils.LessOrEqual(hh0, vv1)); } }
public void SetNode(Node n, float loose) { n.parent = this; if (children == null) { children = new Node[4]; } children[n.index] = n; #if UNITY_EDITOR var b = GetSubBounds(n.index, loose); Debug.Assert(MUtils.Approximately(n.bounds.min, b.min)); Debug.Assert(MUtils.Approximately(n.bounds.max, b.max)); #endif }
public Triangle GetWinding(Vector3 normal) { var d0 = (p1.vertex - p0.vertex).normalized; var d1 = (p2.vertex - p0.vertex).normalized; var cross = Vector3.Cross(d0, d1); if (Vector3.Dot(normal, cross) < 0f) { var pp1 = p1; var pp2 = p2; MUtils.Swap(ref pp1, ref pp2); return(new Triangle(p0, pp1, pp2)); } return(new Triangle(p0, p1, p2)); }
// this -> P + D*t // other -> line.P + line.D*s public bool Intersects(Line2D line, out float t, out float s) { // P0 + D0t = P1 + D1s => D0t - D1s = P1 - P0 // P1 - P0 -> K // Kross D0 at both side -> -Kross(D0, D1)s = Kross(D0, K) => s = Kross(D0, K)/Kross(D1, D0) // Kross D1 at both side -> -Kross(D0, D1)t = Kross(D1, K) => t = Kross(D1, K)/Kross(D1, D0) // condition -> Kross(D1, D0) != 0 float kross = Kross(line.D, D); if (!MUtils.Approximately(kross, 0f)) { Vector2 K = line.P - P; s = Kross(D, K) / kross; t = Kross(line.D, K) / kross; return(true); } s = t = 0; return(false); }
void GetProjParams(Camera c, out Vector3 wCamMinOnPlane, out Vector3 wCamMaxOnPlane) { if (c.orthographic) { var camPos = c.transform.position; var size = (c.transform.up + c.transform.right * c.aspect) * c.orthographicSize; var camMin = camPos - size; var camMax = camPos + size; var plane = new Plane(transform.up, transform.position); float enter; var r = new Ray(camMin, c.transform.forward); plane.Raycast(r, out enter); camMin = r.GetPoint(enter); r = new Ray(camMax, c.transform.forward); plane.Raycast(r, out enter); camMax = r.GetPoint(enter); wCamMinOnPlane = new Vector3( Mathf.Min(camMin.x, camMax.x), Mathf.Min(camMin.y, camMax.y), Mathf.Min(camMin.z, camMax.z)); wCamMaxOnPlane = new Vector3( Mathf.Max(camMin.x, camMax.x), Mathf.Max(camMin.y, camMax.y), Mathf.Max(camMin.z, camMax.z)); } else { var corners = c.ProjectFrustumOnXZPlane(); float minX, maxX, minY, maxY, minZ, maxZ; MUtils.MinMax(out minX, out maxX, corners[0].x, corners[1].x, corners[2].x, corners[3].x); MUtils.MinMax(out minY, out maxY, corners[0].y, corners[1].y, corners[2].y, corners[3].y); MUtils.MinMax(out minZ, out maxZ, corners[0].z, corners[1].z, corners[2].z, corners[3].z); wCamMinOnPlane = new Vector3(minX, minY, minZ); wCamMaxOnPlane = new Vector3(maxX, maxY, maxZ); } }
public static Vector3[] ProjectFrustumOnXZPlane(this Camera camera) { Plane plane = new Plane(Vector3.up, Vector3.zero); Plane[] planes = GeometryUtility.CalculateFrustumPlanes(camera); Line L0; MUtils.Intersects(planes[0], plane, out L0); Line L1; MUtils.Intersects(planes[1], plane, out L1); Line L2; MUtils.Intersects(planes[2], plane, out L2); Line L3; MUtils.Intersects(planes[3], plane, out L3); Line2D l2d0 = MappingAxis.Map(L0); Line2D l2d1 = MappingAxis.Map(L1); Line2D l2d2 = MappingAxis.Map(L2); Line2D l2d3 = MappingAxis.Map(L3); float s, t; l2d0.Intersects(l2d2, out t, out s); Vector3 rightTop = MappingAxis.Map(l2d0.GetPoint(t)); l2d0.Intersects(l2d3, out t, out s); Vector3 rightBottom = MappingAxis.Map(l2d0.GetPoint(t)); l2d1.Intersects(l2d2, out t, out s); Vector3 leftTop = MappingAxis.Map(l2d1.GetPoint(t)); l2d1.Intersects(l2d3, out t, out s); Vector3 leftBottom = MappingAxis.Map(l2d1.GetPoint(t)); return(new Vector3[] { leftTop, rightTop, rightBottom, leftBottom }); }
public bool PointOnSegment(float t) { return(MUtils.LessOrEqual(d0, t) && MUtils.LessOrEqual(t, d1)); }
/* * +---+---+ * | 3 | 2 | * +---+---+ * | 0 | 1 | * +---+---+ */ public bool BoundsInSub(int s, Bounds b, float loose) { return(MUtils.QuadTree_IsBoundsInSub(bounds, s, b, loose)); }
public Bounds GetSubBounds(int s, float loose) { return(MUtils.QuadTree_GetSubBounds(bounds, s, loose)); }
public Triangle[] ClipBy(Plane inPlane) { Vector3 ptOnPlane = -inPlane.normal * inPlane.distance; float dot0 = Vector3.Dot(p0.vertex - ptOnPlane, inPlane.normal); float dot1 = Vector3.Dot(p1.vertex - ptOnPlane, inPlane.normal); float dot2 = Vector3.Dot(p2.vertex - ptOnPlane, inPlane.normal); int dr0 = MUtils.Approximately(dot0, 0f) ? 0 : (dot0 < 0f ? -1 : 1); int dr1 = MUtils.Approximately(dot1, 0f) ? 0 : (dot1 < 0f ? -1 : 1); int dr2 = MUtils.Approximately(dot2, 0f) ? 0 : (dot2 < 0f ? -1 : 1); if (dr0 > 0 && dr1 > 0 && dr2 > 0) { return(null); } if (dr0 < 0 && dr1 < 0 && dr2 < 0) { return new Triangle[] { this } } ; // one edge lay on the plane System.Func <int, int, int, bool> check = delegate(int kr0, int kr1, int kr2) { if (kr0 == 0 && kr1 == 0) { return(kr2 <= 0); } return(false); }; if (check(dr0, dr1, dr2) || check(dr0, dr2, dr1) || check(dr1, dr0, dr2) || check(dr1, dr2, dr0) || check(dr2, dr0, dr1) || check(dr2, dr1, dr0)) { return(new Triangle[] { this }); } List <Triangle> tris = new List <Triangle>(); Func <int, int, int, Vertex, Vertex, Vertex, bool> clip = delegate(int kr0, int kr1, int kr2, Vertex pt0, Vertex pt1, Vertex pt2) { if (kr0 > 0) // p0 at positive side { float enter; if (kr1 < 0 && kr2 < 0) // other two on nagetive plane { var r = new Ray(pt0.vertex, pt1.vertex - pt0.vertex); inPlane.Raycast(r, out enter); var t0 = r.GetPoint(enter); Vertex tt0 = new Vertex(); tt0.vertex = t0; tt0.uv = pt0.uv + (pt1.uv - pt0.uv) * enter; tt0.uv2 = pt0.uv2 + (pt1.uv2 - pt0.uv2) * enter; tt0.uv3 = pt0.uv3 + (pt1.uv3 - pt0.uv3) * enter; tt0.uv4 = pt0.uv4 + (pt1.uv4 - pt0.uv4) * enter; r = new Ray(pt0.vertex, pt2.vertex - pt0.vertex); inPlane.Raycast(r, out enter); var t1 = r.GetPoint(enter); Vertex tt1 = new Vertex(); tt1.vertex = t1; tt1.uv = pt0.uv + (pt2.uv - pt0.uv) * enter; tt1.uv2 = pt0.uv2 + (pt2.uv2 - pt0.uv2) * enter; tt1.uv3 = pt0.uv3 + (pt2.uv3 - pt0.uv3) * enter; tt1.uv4 = pt0.uv4 + (pt2.uv4 - pt0.uv4) * enter; tris.Add(new Triangle(tt0, pt1, pt2)); tris.Add(new Triangle(tt0, pt2, tt1)); } else if (kr1 > 0 && kr2 < 0) // p1 at positive side. p2 at nagetive side { var r = new Ray(pt0.vertex, pt2.vertex - pt0.vertex); inPlane.Raycast(r, out enter); var t0 = r.GetPoint(enter); Vertex tt0 = new Vertex(); tt0.vertex = t0; tt0.uv = pt0.uv + (pt2.uv - pt0.uv) * enter; tt0.uv2 = pt0.uv2 + (pt2.uv2 - pt0.uv2) * enter; tt0.uv3 = pt0.uv3 + (pt2.uv3 - pt0.uv3) * enter; tt0.uv4 = pt0.uv4 + (pt2.uv4 - pt0.uv4) * enter; r = new Ray(pt1.vertex, pt2.vertex - pt1.vertex); inPlane.Raycast(r, out enter); var t1 = r.GetPoint(enter); Vertex tt1 = new Vertex(); tt1.vertex = t1; tt1.uv = pt1.uv + (pt2.uv - pt1.uv) * enter; tt1.uv2 = pt1.uv2 + (pt2.uv2 - pt1.uv2) * enter; tt1.uv3 = pt1.uv3 + (pt2.uv3 - pt1.uv3) * enter; tt1.uv4 = pt1.uv4 + (pt2.uv4 - pt1.uv4) * enter; tris.Add(new Triangle(tt0, pt2, tt1)); } else if (kr1 < 0 && kr2 > 0) // p2 at positive side, p1 at nagetive side, { var r = new Ray(pt0.vertex, pt1.vertex - pt0.vertex); inPlane.Raycast(r, out enter); var t0 = r.GetPoint(enter); Vertex tt0 = new Vertex(); tt0.vertex = t0; tt0.uv = pt0.uv + (pt1.uv - pt0.uv) * enter; tt0.uv2 = pt0.uv2 + (pt1.uv2 - pt0.uv2) * enter; tt0.uv3 = pt0.uv3 + (pt1.uv3 - pt0.uv3) * enter; tt0.uv4 = pt0.uv4 + (pt1.uv4 - pt0.uv4) * enter; r = new Ray(pt2.vertex, pt1.vertex - pt2.vertex); inPlane.Raycast(r, out enter); var t1 = r.GetPoint(enter); Vertex tt1 = new Vertex(); tt1.vertex = t1; tt1.uv = pt2.uv + (pt2.uv - pt1.uv) * enter; tt1.uv2 = pt2.uv2 + (pt2.uv2 - pt1.uv2) * enter; tt1.uv3 = pt2.uv3 + (pt2.uv3 - pt1.uv3) * enter; tt1.uv4 = pt2.uv4 + (pt2.uv4 - pt1.uv4) * enter; tris.Add(new Triangle(tt0, pt1, tt1)); } return(true); } return(false); }; bool clipped = clip(dr0, dr1, dr2, p0, p1, p2); clipped = clipped || clip(dr1, dr2, dr0, p1, p2, p0); clipped = clipped || clip(dr2, dr0, dr1, p2, p0, p1); return(tris.ToArray()); } }