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

        //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;
    }