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()); } }
public Triangle(Vertex inP0, Vertex inP1, Vertex inP2) { p0 = inP0; p1 = inP1; p2 = inP2; }