void OnDrawGizmos() { Gizmos.color = Color.red; if (drawing) { List <Vector3> allIntercepts = new List <Vector3>(); //TODO: Much should be in cutter in future cutter.RecalculateMeshlike(); Vector3[] l = line.Line.ToArray(); Vector3 normal = Vector3.Cross(l[1] - l[0], l[2] - l[0]).normalized; int[] outTriangle = new int[3] { 0, 1, 2 }; Dictionary <int, List <Vector3> > cuts = cutter.GetCuts(l, outTriangle, 0, normal); foreach (List <Vector3> cutz in cuts.Values) { allIntercepts.AddRange(cutz); } foreach (Vector3 intercept in allIntercepts) { Gizmos.DrawSphere(intercept, gizmoSize); } subPaths = cutter.GetSubPaths(l, outTriangle, 0, normal, cuts, allIntercepts); //Debug.Log(subPaths.Count() + " paths"); Gizmos.color = Color.red; for (int subP = 0; subP < subPaths.Count(); subP++) { List <int> tris = ProcGenHelpers.PolyToTriangles(subPaths[subP], normal, 0); //Debug.Log(tris.Count() + " triangle points"); for (int idT = 0, lT = tris.Count(); idT < lT; idT += 3) { Gizmos.DrawLine(subPaths[subP][tris[idT]], subPaths[subP][tris[idT + 1]]); Gizmos.DrawLine(subPaths[subP][tris[idT + 1]], subPaths[subP][tris[idT + 2]]); Gizmos.DrawLine(subPaths[subP][tris[idT + 2]], subPaths[subP][tris[idT]]); Vector3 center = (subPaths[subP][tris[idT]] + subPaths[subP][tris[idT + 1]] + subPaths[subP][tris[idT + 2]]) / 3; Gizmos.DrawWireCube(center, gizmoSize * Vector3.one); Gizmos.DrawLine(center, center + Vector3.Cross(subPaths[subP][tris[idT + 1]] - subPaths[subP][tris[idT]], subPaths[subP][tris[idT + 2]] - subPaths[subP][tris[idT]])); } } } }
public void CutDough(Mesh dough, MeshFilter mFilt) { Debug.Log("Cutting " + mFilt.gameObject); Transform doughTransform = mFilt.transform; List <Vector3> allIntercepts = new List <Vector3>(); Vector3[] verts = dough.vertices.Select(v => doughTransform.TransformPoint(v)).ToArray(); int[] tris = dough.triangles; Vector2[] uvs = dough.uv; List <Vector3> newVerts = new List <Vector3>(); List <Vector2> newUVs = new List <Vector2>(); List <int> newTris = new List <int>(); for (int triStart = 0, nTris = tris.Length; triStart < nTris; triStart += 3) { Vector3[] triCorners = new Vector3[3] { verts[tris[triStart]], verts[tris[triStart + 1]], verts[tris[triStart + 2]] }; if (triCorners.All(v => PointInMesh(v))) { Debug.Log(string.Format("Remove tri {0} {1} {2} because entirely inside cutter", tris[triStart], tris[triStart + 1], tris[triStart + 2])); continue; } Vector2[] triUVs = new Vector2[3] { uvs[tris[triStart]], uvs[tris[triStart + 1]], uvs[tris[triStart + 2]] }; Vector3 normal = Vector3.Cross(triCorners[1] - triCorners[0], triCorners[2] - triCorners[0]).normalized; Debug.Log(string.Format("Tri {0} {1} {2}, Normal {3}", triCorners[0], triCorners[1], triCorners[2], normal)); int[] outTriangle = new int[3] { 0, 1, 2 }; Dictionary <int, List <Vector3> > cuts = GetCuts(triCorners, outTriangle, 0, normal); foreach (List <Vector3> cutz in cuts.Values) { allIntercepts.AddRange(cutz); } //TODO: add stuff here to fix entirely inside if (allIntercepts.Count() > 0) { List <List <Vector3> > subPaths = GetSubPaths(triCorners, outTriangle, 0, normal, cuts, allIntercepts); for (int subP = 0; subP < subPaths.Count(); subP++) { Debug.Log(string.Format("Creating tris on {0} for poly {1} (length {3}) of original tri {2} +1 +2", mFilt.gameObject, subP, triStart, subPaths[subP].Count())); newTris.AddRange(ProcGenHelpers.PolyToTriangles(subPaths[subP], normal, newVerts.Count())); newVerts.AddRange(subPaths[subP]); newUVs.AddRange(ProcGenHelpers.GetProjectedUVs(triCorners, triUVs, subPaths[subP])); } } else { //Triangle outside cutter entirely int nVerts = newVerts.Count(); newVerts.AddRange(triCorners); newUVs.AddRange(triUVs); for (int i = 0; i < 3; i++) { newTris.Add(nVerts + i); } } } Mesh cutDough = new Mesh(); cutDough.name = dough.name + ".CCut"; cutDough.Clear(); cutDough.SetVertices(newVerts.Select(v => doughTransform.InverseTransformPoint(v)).ToList()); cutDough.SetUVs(0, newUVs); cutDough.SetTriangles(newTris, 0); cutDough.RecalculateBounds(); cutDough.RecalculateNormals(); mFilt.sharedMesh = cutDough; MeshCollider mCol = mFilt.GetComponent <MeshCollider>(); if (mCol && mCol.sharedMesh == dough) { mCol.sharedMesh = cutDough; } }