Ejemplo n.º 1
0
    private static void MakeTriangles(Plane _plane, MeshTriangle _triangle, GeneratedMesh _currentSide, List <Vector3> _addedVertices, MeshTriangle currentMeshTriangle, MeshTriangle oppositeMeshTriangle, bool addVertices)
    {
        float normalizedDistance;
        float distance;

        // Get the distance from the vertex to the intersecting plane, in the direction of a vertex that we know exists on the other side of the intersection
        // From our original triangle
        _plane.Raycast(new Ray(currentMeshTriangle.Vertices[0], (oppositeMeshTriangle.Vertices[0] - currentMeshTriangle.Vertices[0]).normalized), out distance);
        normalizedDistance = distance / (oppositeMeshTriangle.Vertices[0] - currentMeshTriangle.Vertices[0]).magnitude;

        Vector3 vertLeft   = Vector3.Lerp(currentMeshTriangle.Vertices[0], oppositeMeshTriangle.Vertices[0], normalizedDistance);
        Vector3 normalLeft = Vector3.Lerp(currentMeshTriangle.Normals[0], oppositeMeshTriangle.Normals[0], normalizedDistance);
        Vector2 uvLeft     = Vector2.Lerp(currentMeshTriangle.UVs[0], oppositeMeshTriangle.UVs[0], normalizedDistance);

        _plane.Raycast(new Ray(currentMeshTriangle.Vertices[1], (oppositeMeshTriangle.Vertices[1] - currentMeshTriangle.Vertices[1]).normalized), out distance);

        normalizedDistance = distance / (oppositeMeshTriangle.Vertices[1] - currentMeshTriangle.Vertices[1]).magnitude;
        Vector3 vertRight = Vector3.Lerp(currentMeshTriangle.Vertices[1], oppositeMeshTriangle.Vertices[1], normalizedDistance);

        // Since we call this method twice, prevent adding new vertices twice
        if (addVertices)
        {
            _addedVertices.Add(vertLeft);
            _addedVertices.Add(vertRight);
        }
        Vector3 normalRight = Vector3.Lerp(currentMeshTriangle.Normals[1], oppositeMeshTriangle.Normals[1], normalizedDistance);
        Vector3 uvRight     = Vector2.Lerp(currentMeshTriangle.UVs[1], oppositeMeshTriangle.UVs[1], normalizedDistance);

        MeshTriangle currentTriangle;

        Vector3[] updatedVertices = new Vector3[] { currentMeshTriangle.Vertices[0], vertLeft, vertRight };
        Vector3[] updatedNormals  = new Vector3[] { currentMeshTriangle.Normals[0], normalLeft, normalRight };
        Vector2[] updatedUVs      = new Vector2[] { currentMeshTriangle.UVs[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            _currentSide.AddTriangle(currentTriangle);
        }

        updatedVertices = new Vector3[] { currentMeshTriangle.Vertices[0], currentMeshTriangle.Vertices[1], vertRight };
        updatedNormals  = new Vector3[] { currentMeshTriangle.Normals[0], currentMeshTriangle.Normals[1], normalRight };
        updatedUVs      = new Vector2[] { currentMeshTriangle.UVs[0], currentMeshTriangle.UVs[1], uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            _currentSide.AddTriangle(currentTriangle);
        }
    }
Ejemplo n.º 2
0
    public static void Cut(GameObject oGO, Vector3 _contactPoint,
                           Vector3 _direction, Material _cutMaterial = null,
                           bool fill = true, bool _addRigidbody = false)
    {
        if (currentCut)
        {
            return;
        }

        currentCut = true;

        Plane plane = new Plane(oGO.transform.InverseTransformDirection(-_direction),
                                oGO.transform.InverseTransformPoint(_contactPoint));

        originalMesh = oGO.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 < originalMesh.subMeshCount; 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
                {
                }
            }
        }
    }
Ejemplo n.º 3
0
    private static void Fill(List <Vector3> _vertices, Plane plane, GeneratedMesh leftMesh, GeneratedMesh rightMesh)
    {
        Vector3 centerPosition = Vector3.zero;

        for (int i = 0; i < _vertices.Count; i++)
        {
            centerPosition += _vertices[i];
        }
        centerPosition /= _vertices.Count;

        Vector3 up = plane.normal;

        Vector3 left = Vector3.Cross(plane.normal, plane.normal);

        Vector3 displacement = Vector3.zero;
        Vector2 uv1, uv2;

        for (int i = 0; i < _vertices.Count; i++)
        {
            displacement = _vertices[i] - centerPosition;
            uv1          = new Vector2(0.5f + Vector3.Dot(displacement, left), 0.5f + Vector3.Dot(displacement, up));
            displacement = _vertices[(i + 1) % _vertices.Count] - centerPosition;
            uv2          = new Vector2(0.5f + Vector3.Dot(displacement, left), 0.5f + Vector3.Dot(displacement, up));

            Vector3[] vertices = new Vector3[] { _vertices[i], _vertices[(i + 1) % _vertices.Count], centerPosition };
            Vector3[] normals  = new Vector3[] { -plane.normal, -plane.normal, -plane.normal };
            Vector2[] uvs      = new Vector2[] { uv1, uv2, new Vector2(0.5f, 0.5f) };

            MeshTriangle currenTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount - 1);

            if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0)
            {
                FlipTriangle(currenTriangle);
            }
            leftMesh.AddTriangle(currenTriangle);

            normals        = new Vector3[] { plane.normal, plane.normal, plane.normal };
            currenTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount - 1);

            if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0)
            {
                FlipTriangle(currenTriangle);
            }
            rightMesh.AddTriangle(currenTriangle);
        }
    }
