public void Bake(GameObject go) { NvBlastExtUnity.setSeed(seed); var nvMesh = new NvMesh( mesh.vertices, mesh.normals, mesh.uv, mesh.vertexCount, mesh.GetIndices(0), (int)mesh.GetIndexCount(0) ); var fractureTool = new NvFractureTool(); fractureTool.setRemoveIslands(false); fractureTool.setSourceMesh(nvMesh); Voronoi(fractureTool, nvMesh); fractureTool.finalizeFracturing(); for (var i = 1; i < fractureTool.getChunkCount(); i++) { var chunk = new GameObject("Chunk" + i); chunk.transform.SetParent(go.transform, false); Setup(i, chunk, fractureTool); FractureUtils.ConnectTouchingChunks(chunk, jointBreakForce); } }
public static ChunkGraphManager FractureGameObject(GameObject gameObject, Anchor anchor, int seed, int totalChunks, Material insideMaterial, Material outsideMaterial, float jointBreakForce, float density) { // Translate all meshes to one world mesh var mesh = GetWorldMesh(gameObject); NvBlastExtUnity.setSeed(seed); var nvMesh = new NvMesh( mesh.vertices, mesh.normals, mesh.uv, mesh.vertexCount, mesh.GetIndices(0), (int)mesh.GetIndexCount(0) ); var meshes = FractureMeshesInNvblast(totalChunks, nvMesh); // Build chunks gameobjects var chunkMass = mesh.Volume() * density / totalChunks; var chunks = BuildChunks(insideMaterial, outsideMaterial, meshes, chunkMass); // Connect blocks that are touching with fixed joints foreach (var chunk in chunks) { ConnectTouchingChunks(chunk, jointBreakForce); } // Set anchored chunks as kinematic AnchorChunks(gameObject, anchor); var fractureGameObject = new GameObject("Fracture"); foreach (var chunk in chunks) { chunk.transform.SetParent(fractureGameObject.transform, false); } // Graph manager freezes/unfreezes blocks depending on whether they are connected to the graph or not var graphManager = fractureGameObject.AddComponent <ChunkGraphManager>(); graphManager.Setup(fractureGameObject.GetComponentsInChildren <Rigidbody>()); return(graphManager); }
private void _Visualize() { NvBlastExtUnity.setSeed(seed); CleanUp(); if (source == null) { return; } GameObject ps = new GameObject("POINTS"); ps.transform.position = Vector3.zero; ps.transform.rotation = Quaternion.identity; ps.transform.localScale = Vector3.one; Mesh ms = null; MeshFilter mf = source.GetComponent <MeshFilter>(); SkinnedMeshRenderer smr = source.GetComponent <SkinnedMeshRenderer>(); if (mf != null) { ms = source.GetComponent <MeshFilter>().sharedMesh; } if (smr != null) { smr.gameObject.transform.position = Vector3.zero; smr.gameObject.transform.rotation = Quaternion.identity; smr.gameObject.transform.localScale = Vector3.one; ms = new Mesh(); smr.BakeMesh(ms); //ms = smr.sharedMesh; //OYM:储存mesh } if (ms == null) { return; } NvMesh mymesh = new NvMesh(ms.vertices, ms.normals, ms.uv, ms.vertexCount, ms.GetIndices(0), (int)ms.GetIndexCount(0));//OYM:这里是把mesh丢给一个dll并返回一个intptr NvVoronoiSitesGenerator sites = new NvVoronoiSitesGenerator(mymesh); //OYM:根据IntPtr获取voronoiSites if (fractureType == FractureTypes.Voronoi) { sites.uniformlyGenerateSitesInMesh(totalChunks); //OYM:裂开 } if (fractureType == FractureTypes.Clustered) { sites.clusteredSitesGeneration(clusters, sitesPerCluster, clusterRadius); //OYM:拥挤 } if (fractureType == FractureTypes.Skinned) { sites.boneSiteGeneration(smr); //OYM:骨骼 } Vector3[] vs = sites.getSites(); //OYM:获取..我也不知道啥 for (int i = 0; i < vs.Length; i++) { GameObject po = Instantiate(point, vs[i], Quaternion.identity, ps.transform); //OYM:把这些点标记出来 po.hideFlags = HideFlags.NotEditable; //OYM:不可车裂 } ps.transform.rotation = source.transform.rotation;//OYM:把坐标拷走? ps.transform.position = source.transform.position; }
private void _createPreview(bool makePrefab) { float startTime = System.Environment.TickCount; //OYM:计时 NvBlastExtUnity.setSeed(seed); //OYM:设置中子 CleanUp(); //OYM:清除上一次生成的point与Chunk GameObject cs = new GameObject("CHUNKS"); //OYM:新建一个chunk出来 cs.transform.position = Vector3.zero; cs.transform.rotation = Quaternion.identity; cs.transform.localScale = Vector3.one; Mesh ms = null; Material[] mats = new Material[2]; mats[1] = insideMaterial; //OYM:似曾相识啊 MeshFilter mf = source.GetComponent <MeshFilter>(); SkinnedMeshRenderer smr = source.GetComponent <SkinnedMeshRenderer>(); if (mf != null) { mats[0] = source.GetComponent <MeshRenderer>().sharedMaterial; ms = source.GetComponent <MeshFilter>().sharedMesh; } if (smr != null) { mats[0] = smr.sharedMaterial; smr.gameObject.transform.position = Vector3.zero; smr.gameObject.transform.rotation = Quaternion.identity; smr.gameObject.transform.localScale = Vector3.one; ms = new Mesh(); smr.BakeMesh(ms); //ms = smr.sharedMesh; } if (ms == null) { return; } NvMesh mymesh = new NvMesh(ms.vertices, ms.normals, ms.uv, ms.vertexCount, ms.GetIndices(0), (int)ms.GetIndexCount(0)); //NvMeshCleaner cleaner = new NvMeshCleaner(); //cleaner.cleanMesh(mymesh); //OYM:设置是否为mesh NvFractureTool fractureTool = new NvFractureTool(); fractureTool.setRemoveIslands(islands); fractureTool.setSourceMesh(mymesh); Debug.Log("sittingTime =" + (System.Environment.TickCount - startTime).ToString()); if (fractureType == FractureTypes.Voronoi) { _Voronoi(fractureTool, mymesh); //OYM:这两个方法差不多快 } if (fractureType == FractureTypes.Clustered) { _Clustered(fractureTool, mymesh); } if (fractureType == FractureTypes.Slicing) { _Slicing(fractureTool, mymesh); } if (fractureType == FractureTypes.Skinned) { _Skinned(fractureTool, mymesh); } if (fractureType == FractureTypes.Plane) { _Plane(fractureTool, mymesh); } if (fractureType == FractureTypes.Cutout) { _Cutout(fractureTool, mymesh); } fractureTool.finalizeFracturing(); NvLogger.Log("Chunk Count: " + fractureTool.getChunkCount()); Debug.Log("fractureTime =" + (System.Environment.TickCount - startTime).ToString()); if (makePrefab)//OYM:创建文件夹(很明显我不需要搞这些) { if (!AssetDatabase.IsValidFolder("Assets/NvBlast Prefabs")) { AssetDatabase.CreateFolder("Assets", "NvBlast Prefabs"); } if (!AssetDatabase.IsValidFolder("Assets/NvBlast Prefabs/Meshes")) { AssetDatabase.CreateFolder("Assets/NvBlast Prefabs", "Meshes"); } if (!AssetDatabase.IsValidFolder("Assets/NvBlast Prefabs/Fractured")) { AssetDatabase.CreateFolder("Assets/NvBlast Prefabs", "Fractured"); } FileUtil.DeleteFileOrDirectory("Assets/NvBlast Prefabs/Meshes/" + source.name); AssetDatabase.Refresh(); AssetDatabase.CreateFolder("Assets/NvBlast Prefabs/Meshes", source.name); } Debug.Log("GenerateTime=" + (System.Environment.TickCount - startTime).ToString()); for (int i = 1; i < fractureTool.getChunkCount(); i++) { GameObject ck = new GameObject("Chunk" + i); ck.transform.parent = cs.transform; ck.transform.position = Vector3.zero; ck.transform.rotation = Quaternion.identity; MeshFilter ckmf = ck.AddComponent <MeshFilter>(); MeshRenderer ckmr = ck.AddComponent <MeshRenderer>(); ckmr.sharedMaterials = mats; NvMesh outside = fractureTool.getChunkMesh(i, false); NvMesh inside = fractureTool.getChunkMesh(i, true); Mesh m = outside.toUnityMesh(); m.subMeshCount = 2; m.SetIndices(inside.getIndexes(), MeshTopology.Triangles, 1); ckmf.sharedMesh = m; if (makePrefab) { AssetDatabase.CreateAsset(m, "Assets/NvBlast Prefabs/Meshes/" + source.name + "/Chunk" + i + ".asset"); } if (!makePrefab) { ck.AddComponent <ChunkInfo>(); } if (makePrefab || previewColliders) { ck.AddComponent <Rigidbody>(); MeshCollider mc = ck.AddComponent <MeshCollider>(); mc.inflateMesh = true; mc.convex = true; } } Debug.Log("GenerateTimeA=" + (System.Environment.TickCount - startTime).ToString()); if (makePrefab) { GameObject p = PrefabUtility.CreatePrefab("Assets/NvBlast Prefabs/Fractured/" + source.name + "_fractured.prefab", cs); GameObject fo; bool skinnedMesh = false; if (source.GetComponent <SkinnedMeshRenderer>() != null) { skinnedMesh = true; } if (skinnedMesh) { fo = Instantiate(source.transform.root.gameObject); } else { fo = Instantiate(source); } Destructible d = fo.AddComponent <Destructible>(); d.fracturedPrefab = p; bool hasCollider = false; if (fo.GetComponent <MeshCollider>() != null) { hasCollider = true; } if (fo.GetComponent <BoxCollider>() != null) { hasCollider = true; } if (fo.GetComponent <SphereCollider>() != null) { hasCollider = true; } if (fo.GetComponent <CapsuleCollider>() != null) { hasCollider = true; } if (!hasCollider) { BoxCollider bc = fo.AddComponent <BoxCollider>(); if (skinnedMesh) { Bounds b = source.GetComponent <SkinnedMeshRenderer>().bounds; bc.center = new Vector3(0, .5f, 0); bc.size = b.size; } } PrefabUtility.CreatePrefab("Assets/NvBlast Prefabs/" + source.name + ".prefab", fo); DestroyImmediate(fo); } cs.transform.rotation = source.transform.rotation; UpdatePreview(); Debug.Log("GenerateTimeB=" + (System.Environment.TickCount - startTime).ToString()); }
private void _createPreview(bool makePrefab) { // New code: Added to iterate through the sources in sourceList foreach (var source in sourceList) { NvBlastExtUnity.setSeed(seed); CleanUp(); GameObject cs = new GameObject("CHUNKS"); cs.transform.position = Vector3.zero; cs.transform.rotation = Quaternion.identity; cs.transform.localScale = Vector3.one; Mesh ms = null; Material[] mats = new Material[2]; mats[1] = insideMaterial; MeshFilter mf = source.GetComponent <MeshFilter>(); SkinnedMeshRenderer smr = source.GetComponent <SkinnedMeshRenderer>(); if (mf != null) { mats[0] = source.GetComponent <MeshRenderer>().sharedMaterial; ms = source.GetComponent <MeshFilter>().sharedMesh; } if (smr != null) { mats[0] = smr.sharedMaterial; smr.gameObject.transform.position = Vector3.zero; smr.gameObject.transform.rotation = Quaternion.identity; smr.gameObject.transform.localScale = Vector3.one; ms = new Mesh(); smr.BakeMesh(ms); //ms = smr.sharedMesh; } if (ms == null) { return; } NvMesh mymesh = new NvMesh(ms.vertices, ms.normals, ms.uv, ms.vertexCount, ms.GetIndices(0), (int)ms.GetIndexCount(0)); //NvMeshCleaner cleaner = new NvMeshCleaner(); //cleaner.cleanMesh(mymesh); NvFractureTool fractureTool = new NvFractureTool(); fractureTool.setRemoveIslands(islands); fractureTool.setSourceMesh(mymesh); if (fractureType == FractureTypes.Voronoi) { _Voronoi(fractureTool, mymesh); } if (fractureType == FractureTypes.Clustered) { _Clustered(fractureTool, mymesh); } if (fractureType == FractureTypes.Slicing) { _Slicing(fractureTool, mymesh); } if (fractureType == FractureTypes.Skinned) { _Skinned(fractureTool, mymesh); } if (fractureType == FractureTypes.Plane) { _Plane(fractureTool, mymesh); } if (fractureType == FractureTypes.Cutout) { _Cutout(fractureTool, mymesh); } fractureTool.finalizeFracturing(); NvLogger.Log("Chunk Count: " + fractureTool.getChunkCount()); if (makePrefab) { if (!AssetDatabase.IsValidFolder("Assets/Prefabs/NvidaBlast")) { AssetDatabase.CreateFolder("Assets/Prefabs", "NvidaBlast"); } if (!AssetDatabase.IsValidFolder("Assets/Prefabs/NvidaBlast/Chunks")) { AssetDatabase.CreateFolder("Assets/Prefabs/NvidaBlast", "Chunks"); } if (!AssetDatabase.IsValidFolder("Assets/Prefabs/NvidaBlast/Fractured")) { AssetDatabase.CreateFolder("Assets/Prefabs/NvidaBlast", "Fractured"); } FileUtil.DeleteFileOrDirectory("Assets/Prefabs/NvidaBlast/Chunks/" + source.name); AssetDatabase.Refresh(); AssetDatabase.CreateFolder("Assets/Prefabs/NvidaBlast/Chunks", source.name); } for (int i = 1; i < fractureTool.getChunkCount(); i++) { GameObject ck = new GameObject("Chunk" + i); ck.transform.parent = cs.transform; ck.transform.position = Vector3.zero; ck.transform.rotation = Quaternion.identity; MeshFilter ckmf = ck.AddComponent <MeshFilter>(); MeshRenderer ckmr = ck.AddComponent <MeshRenderer>(); ckmr.sharedMaterials = mats; NvMesh outside = fractureTool.getChunkMesh(i, false); NvMesh inside = fractureTool.getChunkMesh(i, true); Mesh m = outside.toUnityMesh(); m.subMeshCount = 2; m.SetIndices(inside.getIndexes(), MeshTopology.Triangles, 1); ckmf.sharedMesh = m; if (makePrefab) { AssetDatabase.CreateAsset(m, "Assets/Prefabs/NvidaBlast/Chunks/" + source.name + "/Chunk" + i + ".asset"); } if (!makePrefab) { ck.AddComponent <ChunkInfo>(); } if (makePrefab || previewColliders) { ck.AddComponent <Rigidbody>(); MeshCollider mc = ck.AddComponent <MeshCollider>(); //mc.inflateMesh = true; mc.convex = true; } } if (makePrefab) { // OLD CODE: PrefabUtility.CreatePrefab("Assets/NvBlast Prefabs/Fractured/" + source.name + "_fractured.prefab", cs); GameObject p = PrefabUtility.SaveAsPrefabAsset(cs, "Assets/Prefabs/NvidaBlast/Fractured/" + source.name + "_fractured.prefab"); // Extra code added to make the destructable mesh work with realistic explosion physics p.layer = LayerMask.AssignDestructable; // Assign the layer to the children (debris) p.ApplyToChildren(child => child.layer = LayerMask.AssignDestructable); p.AddComponent <ExplodeAfterInstantiate>(); // Assign the fractured prefab to the 'normal' prefab source.GetComponent <Destructible>().fracturedPrefab = p; GameObject fo; bool skinnedMesh = false; if (source.GetComponent <SkinnedMeshRenderer>() != null) { skinnedMesh = true; } if (skinnedMesh) { fo = Instantiate(source.transform.root.gameObject); } else { fo = Instantiate(source); } Destructible d = fo.AddComponent <Destructible>(); d.fracturedPrefab = p; bool hasCollider = false; if (fo.GetComponent <MeshCollider>() != null) { hasCollider = true; } if (fo.GetComponent <BoxCollider>() != null) { hasCollider = true; } if (fo.GetComponent <SphereCollider>() != null) { hasCollider = true; } if (fo.GetComponent <CapsuleCollider>() != null) { hasCollider = true; } if (!hasCollider) { BoxCollider bc = fo.AddComponent <BoxCollider>(); if (skinnedMesh) { Bounds b = source.GetComponent <SkinnedMeshRenderer>().bounds; bc.center = new Vector3(0, .5f, 0); bc.size = b.size; } } // OLD CODE: PrefabUtility.CreatePrefab("Assets/NvBlast Prefabs/" + source.name + ".prefab", fo); // This saves out an unessacary prefab so I have commented it out //PrefabUtility.SaveAsPrefabAsset(fo, "Assets/Prefabs/NvidaBlast/" + source.name + ".prefab"); DestroyImmediate(fo); } cs.transform.rotation = source.transform.rotation; UpdatePreview(makePrefab); } }