public static void AddRelations(GameObject parentFx, GameObject[] arrGameObject, List <Tuple2 <Caronte_Fx, int> > listCaronteFx) { for (int i = 0; i < arrGameObject.Length; i++) { GameObject go = arrGameObject[i]; Caronte_Fx fxChild = go.GetComponent <Caronte_Fx>(); if (fxChild != null) { int depth = go.GetFxHierachyDepthFrom(parentFx); listCaronteFx.Add(Tuple2.New(fxChild, depth)); } } }
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(); }
private void UpdateSoftBody( Transform tr, BodyInfo bdInfo ) { SoftBodyInfo softInfo = (SoftBodyInfo)bdInfo; tr.localPosition = softInfo.center_; tr.localRotation = Quaternion.identity; tr.localScale = Vector3.one; GameObject go = tr.gameObject; Caronte_Fx_Body cfxBody = go.GetComponent<Caronte_Fx_Body>(); if (cfxBody != null && entityManager_.HasBodyMeshColliderRef(bdInfo.idBody_) ) { UnityEngine.Mesh meshCollider = entityManager_.GetBodyMeshColliderRef(bdInfo.idBody_); if (meshCollider != null) { meshCollider.vertices = softInfo.arrVerticesCollider_; meshCollider.RecalculateNormals(); meshCollider.RecalculateBounds(); } if (cfxBody.colliderMesh_ != meshCollider) { meshCollider.name = cfxBody.colliderMesh_.name; cfxBody.colliderMesh_ = meshCollider; } } Tuple2<UnityEngine.Mesh, MeshUpdater> meshRenderData = entityManager_.GetBodyMeshRenderUpdaterRef(bdInfo.idBody_); UnityEngine.Mesh meshToUpdate = meshRenderData.First; MeshUpdater meshUpdater = meshRenderData.Second; meshToUpdate.vertices = softInfo.arrVerticesRender_; mcForUpdates.Clear(); mcForUpdates.SetForUpdate(meshToUpdate); CaronteSharp.Tools.UpdateVertexNormalsAndTangents( meshUpdater, mcForUpdates ); meshToUpdate.normals = mcForUpdates.arrNormal_; meshToUpdate.tangents = mcForUpdates.arrTan_; meshToUpdate.RecalculateBounds(); }
private void CreateNewObjects(Vector3 position, List <GameObject> listParentGO, List <GameObject> listChoppedParentGO, CaronteSharp.MeshParentInfo[] arrMeshParentInfo, UnityEngine.Mesh[] arrMeshPieceUnity, Tuple2 <int, int>[] arrSubmeshRange, int[] arrMeshComplexIdx, Vector3[] arrMeshPosition, uint[] arrOutsideInsideIdx) { List <GameObject> listChoppedGO = new List <GameObject>(); List <Tuple2 <GameObject, GameObject> > listOutsideInsideGOParent = new List <Tuple2 <GameObject, GameObject> >(); bool hasBeenSplitted = arrOutsideInsideIdx != null; // Create InsideOutSidePieces for (int i = 0; i < listParentGO.Count; i++) { GameObject parentGO = listParentGO[i]; GameObject chopParentGO = listChoppedParentGO[i]; if (hasBeenSplitted) { GameObject outsideGO = parentGO.CreateDummy(parentGO.name + "_outside"); GameObject insideGO = parentGO.CreateDummy(parentGO.name + "_inside"); outsideGO.transform.parent = chopParentGO.transform; insideGO.transform.parent = chopParentGO.transform; listOutsideInsideGOParent.Add(Tuple2.New(outsideGO, insideGO)); } if (Data.HideParentObjectAuto) { Undo.RecordObject(parentGO, "Change activate state - " + parentGO.name); parentGO.SetActive(false); EditorUtility.SetDirty(parentGO); } } //Create Chopped Pieces Dictionary <GameObject, int> dictChoppedGOInteriorSubmeshIdx = new Dictionary <GameObject, int>(); int nMeshPieces = arrMeshPieceUnity.Length; for (int i = 0; i < nMeshPieces; i++) { UnityEngine.Mesh meshPiece = arrMeshPieceUnity[i]; Tuple2 <int, int> submeshRange = arrSubmeshRange[i]; int meshComplexIdx = arrMeshComplexIdx[i]; Vector3 goPosition = arrMeshPosition[i]; MeshParentInfo parentInfo = arrMeshParentInfo[meshComplexIdx]; int parentIdx = (int)parentInfo.parentMeshIdx_; GameObject parentGO = listParentGO[parentIdx]; GameObject chopParentGO = listChoppedParentGO[parentIdx]; int interiorPieceSubmeshIdx; GameObject goPiece = CRGeometryUtils.CreatePiece(i, meshPiece, parentInfo, goPosition, submeshRange, Data.InteriorMaterial, parentGO, chopParentGO, out interiorPieceSubmeshIdx); if (hasBeenSplitted) { Tuple2 <GameObject, GameObject> tupleOutsideInside = listOutsideInsideGOParent[parentIdx]; GameObject outsideGO = tupleOutsideInside.First; GameObject insideGO = tupleOutsideInside.Second; uint outsideInsideIdx = arrOutsideInsideIdx[meshComplexIdx]; if (outsideInsideIdx == 0) { goPiece.transform.parent = outsideGO.transform; goPiece.name = parentGO.name + "_out_" + i; } else if (outsideInsideIdx == 1) { goPiece.transform.parent = insideGO.transform; goPiece.name = parentGO.name + "_in_" + i; } } listChoppedGO.Add(goPiece); dictChoppedGOInteriorSubmeshIdx.Add(goPiece, interiorPieceSubmeshIdx); } GameObject chopRoot = new GameObject(Data.Name + "_output"); chopRoot.transform.position = position; Undo.RegisterCreatedObjectUndo(chopRoot, "Created " + Data.Name + "_output"); Data.GameObjectChoppedRoot = chopRoot; for (int i = 0; i < listChoppedParentGO.Count; i++) { GameObject chopParentGO = listChoppedParentGO[i]; chopParentGO.transform.parent = Data.GameObjectChoppedRoot.transform; chopParentGO.transform.SetAsFirstSibling(); } Selection.activeGameObject = Data.GameObjectChoppedRoot; SaveNewChopInfo(dictChoppedGOInteriorSubmeshIdx); }
private static void CreateMeshesFromComplex(CaronteSharp.MeshComplex inputMesh, out UnityEngine.Mesh[] outputMeshes, out Tuple2 <int, int>[] outputSubmeshRange) { Vector3[] vertices = inputMesh.arrPosition_; Vector3[] normals = inputMesh.arrNormal_; Vector4[] tangents = inputMesh.arrTan_; Vector2[] uv = inputMesh.arrUV_; bool hasNormals = (normals != null) && (normals.Length > 0); bool hasTangents = (tangents != null) && (tangents.Length > 0); bool hasUVs = (uv != null) && (uv.Length > 0); int maxVertexesPerMesh = 65533; List <UnityEngine.Mesh> listMeshes = new List <UnityEngine.Mesh>(); List <Tuple2 <int, int> > listSubmeshRange = new List <Tuple2 <int, int> >(); List <Vector3> listCurPos = new List <Vector3>(); List <Vector3> listCurNor = new List <Vector3>(); List <Vector4> listCurTan = new List <Vector4>(); List <Vector2> listCurUVs = new List <Vector2>(); List <List <int> > listListCurIndices = new List <List <int> >(); Dictionary <int, int> dictOldIndexToNew = new Dictionary <int, int>(); int indexMin = 0; int indexMax = 0; int submeshIdMin = 0; int[] subMeshesIdx = inputMesh.arrSubmeshIdx_; int nSubmeshIdx = subMeshesIdx.Length; for (int i = 0; i < nSubmeshIdx; i++) { indexMin = indexMax; indexMax = subMeshesIdx[i] * 3; List <int> listCurIndices = new List <int>(); listListCurIndices.Add(listCurIndices); for (int j = indexMin; j < indexMax; j++) { int oldIndex = inputMesh.arrIndex_[j]; if (!dictOldIndexToNew.ContainsKey(oldIndex)) { dictOldIndexToNew.Add(oldIndex, listCurPos.Count); listCurPos.Add(vertices[oldIndex]); if (hasNormals) { listCurNor.Add(normals[oldIndex]); } if (hasTangents) { listCurTan.Add(tangents[oldIndex]); } if (hasUVs) { listCurUVs.Add(uv[oldIndex]); } } int index = dictOldIndexToNew[oldIndex]; listCurIndices.Add(index); bool isTriangleEnd = ((j % 3) == 2); bool isMaxVertexReached = (listCurPos.Count >= maxVertexesPerMesh); bool isLastMeshTriangle = ((i == (nSubmeshIdx - 1)) && (j == (indexMax - 1))); if ((isMaxVertexReached && isTriangleEnd) || isLastMeshTriangle) { Mesh mesh; GenerateUnityMesh(listCurPos, listCurNor, listCurTan, listCurUVs, listListCurIndices, out mesh); listMeshes.Add(mesh); listSubmeshRange.Add(Tuple2.New(submeshIdMin, i)); submeshIdMin = i; listListCurIndices.Add(listCurIndices); dictOldIndexToNew.Clear(); } } } outputMeshes = listMeshes.ToArray(); outputSubmeshRange = listSubmeshRange.ToArray(); }
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(); }
private static void AssignPieceMaterials(GameObject pieceGO, GameObject parentGO, MeshParentInfo parentInfo, Material interiorMaterial, Tuple2 <int, int> submeshRange, out int interiorSubmeshIdx) { interiorSubmeshIdx = -1; MeshRenderer pieceRenderer = pieceGO.GetComponent <MeshRenderer>(); MeshRenderer parentRenderer = parentGO.GetComponent <MeshRenderer>(); if (parentRenderer != null) { Material[] arrMaterials = parentRenderer.sharedMaterials; List <Material> pieceMaterials = new List <Material>(); uint[] arrParentSubmeshIdx = parentInfo.arrParentSubMeshIdx_; for (int i = submeshRange.First; i <= submeshRange.Second; i++) { uint submeshIndex = arrParentSubmeshIdx[i]; if (submeshIndex == uint.MaxValue) { pieceMaterials.Add(interiorMaterial); interiorSubmeshIdx = i; } else { pieceMaterials.Add(arrMaterials[submeshIndex]); } } pieceRenderer.sharedMaterials = pieceMaterials.ToArray(); } }
public static GameObject CreatePiece(int id, Mesh mesh, MeshParentInfo parentInfo, Vector3 goPosition, Tuple2 <int, int> submeshRange, Material interiorMaterial, GameObject parentGO, GameObject chopGO, out int interiorSubmeshIdx) { string name = parentGO.name + "_" + id; GameObject pieceGO = new GameObject(name); mesh.name = name; pieceGO.transform.parent = chopGO.transform; pieceGO.transform.position = goPosition; pieceGO.AddMesh(mesh); AssignPieceMaterials(pieceGO, parentGO, parentInfo, interiorMaterial, submeshRange, out interiorSubmeshIdx); return(pieceGO); }