コード例 #1
0
        private void AddTriangle(int[] indices, int submesh)
        {
            // vertices
            Vector3[] verts = new Vector3[3] {
                segmentSourceMesh.vertices[indices[0]],
                segmentSourceMesh.vertices[indices[1]],
                segmentSourceMesh.vertices[indices[2]]
            };
            // normals
            Vector3[] norms = new Vector3[3] {
                segmentSourceMesh.normals[indices[0]],
                segmentSourceMesh.normals[indices[1]],
                segmentSourceMesh.normals[indices[2]]
            };
            // uvs
            Vector2[] uvs = new Vector2[3] {
                segmentSourceMesh.uv[indices[0]],
                segmentSourceMesh.uv[indices[1]],
                segmentSourceMesh.uv[indices[2]]
            };
            // tangent
            Vector4[] tangents = new Vector4[3] {
                segmentSourceMesh.tangents[indices[0]],
                segmentSourceMesh.tangents[indices[1]],
                segmentSourceMesh.tangents[indices[2]]
            };

            // apply offset
            float   lerpValue = 0.0f;
            Vector3 pointA, pointB;
            Vector3 normA, normB;
            Vector4 tangentA, tangentB;
            //Matrix4x4 4*4 矩阵;Transform.localToWorldMatrix 局部转世界矩阵
            Matrix4x4 localToWorld_A = _helpTransform1.localToWorldMatrix;
            Matrix4x4 localToWorld_B = _helpTransform2.localToWorldMatrix;
            Matrix4x4 worldToLocal   = transform.worldToLocalMatrix;

            for (int i = 0; i < 3; i++)
            {
                lerpValue  = Math_Functions.Value_from_another_Scope(verts[i].z, _segment_MinZ, _segment_MaxZ, 0.0f, 1.0f);
                verts[i].z = 0.0f;

                pointA = localToWorld_A.MultiplyPoint(verts[i]); // to world
                pointB = localToWorld_B.MultiplyPoint(verts[i]);

                verts[i] = worldToLocal.MultiplyPoint(Vector3.Lerp(pointA, pointB, lerpValue)); // to local

                normA = localToWorld_A.MultiplyVector(norms[i]);
                normB = localToWorld_B.MultiplyVector(norms[i]);

                norms[i] = worldToLocal.MultiplyVector(Vector3.Lerp(normA, normB, lerpValue));

                tangentA = localToWorld_A.MultiplyVector(tangents[i]);
                tangentB = localToWorld_B.MultiplyVector(tangents[i]);

                tangents[i] = worldToLocal.MultiplyVector(Vector3.Lerp(tangentA, tangentB, lerpValue));
            }

            _maker.AddTriangle(verts, norms, uvs, tangents, submesh);
        }
コード例 #2
0
        public void AddTriangle(int[] indices, int submesh)
        {
            // vertices
            Vector3[] verts = new Vector3[3] {
                segment_sourceMesh.vertices[indices[0]],
                segment_sourceMesh.vertices[indices[1]],
                segment_sourceMesh.vertices[indices[2]]
            };
            // normals
            Vector3[] norms = new Vector3[3] {
                segment_sourceMesh.normals[indices[0]],
                segment_sourceMesh.normals[indices[1]],
                segment_sourceMesh.normals[indices[2]]
            };

            // uvs
            Vector2[] uvs = new Vector2[3] {
                segment_sourceMesh.uv[indices[0]],
                segment_sourceMesh.uv[indices[1]],
                segment_sourceMesh.uv[indices[2]]
            };

            // apply offset
            float   lerpValue = 0.0f;
            Vector3 pointA, pointB;
            Vector3 normA, normB;

            for (int i = 0; i < 3; i++)
            {
                lerpValue  = Math_Functions.Value_from_another_Scope(verts[i].z, _segment_MinZ, _segment_MaxZ, 0.0f, 1.0f);
                verts[i].z = 0.0f;

                pointA = _helpTransform1.TransformPoint(verts[i]);                 // to world
                pointB = _helpTransform2.TransformPoint(verts[i]);

                verts[i] = transform.InverseTransformPoint(Vector3.Lerp(pointA, pointB, lerpValue));                // to local

                normA = _helpTransform1.TransformDirection(norms[i]);
                normB = _helpTransform2.TransformDirection(norms[i]);

                norms[i] = transform.InverseTransformDirection(Vector3.Lerp(normA, normB, lerpValue));
            }

            _maker.AddTriangle(verts, norms, uvs, submesh);
        }