Ejemplo n.º 4
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);
        }

        // 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;
    }
Ejemplo n.º 5
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;
    }
Ejemplo n.º 6
0
    private static void CutTriangle(Plane _plane, MeshTriangle meshTri, bool tALS, bool TBLS, bool TCLS,
                                    GeneratedMesh lSide, GeneratedMesh rSide, List <Vector3> addedVert)
    {
        List <bool> leftSide = new List <bool>();

        leftSide.Add(tALS);
        leftSide.Add(TBLS);
        leftSide.Add(TCLS);

        MeshTriangle leftMeshTriangle  = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], meshTri.SMIndex);
        MeshTriangle rightMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], meshTri.SMIndex);

        bool left  = false;
        bool right = false;

        for (int i = 0; i < 3; i++)
        {
            if (leftSide[i])
            {
                if (!left)
                {
                    left = true;

                    leftMeshTriangle.Vert[0] = meshTri.Vert[i];
                    leftMeshTriangle.Vert[1] = leftMeshTriangle.Vert[0];

                    leftMeshTriangle.UV[0] = meshTri.UV[i];
                    leftMeshTriangle.UV[1] = leftMeshTriangle.UV[0];

                    leftMeshTriangle.Norm[0] = meshTri.Norm[i];
                    leftMeshTriangle.Norm[1] = leftMeshTriangle.Norm[0];
                }
                else
                {
                    leftMeshTriangle.Vert[1] = meshTri.Vert[i];
                    leftMeshTriangle.Norm[1] = meshTri.Vert[i];
                    leftMeshTriangle.UV[1]   = meshTri.Vert[i];
                }
            }
            else
            {
                if (!right)
                {
                    right = true;

                    rightMeshTriangle.Vert[0] = meshTri.Vert[i];
                    rightMeshTriangle.Vert[1] = rightMeshTriangle.Vert[0];

                    rightMeshTriangle.UV[0] = meshTri.UV[i];
                    rightMeshTriangle.UV[1] = rightMeshTriangle.UV[0];

                    rightMeshTriangle.Norm[0] = meshTri.Norm[i];
                    rightMeshTriangle.Norm[1] = rightMeshTriangle.Norm[0];
                }
                else
                {
                    rightMeshTriangle.Vert[1] = meshTri.Vert[i];
                    rightMeshTriangle.Norm[1] = meshTri.Vert[i];
                    rightMeshTriangle.UV[1]   = meshTri.Vert[i];
                }
            }
        }

        float normalizedDistance;
        float distance;

        _plane.Raycast(new Ray(leftMeshTriangle.Vert[0],
                               (rightMeshTriangle.Vert[0] - leftMeshTriangle.Vert[0]).normalized), out distance);

        normalizedDistance = distance / (rightMeshTriangle.Vert[0] - leftMeshTriangle.Vert[0]).magnitude;
        Vector3 vertLeft = Vector3.Lerp(leftMeshTriangle.Vert[0], rightMeshTriangle.Vert[0], normalizedDistance);

        addedVert.Add(vertLeft);

        Vector3 normalLeft = Vector3.Lerp(leftMeshTriangle.Norm[0], rightMeshTriangle.Norm[0], normalizedDistance);
        Vector2 uvLeft     = Vector2.Lerp(leftMeshTriangle.UV[0], rightMeshTriangle.UV[0], normalizedDistance);

        _plane.Raycast(new Ray(leftMeshTriangle.Vert[1],
                               (rightMeshTriangle.Vert[1] - leftMeshTriangle.Vert[1]).normalized), out distance);

        normalizedDistance = distance / (rightMeshTriangle.Vert[1] - leftMeshTriangle.Vert[1]).magnitude;
        Vector3 vertRight = Vector3.Lerp(leftMeshTriangle.Vert[1], rightMeshTriangle.Vert[1], normalizedDistance);

        addedVert.Add(vertLeft);

        Vector3 normalRight = Vector3.Lerp(leftMeshTriangle.Norm[1], rightMeshTriangle.Norm[1], normalizedDistance);
        Vector2 uvRight     = Vector2.Lerp(leftMeshTriangle.UV[1], rightMeshTriangle.UV[1], normalizedDistance);

        MeshTriangle currentTriangle;

        Vector3[] updatedVert = new Vector3[] { leftMeshTriangle.Vert[0], vertLeft, vertRight };
        Vector3[] updatedNorm = new Vector3[] { leftMeshTriangle.Norm[0], normalLeft, normalRight };
        Vector2[] updatedUV   = new Vector2[] { leftMeshTriangle.UV[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVert, updatedNorm, updatedUV, meshTri.SMIndex);

        if (updatedVert[0] != updatedVert[1] && updatedVert[0] != updatedVert[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVert[1] - updatedVert[0], updatedVert[2] - updatedVert[0]), updatedVert[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            lSide.AddTriangle(currentTriangle);
        }

        updatedVert = new Vector3[] { leftMeshTriangle.Vert[0], leftMeshTriangle.Vert[1], vertRight };
        updatedNorm = new Vector3[] { leftMeshTriangle.Norm[0], leftMeshTriangle.Norm[1], normalRight };
        updatedUV   = new Vector2[] { leftMeshTriangle.UV[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVert, updatedNorm, updatedUV, meshTri.SMIndex);

        if (updatedVert[0] != updatedVert[1] && updatedVert[0] != updatedVert[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVert[1] - updatedVert[0], updatedVert[2] - updatedVert[0]), updatedVert[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            lSide.AddTriangle(currentTriangle);
        }

        updatedVert = new Vector3[] { rightMeshTriangle.Vert[0], vertLeft, vertRight };
        updatedNorm = new Vector3[] { rightMeshTriangle.Norm[0], normalLeft, normalRight };
        updatedUV   = new Vector2[] { rightMeshTriangle.UV[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVert, updatedNorm, updatedUV, meshTri.SMIndex);

        if (updatedVert[0] != updatedVert[1] && updatedVert[0] != updatedVert[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVert[1] - updatedVert[0], updatedVert[2] - updatedVert[0]), updatedVert[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            rSide.AddTriangle(currentTriangle);
        }

        updatedVert = new Vector3[] { rightMeshTriangle.Vert[0], rightMeshTriangle.Vert[1], vertRight };
        updatedNorm = new Vector3[] { rightMeshTriangle.Norm[0], rightMeshTriangle.Norm[1], normalRight };
        updatedUV   = new Vector2[] { rightMeshTriangle.UV[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVert, updatedNorm, updatedUV, meshTri.SMIndex);

        if (updatedVert[0] != updatedVert[1] && updatedVert[0] != updatedVert[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVert[1] - updatedVert[0], updatedVert[2] - updatedVert[0]), updatedVert[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            rSide.AddTriangle(currentTriangle);
        }
    }
Ejemplo n.º 7
0
    private static void Fill(List <Vector3> _vertices, Plane _plane, GeneratedMesh _leftMesh, GeneratedMesh _rightMesh)
    {
        Vector3 centerPosition = Vector3.zero;

        for (int i = 0; i < _vertices.Count; i++)
        {
            centerPosition += _vertices[i];
        }
        centerPosition = centerPosition / _vertices.Count;

        Vector3 up = new Vector3()
        {
            x = _plane.normal.x,
            y = _plane.normal.y,
            z = _plane.normal.z
        };

        Vector3 left         = Vector3.zero;
        Vector3 displacement = Vector3.zero;
        Vector2 uv1          = Vector2.zero;
        Vector2 uv2          = Vector2.zero;

        for (int i = 0; i < _vertices.Count; i++)
        {
            displacement = _vertices[i] - centerPosition;
            uv1          = new Vector2()
            {
                x = .5f + Vector3.Dot(displacement, left),
                y = .5f + Vector3.Dot(displacement, up)
            };

            displacement = _vertices[(i + 1) % _vertices.Count] - centerPosition;
            uv2          = new Vector2()
            {
                x = .5f + Vector3.Dot(displacement, left),
                y = .5f + Vector3.Dot(displacement, up)
            };

            Vector3[] vertices = new Vector3[] { _vertices[i], _vertices[(i + 1) % _vertices.Count], centerPosition };
            Vector3[] normals  = new Vector3[] { -_plane.normal, -_plane.normal, -_plane.normal };
            Vector2[] uvs      = new Vector2[] { uv1, uv2, new Vector2(0.5f, 0.5f) };

            MeshTriangle currentTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount + 1);

            // Make sure triangle is facing the right way
            if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }

            _leftMesh.AddTriangle(currentTriangle);

            normals         = new Vector3[] { _plane.normal, _plane.normal, _plane.normal };
            currentTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount + 1);

            if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            _rightMesh.AddTriangle(currentTriangle);
        }
    }
Ejemplo n.º 8
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;
    }
Ejemplo n.º 9
0
    public static void CutGameobject(GameObject originalGameObject, Vector3 contactPoint, Vector3 direction, bool addRigidbody = false)
    {
        if (currentlyCutting)
        {
            return;
        }

        currentlyCutting = true;

        originalMesh = originalGameObject.GetComponent <MeshFilter>().mesh;

        var plane = new Plane(originalGameObject.transform.InverseTransformDirection(direction), originalGameObject.transform.InverseTransformPoint(contactPoint));

        var addedVertices = new List <Vector3>();

        var leftMesh  = new GeneratedMesh();
        var 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[] pointsOnLeftSide = new bool [3];

                pointsOnLeftSide[0] = plane.GetSide(originalMesh.vertices[triangleIndexA]);
                pointsOnLeftSide[1] = plane.GetSide(originalMesh.vertices[triangleIndexB]);
                pointsOnLeftSide[2] = plane.GetSide(originalMesh.vertices[triangleIndexC]);

                if (pointsOnLeftSide[0] && pointsOnLeftSide[1] && pointsOnLeftSide[2])
                {
                    leftMesh.AddTriangle(currentTriangle);
                }
                else if (!pointsOnLeftSide[0] && !pointsOnLeftSide[1] && !pointsOnLeftSide[2])
                {
                    rightMesh.AddTriangle(currentTriangle);
                }
                else
                {
                    CutTriangle(plane, currentTriangle, pointsOnLeftSide, leftMesh, rightMesh, addedVertices);
                }
            }

            FillCut(addedVertices, plane, leftMesh, rightMesh);

            GenerateCutterGameobject(originalGameObject, leftMesh, addRigidbody, Vector3.up);
            GenerateCutterGameobject(originalGameObject, rightMesh, addRigidbody, Vector3.left);

            currentlyCutting = false;
        }
    }
Ejemplo n.º 10
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);
    }
