Ejemplo n.º 1
0
    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;
        }
    }