コード例 #3
0
ファイル: MeshCut.cs プロジェクト: lefton22/qs399_CodeLab1WK6
        /// <summary>
        /// Cut the specified victim
        /// </summary>
        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;

            // reset values
            _new_vertices.Clear();

            _leftSide  = new Mesh_Maker();
            _rightSide = new Mesh_Maker();


            bool[] sides = new bool[3];
            int[]  indices;
            int    p1, p2, p3;

            // go throught the submeshes
            for (int sub = 0; sub < _victim_mesh.subMeshCount; sub++)
            {
                indices = _victim_mesh.GetTriangles(sub);

                for (int i = 0; i < indices.Length; i += 3)
                {
                    p1 = indices[i];
                    p2 = indices[i + 1];
                    p3 = indices[i + 2];

                    sides[0] = _blade.GetSide(_victim_mesh.vertices[p1]);
                    sides[1] = _blade.GetSide(_victim_mesh.vertices[p2]);
                    sides[2] = _blade.GetSide(_victim_mesh.vertices[p3]);


                    // whole triangle
                    if (sides[0] == sides[1] && sides[0] == sides[2])
                    {
                        if (sides[0])                         // left side

                        {
                            _leftSide.AddTriangle(
                                new Vector3[] { _victim_mesh.vertices[p1], _victim_mesh.vertices[p2], _victim_mesh.vertices[p3] },
                                new Vector3[] { _victim_mesh.normals[p1], _victim_mesh.normals[p2], _victim_mesh.normals[p3] },
                                new Vector2[] { _victim_mesh.uv[p1], _victim_mesh.uv[p2], _victim_mesh.uv[p3] },
                                new Vector4[] { _victim_mesh.tangents[p1], _victim_mesh.tangents[p2], _victim_mesh.tangents[p3] },
                                sub);
                        }
                        else
                        {
                            _rightSide.AddTriangle(
                                new Vector3[] { _victim_mesh.vertices[p1], _victim_mesh.vertices[p2], _victim_mesh.vertices[p3] },
                                new Vector3[] { _victim_mesh.normals[p1], _victim_mesh.normals[p2], _victim_mesh.normals[p3] },
                                new Vector2[] { _victim_mesh.uv[p1], _victim_mesh.uv[p2], _victim_mesh.uv[p3] },
                                new Vector4[] { _victim_mesh.tangents[p1], _victim_mesh.tangents[p2], _victim_mesh.tangents[p3] },
                                sub);
                        }
                    }
                    else                       // cut the triangle

                    {
                        Cut_this_Face(
                            new Vector3[] { _victim_mesh.vertices[p1], _victim_mesh.vertices[p2], _victim_mesh.vertices[p3] },
                            new Vector3[] { _victim_mesh.normals[p1], _victim_mesh.normals[p2], _victim_mesh.normals[p3] },
                            new Vector2[] { _victim_mesh.uv[p1], _victim_mesh.uv[p2], _victim_mesh.uv[p3] },
                            new Vector4[] { _victim_mesh.tangents[p1], _victim_mesh.tangents[p2], _victim_mesh.tangents[p3] },
                            sub);
                    }
                }
            }

            // 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
            Capping();


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


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

            return(new GameObject[] { leftSideObj, rightSideObj });
        }