Ejemplo n.º 11
0
    private static void CutTriangle(Plane plane, MeshTriangle triangle, bool [] pointsOnLeftSide, GeneratedMesh leftMesh, GeneratedMesh rightMesh, List <Vector3> addedVertices)
    {
        MeshTriangle leftMeshTriangle  = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], triangle.SubmeshIndices);
        MeshTriangle rightMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], triangle.SubmeshIndices);

        bool left  = false;
        bool right = false;

        for (int i = 0; i < 3; i++)
        {
            if (pointsOnLeftSide[i])
            {
                if (!left)
                {
                    left = true;

                    leftMeshTriangle.Vertices[0] = leftMeshTriangle.Vertices[1] = triangle.Vertices[i];
                    leftMeshTriangle.Uvs[0]      = leftMeshTriangle.Uvs[1] = triangle.Uvs[i];
                    leftMeshTriangle.Normals[0]  = leftMeshTriangle.Normals[1] = triangle.Normals[i];
                }
                else
                {
                    leftMeshTriangle.Vertices[1] = triangle.Vertices[i];
                    leftMeshTriangle.Uvs[1]      = triangle.Uvs[i];
                    leftMeshTriangle.Normals[1]  = triangle.Normals[i];
                }
            }
            else
            {
                if (!right)
                {
                    right = true;

                    rightMeshTriangle.Vertices[0] = rightMeshTriangle.Vertices[1] = triangle.Vertices[i];
                    rightMeshTriangle.Uvs[0]      = rightMeshTriangle.Uvs[1] = triangle.Uvs[i];
                    rightMeshTriangle.Normals[0]  = rightMeshTriangle.Normals[1] = triangle.Normals[i];
                }
                else
                {
                    rightMeshTriangle.Vertices[1] = triangle.Vertices[i];
                    rightMeshTriangle.Uvs[1]      = triangle.Uvs[i];
                    rightMeshTriangle.Normals[1]  = triangle.Normals[i];
                }
            }
        }


        // можно переписать черех цикл и сократить количество кода в 2 раза и вынести в новую функцию добавление новой вершины
        float normalizedDistance;
        float distance;

        plane.Raycast(new Ray(leftMeshTriangle.Vertices[0], (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).normalized), out distance);

        normalizedDistance = distance / (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).magnitude;
        Vector3 vertLeft = Vector3.Lerp(leftMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[0], normalizedDistance);

        addedVertices.Add(vertLeft);

        Vector3 normalLeft = Vector3.Lerp(leftMeshTriangle.Normals[0], rightMeshTriangle.Normals[0], normalizedDistance);
        Vector3 uvLeft     = Vector3.Lerp(leftMeshTriangle.Uvs[0], rightMeshTriangle.Uvs[0], normalizedDistance);

        plane.Raycast(new Ray(leftMeshTriangle.Vertices[1], (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).normalized), out distance);

        normalizedDistance = distance / (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).magnitude;
        Vector3 vertRight = Vector3.Lerp(leftMeshTriangle.Vertices[1], rightMeshTriangle.Vertices[1], normalizedDistance);

        addedVertices.Add(vertRight);

        Vector3 normalRight = Vector3.Lerp(leftMeshTriangle.Normals[1], rightMeshTriangle.Normals[1], normalizedDistance);
        Vector3 uvRight     = Vector3.Lerp(leftMeshTriangle.Uvs[1], rightMeshTriangle.Uvs[1], normalizedDistance);

        // до сюда

        // можно сократить код в 4 раза и вынести в новую функцию
        Vector3[] updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], vertLeft, vertRight };
        Vector3[] updatedNormals  = new Vector3[] { leftMeshTriangle.Normals[0], normalLeft, normalRight };
        Vector2[] updatedUvs      = new Vector2[] { leftMeshTriangle.Uvs[0], uvLeft, uvRight };

        MeshTriangle currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, triangle.SubmeshIndices);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            leftMesh.AddTriangle(currentTriangle);
        }

        updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], leftMeshTriangle.Vertices[1], vertRight };
        updatedNormals  = new Vector3[] { leftMeshTriangle.Normals[0], leftMeshTriangle.Normals[1], normalRight };
        updatedUvs      = new Vector2[] { leftMeshTriangle.Uvs[0], leftMeshTriangle.Uvs[1], uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, triangle.SubmeshIndices);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            leftMesh.AddTriangle(currentTriangle);
        }

        updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], vertLeft, vertRight };
        updatedNormals  = new Vector3[] { rightMeshTriangle.Normals[0], normalLeft, normalRight };
        updatedUvs      = new Vector2[] { rightMeshTriangle.Uvs[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, triangle.SubmeshIndices);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            rightMesh.AddTriangle(currentTriangle);
        }

        updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[1], vertRight };
        updatedNormals  = new Vector3[] { rightMeshTriangle.Normals[0], rightMeshTriangle.Normals[1], normalRight };
        updatedUvs      = new Vector2[] { rightMeshTriangle.Uvs[0], rightMeshTriangle.Uvs[1], uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, triangle.SubmeshIndices);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            rightMesh.AddTriangle(currentTriangle);
        }
        // до сюда
    }
