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