/** * 1.需要清除相同顶点则清除 * 2.将新生成的mesh,赋给当前GameObject */ private void Apply() { if (removeDuplicateVertices) { _maker.RemoveDoubles(); } #if UNITY_EDITOR if (!Application.isPlaying) { switch (lightmapUnwrapping) { case LightmapUnwrapping.UseFirstUvSet: GetComponent <MeshFilter>().mesh = _maker.GetMesh(); break; case LightmapUnwrapping.DefaultUnwrapParam: GetComponent <MeshFilter>().mesh = _maker.GetMesh_GenerateSecondaryUVSet(); break; default: GetComponent <MeshFilter>().mesh = _maker.GetMesh(); break; } } else { GetComponent <MeshFilter>().mesh = _maker.GetMesh(); } #else GetComponent <MeshFilter>().mesh = _maker.GetMesh(); #endif }
public void Apply() { if (removeDoubles) { _maker.RemoveDoubles(); } GetComponent <MeshFilter>().mesh = _maker.GetMesh(); }
/// <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> /// 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 }); }
/// <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 }); }