/// <summary> /// 线段与面的交点 /// </summary> /// <param name="plane"></param> /// <param name="segmentStartPoint"></param> /// <param name="segmentEndPoint"></param> /// <returns></returns> public static bool GetSegmentPlaneIntersectionPoint(this Plane plane, Vector3 segmentStartPoint, Vector3 segmentEndPoint, out Vector3 intersectionPoint) { intersectionPoint = default(Vector3); SideOfPlane point0Side = PointSideOfPlane(plane, segmentStartPoint); SideOfPlane point1Side = PointSideOfPlane(plane, segmentEndPoint); if (point0Side == point1Side) { return(false); } return(GetRayPlaneIntersectionPoint(plane, segmentStartPoint, segmentEndPoint, out intersectionPoint)); }
/** * Slice the gameobject mesh (if any) using the Plane, which will generate * a maximum of 2 other Meshes. * This function will recalculate new UV coordinates to ensure textures are applied * properly. * Returns null if no intersection has been found or the GameObject does not contain * a valid mesh to cut. */ public static SlicedHull Slice(Mesh sharedMesh, Plane pl, bool genCrossSection = true) { if (sharedMesh == null) { return(null); } Vector3[] verts = sharedMesh.vertices; Vector2[] uv = sharedMesh.uv; Vector3[] norm = sharedMesh.normals; Vector4[] tan = sharedMesh.tangents; int submeshCount = sharedMesh.subMeshCount; // each submesh will be sliced and placed in its own array structure SlicedSubmesh[] slices = new SlicedSubmesh[submeshCount]; // the cross section hull is common across all submeshes List <Vector3> crossHull = new List <Vector3>(); // we reuse this object for all intersection tests IntersectionResult result = new IntersectionResult(); // see if we would like to split the mesh using uv, normals and tangents bool genUV = verts.Length == uv.Length; bool genNorm = verts.Length == norm.Length; bool genTan = verts.Length == tan.Length; // iterate over all the submeshes individually. vertices and indices // are all shared within the submesh for (int submesh = 0; submesh < submeshCount; submesh++) { int[] indices = sharedMesh.GetTriangles(submesh); int indicesCount = indices.Length; SlicedSubmesh mesh = new SlicedSubmesh(); // loop through all the mesh vertices, generating upper and lower hulls // and all intersection points for (int index = 0; index < indicesCount; index += 3) { int i0 = indices[index + 0]; int i1 = indices[index + 1]; int i2 = indices[index + 2]; Triangle newTri = new Triangle(verts[i0], verts[i1], verts[i2]); // generate UV if available if (genUV) { newTri.SetUV(uv[i0], uv[i1], uv[i2]); } // generate normals if available if (genNorm) { newTri.SetNormal(norm[i0], norm[i1], norm[i2]); } // generate tangents if available if (genTan) { newTri.SetTangent(tan[i0], tan[i1], tan[i2]); } // slice this particular triangle with the provided // plane if (newTri.Split(pl, result)) { int upperHullCount = result.upperHullCount; int lowerHullCount = result.lowerHullCount; int interHullCount = result.intersectionPointCount; for (int i = 0; i < upperHullCount; i++) { mesh.upperHull.Add(result.upperHull[i]); } for (int i = 0; i < lowerHullCount; i++) { mesh.lowerHull.Add(result.lowerHull[i]); } for (int i = 0; i < interHullCount; i++) { crossHull.Add(result.intersectionPoints[i]); } } else { SideOfPlane side = pl.SideOf(verts[i0]); if (side == SideOfPlane.UP || side == SideOfPlane.ON) { mesh.upperHull.Add(newTri); } else { mesh.lowerHull.Add(newTri); } } } // register into the index slices[submesh] = mesh; } return(CreateFrom(slices, CreateFrom(crossHull, pl.normal))); }
/** * Perform an intersection between Plane and Triangle. This is a comprehensive function * which alwo builds a HULL Hirearchy useful for decimation projects. This obviously * comes at the cost of more complex code and runtime checks, but the returned results * are much more flexible. * Results will be filled into the IntersectionResult reference. Check result.isValid() * for the final results. */ public static void Intersect(Plane pl, Triangle tri, ref IntersectionResult result) { // clear the previous results from the IntersectionResult result.Clear(); // grab local variables for easier access Vector3 a = tri.positionA; Vector3 b = tri.positionB; Vector3 c = tri.positionC; // check to see which side of the plane the points all // lay in. SideOf operation is a simple dot product and some comparison // operations, so these are a very quick checks SideOfPlane sa = pl.SideOf(a); SideOfPlane sb = pl.SideOf(b); SideOfPlane sc = pl.SideOf(c); // we cannot intersect if the triangle points all fall on the same side // of the plane. This is an easy early out test as no intersections are possible. if (sa == sb && sb == sc) { return; } // detect cases where two points lay straight on the plane, meaning // that the plane is actually parralel with one of the edges of the triangle else if ((sa == SideOfPlane.ON && sa == sb) || (sa == SideOfPlane.ON && sa == sc) || (sb == SideOfPlane.ON && sb == sc)) { return; } // keep in mind that intersection points are shared by both // the upper HULL and lower HULL hence they lie perfectly // on the plane that cut them Vector3 qa; Vector3 qb; // check the cases where the points of the triangle actually lie on the plane itself // in these cases, there is only going to be 2 triangles, one for the upper HULL and // the other on the lower HULL // we just need to figure out which points to accept into the upper or lower hulls. if (sa == SideOfPlane.ON) { // if the point a is on the plane, test line b-c if (Intersector.Intersect(pl, b, c, out qa)) { // line b-c intersected, construct out triangles and return approprietly result.AddIntersectionPoint(qa); result.AddIntersectionPoint(a); // our two generated triangles, we need to figure out which // triangle goes into the UPPER hull and which goes into the LOWER hull Triangle ta = new Triangle(a, b, qa); Triangle tb = new Triangle(a, qa, c); // generate UV coordinates if there is any if (tri.hasUV) { // the computed UV coordinate if the intersection point Vector2 pq = tri.GenerateUV(qa); Vector2 pa = tri.uvA; Vector2 pb = tri.uvB; Vector2 pc = tri.uvC; ta.SetUV(pa, pb, pq); tb.SetUV(pa, pq, pc); } // generate Normal coordinates if there is any if (tri.hasNormal) { // the computed Normal coordinate if the intersection point Vector3 pq = tri.GenerateNormal(qa); Vector3 pa = tri.normalA; Vector3 pb = tri.normalB; Vector3 pc = tri.normalC; ta.SetNormal(pa, pb, pq); tb.SetNormal(pa, pq, pc); } // generate Tangent coordinates if there is any if (tri.hasTangent) { // the computed Tangent coordinate if the intersection point Vector4 pq = tri.GenerateTangent(qa); Vector4 pa = tri.tangentA; Vector4 pb = tri.tangentB; Vector4 pc = tri.tangentC; ta.SetTangent(pa, pb, pq); tb.SetTangent(pa, pq, pc); } // b point lies on the upside of the plane if (sb == SideOfPlane.UP) { result.AddUpperHull(ta).AddLowerHull(tb); } // b point lies on the downside of the plane else if (sb == SideOfPlane.DOWN) { result.AddUpperHull(tb).AddLowerHull(ta); } } } // test the case where the b point lies on the plane itself else if (sb == SideOfPlane.ON) { // if the point b is on the plane, test line a-c if (Intersector.Intersect(pl, a, c, out qa)) { // line a-c intersected, construct out triangles and return approprietly result.AddIntersectionPoint(qa); result.AddIntersectionPoint(b); // our two generated triangles, we need to figure out which // triangle goes into the UPPER hull and which goes into the LOWER hull Triangle ta = new Triangle(a, b, qa); Triangle tb = new Triangle(qa, b, c); // generate UV coordinates if there is any if (tri.hasUV) { // the computed UV coordinate if the intersection point Vector2 pq = tri.GenerateUV(qa); Vector2 pa = tri.uvA; Vector2 pb = tri.uvB; Vector2 pc = tri.uvC; ta.SetUV(pa, pb, pq); tb.SetUV(pq, pb, pc); } // generate Normal coordinates if there is any if (tri.hasNormal) { // the computed Normal coordinate if the intersection point Vector3 pq = tri.GenerateNormal(qa); Vector3 pa = tri.normalA; Vector3 pb = tri.normalB; Vector3 pc = tri.normalC; ta.SetNormal(pa, pb, pq); tb.SetNormal(pq, pb, pc); } // generate Tangent coordinates if there is any if (tri.hasTangent) { // the computed Tangent coordinate if the intersection point Vector4 pq = tri.GenerateTangent(qa); Vector4 pa = tri.tangentA; Vector4 pb = tri.tangentB; Vector4 pc = tri.tangentC; ta.SetTangent(pa, pb, pq); tb.SetTangent(pq, pb, pc); } // a point lies on the upside of the plane if (sa == SideOfPlane.UP) { result.AddUpperHull(ta).AddLowerHull(tb); } // a point lies on the downside of the plane else if (sa == SideOfPlane.DOWN) { result.AddUpperHull(tb).AddLowerHull(ta); } } } // test the case where the c point lies on the plane itself else if (sc == SideOfPlane.ON) { // if the point c is on the plane, test line a-b if (Intersector.Intersect(pl, a, b, out qa)) { // line a-c intersected, construct out triangles and return approprietly result.AddIntersectionPoint(qa); result.AddIntersectionPoint(c); // our two generated triangles, we need to figure out which // triangle goes into the UPPER hull and which goes into the LOWER hull Triangle ta = new Triangle(a, qa, c); Triangle tb = new Triangle(qa, b, c); // generate UV coordinates if there is any if (tri.hasUV) { // the computed UV coordinate if the intersection point Vector2 pq = tri.GenerateUV(qa); Vector2 pa = tri.uvA; Vector2 pb = tri.uvB; Vector2 pc = tri.uvC; ta.SetUV(pa, pq, pc); tb.SetUV(pq, pb, pc); } // generate Normal coordinates if there is any if (tri.hasNormal) { // the computed Normal coordinate if the intersection point Vector3 pq = tri.GenerateNormal(qa); Vector3 pa = tri.normalA; Vector3 pb = tri.normalB; Vector3 pc = tri.normalC; ta.SetNormal(pa, pq, pc); tb.SetNormal(pq, pb, pc); } // generate Tangent coordinates if there is any if (tri.hasTangent) { // the computed Tangent coordinate if the intersection point Vector4 pq = tri.GenerateTangent(qa); Vector4 pa = tri.tangentA; Vector4 pb = tri.tangentB; Vector4 pc = tri.tangentC; ta.SetTangent(pa, pq, pc); tb.SetTangent(pq, pb, pc); } // a point lies on the upside of the plane if (sa == SideOfPlane.UP) { result.AddUpperHull(ta).AddLowerHull(tb); } // a point lies on the downside of the plane else if (sa == SideOfPlane.DOWN) { result.AddUpperHull(tb).AddLowerHull(ta); } } } // at this point, all edge cases have been tested and failed, we need to perform // full intersection tests against the lines. From this point onwards we will generate // 3 triangles else if (sa != sb && Intersector.Intersect(pl, a, b, out qa)) { // intersection found against a - b result.AddIntersectionPoint(qa); // since intersection was found against a - b, we need to check which other // lines to check (we only need to check one more line) for intersection. // the line we check against will be the line against the point which lies on // the other side of the plane. if (sa == sc) { // we likely have an intersection against line b-c which will complete this loop if (Intersector.Intersect(pl, b, c, out qb)) { result.AddIntersectionPoint(qb); // our three generated triangles. Two of these triangles will end // up on either the UPPER or LOWER hulls. Triangle ta = new Triangle(qa, b, qb); Triangle tb = new Triangle(a, qa, qb); Triangle tc = new Triangle(a, qb, c); // generate UV coordinates if there is any if (tri.hasUV) { // the computed UV coordinate if the intersection point Vector2 pqa = tri.GenerateUV(qa); Vector2 pqb = tri.GenerateUV(qb); Vector2 pa = tri.uvA; Vector2 pb = tri.uvB; Vector2 pc = tri.uvC; ta.SetUV(pqa, pb, pqb); tb.SetUV(pa, pqa, pqb); tc.SetUV(pa, pqb, pc); } // generate Normal coordinates if there is any if (tri.hasNormal) { // the computed Normal coordinate if the intersection point Vector3 pqa = tri.GenerateNormal(qa); Vector3 pqb = tri.GenerateNormal(qb); Vector3 pa = tri.normalA; Vector3 pb = tri.normalB; Vector3 pc = tri.normalC; ta.SetNormal(pqa, pb, pqb); tb.SetNormal(pa, pqa, pqb); tc.SetNormal(pa, pqb, pc); } // generate Tangent coordinates if there is any if (tri.hasTangent) { // the computed Tangent coordinate if the intersection point Vector4 pqa = tri.GenerateTangent(qa); Vector4 pqb = tri.GenerateTangent(qb); Vector4 pa = tri.tangentA; Vector4 pb = tri.tangentB; Vector4 pc = tri.tangentC; ta.SetTangent(pqa, pb, pqb); tb.SetTangent(pa, pqa, pqb); tc.SetTangent(pa, pqb, pc); } if (sa == SideOfPlane.UP) { result.AddUpperHull(tb).AddUpperHull(tc).AddLowerHull(ta); } else { result.AddLowerHull(tb).AddLowerHull(tc).AddUpperHull(ta); } } } else { // in this scenario, the point a is a "lone" point which lies in either upper // or lower HULL. We need to perform another intersection to find the last point if (Intersector.Intersect(pl, a, c, out qb)) { result.AddIntersectionPoint(qb); // our three generated triangles. Two of these triangles will end // up on either the UPPER or LOWER hulls. Triangle ta = new Triangle(a, qa, qb); Triangle tb = new Triangle(qa, b, c); Triangle tc = new Triangle(qb, qa, c); // generate UV coordinates if there is any if (tri.hasUV) { // the computed UV coordinate if the intersection point Vector2 pqa = tri.GenerateUV(qa); Vector2 pqb = tri.GenerateUV(qb); Vector2 pa = tri.uvA; Vector2 pb = tri.uvB; Vector2 pc = tri.uvC; ta.SetUV(pa, pqa, pqb); tb.SetUV(pqa, pb, pc); tc.SetUV(pqb, pqa, pc); } // generate Normal coordinates if there is any if (tri.hasNormal) { // the computed Normal coordinate if the intersection point Vector3 pqa = tri.GenerateNormal(qa); Vector3 pqb = tri.GenerateNormal(qb); Vector3 pa = tri.normalA; Vector3 pb = tri.normalB; Vector3 pc = tri.normalC; ta.SetNormal(pa, pqa, pqb); tb.SetNormal(pqa, pb, pc); tc.SetNormal(pqb, pqa, pc); } // generate Tangent coordinates if there is any if (tri.hasTangent) { // the computed Tangent coordinate if the intersection point Vector4 pqa = tri.GenerateTangent(qa); Vector4 pqb = tri.GenerateTangent(qb); Vector4 pa = tri.tangentA; Vector4 pb = tri.tangentB; Vector4 pc = tri.tangentC; ta.SetTangent(pa, pqa, pqb); tb.SetTangent(pqa, pb, pc); tc.SetTangent(pqb, pqa, pc); } if (sa == SideOfPlane.UP) { result.AddUpperHull(ta).AddLowerHull(tb).AddLowerHull(tc); } else { result.AddLowerHull(ta).AddUpperHull(tb).AddUpperHull(tc); } } } } // if line a-b did not intersect (or the lie on the same side of the plane) // this simplifies the problem a fair bit. This means we have an intersection // in line a-c and b-c, which we can use to build a new UPPER and LOWER hulls // we are expecting both of these intersection tests to pass, otherwise something // went wrong (float errors? missed a checked case?) else if (Intersector.Intersect(pl, c, a, out qa) && Intersector.Intersect(pl, c, b, out qb)) { // in here we know that line a-b actually lie on the same side of the plane, this will // simplify the rest of the logic. We also have our intersection points // the computed UV coordinate of the intersection point result.AddIntersectionPoint(qa); result.AddIntersectionPoint(qb); // our three generated triangles. Two of these triangles will end // up on either the UPPER or LOWER hulls. Triangle ta = new Triangle(qa, qb, c); Triangle tb = new Triangle(a, qb, qa); Triangle tc = new Triangle(a, b, qb); // generate UV coordinates if there is any if (tri.hasUV) { // the computed UV coordinate if the intersection point Vector2 pqa = tri.GenerateUV(qa); Vector2 pqb = tri.GenerateUV(qb); Vector2 pa = tri.uvA; Vector2 pb = tri.uvB; Vector2 pc = tri.uvC; ta.SetUV(pqa, pqb, pc); tb.SetUV(pa, pqb, pqa); tc.SetUV(pa, pb, pqb); } // generate Normal coordinates if there is any if (tri.hasNormal) { // the computed Normal coordinate if the intersection point Vector3 pqa = tri.GenerateNormal(qa); Vector3 pqb = tri.GenerateNormal(qb); Vector3 pa = tri.normalA; Vector3 pb = tri.normalB; Vector3 pc = tri.normalC; ta.SetNormal(pqa, pqb, pc); tb.SetNormal(pa, pqb, pqa); tc.SetNormal(pa, pb, pqb); } // generate Tangent coordinates if there is any if (tri.hasTangent) { // the computed Tangent coordinate if the intersection point Vector4 pqa = tri.GenerateTangent(qa); Vector4 pqb = tri.GenerateTangent(qb); Vector4 pa = tri.tangentA; Vector4 pb = tri.tangentB; Vector4 pc = tri.tangentC; ta.SetTangent(pqa, pqb, pc); tb.SetTangent(pa, pqb, pqa); tc.SetTangent(pa, pb, pqb); } if (sa == SideOfPlane.UP) { result.AddUpperHull(tb).AddUpperHull(tc).AddLowerHull(ta); } else { result.AddLowerHull(tb).AddLowerHull(tc).AddUpperHull(ta); } } }
/** * Slice the gameobject mesh (if any) using the Plane, which will generate * a maximum of 2 other Meshes. * This function will recalculate new UV coordinates to ensure textures are applied * properly. * Returns null if no intersection has been found or the GameObject does not contain * a valid mesh to cut. */ public static SlicedHull Slice(Mesh sharedMesh, Plane pl, TextureRegion region, int crossIndex) { if (sharedMesh == null) { return(null); } Vector3[] verts = sharedMesh.vertices; Vector2[] uv = sharedMesh.uv; Vector3[] norm = sharedMesh.normals; Vector4[] tan = sharedMesh.tangents; int submeshCount = sharedMesh.subMeshCount; // each submesh will be sliced and placed in its own array structure SlicedSubmesh[] slices = new SlicedSubmesh[submeshCount]; // the cross section hull is common across all submeshes List <Vector3> crossHull = new List <Vector3>(); // we reuse this object for all intersection tests IntersectionResult result = new IntersectionResult(); // see if we would like to split the mesh using uv, normals and tangents bool genUV = verts.Length == uv.Length; bool genNorm = verts.Length == norm.Length; bool genTan = verts.Length == tan.Length; // iterate over all the submeshes individually. vertices and indices // are all shared within the submesh for (int submesh = 0; submesh < submeshCount; submesh++) { int[] indices = sharedMesh.GetTriangles(submesh); int indicesCount = indices.Length; SlicedSubmesh mesh = new SlicedSubmesh(); // loop through all the mesh vertices, generating upper and lower hulls // and all intersection points for (int index = 0; index < indicesCount; index += 3) { int i0 = indices[index + 0]; int i1 = indices[index + 1]; int i2 = indices[index + 2]; Triangle newTri = new Triangle(verts[i0], verts[i1], verts[i2]); // generate UV if available if (genUV) { newTri.SetUV(uv[i0], uv[i1], uv[i2]); } // generate normals if available if (genNorm) { newTri.SetNormal(norm[i0], norm[i1], norm[i2]); } // generate tangents if available if (genTan) { newTri.SetTangent(tan[i0], tan[i1], tan[i2]); } // slice this particular triangle with the provided // plane if (newTri.Split(pl, result)) { int upperHullCount = result.upperHullCount; int lowerHullCount = result.lowerHullCount; int interHullCount = result.intersectionPointCount; for (int i = 0; i < upperHullCount; i++) { mesh.upperHull.Add(result.upperHull[i]); } for (int i = 0; i < lowerHullCount; i++) { mesh.lowerHull.Add(result.lowerHull[i]); } for (int i = 0; i < interHullCount; i++) { crossHull.Add(result.intersectionPoints[i]); } } else { SideOfPlane sa = pl.SideOf(verts[i0]); SideOfPlane sb = pl.SideOf(verts[i1]); SideOfPlane sc = pl.SideOf(verts[i2]); SideOfPlane side = SideOfPlane.ON; if (sa != SideOfPlane.ON) { side = sa; } if (sb != SideOfPlane.ON) { Debug.Assert(side == SideOfPlane.ON || side == sb); side = sb; } if (sc != SideOfPlane.ON) { Debug.Assert(side == SideOfPlane.ON || side == sc); side = sc; } if (side == SideOfPlane.UP || side == SideOfPlane.ON) { mesh.upperHull.Add(newTri); } else { mesh.lowerHull.Add(newTri); } } } // register into the index slices[submesh] = mesh; } // check if slicing actually occured for (int i = 0; i < slices.Length; i++) { // check if at least one of the submeshes was sliced. If so, stop checking // because we need to go through the generation step if (slices[i] != null && slices[i].isValid) { return(CreateFrom(slices, CreateFrom(crossHull, pl.normal, region), crossIndex)); } } // no slicing occured, just return null to signify return(null); }
/** * Slice the gameobject mesh (if any) using the Plane, which will generate * a maximum of 2 other Meshes. * This function will recalculate new UV coordinates to ensure textures are applied * properly. * Returns null if no intersection has been found or the GameObject does not contain * a valid mesh to cut. */ public static SlicedHull Slice(Mesh sharedMesh, Plane pl, bool genCrossSection = true) { if (sharedMesh == null) { return(null); } Vector3[] ve = sharedMesh.vertices; Vector2[] uv = sharedMesh.uv; int[] indices = sharedMesh.triangles; int indicesCount = indices.Length; // we reuse this object for all intersection tests IntersectionResult result = new IntersectionResult(); // all our buffers, as Triangles List <Triangle> upperHull = new List <Triangle>(); List <Triangle> lowerHull = new List <Triangle>(); List <Vector3> crossHull = new List <Vector3>(); // loop through all the mesh vertices, generating upper and lower hulls // and all intersection points for (int index = 0; index < indicesCount; index += 3) { int i0 = indices[index + 0]; int i1 = indices[index + 1]; int i2 = indices[index + 2]; Triangle newTri = new Triangle(ve[i0], ve[i1], ve[i2], uv[i0], uv[i1], uv[i2]); // slice this particular triangle with the provided // plane if (newTri.Split(pl, result)) { int upperHullCount = result.upperHullCount; int lowerHullCount = result.lowerHullCount; int interHullCount = result.intersectionPointCount; for (int i = 0; i < upperHullCount; i++) { upperHull.Add(result.upperHull[i]); } for (int i = 0; i < lowerHullCount; i++) { lowerHull.Add(result.lowerHull[i]); } for (int i = 0; i < interHullCount; i++) { crossHull.Add(result.intersectionPoints[i]); } } else { SideOfPlane side = pl.SideOf(ve[i0]); if (side == SideOfPlane.UP || side == SideOfPlane.ON) { upperHull.Add(newTri); } else { lowerHull.Add(newTri); } } } // start creating our hulls Mesh finalUpperHull = CreateFrom(upperHull); Mesh finalLowerHull = CreateFrom(lowerHull); // we need to generate the cross section if set // NOTE -> This uses a MonotoneChain algorithm which will only work // on cross sections which are Convex if (genCrossSection) { Mesh[] crossSections = CreateFrom(crossHull, pl.normal); if (crossSections != null) { return(new SlicedHull(finalUpperHull, finalLowerHull, crossSections[0], crossSections[1])); } } return(new SlicedHull(finalUpperHull, finalLowerHull)); }
/// <summary> /// 获取面与三角形相交结果 /// </summary> /// <param name="plane">平面</param> /// <param name="triangle">三角形</param> /// <param name="includePlaneBack">是否包括Plane的反面</param> /// <returns></returns> public static PlaneTriangleIntersectionResult GetPlaneTriangleIntersectionResult(Plane plane, Triangle triangle, bool includePlaneBack = false) { PlaneTriangleIntersectionResult intersectionResult = new PlaneTriangleIntersectionResult(); Vector3 p0 = triangle.VertexPosition0; Vector3 p1 = triangle.VertexPosition1; Vector3 p2 = triangle.VertexPosition2; SideOfPlane p0SideOfPlane = plane.PointSideOfPlane(p0); SideOfPlane p1SideOfPlane = plane.PointSideOfPlane(p1); SideOfPlane p2SideOfPlane = plane.PointSideOfPlane(p2); //三个点在同一方向 if (p0SideOfPlane == p1SideOfPlane && p0SideOfPlane == p2SideOfPlane) { if (p0SideOfPlane == SideOfPlane.UP) { intersectionResult.UpperTriangleList.Add(triangle); } if (includePlaneBack && p0SideOfPlane == SideOfPlane.DOWN) { intersectionResult.UnderTriangleList.Add(triangle); } return(intersectionResult); } //两个点在Plane上 if ((p0SideOfPlane == SideOfPlane.ON) && p0SideOfPlane == p1SideOfPlane) { if (p2SideOfPlane == SideOfPlane.UP) { intersectionResult.UpperTriangleList.Add(triangle); } else { if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle); } } } else if ((p0SideOfPlane == SideOfPlane.ON) && p0SideOfPlane == p2SideOfPlane) { if (p1SideOfPlane == SideOfPlane.UP) { intersectionResult.UpperTriangleList.Add(triangle); } else { if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle); } } } else if ((p1SideOfPlane == SideOfPlane.ON) && p1SideOfPlane == p2SideOfPlane) { if (p0SideOfPlane == SideOfPlane.UP) { intersectionResult.UpperTriangleList.Add(triangle); } else { if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle); } } } //相交点 Vector3 intersectionPoint0; Vector3 intersectionPoint1; //一个点在面上,两个点在两侧 if (p0SideOfPlane == SideOfPlane.ON) { //b - c if (plane.GetSegmentPlaneIntersectionPoint(p1, p2, out intersectionPoint0)) { //交点的barycentric Vector3 barycentricWeight = PointBarycentricInTriangle(intersectionPoint0, p0, p1, p2); Vector2 intersectionPointUV = GetTrianglePointByBarycentricWeight2D(barycentricWeight, triangle.UV0, triangle.UV1, triangle.UV2); Triangle triangle1 = new Triangle(p0, p1, intersectionPoint0, triangle.UV0, triangle.UV1, intersectionPointUV); Triangle triangle2 = new Triangle(p0, intersectionPoint0, p2, triangle.UV0, intersectionPointUV, triangle.UV1); intersectionResult.IntersectionPointList.Add(p0); intersectionResult.IntersectionPointList.Add(intersectionPoint0); if (p1SideOfPlane == SideOfPlane.UP) { intersectionResult.UpperTriangleList.Add(triangle1); if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle2); } } else { intersectionResult.UpperTriangleList.Add(triangle2); if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle1); } } } } else if (p1SideOfPlane == SideOfPlane.ON) { //a - c if (plane.GetSegmentPlaneIntersectionPoint(p0, p2, out intersectionPoint0)) { Vector3 barycentricWeight = PointBarycentricInTriangle(intersectionPoint0, p0, p1, p2); Vector2 intersectionPointUV = GetTrianglePointByBarycentricWeight2D(barycentricWeight, triangle.UV0, triangle.UV1, triangle.UV2); Triangle triangle1 = new Triangle(p1, intersectionPoint0, p2, triangle.UV1, intersectionPointUV, triangle.UV2); Triangle triangle2 = new Triangle(p0, intersectionPoint0, p1, triangle.UV0, intersectionPointUV, triangle.UV1); intersectionResult.IntersectionPointList.Add(p1); intersectionResult.IntersectionPointList.Add(intersectionPoint0); if (p0SideOfPlane == SideOfPlane.UP) { intersectionResult.UpperTriangleList.Add(triangle2); if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle1); } } else { intersectionResult.UpperTriangleList.Add(triangle1); if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle2); } } } } else if (p2SideOfPlane == SideOfPlane.ON) { //a - b if (plane.GetSegmentPlaneIntersectionPoint(p0, p2, out intersectionPoint0)) { Vector3 barycentricWeight = PointBarycentricInTriangle(intersectionPoint0, p0, p1, p2); Vector2 intersectionPointUV = GetTrianglePointByBarycentricWeight2D(barycentricWeight, triangle.UV0, triangle.UV1, triangle.UV2); Triangle triangle1 = new Triangle(p0, intersectionPoint0, p2, triangle.UV0, intersectionPointUV, triangle.UV2); Triangle triangle2 = new Triangle(p2, intersectionPoint0, p1, triangle.UV2, intersectionPointUV, triangle.UV1); intersectionResult.IntersectionPointList.Add(p2); intersectionResult.IntersectionPointList.Add(intersectionPoint0); if (p0SideOfPlane == SideOfPlane.UP) { intersectionResult.UpperTriangleList.Add(triangle1); if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle2); } } else { intersectionResult.UpperTriangleList.Add(triangle2); if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle1); } } } } //a - b else if (plane.GetSegmentPlaneIntersectionPoint(p0, p1, out intersectionPoint0)) { Vector3 barycentricWeight0 = PointBarycentricInTriangle(intersectionPoint0, p0, p1, p2); Vector2 intersectionPointUV0 = GetTrianglePointByBarycentricWeight2D(barycentricWeight0, triangle.UV0, triangle.UV1, triangle.UV2); intersectionResult.IntersectionPointList.Add(intersectionPoint0); // b - c if (p0SideOfPlane == p2SideOfPlane) { if (plane.GetSegmentPlaneIntersectionPoint(p1, p2, out intersectionPoint1)) { Vector3 barycentricWeight1 = PointBarycentricInTriangle(intersectionPoint1, p0, p1, p2); Vector2 intersectionPointUV1 = GetTrianglePointByBarycentricWeight2D(barycentricWeight1, triangle.UV0, triangle.UV1, triangle.UV2); Triangle triangle0 = new Triangle(p0, intersectionPoint0, intersectionPoint1, triangle.UV0, intersectionPointUV0, intersectionPointUV1); Triangle triangle1 = new Triangle(p0, intersectionPoint1, p2, triangle.UV0, intersectionPointUV1, triangle.UV2); Triangle triangle2 = new Triangle(intersectionPoint0, p1, intersectionPoint1, intersectionPointUV0, triangle.UV1, intersectionPointUV1); intersectionResult.IntersectionPointList.Add(intersectionPoint1); if (p0SideOfPlane == SideOfPlane.UP) { intersectionResult.UpperTriangleList.Add(triangle0); intersectionResult.UpperTriangleList.Add(triangle1); if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle2); } } else { intersectionResult.UpperTriangleList.Add(triangle2); if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle0); intersectionResult.UnderTriangleList.Add(triangle1); } } } } //a -c else { if (plane.GetSegmentPlaneIntersectionPoint(p0, p2, out intersectionPoint1)) { Vector3 barycentricWeight1 = PointBarycentricInTriangle(intersectionPoint1, p0, p1, p2); Vector2 intersectionPointUV1 = GetTrianglePointByBarycentricWeight2D(barycentricWeight1, triangle.UV0, triangle.UV1, triangle.UV2); intersectionResult.IntersectionPointList.Add(intersectionPoint1); Triangle triangle0 = new Triangle(p0, intersectionPoint0, intersectionPoint1, triangle.UV0, intersectionPointUV0, intersectionPointUV1); Triangle triangle1 = new Triangle(intersectionPoint0, p1, p2, intersectionPointUV0, triangle.UV1, triangle.UV2); Triangle triangle2 = new Triangle(intersectionPoint1, intersectionPoint0, p2, intersectionPointUV1, intersectionPointUV0, triangle.UV2); if (p0SideOfPlane == SideOfPlane.UP) { intersectionResult.UpperTriangleList.Add(triangle0); if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle1); intersectionResult.UnderTriangleList.Add(triangle2); } } else { intersectionResult.UpperTriangleList.Add(triangle1); intersectionResult.UpperTriangleList.Add(triangle2); if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle0); } } } } } //a-c b -c else if (plane.GetSegmentPlaneIntersectionPoint(p0, p2, out intersectionPoint0) && plane.GetSegmentPlaneIntersectionPoint(p1, p2, out intersectionPoint1)) { Vector3 barycentricWeight0 = PointBarycentricInTriangle(intersectionPoint0, p0, p1, p2); Vector2 intersectionPointUV0 = GetTrianglePointByBarycentricWeight2D(barycentricWeight0, triangle.UV0, triangle.UV1, triangle.UV2); Vector3 barycentricWeight1 = PointBarycentricInTriangle(intersectionPoint1, p0, p1, p2); Vector2 intersectionPointUV1 = GetTrianglePointByBarycentricWeight2D(barycentricWeight1, triangle.UV0, triangle.UV1, triangle.UV2); intersectionResult.IntersectionPointList.Add(intersectionPoint0); intersectionResult.IntersectionPointList.Add(intersectionPoint1); Triangle triangle0 = new Triangle(intersectionPoint0, p0, intersectionPoint1, intersectionPointUV0, triangle.UV0, intersectionPointUV1); Triangle triangle1 = new Triangle(p0, p1, intersectionPoint1, triangle.UV0, triangle.UV1, intersectionPointUV1); Triangle triangle2 = new Triangle(intersectionPoint0, intersectionPoint1, p2, intersectionPointUV0, intersectionPointUV1, triangle.UV2); if (p2SideOfPlane == SideOfPlane.UP) { intersectionResult.UpperTriangleList.Add(triangle2); if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle0); intersectionResult.UnderTriangleList.Add(triangle1); } } else { intersectionResult.UpperTriangleList.Add(triangle0); intersectionResult.UpperTriangleList.Add(triangle1); if (includePlaneBack) { intersectionResult.UnderTriangleList.Add(triangle2); } } } return(intersectionResult); }