private static void CreateGlobalBoundsObject(List <GameObject> listGO, out GameObject boundsObject, out Matrix4x4 boundsMatrixWorldToLocal) { Bounds objectsBounds = CREditorUtils.GetGlobalBoundsWorld(listGO); boundsObject = new GameObject(); Transform boundsTransform = boundsObject.transform; boundsTransform.position = objectsBounds.center; boundsMatrixWorldToLocal = boundsTransform.worldToLocalMatrix; }
public void Weld() { GameObject[] arrGOtoWeld = FieldController.GetUnityGameObjects(); int arrGOtoWeld_size = arrGOtoWeld.Length; if (arrGOtoWeld_size == 0) { EditorUtility.DisplayDialog("CaronteFX", "Input objects are mandatory", "Ok"); return; } GameObject[] arrWeldedObject; Mesh[] arrWeldedMesh; int interiorMaterialIdx; EditorUtility.DisplayProgressBar(Data.Name, "Welding...", 1.0f); CRGeometryUtils.WeldObjects(arrGOtoWeld, Data.Name, null, out arrWeldedObject, out arrWeldedMesh, out interiorMaterialIdx); EditorUtility.ClearProgressBar(); if (cnManager.IsFreeVersion() && arrWeldedObject == null) { EditorUtility.DisplayDialog("CaronteFX - Free version", "CaronteFX Free version can only weld the meshes included in the example scenes and the unity primitives (cube, plane, sphere, etc.).", "Ok"); } if (arrWeldedObject != null) { List <GameObject> listWeldedObjects = new List <GameObject>(); listWeldedObjects.AddRange(arrWeldedObject); Bounds bounds = CREditorUtils.GetGlobalBoundsWorld(listWeldedObjects); GameObject go = new GameObject(Data.Name + "_output"); go.transform.position = bounds.center; foreach (GameObject weldedGO in listWeldedObjects) { weldedGO.transform.parent = go.transform; } Data.WeldGameObject = go; UnityEditor.Selection.activeGameObject = go; } }
public void Tessellate() { GameObject[] arrGOtoTessellate = FieldController.GetUnityGameObjects(); DeleteOldObjects(); GameObject[] arrGOTessellated; Mesh[] arrMeshTessellated; EditorUtility.DisplayProgressBar(Data.Name, "Tessellating...", 1.0f); CRGeometryUtils.TessellateObjects(arrGOtoTessellate, Data.MaxEdgeDistance, Data.LimitByMeshDimensions, out arrGOTessellated, out arrMeshTessellated); EditorUtility.ClearProgressBar(); if (cnManager.IsFreeVersion() && arrGOTessellated == null) { EditorUtility.DisplayDialog("CaronteFX - Free version", "CaronteFX Free version can only tessellate the meshes included in the example scenes and the unity primitives (cube, plane, sphere, etc.).", "Ok"); } if (arrGOTessellated != null) { List <GameObject> listGameObject = new List <GameObject>(); listGameObject.AddRange(arrGOTessellated); Bounds bounds = CREditorUtils.GetGlobalBoundsWorld(listGameObject); GameObject nodeGO = new GameObject(Data.Name); nodeGO.transform.position = bounds.center; foreach (GameObject go in arrGOTessellated) { go.transform.parent = nodeGO.transform; } Data.NodeGO = nodeGO; Data.ArrTessellatedGO = arrGOTessellated; Data.ArrTessellatedMesh = arrMeshTessellated; Selection.activeGameObject = nodeGO; } }
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); } }