private void SetRgInitForBalltree(GameObject go, Mesh mesh, RgInit rgInit)
        {
            rgInit.name_ = go.name;

            MeshComplex balltreeMC = new MeshComplex();

            balltreeMC.Set(mesh);

            rgInit.meshCollider_Model_ = balltreeMC;

            Matrix4x4 m_MODEL_to_WORLD = go.transform.localToWorldMatrix;
            Vector3   scale            = m_MODEL_to_WORLD.GetScalePre();
            Vector3   normalizedScale  = scale / scale.x;

            Matrix4x4 m_MODEL_to_NORMALIZEDSCALE = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, normalizedScale);

            rgInit.m_MODEL_to_WORLD_ = m_MODEL_to_NORMALIZEDSCALE;

            rgInit.useBalltree_ = true;

            float radius_rate          = 1.0f - Data.BalltreeLOD;
            float radius_rateSq        = radius_rate * radius_rate;
            float radius_rateSqClamped = Mathf.Clamp(radius_rateSq, 0.02f, 1.0f);

            rgInit.bt_radius_rate_ = radius_rateSqClamped;

            float requested_resolution1 = 10.0f / Mathf.Pow(radius_rateSqClamped, 5.0f);
            float requested_resolution2 = 10000.0f * (300.0f - 299.0f * (1.0f - Data.BalltreePrecision));
            float mixedResolution       = Mathf.Max(requested_resolution1, requested_resolution2);

            rgInit.bt_resolution_ = (uint)Mathf.Clamp(mixedResolution, 10000.0f, 3000000.0f);
            rgInit.bt_diameterMaxHoleToCover_rel_ = Mathf.Clamp(Data.BalltreeHoleCovering, 0.0001f, 1.0f);
        }
Exemple #2
0
        public static void CalculateFingerprint(Mesh mesh, byte[] meshFingerprint)
        {
            MeshComplex car_mesh = new MeshComplex();

            car_mesh.Set(mesh);
            CaronteSharp.Tools.CalculateMeshFingerprint(car_mesh, meshFingerprint);
        }