コード例 #4
0
ファイル: MeshCut.cs プロジェクト: lefton22/qs399_CodeLab1WK6
        /// <summary>
        ///  I have no idea how I made this work
        /// </summary>
        private static void Cut_this_Face(
            Vector3[] vertices,
            Vector3[] normals,
            Vector2[] uvs,
            Vector4[] tangents,
            int submesh)
        {
            bool[] sides = new bool[3];
            sides[0] = _blade.GetSide(vertices[0]);             // true = left
            sides[1] = _blade.GetSide(vertices[1]);
            sides[2] = _blade.GetSide(vertices[2]);


            Vector3[] leftPoints    = new Vector3[2];
            Vector3[] leftNormals   = new Vector3[2];
            Vector2[] leftUvs       = new Vector2[2];
            Vector4[] leftTangents  = new Vector4[2];
            Vector3[] rightPoints   = new Vector3[2];
            Vector3[] rightNormals  = new Vector3[2];
            Vector2[] rightUvs      = new Vector2[2];
            Vector4[] rightTangents = new Vector4[2];

            bool didset_left  = false;
            bool didset_right = false;

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

                        leftPoints[0]   = vertices[i];
                        leftPoints[1]   = leftPoints[0];
                        leftUvs[0]      = uvs[i];
                        leftUvs[1]      = leftUvs[0];
                        leftNormals[0]  = normals[i];
                        leftNormals[1]  = leftNormals[0];
                        leftTangents[0] = tangents[i];
                        leftTangents[1] = leftTangents[0];
                    }
                    else
                    {
                        leftPoints[1]   = vertices[i];
                        leftUvs[1]      = uvs[i];
                        leftNormals[1]  = normals[i];
                        leftTangents[1] = tangents[i];
                    }
                }
                else
                {
                    if (!didset_right)
                    {
                        didset_right = true;

                        rightPoints[0]   = vertices[i];
                        rightPoints[1]   = rightPoints[0];
                        rightUvs[0]      = uvs[i];
                        rightUvs[1]      = rightUvs[0];
                        rightNormals[0]  = normals[i];
                        rightNormals[1]  = rightNormals[0];
                        rightTangents[0] = tangents[i];
                        rightTangents[1] = rightTangents[0];
                    }
                    else
                    {
                        rightPoints[1]   = vertices[i];
                        rightUvs[1]      = uvs[i];
                        rightNormals[1]  = normals[i];
                        rightTangents[1] = tangents[i];
                    }
                }
            }


            float normalizedDistance = 0.0f;
            float distance           = 0;

            _blade.Raycast(new Ray(leftPoints[0], (rightPoints[0] - leftPoints[0]).normalized), out distance);

            normalizedDistance = distance / (rightPoints[0] - leftPoints[0]).magnitude;
            Vector3 newVertex1  = Vector3.Lerp(leftPoints[0], rightPoints[0], normalizedDistance);
            Vector2 newUv1      = Vector2.Lerp(leftUvs[0], rightUvs[0], normalizedDistance);
            Vector3 newNormal1  = Vector3.Lerp(leftNormals[0], rightNormals[0], normalizedDistance);
            Vector4 newTangent1 = Vector3.Lerp(leftTangents[0], rightTangents[0], normalizedDistance);

            _new_vertices.Add(newVertex1);

            _blade.Raycast(new Ray(leftPoints[1], (rightPoints[1] - leftPoints[1]).normalized), out distance);

            normalizedDistance = distance / (rightPoints[1] - leftPoints[1]).magnitude;
            Vector3 newVertex2  = Vector3.Lerp(leftPoints[1], rightPoints[1], normalizedDistance);
            Vector2 newUv2      = Vector2.Lerp(leftUvs[1], rightUvs[1], normalizedDistance);
            Vector3 newNormal2  = Vector3.Lerp(leftNormals[1], rightNormals[1], normalizedDistance);
            Vector4 newTangent2 = Vector3.Lerp(leftTangents[1], rightTangents[1], normalizedDistance);


            _new_vertices.Add(newVertex2);


            // first triangle

            Vector3[] final_verts    = new Vector3[] { leftPoints[0], newVertex1, newVertex2 };
            Vector3[] final_norms    = new Vector3[] { leftNormals[0], newNormal1, newNormal2 };
            Vector2[] final_uvs      = new Vector2[] { leftUvs[0], newUv1, newUv2 };
            Vector4[] final_tangents = new Vector4[] { leftTangents[0], newTangent1, newTangent2 };

            if (Vector3.Dot(Vector3.Cross(final_verts[1] - final_verts[0], final_verts[2] - final_verts[0]), final_norms[0]) < 0)
            {
                FlipFace(final_verts, final_norms, final_uvs, final_tangents);
            }

            _leftSide.AddTriangle(final_verts, final_norms, final_uvs, final_tangents, submesh);

            // second triangle

            final_verts    = new Vector3[] { leftPoints[0], leftPoints[1], newVertex2 };
            final_norms    = new Vector3[] { leftNormals[0], leftNormals[1], newNormal2 };
            final_uvs      = new Vector2[] { leftUvs[0], leftUvs[1], newUv2 };
            final_tangents = new Vector4[] { leftTangents[0], leftTangents[1], newTangent2 };

            if (Vector3.Dot(Vector3.Cross(final_verts[1] - final_verts[0], final_verts[2] - final_verts[0]), final_norms[0]) < 0)
            {
                FlipFace(final_verts, final_norms, final_uvs, final_tangents);
            }

            _leftSide.AddTriangle(final_verts, final_norms, final_uvs, final_tangents, submesh);

            // third triangle

            final_verts    = new Vector3[] { rightPoints[0], newVertex1, newVertex2 };
            final_norms    = new Vector3[] { rightNormals[0], newNormal1, newNormal2 };
            final_uvs      = new Vector2[] { rightUvs[0], newUv1, newUv2 };
            final_tangents = new Vector4[] { rightTangents[0], newTangent1, newTangent2 };

            if (Vector3.Dot(Vector3.Cross(final_verts[1] - final_verts[0], final_verts[2] - final_verts[0]), final_norms[0]) < 0)
            {
                FlipFace(final_verts, final_norms, final_uvs, final_tangents);
            }

            _rightSide.AddTriangle(final_verts, final_norms, final_uvs, final_tangents, submesh);


            // fourth triangle

            final_verts    = new Vector3[] { rightPoints[0], rightPoints[1], newVertex2 };
            final_norms    = new Vector3[] { rightNormals[0], rightNormals[1], newNormal2 };
            final_uvs      = new Vector2[] { rightUvs[0], rightUvs[1], newUv2 };
            final_tangents = new Vector4[] { rightTangents[0], rightTangents[1], newTangent2 };

            if (Vector3.Dot(Vector3.Cross(final_verts[1] - final_verts[0], final_verts[2] - final_verts[0]), final_norms[0]) < 0)
            {
                FlipFace(final_verts, final_norms, final_uvs, final_tangents);
            }

            _rightSide.AddTriangle(final_verts, final_norms, final_uvs, final_tangents, submesh);
        }