Ejemplo n.º 12
0
    // Fill holl when cutting the triangle
    public static void Fill(List <Vector3> _vertices, Plane _plane, GeneratedMesh _leftMesh, GeneratedMesh _rightMesh, int submeshCount)
    {
        // center of the filling
        Vector3 centerPosition = Vector3.zero;

        for (int i = 0; i < _vertices.Count; i++)
        {
            centerPosition += _vertices[i];
        }
        centerPosition = centerPosition / _vertices.Count;

        Vector3 up = new Vector3()
        {
            x = _plane.normal.x,
            y = _plane.normal.y,
            z = _plane.normal.z
        };

        Vector3 left = Vector3.Cross(_plane.normal, _plane.normal);

        Vector3 displacement = Vector3.zero;
        Vector2 uv1          = Vector2.zero;
        Vector2 uv2          = Vector2.zero;

        // go through edges and eliminate by creating triangles with connected edges
        // each new triangle removes 2 edges but creates 1 new edge
        // keep the chain in order
        for (int i = 0; i < _vertices.Count; i++)
        {
            displacement = _vertices[i] - centerPosition;
            uv1          = new Vector2()
            {
                x = .5f + Vector3.Dot(displacement, left),
                y = .5f + Vector3.Dot(displacement, up)
            };

            displacement = _vertices[(i + 1) % _vertices.Count] - centerPosition;
            uv2          = new Vector2()
            {
                x = .5f + Vector3.Dot(displacement, left),
                y = .5f + Vector3.Dot(displacement, up)
            };

            Vector3[] vertices = new Vector3[] { _vertices[i], _vertices[(i + 1) % _vertices.Count], centerPosition };
            Vector3[] normals  = new Vector3[] { -_plane.normal, -_plane.normal, -_plane.normal };
            Vector2[] uvs      = new Vector2[] { uv1, uv2, new Vector2(0.5f, 0.5f) };
            //Update current triangle
            MeshTriangle currentTriangle = new MeshTriangle(vertices, normals, uvs, submeshCount);

            // check if it is facing the right way
            FacingCheck(currentTriangle);
            // add to left side
            _leftMesh.AddTriangle(currentTriangle);

            normals         = new Vector3[] { _plane.normal, _plane.normal, _plane.normal };
            currentTriangle = new MeshTriangle(vertices, normals, uvs, submeshCount);

            // check if it is facing the right way
            FacingCheck(currentTriangle);
            // add to right side
            _rightMesh.AddTriangle(currentTriangle);
        }
    }