Exemple #3
0
        private static void CreateMeshCollapsedUnity(string name, MeshComplex mesh_COLLAPSED_car, ArrayIndex mesh_COLLAPSED_info, GameObject boundsObject,
                                                     List <Material> listMaterial, out GameObject[] arrGameObject, out Mesh[] arrMesh)
        {
            UnityEngine.Mesh[]  arrMesh_COLLAPSED_un;
            Tuple2 <int, int>[] arrSubmeshRange;

            CRGeometryUtils.CreateMeshesFromComplex(mesh_COLLAPSED_car, out arrMesh_COLLAPSED_un, out arrSubmeshRange);

            int nMeshUnity = arrMesh_COLLAPSED_un.Length;

            List <GameObject> listGameObject = new List <GameObject>();
            List <Mesh>       listMesh       = new List <Mesh>();

            for (int i = 0; i < nMeshUnity; i++)
            {
                Mesh mesh_COLLAPSED_un = arrMesh_COLLAPSED_un[i];
                mesh_COLLAPSED_un.name = name + "_" + i;
                listMesh.Add(mesh_COLLAPSED_un);

                GameObject go = Object.Instantiate(boundsObject);
                go.name = name + "_" + i;
                go.AddMesh(mesh_COLLAPSED_un);
                listGameObject.Add(go);

                Tuple2 <int, int> submeshRange = arrSubmeshRange[i];

                List <Material> collapsedMaterials = new List <Material>();
                uint[]          arrMaterialIdx     = mesh_COLLAPSED_info.arrIdx_;

                for (int j = submeshRange.First; j <= submeshRange.Second; j++)
                {
                    uint materialIdx = arrMaterialIdx[j];
                    if (materialIdx != uint.MaxValue)
                    {
                        Material mat = listMaterial[(int)materialIdx];
                        collapsedMaterials.Add(mat);
                    }
                    else
                    {
                        collapsedMaterials.Add(null);
                    }
                }

                Renderer renderer = go.GetComponent <Renderer>();
                renderer.sharedMaterials = collapsedMaterials.ToArray();
            }

            arrGameObject = listGameObject.ToArray();
            arrMesh       = listMesh.ToArray();
        }
        public void Chop()
        {
            GameObject[] goToChop   = FieldController.GetUnityGameObjects();
            int          numObjects = goToChop.Length;

            string errorMessage = string.Empty;

            if (numObjects == 0)
            {
                errorMessage = "Objects field must contain at least one object with geometry";
            }

            if (Data.CropGeometry != null && !Data.CropGeometry.HasMesh())
            {
                errorMessage = "Crop geometry GameObject must contain a mesh";
            }

            if (Data.ChopMode == CNFracture.CHOP_MODE.VORONOI_BY_GEOMETRY)
            {
                if (Data.ChopGeometry == null)
                {
                    errorMessage = "Specifying a steering geometry is mandatory";
                }
                else if (!Data.ChopGeometry.HasMesh())
                {
                    errorMessage = "Steering geometry GameObject must contain a mesh";
                }
            }

            if (Data.ChopMode == CNFracture.CHOP_MODE.VORONOI_RADIAL)
            {
                if (Data.ReferenceSystem == null)
                {
                    errorMessage = "Specifying the reference system is mandatory";
                }
            }

            if (errorMessage != string.Empty)
            {
                EditorUtility.DisplayDialog("CaronteFX", errorMessage, "Ok");
                return;
            }

            Undo.RecordObject(Data, "Chop - " + Data.Name);

            List <GameObject>  listParentGO           = new List <GameObject>();
            List <Mesh>        listParentMesh_un      = new List <Mesh>();
            List <MeshComplex> listParentMesh_car     = new List <MeshComplex>();
            List <Matrix4x4>   listMatrixModelToWorld = new List <Matrix4x4>();

            for (int i = 0; i < numObjects; i++)
            {
                GameObject go      = goToChop[i];
                Mesh       un_mesh = go.GetMesh();

                if (un_mesh != null)
                {
                    MeshComplex mc = new MeshComplex();
                    mc.Set(un_mesh);

                    listParentMesh_car.Add(mc);
                    listParentMesh_un.Add(un_mesh);
                    listParentGO.Add(go);
                    listMatrixModelToWorld.Add(go.transform.localToWorldMatrix);
                }
            }

            Bounds globalBounds = CREditorUtils.GetGlobalBoundsWorld(listParentGO);

            ChopRequest cr = new ChopRequest();

            cr.doKeepUVCoords_          = true;
            cr.doKeepVertexNormals_     = true;
            cr.doParentIndexTriangInfo_ = true;
            cr.arrMeshToChop_           = listParentMesh_car.ToArray();
            cr.arrMatrixModelToWorld_   = listMatrixModelToWorld.ToArray();

            cr.doGlobalPattern_ = Data.DoGlobalPattern;
            cr.seed_            = (uint)Data.Seed;

            bool chopModeUniform  = false;
            bool chopModeGeometry = false;
            bool chopModeRadial   = false;

            cr.pProgressFunction_ = null;

            switch (Data.ChopMode)
            {
            case CNFracture.CHOP_MODE.VORONOI_UNIFORM:
                cr.chopMode_    = CaronteSharp.CP_CHOP_MODE.CP_CHOP_MODE_VORONOI_UNIFORM;
                chopModeUniform = ChopModeUniform(cr);
                break;

            case CNFracture.CHOP_MODE.VORONOI_BY_GEOMETRY:
                cr.chopMode_     = CaronteSharp.CP_CHOP_MODE.CP_CHOP_MODE_VORONOI_BY_GEOMETRY;
                chopModeGeometry = ChopModeGeometry(cr);
                break;

            case CNFracture.CHOP_MODE.VORONOI_RADIAL:
                cr.chopMode_   = CaronteSharp.CP_CHOP_MODE.CP_CHOP_MODE_VORONOI_RADIAL;
                chopModeRadial = ChopModeRadial(cr);
                break;
            }

            if (!chopModeUniform && !chopModeGeometry && !chopModeRadial)
            {
                return;
            }

            WeldRequest wr = GetWeldRequest();

            CaronteSharp.MeshComplex[]    arrMeshPieceCaronte;
            CaronteSharp.MeshParentInfo[] arrMeshParentInfo;
            Vector3[]  arrMeshPosition;
            ArrayIndex arrInsideOutsideIdx;

            EditorUtility.DisplayProgressBar(Data.Name, "Chopping...", 1.0f);
            CaronteSharp.Tools.FractureMeshesV2(cr, wr, out arrMeshPieceCaronte, out arrMeshParentInfo, out arrMeshPosition, out arrInsideOutsideIdx);


            bool thereIsOutput = arrMeshPieceCaronte.Length > 0;

            if (cnManager.IsFreeVersion() && !thereIsOutput)
            {
                EditorUtility.DisplayDialog("CaronteFX - Free version", "CaronteFX Free version can only fracture the meshes included in the example scenes and the unity primitives (cube, plane, sphere, etc.)", "Ok");
            }

            if (thereIsOutput)
            {
                List <GameObject> listChoppedParentGO;
                CreateListChoppedParentGO(listParentGO, out listChoppedParentGO);

                EditorUtility.DisplayProgressBar(Data.Name, "Post processing...", 1.0f);
                UnityEngine.Mesh[]  arrMeshPieceUnity;
                Tuple2 <int, int>[] arrSubmeshRange;
                int[] arrMeshComplexIdx;

                CreateMeshPiecesUnity(listChoppedParentGO, arrMeshPieceCaronte, arrMeshParentInfo, arrMeshPosition,
                                      out arrMeshPieceUnity, out arrSubmeshRange, out arrMeshComplexIdx);

                Transform oldParent = DestroyOldObjects();

                Undo.RecordObject(Data, "Chop - " + Data.Name);
                CreateNewObjects(globalBounds.center, listParentGO, listChoppedParentGO, arrMeshParentInfo,
                                 arrMeshPieceUnity, arrSubmeshRange, arrMeshComplexIdx, arrMeshPosition, arrInsideOutsideIdx.arrIdx_);


                if (oldParent != null)
                {
                    Data.GameObjectChoppedRoot.transform.parent = oldParent;
                }

                SeparatePieces();

                CalculateStatistics();

                EditorUtility.ClearProgressBar();

                Undo.SetCurrentGroupName("Chop - " + Data.Name);
                Undo.CollapseUndoOperations(Undo.GetCurrentGroup());
                EditorUtility.SetDirty(Data);
            }
        }
