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());
    }
Exemple #5
0
    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);
        }
    }