Ejemplo n.º 13
0
    private static void CutTriangle(Plane _plane, MeshTriangle _triangle, bool _triangleALeftSide, bool _triangleBLeftSide, bool _triangleCLeftSide,
                                    GeneratedMesh _leftSide, GeneratedMesh _rightSide, List <Vector3> _addedVertices)
    {
        List <bool> leftSide = new List <bool>();

        leftSide.Add(_triangleALeftSide);
        leftSide.Add(_triangleBLeftSide);
        leftSide.Add(_triangleCLeftSide);


        MeshTriangle leftMeshTriangle  = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex);
        MeshTriangle rightMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex);
        MeshTriangle meshTriangle      = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex);

        bool left  = false;
        bool right = false;

        for (int i = 0; i < 3; i++)
        {
            if (leftSide[i])// left
            {
                if (!left)
                {
                    left = true;
                    leftMeshTriangle.Vertices[0] = _triangle.Vertices[i];
                    leftMeshTriangle.Vertices[1] = leftMeshTriangle.Vertices[0];

                    leftMeshTriangle.Uvs[0] = _triangle.Uvs[i];
                    leftMeshTriangle.Uvs[1] = leftMeshTriangle.Uvs[0];

                    leftMeshTriangle.Normals[0] = _triangle.Normals[i];
                    leftMeshTriangle.Normals[1] = leftMeshTriangle.Normals[0];
                }
                else
                {
                    leftMeshTriangle.Vertices[1] = _triangle.Vertices[i];
                    leftMeshTriangle.Normals[1]  = _triangle.Normals[i];
                    leftMeshTriangle.Uvs[1]      = _triangle.Uvs[i];
                }
            }
            else  // right
            {
                if (!right)
                {
                    right = true;
                    rightMeshTriangle.Vertices[0] = _triangle.Vertices[i];
                    rightMeshTriangle.Vertices[1] = rightMeshTriangle.Vertices[0];

                    rightMeshTriangle.Uvs[0] = _triangle.Uvs[i];
                    rightMeshTriangle.Uvs[1] = rightMeshTriangle.Uvs[0];

                    rightMeshTriangle.Normals[0] = _triangle.Normals[i];
                    rightMeshTriangle.Normals[1] = rightMeshTriangle.Normals[0];
                }
                else
                {
                    rightMeshTriangle.Vertices[1] = _triangle.Vertices[i];
                    rightMeshTriangle.Normals[1]  = _triangle.Normals[i];
                    rightMeshTriangle.Uvs[1]      = _triangle.Uvs[i];
                }
            }
        }

        // now to find the intersection points between the solo point and the others
        float   normalizeDistance;
        float   distance;
        Vector3 edgeVector = Vector3.zero; // edge lenght and direction

        edgeVector = rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0];
        _plane.Raycast(new Ray(leftMeshTriangle.Vertices[0], edgeVector.normalized), out distance);

        normalizeDistance = distance / edgeVector.magnitude;
        Vector3 vertLeft   = Vector3.Lerp(leftMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[0], normalizeDistance);
        Vector3 normalLeft = Vector3.Lerp(leftMeshTriangle.Normals[0], rightMeshTriangle.Normals[0], normalizeDistance);
        Vector2 uvLeft     = Vector2.Lerp(leftMeshTriangle.Uvs[0], rightMeshTriangle.Uvs[0], normalizeDistance);

        edgeVector = rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1];
        _plane.Raycast(new Ray(leftMeshTriangle.Vertices[1], edgeVector.normalized), out distance);

        normalizeDistance = distance / edgeVector.magnitude;
        Vector3 vertRight   = Vector3.Lerp(leftMeshTriangle.Vertices[1], rightMeshTriangle.Vertices[1], normalizeDistance);
        Vector3 normalRight = Vector3.Lerp(leftMeshTriangle.Normals[1], rightMeshTriangle.Normals[1], normalizeDistance);
        Vector2 uvRight     = Vector2.Lerp(leftMeshTriangle.Uvs[1], rightMeshTriangle.Uvs[1], normalizeDistance);

        if (vertLeft != vertRight)
        {
            //tracking newly created points
            _addedVertices.Add(vertLeft);
            _addedVertices.Add(vertRight);
        }

        // make the new triangles
        MeshTriangle currentTriangle;

        Vector3[] updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], vertLeft, vertRight };
        Vector3[] updatedNormals  = new Vector3[] { leftMeshTriangle.Normals[0], normalLeft, normalRight };
        Vector2[] updatedUvs      = new Vector2[] { leftMeshTriangle.Uvs[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, _triangle.SubmeshIndex);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            // check if it is facing the right way
            FacingCheck(currentTriangle);
            // add it
            _leftSide.AddTriangle(currentTriangle);
        }


        updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], leftMeshTriangle.Vertices[1], vertRight };
        updatedNormals  = new Vector3[] { leftMeshTriangle.Normals[0], leftMeshTriangle.Normals[1], normalRight };
        updatedUvs      = new Vector2[] { leftMeshTriangle.Uvs[0], leftMeshTriangle.Uvs[1], uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, _triangle.SubmeshIndex);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            // check if it is facing the right way
            FacingCheck(currentTriangle);
            // add it
            _leftSide.AddTriangle(currentTriangle);
        }


        updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], vertLeft, vertRight };
        updatedNormals  = new Vector3[] { rightMeshTriangle.Normals[0], normalLeft, normalRight };
        updatedUvs      = new Vector2[] { rightMeshTriangle.Uvs[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, _triangle.SubmeshIndex);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            // check if it is facing the right way
            FacingCheck(currentTriangle);
            // add it
            _rightSide.AddTriangle(currentTriangle);
        }


        updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[1], vertRight };
        updatedNormals  = new Vector3[] { rightMeshTriangle.Normals[0], rightMeshTriangle.Normals[1], normalRight };
        updatedUvs      = new Vector2[] { rightMeshTriangle.Uvs[0], rightMeshTriangle.Uvs[1], uvRight };


        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUvs, _triangle.SubmeshIndex);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            // check if it is facing the right way
            FacingCheck(currentTriangle);
            // add it
            _rightSide.AddTriangle(currentTriangle);
        }
    }
