public void Split(Vector3 localPlaneNormal, Vector3 localPlaneDir, Vector3 localPointStart, Vector3 localPointEnd, int faceStart, int faceEnd, bool fillCut) { Debug.LogFormat("Split Point {0} {1} Face {2} {3} Normal {4}", localPointStart, localPointEnd, faceStart, faceEnd, localPlaneNormal); Clear(); planeNormal = localPlaneNormal; planeDir = localPlaneDir; indexStart = faceStart; indexEnd = faceEnd; pointStart = localPointStart; pointEnd = localPointEnd; // 剪切范围 Vector3 center = (pointEnd + pointStart) / 2f; if (localPlaneNormal == Vector3.zero) { localPlaneNormal = Vector3.up; } bool[] vertexAbovePlane = new bool[vertices.Count]; for (int i = 0; i < vertices.Count; i++) { Vector3 vertex = vertices[i]; bool abovePlane = Vector3.Dot(vertex - pointEnd, localPlaneNormal) >= 0.0f; vertexAbovePlane [i] = abovePlane; } // remove int triangleCount = indices.Count / 3; for (int i = 0; i < triangleCount; i++) { int index0 = indices [i * 3 + 0]; int index1 = indices [i * 3 + 1]; int index2 = indices [i * 3 + 2]; bool above0 = vertexAbovePlane [index0]; bool above1 = vertexAbovePlane [index1]; bool above2 = vertexAbovePlane [index2]; if ((above0 && above1 && above2) || (!above0 && !above1 && !above2)) { // 保持不变 //Debug.LogFormat(" old {0} {1} {2}", index0, index1, index2); } else { Vector3 v0 = vertices [index0]; Vector3 v1 = vertices [index1]; Vector3 v2 = vertices [index2]; float a1 = Vector3.Dot(v0 - pointEnd, localPlaneNormal); float a2 = Vector3.Dot(v1 - pointEnd, localPlaneNormal); float a3 = Vector3.Dot(v2 - pointEnd, localPlaneNormal); // 切割点在tri上投影 Vector3 fN = Vector3.Cross(v1 - v0, v2 - v0).normalized; Vector3 projS = MathUtils.LineIntersectPlane(fN, v0, planeDir, pointStart); Vector3 projE = MathUtils.LineIntersectPlane(fN, v0, planeDir, pointEnd); bool InS = MathUtils.PointInTriangle(v0, v1, v2, projS); bool InE = MathUtils.PointInTriangle(v0, v1, v2, projE); bool b1 = MathUtils.LineIntersect(v0, v1, projS, projE); bool b2 = MathUtils.LineIntersect(v0, v2, projS, projE); bool b3 = MathUtils.LineIntersect(v1, v2, projS, projE); //Debug.LogFormat ("Face {0} intersection {1} {2} {3}", i, b1, b2, b3); if (!InS && !InE && !b1 && !b2 && !b3) { // 不相交 tri_backlist.Add(i); } else { // 检查到切割范围内? float d0 = MathUtils.PointDistPlane(planeDir, center, v0); float d1 = MathUtils.PointDistPlane(planeDir, center, v1); float d2 = MathUtils.PointDistPlane(planeDir, center, v2); if (d0 > 1 && d1 > 1 && d2 > 1) { tri_backlist.Add(i); } } } } IList <Vector3> cutEdges; AssignTriangles(vertexAbovePlane, localPointStart, localPlaneNormal, out cutEdges); if (fillCut) { cutEdges.Clear(); cutEdges.Add(pointStart); cutEdges.Add(pointStart + planeDir); cutEdges.Add(pointStart + planeDir); cutEdges.Add(pointEnd + planeDir); cutEdges.Add(pointEnd + planeDir); cutEdges.Add(pointEnd); cutEdges.Add(pointEnd); cutEdges.Add(pointStart); FillCutEdges(cutEdges, localPlaneNormal); } // update mesh & mass springs softbody.SetMesh(GetNewMesh(), _vertices1, _vertices2, _tris); }