/// <summary> /// Append an tetra part to this. /// </summary> public void Append(TetraPart t) { tetrahedra.AddRange(t.tetrahedra); int i = triangles.Count; triangles.AddRange(t.triangles); vertices.AddRange(t.vertices); uvs.AddRange(t.uvs); for (int j = i; j < triangles.Count; j++) { triangles[j] += i; } }
public void SplitSelf() { TetraPart newPart = new TetraPart(); foreach (var t in tetrahedra) { var v1 = t.tetra[0]; var v2 = t.tetra[1]; var v3 = t.tetra[2]; var v4 = t.tetra[3]; var mid12 = (v1 + v2) / 2; var mid13 = (v1 + v3) / 2; var mid14 = (v1 + v4) / 2; var mid23 = (v2 + v3) / 2; var mid24 = (v2 + v4) / 2; var mid34 = (v3 + v4) / 2; newPart.PushBackTetra(new List <Vector3> { v1, mid12, mid13, mid14 }); newPart.PushBackTetra(new List <Vector3> { v2, mid12, mid23, mid24 }); newPart.PushBackTetra(new List <Vector3> { v3, mid13, mid34, mid23 }); newPart.PushBackPyramid(new List <Vector3> { mid13, mid12, mid23, mid14, mid34 }); newPart.PushBackTriPrism(new List <Vector3> { mid14, mid12, mid34, mid23, mid24, v4 }); } tetrahedra = newPart.tetrahedra; triangles = newPart.triangles; uvs = newPart.uvs; vertices = newPart.vertices; }
/// <summary> /// Split a tetrahedron to two tetra parts (fragments). You can invoke TetraPart.Append to merge these fragments. /// </summary> /// <param name="plane"></param> /// <param name="part1"></param> /// <param name="part2"></param> public void Split(Plane plane, out TetraPart part1, out TetraPart part2) { part1 = new TetraPart(); part2 = new TetraPart(); Vector3 P = plane.point; Vector3 normal = plane.normal; List <Vector3> intersections = new List <Vector3>(); Vector3 intersection; int[] segments = { 0, 1, 0, 2, 0, 3, 1, 2, 1, 3, 2, 3 }; for (int j = 0; j < 6; j++) { Vector3 vertex1 = tetra[segments[2 * j]]; Vector3 vertex2 = tetra[segments[2 * j + 1]]; if (ToolFunction.IntersectionForSegmentWithPlane(vertex1, vertex2, P, normal, out intersection)) { intersections.Add(intersection); } } switch (intersections.Count) { case 0: // no intersections. Ignore. part1.PushBackTetra(tetra); return; case 1: intersection = intersections[0]; // 1 intersection (not including two vertices) int pindex = 0, nindex = 0; List <int> remains = new List <int>(); for (int i = 0; i < 4; i++) { Vector3 v = tetra[i]; if (Vector3.Dot(v - intersection, normal) > 0) { pindex = i; } else if (Vector3.Dot(v - intersection, normal) < 0) { nindex = i; } else { remains.Add(i); } } part1.PushBackTetra(new List <Vector3> { tetra[pindex], tetra[remains[0]], tetra[remains[1]], intersection }); part2.PushBackTetra(new List <Vector3> { tetra[nindex], tetra[remains[0]], tetra[remains[1]], intersection }); break; case 2: intersection = intersections[0]; List <int> nindices = new List <int>(); List <int> pindices = new List <int>(); int remainIndex = 0; for (int i = 0; i < 4; i++) { Vector3 v = tetra[i]; if (Vector3.Dot(v - intersection, normal) > 0) { pindices.Add(i); } else if (Vector3.Dot(v - intersection, normal) < 0) { nindices.Add(i); } else { remainIndex = i; } } if (pindices.Count == 2) { part1.PushBackPyramid(new List <Vector3> { tetra[remainIndex], intersections[0], intersections[1], tetra[pindices[0]], tetra[pindices[1]] }); part2.PushBackTetra(new List <Vector3> { tetra[remainIndex], intersections[0], intersections[1], tetra[nindices[0]] }); } else { part2.PushBackPyramid(new List <Vector3> { tetra[remainIndex], intersections[0], intersections[1], tetra[nindices[0]], tetra[nindices[1]] }); part1.PushBackTetra(new List <Vector3> { tetra[remainIndex], intersections[0], intersections[1], tetra[pindices[0]] }); } break; case 3: intersection = intersections[0]; nindices = new List <int>(); pindices = new List <int>(); for (int i = 0; i < 4; i++) { Vector3 v = tetra[i]; if (Vector3.Dot(v - intersection, normal) > 0) { pindices.Add(i); } else if (Vector3.Dot(v - intersection, normal) < 0) { nindices.Add(i); } } if (pindices.Count == 3) { part1.PushBackTriPrism(new List <Vector3> { intersections[0], intersections[1], intersections[2], tetra[pindices[0]], tetra[pindices[1]], tetra[pindices[2]] }); part2.PushBackTetra(new List <Vector3> { intersections[0], intersections[1], intersections[2], tetra[nindices[0]] }); } else { part2.PushBackTriPrism(new List <Vector3> { intersections[0], intersections[1], intersections[2], tetra[nindices[0]], tetra[nindices[1]], tetra[nindices[2]] }); part1.PushBackTetra(new List <Vector3> { intersections[0], intersections[1], intersections[2], tetra[pindices[0]] }); } break; case 4: intersection = intersections[0]; nindices = new List <int>(); pindices = new List <int>(); for (int i = 0; i < 4; i++) { Vector3 v = tetra[i]; if (Vector3.Dot(v - intersection, normal) > 0) { pindices.Add(i); } else { nindices.Add(i); } } part1.PushBackTriPrism(new List <Vector3> { intersections[0], intersections[1], intersections[2], intersections[3], tetra[pindices[0]], tetra[pindices[1]] }); part2.PushBackTriPrism(new List <Vector3> { intersections[0], intersections[1], intersections[2], intersections[3], tetra[nindices[0]], tetra[nindices[1]] }); break; } }
private void Awake() { tetraPart = new TetraPart(); }