Ejemplo n.º 14
0
    private static void CutTriangle(Plane plane, MeshTriangle triangle, bool triALeftSide, bool triBLeftSide, bool triCLeftSide, GeneratedMesh lMesh, GeneratedMesh rMesh, List <Vector3> addVertices)
    {
        List <bool> leftSide = new List <bool>();

        leftSide.Add(triALeftSide);
        leftSide.Add(triBLeftSide);
        leftSide.Add(triCLeftSide);

        MeshTriangle leftMeshTriangle  = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], triangle.SubMeshIndex);
        MeshTriangle rightMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], triangle.SubMeshIndex);

        bool left  = false;
        bool right = false;

        for (int i = 0; i < 3; i++)
        {
            if (leftSide[i])
            {
                if (!left)
                {
                    left = true;

                    leftMeshTriangle.Vertices[0] = triangle.Vertices[i];
                    leftMeshTriangle.Vertices[1] = leftMeshTriangle.Vertices[0];

                    leftMeshTriangle.UVs[0] = triangle.UVs[i];
                    leftMeshTriangle.UVs[1] = leftMeshTriangle.UVs[0];

                    leftMeshTriangle.Normals[0] = triangle.Normals[i];
                    leftMeshTriangle.Normals[1] = leftMeshTriangle.Normals[0];
                }
                else
                {
                    leftMeshTriangle.Vertices[1] = triangle.Vertices[i];
                    leftMeshTriangle.UVs[1]      = triangle.UVs[i];
                    leftMeshTriangle.Normals[1]  = triangle.Normals[i];
                }
            }
            else
            {
                if (!right)
                {
                    right = true;

                    rightMeshTriangle.Vertices[0] = triangle.Vertices[i];
                    rightMeshTriangle.Vertices[1] = rightMeshTriangle.Vertices[0];

                    rightMeshTriangle.UVs[0] = triangle.UVs[i];
                    rightMeshTriangle.UVs[1] = rightMeshTriangle.UVs[0];

                    rightMeshTriangle.Normals[0] = triangle.Normals[i];
                    rightMeshTriangle.Normals[1] = rightMeshTriangle.Normals[0];
                }
                else
                {
                    rightMeshTriangle.Vertices[1] = triangle.Vertices[i];
                    rightMeshTriangle.UVs[1]      = triangle.UVs[i];
                    rightMeshTriangle.Normals[1]  = triangle.Normals[i];
                }
            }
        }
        float normalizedDistance;
        float distance;

        plane.Raycast(new Ray(leftMeshTriangle.Vertices[0], (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).normalized), out distance);

        normalizedDistance = distance / (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).magnitude;
        Vector3 vertLeft = Vector3.Lerp(leftMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[0], normalizedDistance);

        addVertices.Add(vertLeft);

        Vector3 normalLeft = Vector3.Lerp(leftMeshTriangle.Normals[0], rightMeshTriangle.Normals[0], normalizedDistance);
        Vector2 uvLeft     = Vector2.Lerp(leftMeshTriangle.UVs[0], rightMeshTriangle.UVs[0], normalizedDistance);

        plane.Raycast(new Ray(leftMeshTriangle.Vertices[1], (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).normalized), out distance);

        normalizedDistance = distance / (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).magnitude;
        Vector3 vertRight = Vector3.Lerp(leftMeshTriangle.Vertices[1], rightMeshTriangle.Vertices[1], normalizedDistance);

        addVertices.Add(vertRight);

        Vector3 normalRight = Vector3.Lerp(leftMeshTriangle.Normals[1], rightMeshTriangle.Normals[1], normalizedDistance);
        Vector2 uvRight     = Vector2.Lerp(leftMeshTriangle.UVs[1], rightMeshTriangle.UVs[1], normalizedDistance);

        MeshTriangle currentTriangle;

        Vector3[] updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], vertLeft, vertRight };
        Vector3[] updatedNormals  = new Vector3[] { leftMeshTriangle.Normals[0], normalLeft, normalRight };
        Vector2[] updatedUVs      = new Vector2[] { leftMeshTriangle.UVs[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, triangle.SubMeshIndex);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            lMesh.AddTriangle(currentTriangle);
        }

        updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], leftMeshTriangle.Vertices[1], vertRight };
        updatedNormals  = new Vector3[] { leftMeshTriangle.Normals[0], leftMeshTriangle.Normals[1], normalRight };
        updatedUVs      = new Vector2[] { leftMeshTriangle.UVs[0], leftMeshTriangle.UVs[1], uvRight };


        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, triangle.SubMeshIndex);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            lMesh.AddTriangle(currentTriangle);
        }

        updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], vertLeft, vertRight };
        updatedNormals  = new Vector3[] { rightMeshTriangle.Normals[0], normalLeft, normalRight };
        updatedUVs      = new Vector2[] { rightMeshTriangle.UVs[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, triangle.SubMeshIndex);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            rMesh.AddTriangle(currentTriangle);
        }

        updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[1], vertRight };
        updatedNormals  = new Vector3[] { rightMeshTriangle.Normals[0], rightMeshTriangle.Normals[1], normalRight };
        updatedUVs      = new Vector2[] { rightMeshTriangle.UVs[0], rightMeshTriangle.UVs[1], uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, triangle.SubMeshIndex);

        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangle(currentTriangle);
            }
            rMesh.AddTriangle(currentTriangle);
        }
    }
