// called by Button
        public void ShapeIt()
        {
            if (segment_sourceMesh == null)
            {
                Debug.LogError("missing source mesh");
                return;
            }


            _helpTransform1 = new GameObject("_helpTransform1").transform;
            _helpTransform2 = new GameObject("_helpTransform2").transform;

            // because it messes it up
            Quaternion oldRotation = transform.rotation;

            transform.rotation = Quaternion.identity;


            _maker = new Mesh_Maker();
            ScanSourceMesh();
            Craft();             // make segments
            Apply();             // apply values

            transform.rotation = oldRotation;

            DestroyImmediate(_helpTransform1.gameObject);
            DestroyImmediate(_helpTransform2.gameObject);
        }
Exemple #2
0
        /// <summary>
        /// You can call this during runtime and in the editor
        /// </summary>
        public void ShapeIt()
        {
            //====================!!!segmentSourceMesh 如何被初始化?
            //----------------可能因为添加[RequireComponent(typeof(MeshFilter))]组件,MeshFilter中有mesh变量
            if (segmentSourceMesh == null)
            {//segmentSourceMesh 没有添加源报错:缺失
                Debug.LogError("missing source mesh");
                return;
            }
            _helpTransform1 = new GameObject("_helpTransform1").transform; //新建游戏对象1
            _helpTransform2 = new GameObject("_helpTransform2").transform; //新建游戏对象2

            // because it messes it up
            //Quaternion是四元数 用Quaternion来存储和表示对象的旋转角度

            //====================!!! transform 谁的转换坐标?为什么将旋转角值初始值?
            //--------------猜想可能是调用本方法的gameObject,的transform
            Quaternion oldRotation = transform.rotation;//旧的旋转

            transform.rotation = Quaternion.identity;
            //Quaternion.identity就是指Quaternion(0,0,0,0),就是没旋转前的初始角度,是一个确切的值,而transform.rotation是指本物体的角度,值是不确定的,比如可以这么设置transform.rotation = Quaternion.identity;

            // 生成新对象时覆盖之前的Mesh_Maker
            // 新生成两个GameObject 获取他们的transform,以及将原有对象的transform的rotation 设为初始角度=================对下面处理有何影响?????
            _maker = new Mesh_Maker();
            //获取所有顶点的min_z,max_z,赋值_segment_length
            ScanSourceMesh();
            Craft(); // make segments
            //1.需要清除相同顶点则清除;2.将新生成的mesh,赋给当前GameObject
            Apply(); // apply values

            transform.rotation = oldRotation;

            //g_1.GetComponent<Renderer>().marterial = Dl_COLOR;

            //清除之前申请的两个gameObject 对象
            // #if UNITY_EDITOR unity 代码运行平台判断代码,类似的有UNITY_IPHONE,UNITY_ANDROID
#if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                //程序运行异步销毁 程序停止,立即销毁
                //DestroyImmediate是立即销毁,立即释放资源,做这个操作的时候,会消耗很多时间的,影响主线程运行
                //Destroy是异步销毁,一般在下一帧就销毁了,不会影响主线程的运行。
                DestroyImmediate(_helpTransform1.gameObject);
                DestroyImmediate(_helpTransform2.gameObject);
            }
            else
            {
                //程序运行,正常销毁
                Destroy(_helpTransform1.gameObject);
                Destroy(_helpTransform2.gameObject);
            }
#else
            Destroy(_helpTransform1.gameObject);
            Destroy(_helpTransform2.gameObject);
#endif
        }
        /// <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 });
        }
        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];
            }
        }
        /// <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 });
        }
Exemple #6
0
        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 });
        }