private static TriIntersections CalculateIntersections(Vector3[] meshVertices, int[] meshTriangles, Vector3[] meshNormals, int triStartIndex, Vector3 cutStartObjectSpace, Vector3 cutNormal, bool log) { var result = new TriIntersections(); var indexA = meshTriangles[triStartIndex]; var indexB = meshTriangles[triStartIndex + 1]; var indexC = meshTriangles[triStartIndex + 2]; var pointA = meshVertices[indexA]; var pointB = meshVertices[indexB]; var pointC = meshVertices[indexC]; // It doesn't really matter where the origin is, the point is that // it's a point on the plane. I think. So this could be an optimization. var cutPlaneOrigin = cutStartObjectSpace; var intersectsAB = TryIntersect(pointA, pointB, cutPlaneOrigin, cutNormal, log, ref result.Iab); var intersectsBC = TryIntersect(pointB, pointC, cutPlaneOrigin, cutNormal, log, ref result.Ibc); var intersectsCA = TryIntersect(pointC, pointA, cutPlaneOrigin, cutNormal, log, ref result.Ica); var intersectCount = 0; if (intersectsAB) { intersectCount++; } if (intersectsBC) { intersectCount++; } if (intersectsCA) { intersectCount++; } if (intersectCount == 2) { if (intersectsAB && intersectsBC) { result.type = CutType.ABBC; } else if (intersectsAB && intersectsCA) { result.type = CutType.ABCA; } else { result.type = CutType.BCCA; } result.A = pointA; result.B = pointB; result.C = pointC; result.normalA = meshNormals[indexA]; result.normalB = meshNormals[indexB]; result.normalC = meshNormals[indexC]; //TODO: actually weigh-blend the normals depending on where the cut is result.normalIAB = (result.normalA + result.normalB) / 2f; result.normalIBC = (result.normalB + result.normalC) / 2f; result.normalICA = (result.normalC + result.normalA) / 2f; } return(result); }
private static void CutTriangleAndCopyVertsAndNormals(Mesh mesh, TriIntersections cut, Vector3 cutStartPos, Vector3 cutNormal, List <Vector3> vertsAbove, List <Vector3> normsAbove, List <Vector3> vertsBelow, List <Vector3> normsBelow, List <Edge> cutSurfaceEdges, bool log) { switch (cut.type) { case CutType.ABCA: { var isSmallPieceAboveCut = Vector3.Dot(cutNormal, cut.A - cutStartPos) > 0f; List <Vector3> smallPieceVerts = isSmallPieceAboveCut ? vertsAbove : vertsBelow; List <Vector3> smallPieceNorms = isSmallPieceAboveCut ? normsAbove : normsBelow; List <Vector3> bigPieceVerts = isSmallPieceAboveCut ? vertsBelow : vertsAbove; List <Vector3> bigPieceNorms = isSmallPieceAboveCut ? normsBelow : normsAbove; smallPieceVerts.Add(cut.A); smallPieceVerts.Add(cut.Iab); smallPieceVerts.Add(cut.Ica); smallPieceNorms.Add(cut.normalA); smallPieceNorms.Add(cut.normalIAB); smallPieceNorms.Add(cut.normalICA); bigPieceVerts.Add(cut.C); bigPieceVerts.Add(cut.Ica); bigPieceVerts.Add(cut.Iab); bigPieceVerts.Add(cut.C); bigPieceVerts.Add(cut.Iab); bigPieceVerts.Add(cut.B); bigPieceNorms.Add(cut.normalC); bigPieceNorms.Add(cut.normalICA); bigPieceNorms.Add(cut.normalIAB); bigPieceNorms.Add(cut.normalC); bigPieceNorms.Add(cut.normalIAB); bigPieceNorms.Add(cut.normalB); if (!isSmallPieceAboveCut) { cutSurfaceEdges.Add(new Edge(cut.Iab, cut.Ica)); } else { cutSurfaceEdges.Add(new Edge(cut.Ica, cut.Iab)); } break; } case CutType.ABBC: { var isSmallPieceAboveCut = Vector3.Dot(cutNormal, cut.B - cutStartPos) > 0f; List <Vector3> smallPieceVerts = isSmallPieceAboveCut ? vertsAbove : vertsBelow; List <Vector3> smallPieceNorms = isSmallPieceAboveCut ? normsAbove : normsBelow; List <Vector3> bigPieceVerts = isSmallPieceAboveCut ? vertsBelow : vertsAbove; List <Vector3> bigPieceNorms = isSmallPieceAboveCut ? normsBelow : normsAbove; smallPieceVerts.Add(cut.B); smallPieceVerts.Add(cut.Ibc); smallPieceVerts.Add(cut.Iab); smallPieceNorms.Add(cut.normalB); smallPieceNorms.Add(cut.normalIBC); smallPieceNorms.Add(cut.normalIAB); bigPieceVerts.Add(cut.A); bigPieceVerts.Add(cut.Iab); bigPieceVerts.Add(cut.Ibc); bigPieceVerts.Add(cut.A); bigPieceVerts.Add(cut.Ibc); bigPieceVerts.Add(cut.C); bigPieceNorms.Add(cut.normalA); bigPieceNorms.Add(cut.normalIAB); bigPieceNorms.Add(cut.normalIBC); bigPieceNorms.Add(cut.normalA); bigPieceNorms.Add(cut.normalIBC); bigPieceNorms.Add(cut.normalC); if (!isSmallPieceAboveCut) { cutSurfaceEdges.Add(new Edge(cut.Ibc, cut.Iab)); } else { cutSurfaceEdges.Add(new Edge(cut.Iab, cut.Ibc)); } break; } case CutType.BCCA: { var isSmallPieceAboveCut = Vector3.Dot(cutNormal, cut.C - cutStartPos) > 0f; List <Vector3> smallPieceVerts = isSmallPieceAboveCut ? vertsAbove : vertsBelow; List <Vector3> smallPieceNorms = isSmallPieceAboveCut ? normsAbove : normsBelow; List <Vector3> bigPieceVerts = isSmallPieceAboveCut ? vertsBelow : vertsAbove; List <Vector3> bigPieceNorms = isSmallPieceAboveCut ? normsBelow : normsAbove; smallPieceVerts.Add(cut.C); smallPieceVerts.Add(cut.Ica); smallPieceVerts.Add(cut.Ibc); smallPieceNorms.Add(cut.normalC); smallPieceNorms.Add(cut.normalICA); smallPieceNorms.Add(cut.normalIBC); bigPieceVerts.Add(cut.B); bigPieceVerts.Add(cut.Ibc); bigPieceVerts.Add(cut.Ica); bigPieceVerts.Add(cut.B); bigPieceVerts.Add(cut.Ica); bigPieceVerts.Add(cut.A); bigPieceNorms.Add(cut.normalB); bigPieceNorms.Add(cut.normalIBC); bigPieceNorms.Add(cut.normalICA); bigPieceNorms.Add(cut.normalB); bigPieceNorms.Add(cut.normalICA); bigPieceNorms.Add(cut.normalA); if (!isSmallPieceAboveCut) { cutSurfaceEdges.Add(new Edge(cut.Ica, cut.Ibc)); } else { cutSurfaceEdges.Add(new Edge(cut.Ibc, cut.Ica)); } break; } default: break; } }