コード例 #5
0
        public void Button_MakeIt()
        {
            Mesh         _mesh     = GetComponent <MeshFilter>().sharedMesh;
            MeshRenderer _renderer = GetComponent <MeshRenderer>();

            Mesh[] _made_meshes = new Mesh[_mesh.subMeshCount];

            // go through the sub indices
            for (int sub = 0; sub < _mesh.subMeshCount; sub++)
            {
                Mesh_Maker maker     = new Mesh_Maker();
                int[]      trinagles = _mesh.GetTriangles(sub);

                // go through the triangles
                for (int i = 0; i < trinagles.Length; i += 3)
                {
                    maker.AddTriangle(new Vector3[] {
                        _mesh.vertices[trinagles[i]], _mesh.vertices[trinagles[i + 1]], _mesh.vertices[trinagles[i + 2]]
                    }, new Vector2[] {
                        _mesh.uv[trinagles[i]], _mesh.uv[trinagles[i + 1]], _mesh.uv[trinagles[i + 2]]
                    }, new Vector3[] {
                        _mesh.normals[trinagles[i]], _mesh.normals[trinagles[i + 1]], _mesh.normals[trinagles[i + 2]]
                    }, 0);
                }

                maker.RemoveDoubles();

                _made_meshes[sub] = maker.GetMesh();
            }



            // too many
            while (transform.childCount > _mesh.subMeshCount)
            {
                Transform obj = transform.GetChild(transform.childCount - 1);
                obj.parent = null;
                DestroyImmediate(obj.gameObject);
            }

            // too little
            while (transform.childCount < _mesh.subMeshCount)
            {
                Transform obj = new GameObject("child").transform;
                obj.SetParent(transform);
                obj.localPosition = Vector3.zero;
                obj.localRotation = Quaternion.identity;
                obj.gameObject.AddComponent <MeshCollider>();
            }

            for (int i = 0; i < transform.childCount; i++)
            {
                Transform obj = transform.GetChild(i);

                obj.gameObject.name = _renderer.sharedMaterials[i].name;

                _made_meshes[i].name = obj.gameObject.name;

                obj.GetComponent <MeshCollider>().sharedMesh = _made_meshes[i];
            }
        }
コード例 #6
0
ファイル: MeshCut.cs プロジェクト: polyphonic13/UnityAssets
        /// <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 });
        }