Ejemplo n.º 15
0
    private static void CutTriangle(Plane _plane, MeshTriangle _triangle, bool _triangleALeftSide, bool _triangleBLeftSide, bool _triangleCLeftSide,
                                    GeneratedMesh _leftSide, GeneratedMesh _rightSide, List <Vector3> _addedVertices)
    {
        List <bool> leftSide = new List <bool>();

        leftSide.Add(_triangleALeftSide);
        leftSide.Add(_triangleBLeftSide);
        leftSide.Add(_triangleCLeftSide);

        MeshTriangle leftMeshTriangle  = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex);
        MeshTriangle rightMeshTriangle = new MeshTriangle(new Vector3[2], new Vector3[2], new Vector2[2], _triangle.SubmeshIndex);

        bool left  = false;
        bool right = false;

        for (int i = 0; i < 3; i++)
        {
            if (leftSide[i])
            {
                if (!left)
                {
                    left = true;

                    leftMeshTriangle.Vertices[0] = _triangle.Vertices[i];
                    leftMeshTriangle.Vertices[1] = leftMeshTriangle.Vertices[0];

                    leftMeshTriangle.UVs[0] = _triangle.UVs[i];
                    leftMeshTriangle.UVs[1] = leftMeshTriangle.UVs[0];

                    leftMeshTriangle.Normals[0] = _triangle.Normals[i];
                    leftMeshTriangle.Normals[1] = leftMeshTriangle.Normals[0];
                }
                else
                {
                    leftMeshTriangle.Vertices[1] = _triangle.Vertices[i];
                    leftMeshTriangle.Normals[1]  = _triangle.Normals[i];
                    leftMeshTriangle.UVs[1]      = _triangle.UVs[i];
                }
            }
            else
            {
                if (!right)
                {
                    right = true;

                    rightMeshTriangle.Vertices[0] = _triangle.Vertices[i];
                    rightMeshTriangle.Vertices[1] = rightMeshTriangle.Vertices[0];

                    rightMeshTriangle.UVs[0] = _triangle.UVs[i];
                    rightMeshTriangle.UVs[1] = rightMeshTriangle.UVs[0];

                    rightMeshTriangle.Normals[0] = _triangle.Normals[i];
                    rightMeshTriangle.Normals[1] = rightMeshTriangle.Normals[0];
                }
                else
                {
                    rightMeshTriangle.Vertices[1] = _triangle.Vertices[i];
                    rightMeshTriangle.Normals[1]  = _triangle.Normals[i];
                    rightMeshTriangle.UVs[1]      = _triangle.UVs[i];
                }
            }
        }

        float normalizedDistance;
        float distance;

        _plane.Raycast(new Ray(leftMeshTriangle.Vertices[0], (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).normalized), out distance);

        normalizedDistance = distance / (rightMeshTriangle.Vertices[0] - leftMeshTriangle.Vertices[0]).magnitude;
        Vector3 vertLeft = Vector3.Lerp(leftMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[0], normalizedDistance);

        _addedVertices.Add(vertLeft);

        Vector3 normalLeft = Vector3.Lerp(leftMeshTriangle.Normals[0], rightMeshTriangle.Normals[0], normalizedDistance);
        Vector2 uvLeft     = Vector2.Lerp(leftMeshTriangle.UVs[0], rightMeshTriangle.UVs[0], normalizedDistance);

        _plane.Raycast(new Ray(leftMeshTriangle.Vertices[1], (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).normalized), out distance);

        normalizedDistance = distance / (rightMeshTriangle.Vertices[1] - leftMeshTriangle.Vertices[1]).magnitude;
        Vector3 vertRight = Vector3.Lerp(leftMeshTriangle.Vertices[1], rightMeshTriangle.Vertices[1], normalizedDistance);

        _addedVertices.Add(vertRight);

        Vector3 normalRight = Vector3.Lerp(leftMeshTriangle.Normals[1], rightMeshTriangle.Normals[1], normalizedDistance);
        Vector2 uvRight     = Vector2.Lerp(leftMeshTriangle.UVs[1], rightMeshTriangle.UVs[1], normalizedDistance);

        //TESTING OUR FIRST TRIANGLE
        MeshTriangle currentTriangle;

        Vector3[] updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], vertLeft, vertRight };
        Vector3[] updatedNormals  = new Vector3[] { leftMeshTriangle.Normals[0], normalLeft, normalRight };
        Vector2[] updatedUVs      = new Vector2[] { leftMeshTriangle.UVs[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex);

        //If our vertices arent the same
        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangel(currentTriangle);
            }
            _leftSide.AddTriangle(currentTriangle);
        }

        //SECOND TRIANGLE
        updatedVertices = new Vector3[] { leftMeshTriangle.Vertices[0], leftMeshTriangle.Vertices[1], vertRight };
        updatedNormals  = new Vector3[] { leftMeshTriangle.Normals[0], leftMeshTriangle.Normals[1], normalRight };
        updatedUVs      = new Vector2[] { leftMeshTriangle.UVs[0], leftMeshTriangle.UVs[1], uvRight };


        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex);
        //If our vertices arent the same
        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangel(currentTriangle);
            }
            _leftSide.AddTriangle(currentTriangle);
        }

        //THIRD TRIANGLE
        updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], vertLeft, vertRight };
        updatedNormals  = new Vector3[] { rightMeshTriangle.Normals[0], normalLeft, normalRight };
        updatedUVs      = new Vector2[] { rightMeshTriangle.UVs[0], uvLeft, uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex);
        //If our vertices arent the same
        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangel(currentTriangle);
            }
            _rightSide.AddTriangle(currentTriangle);
        }

        //FOURTH TRIANGLE
        updatedVertices = new Vector3[] { rightMeshTriangle.Vertices[0], rightMeshTriangle.Vertices[1], vertRight };
        updatedNormals  = new Vector3[] { rightMeshTriangle.Normals[0], rightMeshTriangle.Normals[1], normalRight };
        updatedUVs      = new Vector2[] { rightMeshTriangle.UVs[0], rightMeshTriangle.UVs[1], uvRight };

        currentTriangle = new MeshTriangle(updatedVertices, updatedNormals, updatedUVs, _triangle.SubmeshIndex);
        //If our vertices arent the same
        if (updatedVertices[0] != updatedVertices[1] && updatedVertices[0] != updatedVertices[2])
        {
            if (Vector3.Dot(Vector3.Cross(updatedVertices[1] - updatedVertices[0], updatedVertices[2] - updatedVertices[0]), updatedNormals[0]) < 0)
            {
                FlipTriangel(currentTriangle);
            }
            _rightSide.AddTriangle(currentTriangle);
        }
    }
