Пример #1
0
    /// <summary>
    /// Yeah
    /// </summary>
    /// <param name="victim">self discribed</param>
    /// <param name="anchorPoint">blade world position</param>
    /// <param name="normalDirection">blade right direction</param>
    /// <param name="capMaterial">Meat</param>
    /// <returns></returns>
    public static GameObject[] Cut(GameObject victim, Vector3 anchorPoint, Vector3 normalDirection, Material capMaterial)
    {
        // set the blade relative to victim
        _blade = new Plane(victim.transform.InverseTransformDirection(-normalDirection),
                           victim.transform.InverseTransformPoint(anchorPoint));

        // get the victims mesh
        _victim_mesh = victim.GetComponent <MeshFilter>().mesh;

        // two new meshes
        _leftSide.Clear();
        _rightSide.Clear();
        _newVerticesCache.Clear();


        int index_1, index_2, index_3;

        var mesh_vertices = _victim_mesh.vertices;
        var mesh_normals  = _victim_mesh.normals;
        var mesh_uvs      = _victim_mesh.uv;
        var mesh_tangents = _victim_mesh.tangents;

        if (mesh_tangents != null && mesh_tangents.Length == 0)
        {
            mesh_tangents = null;
        }

        // go through the submeshes
        for (int submeshIterator = 0; submeshIterator < _victim_mesh.subMeshCount; submeshIterator++)
        {
            // Triangles
            var indices = _victim_mesh.GetTriangles(submeshIterator);

            for (int i = 0; i < indices.Length; i += 3)
            {
                index_1 = indices[i];
                index_2 = indices[i + 1];
                index_3 = indices[i + 2];

                // verts
                _triangleCache.vertices[0] = mesh_vertices[index_1];
                _triangleCache.vertices[1] = mesh_vertices[index_2];
                _triangleCache.vertices[2] = mesh_vertices[index_3];

                // normals
                _triangleCache.normals[0] = mesh_normals[index_1];
                _triangleCache.normals[1] = mesh_normals[index_2];
                _triangleCache.normals[2] = mesh_normals[index_3];

                // uvs
                _triangleCache.uvs[0] = mesh_uvs[index_1];
                _triangleCache.uvs[1] = mesh_uvs[index_2];
                _triangleCache.uvs[2] = mesh_uvs[index_3];

                // tangents
                if (mesh_tangents != null)
                {
                    _triangleCache.tangents[0] = mesh_tangents[index_1];
                    _triangleCache.tangents[1] = mesh_tangents[index_2];
                    _triangleCache.tangents[2] = mesh_tangents[index_3];
                }
                else
                {
                    _triangleCache.tangents[0] = Vector4.zero;
                    _triangleCache.tangents[1] = Vector4.zero;
                    _triangleCache.tangents[2] = Vector4.zero;
                }

                // which side are the vertices on
                _isLeftSideCache[0] = _blade.GetSide(mesh_vertices[index_1]);
                _isLeftSideCache[1] = _blade.GetSide(mesh_vertices[index_2]);
                _isLeftSideCache[2] = _blade.GetSide(mesh_vertices[index_3]);


                // whole triangle
                if (_isLeftSideCache[0] == _isLeftSideCache[1] && _isLeftSideCache[0] == _isLeftSideCache[2])
                {
                    if (_isLeftSideCache[0]) // left side
                    {
                        _leftSide.AddTriangle(_triangleCache, submeshIterator);
                    }
                    else // right side
                    {
                        _rightSide.AddTriangle(_triangleCache, submeshIterator);
                    }
                }
                else
                { // cut the triangle
                    Cut_this_Face(ref _triangleCache, submeshIterator);
                }
            }
        }

        // The capping Material will be at the end
        Material[] mats = victim.GetComponent <MeshRenderer>().sharedMaterials;
        if (mats[mats.Length - 1].name != capMaterial.name)
        {
            Material[] newMats = new Material[mats.Length + 1];
            mats.CopyTo(newMats, 0);
            newMats[mats.Length] = capMaterial;
            mats = newMats;
        }
        _capMatSub = mats.Length - 1; // for later use

        // cap the opennings
        Cap_the_Cut();


        // Left Mesh
        Mesh left_HalfMesh = _leftSide.GetMesh();

        left_HalfMesh.name = "Split Mesh Left";

        // Right Mesh
        Mesh right_HalfMesh = _rightSide.GetMesh();

        right_HalfMesh.name = "Split Mesh Right";

        // assign the game objects

        victim.name = "left side";
        victim.GetComponent <MeshFilter>().mesh = left_HalfMesh;

        GameObject leftSideObj = victim;

        GameObject rightSideObj = new GameObject("right side", typeof(MeshFilter), typeof(MeshRenderer));

        rightSideObj.transform.position = victim.transform.position;
        rightSideObj.transform.rotation = victim.transform.rotation;
        rightSideObj.GetComponent <MeshFilter>().mesh = right_HalfMesh;

        if (victim.transform.parent != null)
        {
            rightSideObj.transform.parent = victim.transform.parent;
        }

        rightSideObj.transform.localScale = victim.transform.localScale;


        // assign mats
        leftSideObj.GetComponent <MeshRenderer>().materials  = mats;
        rightSideObj.GetComponent <MeshRenderer>().materials = mats;

        return(new GameObject[] { leftSideObj, rightSideObj });
    }