コード例 #7
0
        /// <summary>
        /// Cut the specified victim
        /// </summary>
        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;

            // reset values
            _new_vertices.Clear();

            _leftSide  = new Mesh_Maker();
            _rightSide = new Mesh_Maker();


            bool[] sides = new bool[3];
            int[]  indices;
            int    p1, p2, p3;

            // go throught the submeshes
            for (int sub = 0; sub < _victim_mesh.subMeshCount; sub++)
            {
                indices = _victim_mesh.GetTriangles(sub);

                for (int i = 0; i < indices.Length; i += 3)
                {
                    p1 = indices[i];
                    p2 = indices[i + 1];
                    p3 = indices[i + 2];

                    sides[0] = _blade.GetSide(_victim_mesh.vertices[p1]);
                    sides[1] = _blade.GetSide(_victim_mesh.vertices[p2]);
                    sides[2] = _blade.GetSide(_victim_mesh.vertices[p3]);

                    // whole triangle
                    if (sides[0] == sides[1] && sides[0] == sides[2])
                    {
                        if (sides[0])
                        { // left side
                            _leftSide.AddTriangle(
                                new Vector3[] { _victim_mesh.vertices[p1], _victim_mesh.vertices[p2], _victim_mesh.vertices[p3] },
                                new Vector3[] { _victim_mesh.normals[p1], _victim_mesh.normals[p2], _victim_mesh.normals[p3] },
                                new Vector2[] { _victim_mesh.uv[p1], _victim_mesh.uv[p2], _victim_mesh.uv[p3] },
                                new Vector4[] { _victim_mesh.tangents[p1], _victim_mesh.tangents[p2], _victim_mesh.tangents[p3] },
                                sub);
                        }
                        else
                        {
                            _rightSide.AddTriangle(
                                new Vector3[] { _victim_mesh.vertices[p1], _victim_mesh.vertices[p2], _victim_mesh.vertices[p3] },
                                new Vector3[] { _victim_mesh.normals[p1], _victim_mesh.normals[p2], _victim_mesh.normals[p3] },
                                new Vector2[] { _victim_mesh.uv[p1], _victim_mesh.uv[p2], _victim_mesh.uv[p3] },
                                new Vector4[] { _victim_mesh.tangents[p1], _victim_mesh.tangents[p2], _victim_mesh.tangents[p3] },
                                sub);
                        }
                    }
                    else
                    { // cut the triangle
                        Cut_this_Face(
                            new Vector3[] { _victim_mesh.vertices[p1], _victim_mesh.vertices[p2], _victim_mesh.vertices[p3] },
                            new Vector3[] { _victim_mesh.normals[p1], _victim_mesh.normals[p2], _victim_mesh.normals[p3] },
                            new Vector2[] { _victim_mesh.uv[p1], _victim_mesh.uv[p2], _victim_mesh.uv[p3] },
                            new Vector4[] { _victim_mesh.tangents[p1], _victim_mesh.tangents[p2], _victim_mesh.tangents[p3] },
                            sub);
                    }
                }
            }

            // 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
            Capping();


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

            //se di default vi è uno dei seguenti collider, li distruggo
            // Destroy(leftSideObj.GetComponent<BoxCollider>());
            //Destroy(leftSideObj.GetComponent<SphereCollider>());
            //Destroy(leftSideObj.GetComponent<CapsuleCollider>());

            //ogni volta che taglio la parte sinistra distruggo il vecchio MeshCollider (mesh dell'oggetto intero originale)
            //Destroy(leftSideObj.GetComponent<MeshCollider>());

            //e riassegno il nuovo MeshCollider adattato perfettamente alla dimensione del nuovo frammento tagliato
            //leftSideObj.AddComponent<MeshCollider>();

            GameObject leftSideObj = new GameObject("left side", typeof(MeshFilter), typeof(MeshRenderer));

            leftSideObj.transform.position = victim.transform.position;
            leftSideObj.transform.rotation = victim.transform.rotation;
            leftSideObj.GetComponent <MeshFilter>().mesh = left_HalfMesh;

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

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

            // in questo modo aggiungo un mesh collider anche all'oggetto rightSide ottenuto dal taglio in modo che possa anche lui esser tagliato a sua volta.
            leftSideObj.AddComponent <MeshCollider>();
            rightSideObj.AddComponent <MeshCollider>();



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

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



            //NB: per implementare le funzionalità per utilizzare LeapMotion:
            //***************************************************************
            //leftSide
            leftSideObj.AddComponent <InteractionBehaviour>();
            leftSideObj.GetComponent <MeshCollider>().convex = true; //L'interazione con i mesh collider richiede che sia Convex
            if (!leftSideObj.GetComponent <Rigidbody>())
            {
                leftSideObj.AddComponent <Rigidbody>();
            }
            leftSideObj.GetComponent <Rigidbody>().useGravity  = false;
            leftSideObj.GetComponent <Rigidbody>().isKinematic = true; //non viene scaraventato via al contatto.

            //rightSide
            rightSideObj.AddComponent <InteractionBehaviour>();
            rightSideObj.GetComponent <MeshCollider>().convex = true; //L'interazione con i mesh collider richiede che sia Convex
            if (!rightSideObj.GetComponent <Rigidbody>())
            {
                rightSideObj.AddComponent <Rigidbody>();
            }
            rightSideObj.GetComponent <Rigidbody>().useGravity  = false;
            rightSideObj.GetComponent <Rigidbody>().isKinematic = true; //non viene scaraventato via al contatto.


            //***************************************************************

            return(new GameObject[] { leftSideObj, rightSideObj });
        }
