private static void MakeTriangles(Plane _plane, MeshTriangle _triangle, GeneratedMesh _currentSide, List <Vector3> _addedVertices, MeshTriangle currentMeshTriangle, MeshTriangle oppositeMeshTriangle, bool addVertices) { float normalizedDistance; float distance; // Get the distance from the vertex to the intersecting plane, in the direction of a vertex that we know exists on the other side of the intersection // From our original triangle _plane.Raycast(new Ray(currentMeshTriangle.Vertices[0], (oppositeMeshTriangle.Vertices[0] - currentMeshTriangle.Vertices[0]).normalized), out distance); normalizedDistance = distance / (oppositeMeshTriangle.Vertices[0] - currentMeshTriangle.Vertices[0]).magnitude; Vector3 vertLeft = Vector3.Lerp(currentMeshTriangle.Vertices[0], oppositeMeshTriangle.Vertices[0], normalizedDistance); Vector3 normalLeft = Vector3.Lerp(currentMeshTriangle.Normals[0], oppositeMeshTriangle.Normals[0], normalizedDistance); Vector2 uvLeft = Vector2.Lerp(currentMeshTriangle.UVs[0], oppositeMeshTriangle.UVs[0], normalizedDistance); _plane.Raycast(new Ray(currentMeshTriangle.Vertices[1], (oppositeMeshTriangle.Vertices[1] - currentMeshTriangle.Vertices[1]).normalized), out distance); normalizedDistance = distance / (oppositeMeshTriangle.Vertices[1] - currentMeshTriangle.Vertices[1]).magnitude; Vector3 vertRight = Vector3.Lerp(currentMeshTriangle.Vertices[1], oppositeMeshTriangle.Vertices[1], normalizedDistance); // Since we call this method twice, prevent adding new vertices twice if (addVertices) { _addedVertices.Add(vertLeft); _addedVertices.Add(vertRight); } Vector3 normalRight = Vector3.Lerp(currentMeshTriangle.Normals[1], oppositeMeshTriangle.Normals[1], normalizedDistance); Vector3 uvRight = Vector2.Lerp(currentMeshTriangle.UVs[1], oppositeMeshTriangle.UVs[1], normalizedDistance); MeshTriangle currentTriangle; Vector3[] updatedVertices = new Vector3[] { currentMeshTriangle.Vertices[0], vertLeft, vertRight }; Vector3[] updatedNormals = new Vector3[] { currentMeshTriangle.Normals[0], normalLeft, normalRight }; Vector2[] updatedUVs = new Vector2[] { currentMeshTriangle.UVs[0], uvLeft, uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangle(currentTriangle); } _currentSide.AddTriangle(currentTriangle); } updatedVertices = new Vector3[] { currentMeshTriangle.Vertices[0], currentMeshTriangle.Vertices[1], vertRight }; updatedNormals = new Vector3[] { currentMeshTriangle.Normals[0], currentMeshTriangle.Normals[1], normalRight }; updatedUVs = new Vector2[] { currentMeshTriangle.UVs[0], currentMeshTriangle.UVs[1], uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangle(currentTriangle); } _currentSide.AddTriangle(currentTriangle); } }
public static void Cut(GameObject oGO, Vector3 _contactPoint, Vector3 _direction, Material _cutMaterial = null, bool fill = true, bool _addRigidbody = false) { if (currentCut) { return; } currentCut = true; Plane plane = new Plane(oGO.transform.InverseTransformDirection(-_direction), oGO.transform.InverseTransformPoint(_contactPoint)); originalMesh = oGO.GetComponent <MeshFilter>().mesh; List <Vector3> addedVertices = new List <Vector3>(); GeneratedMesh leftMesh = new GeneratedMesh(); GeneratedMesh rightMesh = new GeneratedMesh(); int[] submeshIndices; int triangleIndexA, triangleIndexB, triangleIndexC; for (int i = 0; i < originalMesh.subMeshCount; i++) { submeshIndices = originalMesh.GetTriangles(i); for (int j = 0; j < originalMesh.subMeshCount; j += 3) { triangleIndexA = submeshIndices[j]; triangleIndexB = submeshIndices[j + 1]; triangleIndexC = submeshIndices[j + 2]; MeshTriangle currentTriangle = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i); bool triangleALeftSide = plane.GetSide(originalMesh.vertices[triangleIndexA]); bool triangleBLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexB]); bool triangleCLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexC]); if (triangleALeftSide && triangleBLeftSide && triangleCLeftSide) { leftMesh.AddTriangle(currentTriangle); } else if (!triangleALeftSide && !triangleBLeftSide && !triangleCLeftSide) { rightMesh.AddTriangle(currentTriangle); } else { } } } }
private static void Fill(List <Vector3> _vertices, Plane plane, GeneratedMesh leftMesh, GeneratedMesh rightMesh) { Vector3 centerPosition = Vector3.zero; for (int i = 0; i < _vertices.Count; i++) { centerPosition += _vertices[i]; } centerPosition /= _vertices.Count; Vector3 up = plane.normal; Vector3 left = Vector3.Cross(plane.normal, plane.normal); Vector3 displacement = Vector3.zero; Vector2 uv1, uv2; for (int i = 0; i < _vertices.Count; i++) { displacement = _vertices[i] - centerPosition; uv1 = new Vector2(0.5f + Vector3.Dot(displacement, left), 0.5f + Vector3.Dot(displacement, up)); displacement = _vertices[(i + 1) % _vertices.Count] - centerPosition; uv2 = new Vector2(0.5f + Vector3.Dot(displacement, left), 0.5f + Vector3.Dot(displacement, up)); Vector3[] vertices = new Vector3[] { _vertices[i], _vertices[(i + 1) % _vertices.Count], centerPosition }; Vector3[] normals = new Vector3[] { -plane.normal, -plane.normal, -plane.normal }; Vector2[] uvs = new Vector2[] { uv1, uv2, new Vector2(0.5f, 0.5f) }; MeshTriangle currenTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount - 1); if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0) { FlipTriangle(currenTriangle); } leftMesh.AddTriangle(currenTriangle); normals = new Vector3[] { plane.normal, plane.normal, plane.normal }; currenTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount - 1); if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0) { FlipTriangle(currenTriangle); } rightMesh.AddTriangle(currenTriangle); } }
public static void Cut(GameObject _originalGameObject, Vector3 _contactPoint, Vector3 _direction, Material _cutMaterial = null, bool fill = true, bool _addRigidbody = false) { if (currentlyCutting) { return; } currentlyCutting = true; //We are instantiating a plane through our initial object to seperate the left and right side from each other Plane plane = new Plane(_originalGameObject.transform.InverseTransformDirection(-_direction), _originalGameObject.transform.InverseTransformPoint(_contactPoint)); originalMesh = _originalGameObject.GetComponent <MeshFilter>().mesh; List <Vector3> addedVertices = new List <Vector3>(); //We are getting two new generated meshes for our left and right side GeneratedMesh leftMesh = new GeneratedMesh(); GeneratedMesh rightMesh = new GeneratedMesh(); //Some meshes use different submeshes to have multiple materials attached to them //in an early iteration I had an extra script to turn everything into one mesh to make my life a little easier //however the result was not great because I could only slice objects that had one single material int[] submeshIndices; int triangleIndexA, triangleIndexB, triangleIndexC; for (int i = 0; i < originalMesh.subMeshCount; i++) { submeshIndices = originalMesh.GetTriangles(i); //We are now going through the submesh indices as triangles to determine on what side of the mesh they are. for (int j = 0; j < submeshIndices.Length; j += 3) { triangleIndexA = submeshIndices[j]; triangleIndexB = submeshIndices[j + 1]; triangleIndexC = submeshIndices[j + 2]; MeshTriangle currentTriangle = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i); //We are now using the plane.getside function to see on which side of the cut our trianle is situated //or if it might be cut through bool triangleALeftSide = plane.GetSide(originalMesh.vertices[triangleIndexA]); bool triangleBLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexB]); bool triangleCLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexC]); //All three vertices are on the left side of the plane, so they need to be added to the left //mesh if (triangleALeftSide && triangleBLeftSide && triangleCLeftSide) { leftMesh.AddTriangle(currentTriangle); } //All three vertices are on the right side of the mesh. else if (!triangleALeftSide && !triangleBLeftSide && !triangleCLeftSide) { rightMesh.AddTriangle(currentTriangle); } else { CutTriangle(plane, currentTriangle, triangleALeftSide, triangleBLeftSide, triangleCLeftSide, leftMesh, rightMesh, addedVertices); } } } //Filling our cut if (fill == true) { FillCut(addedVertices, plane, leftMesh, rightMesh); } // Generer de to nye meshes Mesh finishedLeftMesh = leftMesh.GetGeneratedMesh(); Mesh finishedRightMesh = rightMesh.GetGeneratedMesh(); Debug.Log(finishedLeftMesh); Destroy(_originalGameObject.GetComponent <MeshCollider>()); MeshCollider newCollider = _originalGameObject.AddComponent <MeshCollider>(); newCollider.sharedMesh = finishedLeftMesh; newCollider.convex = true; // Materials Material[] mats = new Material[finishedLeftMesh.subMeshCount]; for (int i = 0; i < finishedLeftMesh.subMeshCount; i++) { mats[i] = _originalGameObject.GetComponent <MeshRenderer>().material; } _originalGameObject.GetComponent <MeshRenderer>().materials = mats; // Tildel mesh _originalGameObject.GetComponent <MeshFilter>().mesh = finishedLeftMesh; // Når meshet er tillagt, beregner vi den nye masse. _originalGameObject.GetComponent <Rigidbody>().mass = VolumeAndMass.MassOfMesh(finishedLeftMesh, _originalGameObject.GetComponent <Food>().density); // Opdater center of mass _originalGameObject.GetComponent <Rigidbody>().centerOfMass = _originalGameObject.GetComponent <MeshFilter>().mesh.bounds.center; GameObject rightGO = new GameObject(); rightGO.transform.position = _originalGameObject.transform.position + (_direction * .007f); rightGO.transform.rotation = _originalGameObject.transform.rotation; rightGO.transform.localScale = _originalGameObject.transform.localScale; rightGO.AddComponent <MeshRenderer>(); // Materials mats = new Material[finishedRightMesh.subMeshCount]; for (int i = 0; i < finishedRightMesh.subMeshCount; i++) { mats[i] = _originalGameObject.GetComponent <MeshRenderer>().material; } rightGO.GetComponent <MeshRenderer>().materials = mats; // Tildel mesh rightGO.AddComponent <MeshFilter>().mesh = finishedRightMesh; // Tildel rigidbody if (rightGO.GetComponent <Rigidbody>() == null) { rightGO.AddComponent <Rigidbody>(); } // Når meshet er tillagt, beregner vi den nye masse med samme densitet som det originale objekt (selvfølgelig). rightGO.GetComponent <Rigidbody>().mass = VolumeAndMass.MassOfMesh(finishedRightMesh, _originalGameObject.GetComponent <Food>().density); // Opdater center of mass rightGO.GetComponent <Rigidbody>().centerOfMass = rightGO.GetComponent <MeshFilter>().mesh.bounds.center; rightGO.AddComponent <MeshCollider>().sharedMesh = finishedRightMesh; rightGO.GetComponent <MeshCollider>().convex = true; rightGO.tag = _originalGameObject.tag; // Opdater scripts Food newFoodScript = rightGO.AddComponent <Food>(); Food originFoodScript = _originalGameObject.GetComponent <Food>(); UpdateFoodScript(newFoodScript, originFoodScript); rightGO.AddComponent <Throwable>(); currentlyCutting = false; }
public static void Cut(GameObject _originalGameObject, Vector3 _contactPoint, Vector3 _direction, Material _cutMaterial = null, bool _fill = true, bool _addRigidbody = false) { if (currentlyCutting) { return; } currentlyCutting = true; Plane plane = new Plane(_originalGameObject.transform.InverseTransformDirection(-_direction), _originalGameObject.transform.InverseTransformDirection(_contactPoint)); originalMesh = _originalGameObject.GetComponent <MeshFilter>().mesh; List <Vector3> addedVertices = new List <Vector3>(); GeneratedMesh leftMesh = new GeneratedMesh(); GeneratedMesh rightMesh = new GeneratedMesh(); int[] submeshIndices; int triangleIndexA, triangleIndexB, triangleIndexC; for (int i = 0; i < originalMesh.subMeshCount; ++i) { submeshIndices = originalMesh.GetTriangles(i); for (int j = 0; j < submeshIndices.Length; j += 3) { triangleIndexA = submeshIndices[j]; triangleIndexB = submeshIndices[j + 1]; triangleIndexC = submeshIndices[j + 2]; MeshTriangle currentTriangle = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i); bool triangleALeftSide = plane.GetSide(originalMesh.vertices[triangleIndexA]); bool triangleBLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexB]); bool triangleCLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexC]); if (triangleALeftSide && triangleBLeftSide && triangleCLeftSide) { leftMesh.AddTriangle(currentTriangle); } else if (!triangleALeftSide && !triangleBLeftSide && !triangleCLeftSide) { rightMesh.AddTriangle(currentTriangle); } else { CutTriangle(plane, currentTriangle, triangleALeftSide, triangleBLeftSide, triangleCLeftSide, leftMesh, rightMesh, addedVertices); } } } if (_fill) { FillCut(addedVertices, plane, leftMesh, rightMesh); } originalMesh.Clear(); originalMesh.vertices = leftMesh.Vertices.ToArray(); originalMesh.normals = leftMesh.Normals.ToArray(); originalMesh.uv = leftMesh.UVs.ToArray(); originalMesh.triangles = leftMesh.Indices(0); GameObject secondGameObject = GameObject.Instantiate(_originalGameObject); Mesh secondMesh = secondGameObject.GetComponent <MeshFilter>().mesh; secondMesh.vertices = rightMesh.Vertices.ToArray(); secondMesh.normals = rightMesh.Normals.ToArray(); secondMesh.uv = rightMesh.UVs.ToArray(); secondMesh.triangles = rightMesh.Indices(0); Component.Destroy(_originalGameObject.GetComponent <SphereCollider>()); Component.Destroy(secondGameObject.GetComponent <SphereCollider>()); _originalGameObject.AddComponent <MeshCollider>(); secondGameObject.AddComponent <MeshCollider>(); _originalGameObject.GetComponent <MeshCollider>().convex = true; secondGameObject.GetComponent <MeshCollider>().convex = true; currentlyCutting = false; }
private static void CutTriangle(Plane _plane, MeshTriangle meshTri, bool tALS, bool TBLS, bool TCLS, GeneratedMesh lSide, GeneratedMesh rSide, List <Vector3> addedVert) { List <bool> leftSide = new List <bool>(); leftSide.Add(tALS); leftSide.Add(TBLS); leftSide.Add(TCLS); MeshTriangle leftMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], meshTri.SMIndex); MeshTriangle rightMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], meshTri.SMIndex); bool left = false; bool right = false; for (int i = 0; i < 3; i++) { if (leftSide[i]) { if (!left) { left = true; leftMeshTriangle.Vert[0] = meshTri.Vert[i]; leftMeshTriangle.Vert[1] = leftMeshTriangle.Vert[0]; leftMeshTriangle.UV[0] = meshTri.UV[i]; leftMeshTriangle.UV[1] = leftMeshTriangle.UV[0]; leftMeshTriangle.Norm[0] = meshTri.Norm[i]; leftMeshTriangle.Norm[1] = leftMeshTriangle.Norm[0]; } else { leftMeshTriangle.Vert[1] = meshTri.Vert[i]; leftMeshTriangle.Norm[1] = meshTri.Vert[i]; leftMeshTriangle.UV[1] = meshTri.Vert[i]; } } else { if (!right) { right = true; rightMeshTriangle.Vert[0] = meshTri.Vert[i]; rightMeshTriangle.Vert[1] = rightMeshTriangle.Vert[0]; rightMeshTriangle.UV[0] = meshTri.UV[i]; rightMeshTriangle.UV[1] = rightMeshTriangle.UV[0]; rightMeshTriangle.Norm[0] = meshTri.Norm[i]; rightMeshTriangle.Norm[1] = rightMeshTriangle.Norm[0]; } else { rightMeshTriangle.Vert[1] = meshTri.Vert[i]; rightMeshTriangle.Norm[1] = meshTri.Vert[i]; rightMeshTriangle.UV[1] = meshTri.Vert[i]; } } } float normalizedDistance; float distance; _plane.Raycast(new Ray(leftMeshTriangle.Vert[0], (rightMeshTriangle.Vert[0] - leftMeshTriangle.Vert[0]).normalized), out distance); normalizedDistance = distance / (rightMeshTriangle.Vert[0] - leftMeshTriangle.Vert[0]).magnitude; Vector3 vertLeft = Vector3.Lerp(leftMeshTriangle.Vert[0], rightMeshTriangle.Vert[0], normalizedDistance); addedVert.Add(vertLeft); Vector3 normalLeft = Vector3.Lerp(leftMeshTriangle.Norm[0], rightMeshTriangle.Norm[0], normalizedDistance); Vector2 uvLeft = Vector2.Lerp(leftMeshTriangle.UV[0], rightMeshTriangle.UV[0], normalizedDistance); _plane.Raycast(new Ray(leftMeshTriangle.Vert[1], (rightMeshTriangle.Vert[1] - leftMeshTriangle.Vert[1]).normalized), out distance); normalizedDistance = distance / (rightMeshTriangle.Vert[1] - leftMeshTriangle.Vert[1]).magnitude; Vector3 vertRight = Vector3.Lerp(leftMeshTriangle.Vert[1], rightMeshTriangle.Vert[1], normalizedDistance); addedVert.Add(vertLeft); Vector3 normalRight = Vector3.Lerp(leftMeshTriangle.Norm[1], rightMeshTriangle.Norm[1], normalizedDistance); Vector2 uvRight = Vector2.Lerp(leftMeshTriangle.UV[1], rightMeshTriangle.UV[1], normalizedDistance); MeshTriangle currentTriangle; Vector3[] updatedVert = new Vector3[] { leftMeshTriangle.Vert[0], vertLeft, vertRight }; Vector3[] updatedNorm = new Vector3[] { leftMeshTriangle.Norm[0], normalLeft, normalRight }; Vector2[] updatedUV = new Vector2[] { leftMeshTriangle.UV[0], uvLeft, uvRight }; currentTriangle = new MeshTriangle(updatedVert, updatedNorm, updatedUV, meshTri.SMIndex); if (updatedVert[0] != updatedVert[1] && updatedVert[0] != updatedVert[2]) { if (Vector3.Dot(Vector3.Cross(updatedVert[1] - updatedVert[0], updatedVert[2] - updatedVert[0]), updatedVert[0]) < 0) { FlipTriangle(currentTriangle); } lSide.AddTriangle(currentTriangle); } updatedVert = new Vector3[] { leftMeshTriangle.Vert[0], leftMeshTriangle.Vert[1], vertRight }; updatedNorm = new Vector3[] { leftMeshTriangle.Norm[0], leftMeshTriangle.Norm[1], normalRight }; updatedUV = new Vector2[] { leftMeshTriangle.UV[0], uvLeft, uvRight }; currentTriangle = new MeshTriangle(updatedVert, updatedNorm, updatedUV, meshTri.SMIndex); if (updatedVert[0] != updatedVert[1] && updatedVert[0] != updatedVert[2]) { if (Vector3.Dot(Vector3.Cross(updatedVert[1] - updatedVert[0], updatedVert[2] - updatedVert[0]), updatedVert[0]) < 0) { FlipTriangle(currentTriangle); } lSide.AddTriangle(currentTriangle); } updatedVert = new Vector3[] { rightMeshTriangle.Vert[0], vertLeft, vertRight }; updatedNorm = new Vector3[] { rightMeshTriangle.Norm[0], normalLeft, normalRight }; updatedUV = new Vector2[] { rightMeshTriangle.UV[0], uvLeft, uvRight }; currentTriangle = new MeshTriangle(updatedVert, updatedNorm, updatedUV, meshTri.SMIndex); if (updatedVert[0] != updatedVert[1] && updatedVert[0] != updatedVert[2]) { if (Vector3.Dot(Vector3.Cross(updatedVert[1] - updatedVert[0], updatedVert[2] - updatedVert[0]), updatedVert[0]) < 0) { FlipTriangle(currentTriangle); } rSide.AddTriangle(currentTriangle); } updatedVert = new Vector3[] { rightMeshTriangle.Vert[0], rightMeshTriangle.Vert[1], vertRight }; updatedNorm = new Vector3[] { rightMeshTriangle.Norm[0], rightMeshTriangle.Norm[1], normalRight }; updatedUV = new Vector2[] { rightMeshTriangle.UV[0], uvLeft, uvRight }; currentTriangle = new MeshTriangle(updatedVert, updatedNorm, updatedUV, meshTri.SMIndex); if (updatedVert[0] != updatedVert[1] && updatedVert[0] != updatedVert[2]) { if (Vector3.Dot(Vector3.Cross(updatedVert[1] - updatedVert[0], updatedVert[2] - updatedVert[0]), updatedVert[0]) < 0) { FlipTriangle(currentTriangle); } rSide.AddTriangle(currentTriangle); } }
private static void Fill(List <Vector3> _vertices, Plane _plane, GeneratedMesh _leftMesh, GeneratedMesh _rightMesh) { Vector3 centerPosition = Vector3.zero; for (int i = 0; i < _vertices.Count; i++) { centerPosition += _vertices[i]; } centerPosition = centerPosition / _vertices.Count; Vector3 up = new Vector3() { x = _plane.normal.x, y = _plane.normal.y, z = _plane.normal.z }; Vector3 left = Vector3.zero; Vector3 displacement = Vector3.zero; Vector2 uv1 = Vector2.zero; Vector2 uv2 = Vector2.zero; for (int i = 0; i < _vertices.Count; i++) { displacement = _vertices[i] - centerPosition; uv1 = new Vector2() { x = .5f + Vector3.Dot(displacement, left), y = .5f + Vector3.Dot(displacement, up) }; displacement = _vertices[(i + 1) % _vertices.Count] - centerPosition; uv2 = new Vector2() { x = .5f + Vector3.Dot(displacement, left), y = .5f + Vector3.Dot(displacement, up) }; Vector3[] vertices = new Vector3[] { _vertices[i], _vertices[(i + 1) % _vertices.Count], centerPosition }; Vector3[] normals = new Vector3[] { -_plane.normal, -_plane.normal, -_plane.normal }; Vector2[] uvs = new Vector2[] { uv1, uv2, new Vector2(0.5f, 0.5f) }; MeshTriangle currentTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount + 1); // Make sure triangle is facing the right way if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0) { FlipTriangle(currentTriangle); } _leftMesh.AddTriangle(currentTriangle); normals = new Vector3[] { _plane.normal, _plane.normal, _plane.normal }; currentTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount + 1); if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0) { FlipTriangle(currentTriangle); } _rightMesh.AddTriangle(currentTriangle); } }
public static void Cut(GameObject originalGameObject, Vector3 contactPoint, Vector3 direction, Material cutMaterial = null, bool fill = true, bool canAddRigidBody = false) { if (IsCurrentlyCutting == true) { return; } IsCurrentlyCutting = true; Plane plane = new Plane((originalGameObject.transform.InverseTransformDirection(-direction)), originalGameObject.transform.InverseTransformPoint(contactPoint)); OriginalMesh = originalGameObject.GetComponentInChildren <MeshFilter>().mesh; List <Vector3> addedVertices = new List <Vector3>(); GeneratedMesh leftMesh = new GeneratedMesh(); GeneratedMesh rightMesh = new GeneratedMesh(); int[] submeshIndices; int triangleIndexA, triangleIndexB, triangleIndexC; for (int i = 0; i < OriginalMesh.subMeshCount; i++) { submeshIndices = OriginalMesh.GetTriangles(i); for (int j = 0; j < submeshIndices.Length; j += 3) { triangleIndexA = submeshIndices[j]; triangleIndexB = submeshIndices[j + 1]; triangleIndexC = submeshIndices[j + 2]; MeshTriangle currentTriangle = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i); bool triangleALeftSide = plane.GetSide(OriginalMesh.vertices[triangleIndexA]); bool triangleBLeftSide = plane.GetSide(OriginalMesh.vertices[triangleIndexB]); bool triangleCLeftSide = plane.GetSide(OriginalMesh.vertices[triangleIndexC]); if (triangleALeftSide && triangleBLeftSide && triangleCLeftSide) { leftMesh.AddTriangle(currentTriangle); } else if (!triangleALeftSide && !triangleBLeftSide && !triangleCLeftSide) { rightMesh.AddTriangle(currentTriangle); } else { CutTriangle(plane, currentTriangle, triangleALeftSide, triangleBLeftSide, triangleCLeftSide, leftMesh, rightMesh, addedVertices); } } } if (fill == true) { FillCut(addedVertices, plane, leftMesh, rightMesh); } Mesh finishedLeftMesh = leftMesh.GetGeneratedMesh(); Mesh finishedRightMesh = rightMesh.GetGeneratedMesh(); originalGameObject.GetComponent <MeshFilter>().mesh = finishedLeftMesh; MeshCollider leftMC = originalGameObject.GetComponent <MeshCollider>(); if (leftMC == null) { originalGameObject.AddComponent <MeshCollider>().sharedMesh = finishedLeftMesh; } originalGameObject.GetComponent <MeshCollider>().convex = true; Material[] mats = new Material[finishedLeftMesh.subMeshCount]; for (int i = 0; i < finishedLeftMesh.subMeshCount; i++) { mats[i] = originalGameObject.GetComponent <MeshRenderer>().material; } originalGameObject.GetComponent <MeshRenderer>().materials = mats; GameObject rightGO = new GameObject(); rightGO.transform.position = originalGameObject.transform.position + (Vector3.up * .05f); rightGO.transform.rotation = originalGameObject.transform.rotation; rightGO.transform.localScale = originalGameObject.transform.localScale; rightGO.AddComponent <MeshRenderer>(); mats = new Material[finishedRightMesh.subMeshCount]; for (int i = 0; i < finishedRightMesh.subMeshCount; i++) { mats[i] = originalGameObject.GetComponent <MeshRenderer>().material; } rightGO.GetComponent <MeshRenderer>().materials = mats; rightGO.AddComponent <MeshFilter>().mesh = finishedRightMesh; MeshCollider rightMC = rightGO.GetComponent <MeshCollider>(); if (rightMC == null) { rightGO.AddComponent <MeshCollider>().sharedMesh = finishedRightMesh; } rightGO.GetComponent <MeshCollider>().convex = true; rightGO.tag = "Cut"; if (canAddRigidBody == true) { Rigidbody rb = rightGO.AddComponent <Rigidbody>(); rb.mass = 10000; rb.drag = 2; } IsCurrentlyCutting = false; }
public static void CutGameobject(GameObject originalGameObject, Vector3 contactPoint, Vector3 direction, bool addRigidbody = false) { if (currentlyCutting) { return; } currentlyCutting = true; originalMesh = originalGameObject.GetComponent <MeshFilter>().mesh; var plane = new Plane(originalGameObject.transform.InverseTransformDirection(direction), originalGameObject.transform.InverseTransformPoint(contactPoint)); var addedVertices = new List <Vector3>(); var leftMesh = new GeneratedMesh(); var rightMesh = new GeneratedMesh(); int[] submeshIndices; int triangleIndexA, triangleIndexB, triangleIndexC; for (int i = 0; i < originalMesh.subMeshCount; i++) { submeshIndices = originalMesh.GetTriangles(i); for (int j = 0; j < submeshIndices.Length; j += 3) { triangleIndexA = submeshIndices[j]; triangleIndexB = submeshIndices[j + 1]; triangleIndexC = submeshIndices[j + 2]; MeshTriangle currentTriangle = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i); bool[] pointsOnLeftSide = new bool [3]; pointsOnLeftSide[0] = plane.GetSide(originalMesh.vertices[triangleIndexA]); pointsOnLeftSide[1] = plane.GetSide(originalMesh.vertices[triangleIndexB]); pointsOnLeftSide[2] = plane.GetSide(originalMesh.vertices[triangleIndexC]); if (pointsOnLeftSide[0] && pointsOnLeftSide[1] && pointsOnLeftSide[2]) { leftMesh.AddTriangle(currentTriangle); } else if (!pointsOnLeftSide[0] && !pointsOnLeftSide[1] && !pointsOnLeftSide[2]) { rightMesh.AddTriangle(currentTriangle); } else { CutTriangle(plane, currentTriangle, pointsOnLeftSide, leftMesh, rightMesh, addedVertices); } } FillCut(addedVertices, plane, leftMesh, rightMesh); GenerateCutterGameobject(originalGameObject, leftMesh, addRigidbody, Vector3.up); GenerateCutterGameobject(originalGameObject, rightMesh, addRigidbody, Vector3.left); currentlyCutting = false; } }
public static GameObject Cut(GameObject _originalGameObject, Vector3 _contactPoint, Vector3 _direction, Material _cutMaterial = null, bool fill = true, bool _addRigigibody = false) { if (currentlyCutting) { return(null); } currentlyCutting = true; // set the cutter relative to victim Plane plane = new Plane(_originalGameObject.transform.InverseTransformDirection(-_direction), _originalGameObject.transform.InverseTransformPoint(_contactPoint)); //get the victims mesh originalMesh = _originalGameObject.GetComponent <MeshFilter>() ? _originalGameObject.GetComponent <MeshFilter>().mesh : _originalGameObject.GetComponent <SkinnedMeshRenderer>().sharedMesh; //List for added vertices List <Vector3> addedVertices = new List <Vector3>(); //Create two new meshes GeneratedMesh leftMesh = new GeneratedMesh(); GeneratedMesh rightMesh = new GeneratedMesh(); int[] submeshIndices; int triangleIndexA, triangleIndexB, triangleIndexC; for (int i = 0; i < originalMesh.subMeshCount; i++) { //Fetches the triangle list for the specified sub-mesh on the victim submeshIndices = originalMesh.GetTriangles(i); for (int j = 0; j < submeshIndices.Length; j += 3) { triangleIndexA = submeshIndices[j]; triangleIndexB = submeshIndices[j + 1]; triangleIndexC = submeshIndices[j + 2]; MeshTriangle currentTriangle = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i); // Get vertices sides bool triangleALeftSide = plane.GetSide(originalMesh.vertices[triangleIndexA]); bool triangleBLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexB]); bool triangleCLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexC]); if (triangleALeftSide && triangleBLeftSide && triangleCLeftSide)// left side { leftMesh.AddTriangle(currentTriangle); } else if (!triangleALeftSide && !triangleBLeftSide && !triangleCLeftSide)// right side { rightMesh.AddTriangle(currentTriangle); } else // Cut the triangle { CutTriangle(plane, currentTriangle, triangleALeftSide, triangleBLeftSide, triangleCLeftSide, leftMesh, rightMesh, addedVertices); } } } // Get Materials to apply to the new objects Material[] mats; if (_originalGameObject.GetComponent <MeshRenderer>()) { mats = _originalGameObject.GetComponent <MeshRenderer>().sharedMaterials; } else { mats = _originalGameObject.GetComponent <SkinnedMeshRenderer>().sharedMaterials; } // if there is a material to fill the cut add it to materials list if (_cutMaterial) { if (mats[mats.Length - 1].name != _cutMaterial.name) { Material[] newmats = new Material[mats.Length + 1]; mats.CopyTo(newmats, 0); newmats[mats.Length] = _cutMaterial; mats = newmats; } } int submeshCount = mats.Length - 1; if (fill) { // fill the opennings FillCut(addedVertices, plane, leftMesh, rightMesh, submeshCount); } //// Left Mesh Mesh left_HalfMesh = leftMesh.GetMesh(); left_HalfMesh.name = "Split Mesh Left"; //// Right Mesh Mesh right_HalfMesh = rightMesh.GetMesh(); right_HalfMesh.name = "Split Mesh Right"; //// assign the game objects if (_originalGameObject.GetComponent <MeshFilter>()) { _originalGameObject.GetComponent <MeshFilter>().mesh = left_HalfMesh; } else { _originalGameObject.GetComponent <SkinnedMeshRenderer>().sharedMesh = left_HalfMesh; } GameObject leftSideObj = _originalGameObject; GameObject rightSideObj = null; if (_originalGameObject.GetComponent <MeshRenderer>()) { rightSideObj = new GameObject("right side", typeof(MeshFilter), typeof(MeshRenderer)); rightSideObj.transform.position = _originalGameObject.transform.position; rightSideObj.transform.rotation = _originalGameObject.transform.rotation; rightSideObj.GetComponent <MeshFilter>().mesh = right_HalfMesh; } else if (_originalGameObject.GetComponent <SkinnedMeshRenderer>()) { rightSideObj = new GameObject("right side"); SkinnedMeshRenderer skinMesh = rightSideObj.AddComponent <SkinnedMeshRenderer>(); rightSideObj.transform.position = _originalGameObject.transform.position; rightSideObj.transform.rotation = _originalGameObject.transform.rotation; skinMesh.sharedMesh = right_HalfMesh; } if (_originalGameObject.transform.parent != null) { rightSideObj.transform.parent = _originalGameObject.transform.parent; } rightSideObj.transform.localScale = _originalGameObject.transform.localScale; //Add rigibody to the new object if (_addRigigibody) { var rigibody = rightSideObj.AddComponent <Rigidbody>(); rigibody = _originalGameObject.GetComponent <Rigidbody>(); } // assign materials if (_originalGameObject.GetComponent <MeshRenderer>()) { leftSideObj.GetComponent <MeshRenderer>().materials = mats; rightSideObj.GetComponent <MeshRenderer>().materials = mats; } else if (_originalGameObject.GetComponent <SkinnedMeshRenderer>()) { leftSideObj.GetComponent <SkinnedMeshRenderer>().materials = mats; rightSideObj.GetComponent <SkinnedMeshRenderer>().materials = mats; } return(rightSideObj); }
private static void CutTriangle(Plane plane, MeshTriangle triangle, bool [] pointsOnLeftSide, GeneratedMesh leftMesh, GeneratedMesh rightMesh, List <Vector3> addedVertices) { MeshTriangle leftMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], triangle.SubmeshIndices); MeshTriangle rightMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], triangle.SubmeshIndices); bool left = false; bool right = false; for (int i = 0; i < 3; i++) { if (pointsOnLeftSide[i]) { if (!left) { left = true; leftMeshTriangle.Vertices[0] = leftMeshTriangle.Vertices[1] = triangle.Vertices[i]; leftMeshTriangle.Uvs[0] = leftMeshTriangle.Uvs[1] = triangle.Uvs[i]; leftMeshTriangle.Normals[0] = leftMeshTriangle.Normals[1] = triangle.Normals[i]; } else { leftMeshTriangle.Vertices[1] = triangle.Vertices[i]; leftMeshTriangle.Uvs[1] = triangle.Uvs[i]; leftMeshTriangle.Normals[1] = triangle.Normals[i]; } } else { if (!right) { right = true; rightMeshTriangle.Vertices[0] = rightMeshTriangle.Vertices[1] = triangle.Vertices[i]; rightMeshTriangle.Uvs[0] = rightMeshTriangle.Uvs[1] = triangle.Uvs[i]; rightMeshTriangle.Normals[0] = rightMeshTriangle.Normals[1] = triangle.Normals[i]; } else { rightMeshTriangle.Vertices[1] = triangle.Vertices[i]; rightMeshTriangle.Uvs[1] = triangle.Uvs[i]; rightMeshTriangle.Normals[1] = triangle.Normals[i]; } } } // можно переписать черех цикл и сократить количество кода в 2 раза и вынести в новую функцию добавление новой вершины float normalizedDistance; float distance; plane.Raycast(new Ray(leftMeshTriangle.Vertices[0], (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).normalized), out distance); normalizedDistance = distance / (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).magnitude; Vector3 vertLeft = Vector3.Lerp(leftMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[0], normalizedDistance); addedVertices.Add(vertLeft); Vector3 normalLeft = Vector3.Lerp(leftMeshTriangle.Normals[0], rightMeshTriangle.Normals[0], normalizedDistance); Vector3 uvLeft = Vector3.Lerp(leftMeshTriangle.Uvs[0], rightMeshTriangle.Uvs[0], normalizedDistance); plane.Raycast(new Ray(leftMeshTriangle.Vertices[1], (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).normalized), out distance); normalizedDistance = distance / (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).magnitude; Vector3 vertRight = Vector3.Lerp(leftMeshTriangle.Vertices[1], rightMeshTriangle.Vertices[1], normalizedDistance); addedVertices.Add(vertRight); Vector3 normalRight = Vector3.Lerp(leftMeshTriangle.Normals[1], rightMeshTriangle.Normals[1], normalizedDistance); Vector3 uvRight = Vector3.Lerp(leftMeshTriangle.Uvs[1], rightMeshTriangle.Uvs[1], normalizedDistance); // до сюда // можно сократить код в 4 раза и вынести в новую функцию Vector3[] updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], vertLeft, vertRight }; Vector3[] updatedNormals = new Vector3[] { leftMeshTriangle.Normals[0], normalLeft, normalRight }; Vector2[] updatedUvs = new Vector2[] { leftMeshTriangle.Uvs[0], uvLeft, uvRight }; MeshTriangle currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, triangle.SubmeshIndices); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangle(currentTriangle); } leftMesh.AddTriangle(currentTriangle); } updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], leftMeshTriangle.Vertices[1], vertRight }; updatedNormals = new Vector3[] { leftMeshTriangle.Normals[0], leftMeshTriangle.Normals[1], normalRight }; updatedUvs = new Vector2[] { leftMeshTriangle.Uvs[0], leftMeshTriangle.Uvs[1], uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, triangle.SubmeshIndices); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangle(currentTriangle); } leftMesh.AddTriangle(currentTriangle); } updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], vertLeft, vertRight }; updatedNormals = new Vector3[] { rightMeshTriangle.Normals[0], normalLeft, normalRight }; updatedUvs = new Vector2[] { rightMeshTriangle.Uvs[0], uvLeft, uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, triangle.SubmeshIndices); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangle(currentTriangle); } rightMesh.AddTriangle(currentTriangle); } updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[1], vertRight }; updatedNormals = new Vector3[] { rightMeshTriangle.Normals[0], rightMeshTriangle.Normals[1], normalRight }; updatedUvs = new Vector2[] { rightMeshTriangle.Uvs[0], rightMeshTriangle.Uvs[1], uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, triangle.SubmeshIndices); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangle(currentTriangle); } rightMesh.AddTriangle(currentTriangle); } // до сюда }
// Fill holl when cutting the triangle public static void Fill(List <Vector3> _vertices, Plane _plane, GeneratedMesh _leftMesh, GeneratedMesh _rightMesh, int submeshCount) { // center of the filling Vector3 centerPosition = Vector3.zero; for (int i = 0; i < _vertices.Count; i++) { centerPosition += _vertices[i]; } centerPosition = centerPosition / _vertices.Count; Vector3 up = new Vector3() { x = _plane.normal.x, y = _plane.normal.y, z = _plane.normal.z }; Vector3 left = Vector3.Cross(_plane.normal, _plane.normal); Vector3 displacement = Vector3.zero; Vector2 uv1 = Vector2.zero; Vector2 uv2 = Vector2.zero; // go through edges and eliminate by creating triangles with connected edges // each new triangle removes 2 edges but creates 1 new edge // keep the chain in order for (int i = 0; i < _vertices.Count; i++) { displacement = _vertices[i] - centerPosition; uv1 = new Vector2() { x = .5f + Vector3.Dot(displacement, left), y = .5f + Vector3.Dot(displacement, up) }; displacement = _vertices[(i + 1) % _vertices.Count] - centerPosition; uv2 = new Vector2() { x = .5f + Vector3.Dot(displacement, left), y = .5f + Vector3.Dot(displacement, up) }; Vector3[] vertices = new Vector3[] { _vertices[i], _vertices[(i + 1) % _vertices.Count], centerPosition }; Vector3[] normals = new Vector3[] { -_plane.normal, -_plane.normal, -_plane.normal }; Vector2[] uvs = new Vector2[] { uv1, uv2, new Vector2(0.5f, 0.5f) }; //Update current triangle MeshTriangle currentTriangle = new MeshTriangle(vertices, normals, uvs, submeshCount); // check if it is facing the right way FacingCheck(currentTriangle); // add to left side _leftMesh.AddTriangle(currentTriangle); normals = new Vector3[] { _plane.normal, _plane.normal, _plane.normal }; currentTriangle = new MeshTriangle(vertices, normals, uvs, submeshCount); // check if it is facing the right way FacingCheck(currentTriangle); // add to right side _rightMesh.AddTriangle(currentTriangle); } }
private static void CutTriangle(Plane _plane, MeshTriangle _triangle, bool _triangleALeftSide, bool _triangleBLeftSide, bool _triangleCLeftSide, GeneratedMesh _leftSide, GeneratedMesh _rightSide, List <Vector3> _addedVertices) { List <bool> leftSide = new List <bool>(); leftSide.Add(_triangleALeftSide); leftSide.Add(_triangleBLeftSide); leftSide.Add(_triangleCLeftSide); MeshTriangle leftMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex); MeshTriangle rightMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex); MeshTriangle meshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex); bool left = false; bool right = false; for (int i = 0; i < 3; i++) { if (leftSide[i])// left { if (!left) { left = true; leftMeshTriangle.Vertices[0] = _triangle.Vertices[i]; leftMeshTriangle.Vertices[1] = leftMeshTriangle.Vertices[0]; leftMeshTriangle.Uvs[0] = _triangle.Uvs[i]; leftMeshTriangle.Uvs[1] = leftMeshTriangle.Uvs[0]; leftMeshTriangle.Normals[0] = _triangle.Normals[i]; leftMeshTriangle.Normals[1] = leftMeshTriangle.Normals[0]; } else { leftMeshTriangle.Vertices[1] = _triangle.Vertices[i]; leftMeshTriangle.Normals[1] = _triangle.Normals[i]; leftMeshTriangle.Uvs[1] = _triangle.Uvs[i]; } } else // right { if (!right) { right = true; rightMeshTriangle.Vertices[0] = _triangle.Vertices[i]; rightMeshTriangle.Vertices[1] = rightMeshTriangle.Vertices[0]; rightMeshTriangle.Uvs[0] = _triangle.Uvs[i]; rightMeshTriangle.Uvs[1] = rightMeshTriangle.Uvs[0]; rightMeshTriangle.Normals[0] = _triangle.Normals[i]; rightMeshTriangle.Normals[1] = rightMeshTriangle.Normals[0]; } else { rightMeshTriangle.Vertices[1] = _triangle.Vertices[i]; rightMeshTriangle.Normals[1] = _triangle.Normals[i]; rightMeshTriangle.Uvs[1] = _triangle.Uvs[i]; } } } // now to find the intersection points between the solo point and the others float normalizeDistance; float distance; Vector3 edgeVector = Vector3.zero; // edge lenght and direction edgeVector = rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]; _plane.Raycast(new Ray(leftMeshTriangle.Vertices[0], edgeVector.normalized), out distance); normalizeDistance = distance / edgeVector.magnitude; Vector3 vertLeft = Vector3.Lerp(leftMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[0], normalizeDistance); Vector3 normalLeft = Vector3.Lerp(leftMeshTriangle.Normals[0], rightMeshTriangle.Normals[0], normalizeDistance); Vector2 uvLeft = Vector2.Lerp(leftMeshTriangle.Uvs[0], rightMeshTriangle.Uvs[0], normalizeDistance); edgeVector = rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]; _plane.Raycast(new Ray(leftMeshTriangle.Vertices[1], edgeVector.normalized), out distance); normalizeDistance = distance / edgeVector.magnitude; Vector3 vertRight = Vector3.Lerp(leftMeshTriangle.Vertices[1], rightMeshTriangle.Vertices[1], normalizeDistance); Vector3 normalRight = Vector3.Lerp(leftMeshTriangle.Normals[1], rightMeshTriangle.Normals[1], normalizeDistance); Vector2 uvRight = Vector2.Lerp(leftMeshTriangle.Uvs[1], rightMeshTriangle.Uvs[1], normalizeDistance); if (vertLeft != vertRight) { //tracking newly created points _addedVertices.Add(vertLeft); _addedVertices.Add(vertRight); } // make the new triangles MeshTriangle currentTriangle; Vector3[] updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], vertLeft, vertRight }; Vector3[] updatedNormals = new Vector3[] { leftMeshTriangle.Normals[0], normalLeft, normalRight }; Vector2[] updatedUvs = new Vector2[] { leftMeshTriangle.Uvs[0], uvLeft, uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, _triangle.SubmeshIndex); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { // check if it is facing the right way FacingCheck(currentTriangle); // add it _leftSide.AddTriangle(currentTriangle); } updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], leftMeshTriangle.Vertices[1], vertRight }; updatedNormals = new Vector3[] { leftMeshTriangle.Normals[0], leftMeshTriangle.Normals[1], normalRight }; updatedUvs = new Vector2[] { leftMeshTriangle.Uvs[0], leftMeshTriangle.Uvs[1], uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, _triangle.SubmeshIndex); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { // check if it is facing the right way FacingCheck(currentTriangle); // add it _leftSide.AddTriangle(currentTriangle); } updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], vertLeft, vertRight }; updatedNormals = new Vector3[] { rightMeshTriangle.Normals[0], normalLeft, normalRight }; updatedUvs = new Vector2[] { rightMeshTriangle.Uvs[0], uvLeft, uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, _triangle.SubmeshIndex); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { // check if it is facing the right way FacingCheck(currentTriangle); // add it _rightSide.AddTriangle(currentTriangle); } updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[1], vertRight }; updatedNormals = new Vector3[] { rightMeshTriangle.Normals[0], rightMeshTriangle.Normals[1], normalRight }; updatedUvs = new Vector2[] { rightMeshTriangle.Uvs[0], rightMeshTriangle.Uvs[1], uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, _triangle.SubmeshIndex); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { // check if it is facing the right way FacingCheck(currentTriangle); // add it _rightSide.AddTriangle(currentTriangle); } }
private static void CutTriangle(Plane plane, MeshTriangle triangle, bool triALeftSide, bool triBLeftSide, bool triCLeftSide, GeneratedMesh lMesh, GeneratedMesh rMesh, List <Vector3> addVertices) { List <bool> leftSide = new List <bool>(); leftSide.Add(triALeftSide); leftSide.Add(triBLeftSide); leftSide.Add(triCLeftSide); MeshTriangle leftMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], triangle.SubMeshIndex); MeshTriangle rightMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], triangle.SubMeshIndex); bool left = false; bool right = false; for (int i = 0; i < 3; i++) { if (leftSide[i]) { if (!left) { left = true; leftMeshTriangle.Vertices[0] = triangle.Vertices[i]; leftMeshTriangle.Vertices[1] = leftMeshTriangle.Vertices[0]; leftMeshTriangle.UVs[0] = triangle.UVs[i]; leftMeshTriangle.UVs[1] = leftMeshTriangle.UVs[0]; leftMeshTriangle.Normals[0] = triangle.Normals[i]; leftMeshTriangle.Normals[1] = leftMeshTriangle.Normals[0]; } else { leftMeshTriangle.Vertices[1] = triangle.Vertices[i]; leftMeshTriangle.UVs[1] = triangle.UVs[i]; leftMeshTriangle.Normals[1] = triangle.Normals[i]; } } else { if (!right) { right = true; rightMeshTriangle.Vertices[0] = triangle.Vertices[i]; rightMeshTriangle.Vertices[1] = rightMeshTriangle.Vertices[0]; rightMeshTriangle.UVs[0] = triangle.UVs[i]; rightMeshTriangle.UVs[1] = rightMeshTriangle.UVs[0]; rightMeshTriangle.Normals[0] = triangle.Normals[i]; rightMeshTriangle.Normals[1] = rightMeshTriangle.Normals[0]; } else { rightMeshTriangle.Vertices[1] = triangle.Vertices[i]; rightMeshTriangle.UVs[1] = triangle.UVs[i]; rightMeshTriangle.Normals[1] = triangle.Normals[i]; } } } float normalizedDistance; float distance; plane.Raycast(new Ray(leftMeshTriangle.Vertices[0], (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).normalized), out distance); normalizedDistance = distance / (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).magnitude; Vector3 vertLeft = Vector3.Lerp(leftMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[0], normalizedDistance); addVertices.Add(vertLeft); Vector3 normalLeft = Vector3.Lerp(leftMeshTriangle.Normals[0], rightMeshTriangle.Normals[0], normalizedDistance); Vector2 uvLeft = Vector2.Lerp(leftMeshTriangle.UVs[0], rightMeshTriangle.UVs[0], normalizedDistance); plane.Raycast(new Ray(leftMeshTriangle.Vertices[1], (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).normalized), out distance); normalizedDistance = distance / (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).magnitude; Vector3 vertRight = Vector3.Lerp(leftMeshTriangle.Vertices[1], rightMeshTriangle.Vertices[1], normalizedDistance); addVertices.Add(vertRight); Vector3 normalRight = Vector3.Lerp(leftMeshTriangle.Normals[1], rightMeshTriangle.Normals[1], normalizedDistance); Vector2 uvRight = Vector2.Lerp(leftMeshTriangle.UVs[1], rightMeshTriangle.UVs[1], normalizedDistance); MeshTriangle currentTriangle; Vector3[] updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], vertLeft, vertRight }; Vector3[] updatedNormals = new Vector3[] { leftMeshTriangle.Normals[0], normalLeft, normalRight }; Vector2[] updatedUVs = new Vector2[] { leftMeshTriangle.UVs[0], uvLeft, uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, triangle.SubMeshIndex); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangle(currentTriangle); } lMesh.AddTriangle(currentTriangle); } updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], leftMeshTriangle.Vertices[1], vertRight }; updatedNormals = new Vector3[] { leftMeshTriangle.Normals[0], leftMeshTriangle.Normals[1], normalRight }; updatedUVs = new Vector2[] { leftMeshTriangle.UVs[0], leftMeshTriangle.UVs[1], uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, triangle.SubMeshIndex); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangle(currentTriangle); } lMesh.AddTriangle(currentTriangle); } updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], vertLeft, vertRight }; updatedNormals = new Vector3[] { rightMeshTriangle.Normals[0], normalLeft, normalRight }; updatedUVs = new Vector2[] { rightMeshTriangle.UVs[0], uvLeft, uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, triangle.SubMeshIndex); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangle(currentTriangle); } rMesh.AddTriangle(currentTriangle); } updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[1], vertRight }; updatedNormals = new Vector3[] { rightMeshTriangle.Normals[0], rightMeshTriangle.Normals[1], normalRight }; updatedUVs = new Vector2[] { rightMeshTriangle.UVs[0], rightMeshTriangle.UVs[1], uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, triangle.SubMeshIndex); if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangle(currentTriangle); } rMesh.AddTriangle(currentTriangle); } }
private static void CutTriangle(Plane _plane, MeshTriangle _triangle, bool _triangleALeftSide, bool _triangleBLeftSide, bool _triangleCLeftSide, GeneratedMesh _leftSide, GeneratedMesh _rightSide, List <Vector3> _addedVertices) { List <bool> leftSide = new List <bool>(); leftSide.Add(_triangleALeftSide); leftSide.Add(_triangleBLeftSide); leftSide.Add(_triangleCLeftSide); MeshTriangle leftMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex); MeshTriangle rightMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex); bool left = false; bool right = false; for (int i = 0; i < 3; i++) { if (leftSide[i]) { if (!left) { left = true; leftMeshTriangle.Vertices[0] = _triangle.Vertices[i]; leftMeshTriangle.Vertices[1] = leftMeshTriangle.Vertices[0]; leftMeshTriangle.UVs[0] = _triangle.UVs[i]; leftMeshTriangle.UVs[1] = leftMeshTriangle.UVs[0]; leftMeshTriangle.Normals[0] = _triangle.Normals[i]; leftMeshTriangle.Normals[1] = leftMeshTriangle.Normals[0]; } else { leftMeshTriangle.Vertices[1] = _triangle.Vertices[i]; leftMeshTriangle.Normals[1] = _triangle.Normals[i]; leftMeshTriangle.UVs[1] = _triangle.UVs[i]; } } else { if (!right) { right = true; rightMeshTriangle.Vertices[0] = _triangle.Vertices[i]; rightMeshTriangle.Vertices[1] = rightMeshTriangle.Vertices[0]; rightMeshTriangle.UVs[0] = _triangle.UVs[i]; rightMeshTriangle.UVs[1] = rightMeshTriangle.UVs[0]; rightMeshTriangle.Normals[0] = _triangle.Normals[i]; rightMeshTriangle.Normals[1] = rightMeshTriangle.Normals[0]; } else { rightMeshTriangle.Vertices[1] = _triangle.Vertices[i]; rightMeshTriangle.Normals[1] = _triangle.Normals[i]; rightMeshTriangle.UVs[1] = _triangle.UVs[i]; } } } float normalizedDistance; float distance; _plane.Raycast(new Ray(leftMeshTriangle.Vertices[0], (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).normalized), out distance); normalizedDistance = distance / (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).magnitude; Vector3 vertLeft = Vector3.Lerp(leftMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[0], normalizedDistance); _addedVertices.Add(vertLeft); Vector3 normalLeft = Vector3.Lerp(leftMeshTriangle.Normals[0], rightMeshTriangle.Normals[0], normalizedDistance); Vector2 uvLeft = Vector2.Lerp(leftMeshTriangle.UVs[0], rightMeshTriangle.UVs[0], normalizedDistance); _plane.Raycast(new Ray(leftMeshTriangle.Vertices[1], (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).normalized), out distance); normalizedDistance = distance / (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).magnitude; Vector3 vertRight = Vector3.Lerp(leftMeshTriangle.Vertices[1], rightMeshTriangle.Vertices[1], normalizedDistance); _addedVertices.Add(vertRight); Vector3 normalRight = Vector3.Lerp(leftMeshTriangle.Normals[1], rightMeshTriangle.Normals[1], normalizedDistance); Vector2 uvRight = Vector2.Lerp(leftMeshTriangle.UVs[1], rightMeshTriangle.UVs[1], normalizedDistance); //TESTING OUR FIRST TRIANGLE MeshTriangle currentTriangle; Vector3[] updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], vertLeft, vertRight }; Vector3[] updatedNormals = new Vector3[] { leftMeshTriangle.Normals[0], normalLeft, normalRight }; Vector2[] updatedUVs = new Vector2[] { leftMeshTriangle.UVs[0], uvLeft, uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex); //If our vertices arent the same if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangel(currentTriangle); } _leftSide.AddTriangle(currentTriangle); } //SECOND TRIANGLE updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], leftMeshTriangle.Vertices[1], vertRight }; updatedNormals = new Vector3[] { leftMeshTriangle.Normals[0], leftMeshTriangle.Normals[1], normalRight }; updatedUVs = new Vector2[] { leftMeshTriangle.UVs[0], leftMeshTriangle.UVs[1], uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex); //If our vertices arent the same if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangel(currentTriangle); } _leftSide.AddTriangle(currentTriangle); } //THIRD TRIANGLE updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], vertLeft, vertRight }; updatedNormals = new Vector3[] { rightMeshTriangle.Normals[0], normalLeft, normalRight }; updatedUVs = new Vector2[] { rightMeshTriangle.UVs[0], uvLeft, uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex); //If our vertices arent the same if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangel(currentTriangle); } _rightSide.AddTriangle(currentTriangle); } //FOURTH TRIANGLE updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[1], vertRight }; updatedNormals = new Vector3[] { rightMeshTriangle.Normals[0], rightMeshTriangle.Normals[1], normalRight }; updatedUVs = new Vector2[] { rightMeshTriangle.UVs[0], rightMeshTriangle.UVs[1], uvRight }; currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex); //If our vertices arent the same if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2]) { if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0) { FlipTriangel(currentTriangle); } _rightSide.AddTriangle(currentTriangle); } }
public static void Cut(GameObject _originalGameObject, Vector3 _contactPoint, Vector3 _direction, Material _cutMaterial = null, bool fill = true, bool _addRigidBody = false) { if (currentlyCutting) { return; } currentlyCutting = true; Plane plane = new Plane(_originalGameObject.transform.InverseTransformDirection(-_direction), _originalGameObject.transform.InverseTransformPoint(_contactPoint)); originalGameObject = _originalGameObject; originalMesh = _originalGameObject.GetComponent <MeshFilter>().mesh; List <Vector3> addedVertices = new List <Vector3>(); GeneratedMesh leftMesh = new GeneratedMesh(); GeneratedMesh rightMesh = new GeneratedMesh(); int[] submeshIndices; int triangleIndexA, triangleIndexB, triangleIndexC; for (int i = 0; i < originalMesh.subMeshCount; i++) { submeshIndices = originalMesh.GetTriangles(i); for (int j = 0; j < submeshIndices.Length; j += 3) { triangleIndexA = submeshIndices[j]; triangleIndexB = submeshIndices[j + 1]; triangleIndexC = submeshIndices[j + 2]; MeshTriangle currentTriangle = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i); bool triangleALeftSide = plane.GetSide(originalMesh.vertices[triangleIndexA]); bool triangleBLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexB]); bool triangleCLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexC]); /* * Three different cases: * - The triangle is either above the plane * - The triangle is below the plane * - The place intersects the triangle */ if (triangleALeftSide && triangleBLeftSide && triangleCLeftSide) { leftMesh.AddTriangle(currentTriangle); } else if (!triangleALeftSide && !triangleBLeftSide && !triangleCLeftSide) { rightMesh.AddTriangle(currentTriangle); } else { CutTriangle(plane, currentTriangle, triangleALeftSide, triangleBLeftSide, triangleCLeftSide, leftMesh, rightMesh, addedVertices); } } } // if either mesh has no vertices, return if (leftMesh.Vertices.Count == 0 || rightMesh.Vertices.Count == 0 || addedVertices.Count == 0) { currentlyCutting = false; return; } FillCut(addedVertices, plane, leftMesh, rightMesh); GenerateGameObject(leftMesh); GenerateGameObject(rightMesh); Object.Destroy(_originalGameObject); currentlyCutting = false; }
public static void Fill(List <Vector3> _vertices, Plane _plane, GeneratedMesh _leftMesh, GeneratedMesh _rightMesh) { //Firstly we need the center we do this by adding up all the vertices and then calculating the average Vector3 centerPosition = Vector3.zero; for (int i = 0; i < _vertices.Count; i++) { centerPosition += _vertices[i]; } centerPosition = centerPosition / _vertices.Count; //We now need an Upward Axis we use the plane we cut the mesh with for that Vector3 up = new Vector3() { x = _plane.normal.x, y = _plane.normal.y, z = _plane.normal.z }; Vector3 left = Vector3.Cross(_plane.normal, up); Vector3 displacement = Vector3.zero; Vector2 uv1 = Vector2.zero; Vector2 uv2 = Vector2.zero; for (int i = 0; i < _vertices.Count; i++) { displacement = _vertices[i] - centerPosition; uv1 = new Vector2() { x = .5f + Vector3.Dot(displacement, left), y = .5f + Vector3.Dot(displacement, up) }; displacement = _vertices[(i + 1) % _vertices.Count] - centerPosition; uv2 = new Vector2() { x = .5f + Vector3.Dot(displacement, left), y = .5f + Vector3.Dot(displacement, up) }; Vector3[] vertices = new Vector3[] { _vertices[i], _vertices[(i + 1) % _vertices.Count], centerPosition }; Vector3[] normals = new Vector3[] { -_plane.normal, -_plane.normal, -_plane.normal }; Vector2[] uvs = new Vector2[] { uv1, uv2, new Vector2(0.5f, 0.5f) }; MeshTriangle currentTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount + 1); if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0) { FlipTriangel(currentTriangle); } _leftMesh.AddTriangle(currentTriangle); normals = new Vector3[] { _plane.normal, _plane.normal, _plane.normal }; currentTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount + 1); if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0) { FlipTriangel(currentTriangle); } _rightMesh.AddTriangle(currentTriangle); } }
public static void Cut(GameObject _originalGameObject, Vector3 _contactPoint, Vector3 _direction, Material _cutMaterial = null, bool fill = true, bool _addRigidbody = false) { if (currentlyCutting) { return; } currentlyCutting = true; //We are instantiating a plane through our initial object to seperate the left and right side from each other Plane plane = new Plane(_originalGameObject.transform.InverseTransformDirection(-_direction), _originalGameObject.transform.InverseTransformPoint(_contactPoint)); originalMesh = _originalGameObject.GetComponent <MeshFilter>().mesh; List <Vector3> addedVertices = new List <Vector3>(); //We are getting two new generated meshes for our left and right side GeneratedMesh leftMesh = new GeneratedMesh(); GeneratedMesh rightMesh = new GeneratedMesh(); //Some meshes use different submeshes to have multiple materials attached to them //in an early iteration I had an extra script to turn everything into one mesh to make my life a little easier //however the result was not great because I could only slice objects that had one single material int[] submeshIndices; int triangleIndexA, triangleIndexB, triangleIndexC; for (int i = 0; i < originalMesh.subMeshCount; i++) { submeshIndices = originalMesh.GetTriangles(i); //We are now going through the submesh indices as triangles to determine on what side of the mesh they are. for (int j = 0; j < submeshIndices.Length; j += 3) { triangleIndexA = submeshIndices[j]; triangleIndexB = submeshIndices[j + 1]; triangleIndexC = submeshIndices[j + 2]; MeshTriangle currentTriangle = GetTriangle(triangleIndexA, triangleIndexB, triangleIndexC, i); //We are now using the plane.getside function to see on which side of the cut our trianle is situated //or if it might be cut through bool triangleALeftSide = plane.GetSide(originalMesh.vertices[triangleIndexA]); bool triangleBLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexB]); bool triangleCLeftSide = plane.GetSide(originalMesh.vertices[triangleIndexC]); //All three vertices are on the left side of the plane, so they need to be added to the left //mesh if (triangleALeftSide && triangleBLeftSide && triangleCLeftSide) { leftMesh.AddTriangle(currentTriangle); } //All three vertices are on the right side of the mesh. else if (!triangleALeftSide && !triangleBLeftSide && !triangleCLeftSide) { rightMesh.AddTriangle(currentTriangle); } else { CutTriangle(plane, currentTriangle, triangleALeftSide, triangleBLeftSide, triangleCLeftSide, leftMesh, rightMesh, addedVertices); } } } //Filling our cut if (fill == true) { FillCut(addedVertices, plane, leftMesh, rightMesh); } Mesh finishedLeftMesh = leftMesh.GetGeneratedMesh(); Mesh finishedRightMesh = rightMesh.GetGeneratedMesh(); _originalGameObject.GetComponent <MeshFilter>().mesh = finishedLeftMesh; _originalGameObject.AddComponent <MeshCollider>().sharedMesh = finishedLeftMesh; _originalGameObject.GetComponent <MeshCollider>().convex = true; Material[] mats = new Material[finishedLeftMesh.subMeshCount]; for (int i = 0; i < finishedLeftMesh.subMeshCount; i++) { mats[i] = _originalGameObject.GetComponent <MeshRenderer>().material; } _originalGameObject.GetComponent <MeshRenderer>().materials = mats; GameObject rightGO = new GameObject(); rightGO.transform.position = _originalGameObject.transform.position + (Vector3.up * .05f); rightGO.transform.rotation = _originalGameObject.transform.rotation; rightGO.transform.localScale = _originalGameObject.transform.localScale; rightGO.AddComponent <MeshRenderer>(); mats = new Material[finishedRightMesh.subMeshCount]; for (int i = 0; i < finishedRightMesh.subMeshCount; i++) { mats[i] = _originalGameObject.GetComponent <MeshRenderer>().material; } rightGO.GetComponent <MeshRenderer>().materials = mats; rightGO.AddComponent <MeshFilter>().mesh = finishedRightMesh; rightGO.AddComponent <MeshCollider>().sharedMesh = finishedRightMesh; rightGO.GetComponent <MeshCollider>().convex = true; if (_addRigidbody == true) { rightGO.AddComponent <Rigidbody>(); } currentlyCutting = false; }