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