コード例 #8
0
ファイル: MeshCut.cs プロジェクト: AmitShah/UnityDestruction
        public static IEnumerator Cut(GameObject victim, Vector3 anchorPoint, Vector3 normalDirection, Material capMaterial, System.Action <GameObject[]> callback)
        {
            // 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;

            // reset values
            _new_vertices.Clear();

            _leftSide  = new Mesh_Maker();
            _rightSide = new Mesh_Maker();

            var sides = new bool[3];

            var victimVerticesArr = _victim_mesh.vertices;
            var victimNormalsArr  = _victim_mesh.normals;
            var victimUVArr       = _victim_mesh.uv;
            var victimTangentsArr = _victim_mesh.tangents;

            int p1 = 0;
            int p2 = 0;
            int p3 = 0;

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

                for (var i = 0; i < indices.Length; i += 3)
                {
                    if (i % 7500 == 0)
                    {
                        yield return(null);
                    }

                    p1 = indices[i];
                    p2 = indices[i + 1];
                    p3 = indices[i + 2];

                    sides[0] = _blade.GetSide(victimVerticesArr[p1]);
                    sides[1] = _blade.GetSide(victimVerticesArr[p2]);
                    sides[2] = _blade.GetSide(victimVerticesArr[p3]);

                    // whole triangle
                    if (sides[0] == sides[1] && sides[0] == sides[2])
                    {
                        if (sides[0])
                        {
                            // left side
                            _leftSide.AddTriangle(
                                new[] { victimVerticesArr[p1], victimVerticesArr[p2], victimVerticesArr[p3] },
                                new[] { victimNormalsArr[p1], victimNormalsArr[p2], victimNormalsArr[p3] },
                                new[] { victimUVArr[p1], victimUVArr[p2], victimUVArr[p3] },
                                new[] { victimTangentsArr[p1], victimTangentsArr[p2], victimTangentsArr[p3] },
                                sub);
                        }
                        else
                        {
                            // right side
                            _rightSide.AddTriangle(
                                new[] { victimVerticesArr[p1], victimVerticesArr[p2], victimVerticesArr[p3] },
                                new[] { victimNormalsArr[p1], victimNormalsArr[p2], victimNormalsArr[p3] },
                                new[] { victimUVArr[p1], victimUVArr[p2], victimUVArr[p3] },
                                new[] { victimTangentsArr[p1], victimTangentsArr[p2], victimTangentsArr[p3] },
                                sub);
                        }
                    }
                    else
                    {
                        // cut the triangle
                        Cut_this_Face(
                            new[] { victimVerticesArr[p1], victimVerticesArr[p2], victimVerticesArr[p3] },
                            new[] { victimNormalsArr[p1], victimNormalsArr[p2], victimNormalsArr[p3] },
                            new[] { victimUVArr[p1], victimUVArr[p2], victimUVArr[p3] },
                            new[] { victimTangentsArr[p1], victimTangentsArr[p2], victimTangentsArr[p3] },
                            sub);
                    }
                }
                yield return(null);
            }

            indices = null;

            // The capping Material will be at the end
            var mats = victim.GetComponent <MeshRenderer>().sharedMaterials;

            if (mats[mats.Length - 1].name != capMaterial.name)
            {
                var 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
            Capping();

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

            left_HalfMesh.name = "Split Mesh Left";

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

            right_HalfMesh.name = "Split Mesh Right";

            // assign the game objects

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

            var leftSideObj = victim;

            var 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;

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

            callback(new [] { leftSideObj, rightSideObj });
        }