Example #1
0
    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;
    }