public bool raycastExternalCheck(shatterTriangle toMeasure, int stopCheck = -1) { Vector3 tPos = (toMeasure.verts[0].pos + toMeasure.verts[1].pos + toMeasure.verts[2].pos) / 3; int intersects = 0; List <shatterVert> ignores = new List <shatterVert>(); shatterVert infinity = new shatterVert(new Vector3(99999, 99999, 99999), new Vector2(0, 0)); shatterVert toMeasureVert = new shatterVert(tPos, new Vector2(0, 0)); if (stopCheck < 0) { stopCheck = triangles.Count; } for (int i = 0; i < stopCheck; i++) { shatterTriangle tri = triangles[i]; shatterVert found = tri.intersect(toMeasureVert, infinity); if (found != null && Vector3.Magnitude(found.pos - tPos) < epsilon) { return(false); } if (found != null && Vector3.Dot(found.pos - tPos, new Vector3(1, 1, 1)) > 0 && getDuplicate(found.pos, ignores) == -1) { intersects += 1; ignores.Add(found); //Debug.Log(found.pos); } } return(intersects % 2 == 0); }
private void considerConnectionTunnel(shatterTriangle t) { if (adjacent.Contains(t)) { return; } adjacent.Add(t); t.adjacent.Add(this); }
private void repairTri1(shatterTriangle triangle, shatterVert inter) { for (int i = 0; i < 3; i++) { if (nonLinear(triangle.verts[i].pos, triangle.verts[(i + 1) % 3].pos, inter.pos)) { shatterTriangle newTri = new shatterTriangle(triangle.verts[i], triangle.verts[(i + 1) % 3], inter, triangle.isSubstrate); newTri.storedIntersects = triangle.storedIntersects; triangles.Add(newTri); } } triangle.cull(); }
private shatterMesh floodGenerateFragment(shatterTriangle first, shatterMesh other, int otherOrigTris) { List <shatterTriangle> newSubstrateTris = new List <shatterTriangle>(); List <shatterTriangle> newCutTris = new List <shatterTriangle>(); Queue <shatterTriangle> flood = new Queue <shatterTriangle>(); flood.Enqueue(first); first.isConsumed = true; bool substrateExternType = first.external; while (flood.Count != 0) { shatterTriangle currentTri = flood.Dequeue(); foreach (shatterTriangle a in currentTri.adjacent) { if (!a.isConsumed && !a.culled) { if (!a.isSubstrate || (a.external == substrateExternType)) { //when leaving cut mesh go into the substrate type you started at (otherwise shouldn't matter) flood.Enqueue(a); a.isConsumed = true; } } } if (currentTri.isSubstrate) { newSubstrateTris.Add(currentTri); } else { newCutTris.Add(currentTri); } } foreach (shatterTriangle ct in newCutTris) { ct.isConsumed = false; } shatterMesh newshatter = generateFragment(newSubstrateTris, newCutTris, substrateExternType); Debug.Log(new Vector2(newSubstrateTris.Count, newCutTris.Count)); Debug.Log(substrateExternType); if (substrateExternType) { return(null); } return(newshatter); }
private void cutTri(shatterTriangle tri, shatterTriangle other) { float parallelMetric = Vector3.Dot(tri.norm, other.norm); if (parallelMetric > 1 - epsilon || parallelMetric < epsilon - 1) { return; } List <shatterVert> intersects = new List <shatterVert>(); for (int i = 0; i < 3; i++) { shatterVert intersect = tri.intersect(other.verts[i], other.verts[(i + 1) % 3]); if (intersect != null && getDuplicate(intersect.pos, intersects) == -1) { int dup = getDuplicate(intersect.pos, tri.storedIntersects); if (dup != -1) { tri.storedIntersects[dup].absorb(intersect); intersect = tri.storedIntersects[dup]; } intersects.Add(intersect); other.storedIntersects.Add(other.portIn(intersect)); } shatterVert intersectOther = other.intersect(tri.verts[i], tri.verts[(i + 1) % 3]); if (intersectOther != null && getDuplicate(intersectOther.pos, intersects) == -1) { shatterVert intersectThis = null; int dup = getDuplicate(intersectOther.pos, tri.storedIntersects); if (dup != -1) { tri.storedIntersects[dup].absorb(intersectOther); intersectThis = tri.storedIntersects[dup]; } else { intersectThis = tri.portIn(intersectOther); } intersects.Add(intersectThis); other.storedIntersects.Add(intersectOther); } } if (intersects.Count != 0) { repairTri(tri, intersects); } }
private void considerConnection(shatterTriangle t, shatterVert v) { if (!adjacent.Contains(t)) { int seenIndex = seenOnce.IndexOf(t); if (seenIndex != -1) { if (!(seenOnceVerts[seenIndex].excludeEdges.Contains(v) || v.excludeEdges.Contains(seenOnceVerts[seenIndex]))) { adjacent.Add(t); t.adjacent.Add(this); } } else { seenOnce.Add(t); seenOnceVerts.Add(v); } } }
private void externalFlood(shatterTriangle first) { Queue <shatterTriangle> flood = new Queue <shatterTriangle>(); flood.Enqueue(first); first.isConsumed = true; while (flood.Count != 0) { shatterTriangle currentTri = flood.Dequeue(); foreach (shatterTriangle a in currentTri.adjacent) { if (!a.isConsumed && !a.culled) { flood.Enqueue(a); a.isConsumed = true; a.external = first.external; } } } }
private void repairTri2(shatterTriangle triangle, List <shatterVert> intersects) { for (int i = 0; i < 3; i++) { if (nonLinear(triangle.verts[i].pos, triangle.verts[(i + 1) % 3].pos, intersects[0].pos)) { shatterTriangle newTri = new shatterTriangle(triangle.verts[i], triangle.verts[(i + 1) % 3], intersects[0], triangle.isSubstrate); if (newTri.containsPlanar(intersects[1].pos)) { repairTri1(newTri, intersects[1]); } else { newTri.storedIntersects = triangle.storedIntersects; triangles.Add(newTri); } } } triangle.cull(); }
private void DEBUGcut(shatterTriangle first) { List <shatterTriangle> newCutTris = new List <shatterTriangle>(); Queue <shatterTriangle> flood = new Queue <shatterTriangle>(); flood.Enqueue(first); first.isConsumed = true; while (flood.Count != 0) { shatterTriangle currentTri = flood.Dequeue(); foreach (shatterTriangle a in currentTri.adjacent) { if (!a.isConsumed && !a.culled) { flood.Enqueue(a); a.isConsumed = true; } } newCutTris.Add(currentTri); } generateFragment(new List <shatterTriangle>(), newCutTris, false); }
private void repairTri(shatterTriangle tri, List <shatterVert> intersects) { if (intersects.Count > 2) { Debug.Log("too many intersections"); foreach (shatterVert i in intersects) { Debug.Log(i.pos); } } int dup, dupCount, origID; dupCount = 0; origID = 0; for (int i = 0; i < intersects.Count; i++) { dup = getDuplicate(intersects[i].pos, tri.verts); if (dup != -1) { tri.verts[dup].absorb(intersects[i]); intersects[i] = tri.verts[dup]; dupCount += 1; continue; } else { origID = i; } //this type of merge just combines verticies the triangles //still need to be updated so we don't touch dupCount dup = getDuplicate(intersects[i].pos, activeCuts); if (dup == -1) { verts.Add(intersects[i]); activeCuts.Add(intersects[i]); } else if (intersects[0] != activeCuts[dup]) { activeCuts[dup].absorb(intersects[i]); intersects[i] = activeCuts[dup]; } } int debugCount = triangles.Count; Debug.Log(intersects.Count); if (intersects.Count == 2) { //Debug.Log(new Vector3(dupCount, intersects[0].excludeEdges.Count, intersects[1].excludeEdges.Count)); intersects[0].excludeEdges.Add(intersects[1]); intersects[1].excludeEdges.Add(intersects[0]); if (dupCount == 0) { repairTri2(tri, intersects); } else if (dupCount == 1) { repairTri1(tri, intersects[origID]); } } /*else if (intersects.Count == 1){ * repairTri1(tri, intersects[0]); * }*/ if (triangles.Count != debugCount) { //Debug Mesh newSubMesh = new Mesh(); List <Vector3> vertsDebug = new List <Vector3>(); List <Vector3> normalsDebug = new List <Vector3>(); List <Vector2> uvDebug = new List <Vector2>(); List <int> trianglesDebug = new List <int>(); int meshNum = 0; foreach (shatterTriangle t in triangles) { if (!t.culled) { foreach (shatterVert v in t.verts) { vertsDebug.Add(v.pos); normalsDebug.Add(t.norm); trianglesDebug.Add(meshNum); uvDebug.Add(v.uv); meshNum += 1; } } } newSubMesh.vertices = vertsDebug.ToArray(); newSubMesh.triangles = trianglesDebug.ToArray(); newSubMesh.normals = normalsDebug.ToArray(); newSubMesh.uv = uvDebug.ToArray(); if (debugTemplate != null && debugTemplate.GetComponent <MeshFilter>() != null) { debugTemplate.GetComponent <MeshFilter>().mesh = newSubMesh; GameObject newSub = GameObject.Instantiate(debugTemplate); } } }