Ejemplo n.º 16
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.InverseTransformPoint(_contactPoint));

        originalGameObject = _originalGameObject;
        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]);

                /*
                 *  Three different cases:
                 *  - The triangle is either above the plane
                 *  - The triangle is below the plane
                 *  - The place intersects the triangle
                 */
                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 either mesh has no vertices, return
        if (leftMesh.Vertices.Count == 0 || rightMesh.Vertices.Count == 0 || addedVertices.Count == 0)
        {
            currentlyCutting = false;
            return;
        }

        FillCut(addedVertices, plane, leftMesh, rightMesh);

        GenerateGameObject(leftMesh);
        GenerateGameObject(rightMesh);
        Object.Destroy(_originalGameObject);
        currentlyCutting = false;
    }
Ejemplo n.º 17
0
    public static void Fill(List <Vector3> _vertices, Plane _plane, GeneratedMesh _leftMesh, GeneratedMesh _rightMesh)
    {
        //Firstly we need the center we do this by adding up all the vertices and then calculating the average
        Vector3 centerPosition = Vector3.zero;

        for (int i = 0; i < _vertices.Count; i++)
        {
            centerPosition += _vertices[i];
        }
        centerPosition = centerPosition / _vertices.Count;

        //We now need an Upward Axis we use the plane we cut the mesh with for that
        Vector3 up = new Vector3()
        {
            x = _plane.normal.x,
            y = _plane.normal.y,
            z = _plane.normal.z
        };

        Vector3 left = Vector3.Cross(_plane.normal, up);

        Vector3 displacement = Vector3.zero;
        Vector2 uv1          = Vector2.zero;
        Vector2 uv2          = Vector2.zero;

        for (int i = 0; i < _vertices.Count; i++)
        {
            displacement = _vertices[i] - centerPosition;
            uv1          = new Vector2()
            {
                x = .5f + Vector3.Dot(displacement, left),
                y = .5f + Vector3.Dot(displacement, up)
            };

            displacement = _vertices[(i + 1) % _vertices.Count] - centerPosition;
            uv2          = new Vector2()
            {
                x = .5f + Vector3.Dot(displacement, left),
                y = .5f + Vector3.Dot(displacement, up)
            };

            Vector3[] vertices = new Vector3[] { _vertices[i], _vertices[(i + 1) % _vertices.Count], centerPosition };
            Vector3[] normals  = new Vector3[] { -_plane.normal, -_plane.normal, -_plane.normal };
            Vector2[] uvs      = new Vector2[] { uv1, uv2, new Vector2(0.5f, 0.5f) };

            MeshTriangle currentTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount + 1);

            if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0)
            {
                FlipTriangel(currentTriangle);
            }
            _leftMesh.AddTriangle(currentTriangle);

            normals         = new Vector3[] { _plane.normal, _plane.normal, _plane.normal };
            currentTriangle = new MeshTriangle(vertices, normals, uvs, originalMesh.subMeshCount + 1);

            if (Vector3.Dot(Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]), normals[0]) < 0)
            {
                FlipTriangel(currentTriangle);
            }
            _rightMesh.AddTriangle(currentTriangle);
        }
    }
Ejemplo n.º 18
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;
    }