Exemple #5
0
        public static void TessellateObjects(GameObject[] arrGameObjectToTessellate, float maxEdgeLength, bool limitByMeshDimensions, out GameObject[] arrGameObjectTessellated, out Mesh[] arrMeshTessellated)
        {
            int nGameObject = arrGameObjectToTessellate.Length;

            List <GameObject>         listGameObjectTessellated      = new List <GameObject>();
            List <Mesh>               listMeshTessellated            = new List <Mesh>();
            List <Tuple2 <int, int> > listMeshTessellatedSubmesRange = new List <Tuple2 <int, int> >();

            Dictionary <Mesh, List <int> > dictMeshListMeshIdx = new Dictionary <Mesh, List <int> >();
            MeshComplex auxMesh = new MeshComplex();

            double tssDistance = (double)maxEdgeLength;

            for (int i = 0; i < nGameObject; i++)
            {
                GameObject go   = arrGameObjectToTessellate[i];
                Mesh       mesh = go.GetMesh();

                if (mesh != null)
                {
                    bool alreadyTessellated = dictMeshListMeshIdx.ContainsKey(mesh);
                    if (!alreadyTessellated)
                    {
                        if (limitByMeshDimensions)
                        {
                            Bounds  bounds = mesh.bounds;
                            Vector3 size   = bounds.size;

                            float minDistance = size.magnitude / 50f;
                            tssDistance = (double)Mathf.Clamp(maxEdgeLength, minDistance, float.MaxValue);
                        }

                        auxMesh.Set(mesh);
                        MeshComplex tessellatedMesh;
                        CaronteSharp.Tools.TessellateMesh(auxMesh, (double)tssDistance, out tessellatedMesh);

                        if (tessellatedMesh == null)
                        {
                            arrGameObjectTessellated = null;
                            arrMeshTessellated       = null;
                            return;
                        }

                        Mesh[] auxArrMeshTessellated;
                        Tuple2 <int, int>[] auxArrSubmeshRange;

                        CreateMeshesFromComplex(tessellatedMesh, out auxArrMeshTessellated, out auxArrSubmeshRange);

                        List <int> listMeshTessellatedIdx = new List <int>();
                        for (int j = 0; j < auxArrMeshTessellated.Length; j++)
                        {
                            Mesh auxMeshTessellated           = auxArrMeshTessellated[j];
                            Tuple2 <int, int> auxSubmeshRange = auxArrSubmeshRange[j];
                            auxMeshTessellated.name = mesh.name + "_" + j + "_tss";

                            listMeshTessellatedIdx.Add(listMeshTessellated.Count);
                            listMeshTessellated.Add(auxMeshTessellated);
                            listMeshTessellatedSubmesRange.Add(auxSubmeshRange);
                        }


                        dictMeshListMeshIdx.Add(mesh, listMeshTessellatedIdx);
                    }

                    List <int> listMeshIdx = dictMeshListMeshIdx[mesh];
                    for (int j = 0; j < listMeshIdx.Count; j++)
                    {
                        GameObject goTessellated = Object.Instantiate <GameObject>(go);

                        goTessellated.name                    = go.name + "_" + j + "_tss";
                        goTessellated.transform.parent        = go.transform.parent;
                        goTessellated.transform.localPosition = go.transform.localPosition;
                        goTessellated.transform.localRotation = go.transform.localRotation;
                        goTessellated.transform.localScale    = go.transform.localScale;

                        int  idx             = listMeshIdx[j];
                        Mesh meshTessellated = listMeshTessellated[idx];

                        MeshFilter mf = goTessellated.GetComponent <MeshFilter>();
                        if (mf != null)
                        {
                            mf.sharedMesh = meshTessellated;
                        }

                        Renderer rn = goTessellated.GetComponent <Renderer>();
                        if (rn != null)
                        {
                            Tuple2 <int, int> submeshRange = listMeshTessellatedSubmesRange[idx];
                            Material[]        arrMaterial  = rn.sharedMaterials;

                            List <Material> listMaterial = new List <Material>();
                            for (int k = 0; k < arrMaterial.Length; k++)
                            {
                                if (k >= submeshRange.First && k <= submeshRange.Second)
                                {
                                    Material mat = arrMaterial[k];
                                    listMaterial.Add(mat);
                                }
                            }
                            rn.sharedMaterials = listMaterial.ToArray();
                        }

                        SkinnedMeshRenderer smr = goTessellated.GetComponent <SkinnedMeshRenderer>();
                        if (smr != null)
                        {
                            smr.sharedMesh = meshTessellated;
                        }

                        listGameObjectTessellated.Add(goTessellated);
                    }
                }
            }

            arrGameObjectTessellated = listGameObjectTessellated.ToArray();
            arrMeshTessellated       = listMeshTessellated.ToArray();
        }