public override void OnInspectorGUI() { int nButtonWidth = 200; serializedObject.Update(); CombinedMesh combinedMesh = serializedObject.targetObject as CombinedMesh; EditorGUILayout.Space(); EditorGUILayout.Space(); int nNumObjects = combinedMesh.MeshObjects != null ? combinedMesh.MeshObjects.Length : 0; EditorGUILayout.PropertyField(PropSaveMeshAsset, new GUIContent("Enable Prefab Usage", "If activated, will save the mesh to an asset file on disc. Use this if you want to use the generated mesh in prefabs, otherwise prefabs won't reference the mesh correctly.")); EditorGUILayout.PropertyField(PropKeepPosition, new GUIContent("Keep Position", "If keep position is activated, the gameobject will keep its current position. Otherwise it will reposition itself to match the objects being combined.")); EditorGUILayout.PropertyField(PropPivotMode, new GUIContent("Place Pivot Mode", "Where to place the pivot.")); EditorGUILayout.PropertyField(PropMeshObjects, new GUIContent("Source Mesh Objects List (" + nNumObjects + " elements)", "The list of objects whose meshes to combine."), true); EditorGUILayout.PropertyField(PropRootNode, new GUIContent("Root node", "Specify an object to set it and its whole hierarchy to the list of objects to combine.")); EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); GUILayout.Label(" "); serializedObject.ApplyModifiedProperties(); if (GUILayout.Button(new GUIContent("Build List From Root Node", "Will build the Source Mesh Objects List using the given object and all the hierarchy below it."), GUILayout.Width(nButtonWidth))) { if (PropRootNode.objectReferenceValue) { List <MeshFilter> listMeshFilters = new List <MeshFilter>(); BuildMeshFilterListRecursive(PropRootNode.objectReferenceValue as GameObject, listMeshFilters); combinedMesh.MeshObjects = listMeshFilters.ToArray(); } } GUILayout.Label(" "); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label(" "); if (GUILayout.Button(new GUIContent("Combine", "Starts the combine process."), GUILayout.Width(nButtonWidth))) { try { combinedMesh.Combine(Progress); } catch (System.Exception e) { Debug.LogError("Exception Type: " + e.GetType().ToString() + ". Message: " + e.Message.ToString() + ". Stack Trace: " + e.StackTrace.ToString()); } EditorUtility.ClearProgressBar(); } GUILayout.Label(" "); EditorGUILayout.EndHorizontal(); }
public void GenCombineMesh() { allChildMatGroup = new List <Material>(); allCombineMeshes = new List <CombinedMesh>(); allMeshRenderer = GetComponentsInChildren <MeshRenderer>(); foreach (MeshRenderer m in allMeshRenderer) { if (m.sharedMaterials.Length == 1 && !allChildMatGroup.Contains(m.sharedMaterial)) { allChildMatGroup.Add(m.sharedMaterial); } } for (int i = 0; i < allChildMatGroup.Count; i++) { CombinedMesh cMesh = new CombinedMesh(); cMesh.mat = allChildMatGroup[i]; foreach (MeshRenderer m in allMeshRenderer) { if (m.sharedMaterials.Length == 1) { if (cMesh.mat == m.sharedMaterial) { cMesh.allChildMeshFilter.Add(m.GetComponent <MeshFilter>()); } } } cMesh.GenCombineMesh(); allCombineMeshes.Add(cMesh); } }
public static void RemveGo(GameObject gameObject) { CombinedMesh mesh = GetMesh(gameObject); if (mesh != null) { Debug.Log("mesh:" + mesh.name); Debug.Log("mesh.meshFilters:" + mesh.meshFilters.Count); MeshFilter[] meshFilters = gameObject.GetComponentsInChildren <MeshFilter>(); foreach (var mf in meshFilters) { mesh.meshFilters.Remove(mf); } MeshRenderer[] meshRenderers = gameObject.GetComponentsInChildren <MeshRenderer>(); foreach (var mr in meshRenderers) { mr.enabled = true; mr.material.SetColor("_BaseColor", Color.red); } Debug.Log("mesh.meshFilters:" + mesh.meshFilters.Count); mesh.Refresh();//重新合并 } else { Debug.LogError("未找到CombinedMesh:" + gameObject); } }
public static IEnumerator Combine_Coroutine(GameObject source, int waitCount, bool isDestroy, Action <GameObject> callback) { DateTime start = DateTime.Now; int count = 0; GameObject goNew = CombineMaterials(source, out count);//按材质合并 CombinedMesh combinedMesh = new CombinedMesh(goNew.transform, null, null); yield return(combinedMesh.DoCombine_Coroutine(false, waitCount)); GameObject target = combinedMesh.CreateNewGo(false, null); target.name = source.name + "_Combined"; goNew.transform.SetParent(target.transform); GameObject.DestroyImmediate(goNew); Debug.LogError(string.Format("CombinedMesh 用时:{0}ms,数量:{1}", (DateTime.Now - start).TotalMilliseconds, count)); if (isDestroy) { GameObject.Destroy(source); } if (callback != null) { callback(target); } yield return(target); }
public static GameObject SimpleCombine(GameObject source, GameObject target) { CombinedMesh combinedMesh = new CombinedMesh(source.transform, null, null); combinedMesh.DoCombine(true); target = combinedMesh.CreateNewGo(false, target); target.AddComponent <MeshInfo>(); Debug.Log("Combine:" + source + "->" + target); return(target); }
public void SaveOutCombineMesh(CombinedMesh cMesh) { Mesh outPutMesh = new Mesh(); outPutMesh.vertices = cMesh.vertexList.ToArray(); outPutMesh.normals = cMesh.normalList.ToArray(); outPutMesh.uv = cMesh.uvList.ToArray(); outPutMesh.colors = cMesh.colorList.ToArray(); outPutMesh.subMeshCount = 1; outPutMesh.SetIndices(cMesh.indices.ToArray(), MeshTopology.Triangles, 0); if (!Directory.Exists(Application.dataPath + "/intermediate")) { Directory.CreateDirectory(Application.dataPath + "/intermediate"); } string tempCombineSpriteMeshFolderFinal = "Assets/intermediate/CombineSpritMesh"; if (!Directory.Exists(tempCombineSpriteMeshFolderFinal)) { Directory.CreateDirectory(tempCombineSpriteMeshFolderFinal); } string finalName = tempCombineSpriteMeshFolderFinal + "/" + cMesh.mat.name + "_CombineSpriteMesh.asset"; Unwrapping.GenerateSecondaryUVSet(outPutMesh); if (!File.Exists(finalName)) { AssetDatabase.CreateAsset(outPutMesh, finalName); } else { Mesh existMesh = (Mesh)AssetDatabase.LoadAssetAtPath(finalName, typeof(Mesh)); existMesh.Clear(); existMesh.vertices = outPutMesh.vertices; existMesh.normals = outPutMesh.normals; existMesh.uv = outPutMesh.uv; existMesh.colors = outPutMesh.colors; //existMesh.triangles = outPutMesh.triangles; existMesh.subMeshCount = outPutMesh.subMeshCount; for (int i = 0; i < outPutMesh.subMeshCount; i++) { existMesh.SetIndices(outPutMesh.GetIndices(i), MeshTopology.Triangles, i); } Unwrapping.GenerateSecondaryUVSet(existMesh); } Debug.Log("生成" + cMesh.mat.name + "_CombineSpriteMesh"); }
void Progress(string strMessage, float fT) { CombinedMesh combinedMesh = serializedObject.targetObject as CombinedMesh; Repaint(); if (EditorUtility.DisplayCancelableProgressBar("Combining", strMessage, fT)) { combinedMesh.CancelCombining(); } }
public static void AddGo(GameObject gameObject, CombinedMesh mesh) { if (go2ms.ContainsKey(gameObject)) { go2ms[gameObject] = mesh; } else { go2ms.Add(gameObject, mesh); } }
public override int GetNumVerticesFor(GameObject go) { CombinedMesh c = null; if (obj2MeshCombinerMap.TryGetValue(go.GetInstanceID(), out c)) { return(c.combinedMesh.GetNumVerticesFor(go)); } else { return(-1); } }
public override int GetNumVerticesFor(int gameObjectID) { CombinedMesh c = null; if (obj2MeshCombinerMap.TryGetValue(gameObjectID, out c)) { return(c.combinedMesh.GetNumVerticesFor(gameObjectID)); } else { return(-1); } }
public int GetNumVerticesFor(UnityEngine.GameObject go) { CombinedMesh c = null; if (obj2MeshCombinerMap.TryGetValue(go, out c)) { return(c.combinedMesh.GetNumVerticesFor(go)); } else { return(-1); } }
public override bool UpdateGameObjects(GameObject[] gos, bool recalcBounds, bool updateVertices, bool updateNormals, bool updateTangents, bool updateUV, bool updateUV2, bool updateUV3, bool updateUV4, bool updateUV5, bool updateUV6, bool updateUV7, bool updateUV8, bool updateColors, bool updateSkinningInfo) { if (gos == null) { Debug.LogError("list of game objects cannot be null"); return(false); } //build gos lists for (int i = 0; i < meshCombiners.Count; i++) { meshCombiners[i].gosToUpdate.Clear(); } for (int i = 0; i < gos.Length; i++) { CombinedMesh cm = null; obj2MeshCombinerMap.TryGetValue(gos[i].GetInstanceID(), out cm); if (cm != null) { cm.gosToUpdate.Add(gos[i]); } else { Debug.LogWarning("Object " + gos[i] + " is not in the combined mesh."); } } bool success = true; for (int i = 0; i < meshCombiners.Count; i++) { if (meshCombiners[i].gosToUpdate.Count > 0) { meshCombiners[i].isDirty = true; GameObject[] gosToUpdate = meshCombiners[i].gosToUpdate.ToArray(); success = success && meshCombiners[i].combinedMesh.UpdateGameObjects(gosToUpdate, recalcBounds, updateVertices, updateNormals, updateTangents, updateUV, updateUV2, updateUV3, updateUV4, updateUV5, updateUV6, updateUV7, updateUV8, updateColors, updateSkinningInfo); } } return(success); }
public void Combine(SkinnedMeshRenderer target) { Mesh mesh = target.sharedMesh; Material[] materials = target.materials; CombinedMesh combinedMesh = new CombinedMesh(); combinedMesh.mesh = mesh; combinedMesh.materials = materials; for (int i = 0; i < mesh.subMeshCount; i++) { var submesh = mesh.GetSubMesh(i); } }
public static GameObject Combine(GameObject source) { DateTime start = DateTime.Now; int count = 0; GameObject goNew = CombineMaterials(source, out count);//按材质合并 CombinedMesh combinedMesh = new CombinedMesh(goNew.transform, null, null); combinedMesh.DoCombine(false); GameObject target = combinedMesh.CreateNewGo(false, null); target.name = source.name + "_Combined"; goNew.transform.SetParent(target.transform); GameObject.DestroyImmediate(goNew); Debug.LogError(string.Format("CombinedMesh 用时:{0}ms,数量:{1}", (DateTime.Now - start).TotalMilliseconds, count)); return(target); }
public static IEnumerator SimpleCombine_Coroutine(GameObject source, GameObject target, int waitCount, bool isDestroy, Action <GameObject> callback) { CombinedMesh combinedMesh = new CombinedMesh(source.transform, null, null); yield return(combinedMesh.DoCombine_Coroutine(true, waitCount)); target = combinedMesh.CreateNewGo(false, target); target.AddComponent <MeshInfo>(); Debug.Log("Combine:" + source + "->" + target); if (isDestroy) { GameObject.Destroy(source); } if (callback != null) { callback(source); } yield return(target); }
public static IEnumerator CombineMaterials_Coroutine(GameObject go, int waitCount, bool isDestroy, Action <GameObject> callback) { DateTime start = DateTime.Now; GameObject goNew = new GameObject(); goNew.name = go.name + "_Combined"; goNew.transform.SetParent(go.transform.parent); int count = 0; Dictionary <Material, List <MeshFilter> > mat2Filters = GetMatFilters(go, out count); yield return(null); int i = 0; foreach (var item in mat2Filters) { Material material = item.Key; List <MeshFilter> list = item.Value; Debug.LogWarning(string.Format("CombineMaterials_Coroutine {0} ({1}/{2})", material, i + 1, mat2Filters.Count)); CombinedMesh combinedMesh = new CombinedMesh(go.transform, list, material); yield return(combinedMesh.DoCombine_Coroutine(true, waitCount)); GameObject matGo = combinedMesh.CreateNewGo(false, null); matGo.name = material.name; matGo.transform.SetParent(goNew.transform); yield return(goNew); i++; } if (isDestroy) { GameObject.Destroy(go); } Debug.LogError(string.Format("CombineMaterials 用时:{0},Mat数量:{1},Mesh数量:{2}", (DateTime.Now - start), mat2Filters.Count, count)); if (callback != null) { callback(goNew); } yield return(goNew); }
public void UpdateGameObjects(GameObject[] gos, bool recalcBounds = true, bool updateVertices = true, bool updateNormals = true, bool updateTangents = true, bool updateUV = false, bool updateUV1 = false, bool updateUV2 = false, bool updateColors = false, bool updateSkinningInfo = false) { if (gos == null) { Debug.LogError("list of game objects cannot be null"); return; } //build gos lists for (int i = 0; i < meshCombiners.Count; i++) { meshCombiners[i].gosToUpdate.Clear(); } for (int i = 0; i < gos.Length; i++) { CombinedMesh cm = null; obj2MeshCombinerMap.TryGetValue(gos[i].GetInstanceID(), out cm); if (cm != null) { cm.gosToUpdate.Add(gos[i]); } else { Debug.LogWarning("Object " + gos[i] + " is not in the combined mesh."); } } for (int i = 0; i < meshCombiners.Count; i++) { if (meshCombiners[i].gosToUpdate.Count > 0) { GameObject[] gosToUpdate = meshCombiners[i].gosToUpdate.ToArray(); meshCombiners[i].combinedMesh.UpdateGameObjects(gosToUpdate, recalcBounds, updateVertices, updateNormals, updateTangents, updateUV, updateUV1, updateUV2, updateColors, updateSkinningInfo); } } }
public void UpdateGameObjects(UnityEngine.GameObject[] gos, bool recalcBounds = true) { if (gos == null) { Debug.LogError("list of game objects cannot be null"); return; } //build gos lists for (int i = 0; i < meshCombiners.Count; i++) { meshCombiners[i].gosToUpdate.Clear(); } for (int i = 0; i < gos.Length; i++) { CombinedMesh cm = null; obj2MeshCombinerMap.TryGetValue(gos[i], out cm); if (cm != null) { cm.gosToUpdate.Add(gos[i]); } else { Debug.LogWarning("UnityEngine.Object " + gos[i] + " is not in the combined mesh."); } } for (int i = 0; i < meshCombiners.Count; i++) { if (meshCombiners[i].gosToUpdate.Count > 0) { UnityEngine.GameObject[] gosToUpdate = meshCombiners[i].gosToUpdate.ToArray(); meshCombiners[i].combinedMesh.UpdateGameObjects(gosToUpdate, recalcBounds); } } }
public static GameObject CombineMaterials(GameObject go, out int count) { DateTime start = DateTime.Now; GameObject goNew = new GameObject(); goNew.name = go.name + "_Combined"; goNew.transform.SetParent(go.transform.parent); //int count=0; Dictionary <Material, List <MeshFilter> > mat2Filters = GetMatFilters(go, out count); foreach (var item in mat2Filters) { Material material = item.Key; List <MeshFilter> list = item.Value; CombinedMesh combinedMesh = new CombinedMesh(go.transform, list, material); combinedMesh.DoCombine(true); GameObject matGo = combinedMesh.CreateNewGo(false, null); matGo.name = material.name; matGo.transform.SetParent(goNew.transform); } Debug.LogError(string.Format("CombineMaterials 用时:{0},Mat数量:{1},Mesh数量:{2}", (DateTime.Now - start), mat2Filters.Count, count)); return(goNew); }
void _distributeAmongBakers(GameObject[] gos, int[] deleteGOinstanceIDs){ if (gos == null) gos = empty; if (deleteGOinstanceIDs == null) deleteGOinstanceIDs = emptyIDs; if (resultSceneObject == null) resultSceneObject = new GameObject("CombinedMesh-" + name); //PART 2 ==== calculate which bakers to add objects to for (int i = 0; i < meshCombiners.Count; i++){ meshCombiners[i].extraSpace = _maxVertsInMesh - meshCombiners[i].combinedMesh.GetMesh().vertexCount; } //Profile.End//Profile("MB2_MultiMeshCombiner.AddDeleteGameObjects1"); //Profile.Start//Profile("MB2_MultiMeshCombiner.AddDeleteGameObjects2.1"); //first delete game objects from the existing combinedMeshes keep track of free space for (int i = 0; i < deleteGOinstanceIDs.Length; i++){ CombinedMesh c = null; if (obj2MeshCombinerMap.TryGetValue(deleteGOinstanceIDs[i], out c)){ if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("MB2_MultiMeshCombiner.Removing " + deleteGOinstanceIDs[i] + " from meshCombiner " + meshCombiners.IndexOf(c)); c.numVertsInListToDelete += c.combinedMesh.GetNumVerticesFor(deleteGOinstanceIDs[i]); //m.vertexCount; c.gosToDelete.Add(deleteGOinstanceIDs[i]); } else { Debug.LogWarning("Object " + deleteGOinstanceIDs[i] + " in the list of objects to delete is not in the combined mesh."); } } for (int i = 0; i < gos.Length; i++){ GameObject go = gos[i]; int numVerts = MB_Utility.GetMesh(go).vertexCount; CombinedMesh cm = null; for (int j = 0; j < meshCombiners.Count; j++){ if (meshCombiners[j].extraSpace + meshCombiners[j].numVertsInListToDelete - meshCombiners[j].numVertsInListToAdd > numVerts){ cm = meshCombiners[j]; if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("MB2_MultiMeshCombiner.Added " + gos[i] + " to combinedMesh " + j, LOG_LEVEL); break; } } if (cm == null){ cm = new CombinedMesh(maxVertsInMesh); _setMBValues(cm.combinedMesh); meshCombiners.Add(cm); if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("MB2_MultiMeshCombiner.Created new combinedMesh"); } cm.gosToAdd.Add(go); cm.numVertsInListToAdd += numVerts; // obj2MeshCombinerMap.Add(go,cm); } }
Mesh _bakeStep1(UnityEngine.GameObject[] gos, UnityEngine.GameObject[] deleteGOs, bool disableRendererInSource, bool fixOutOfBoundUVs) { //Profile.EndProfile("MB2_MultiMeshCombiner.AddDeleteGameObjects2.2"); //Profile.StartProfile("MB2_MultiMeshCombiner.AddDeleteGameObjects3"); //PART 3 ==== Add delete meshes from combined for (int i = 0; i < meshCombiners.Count; i++) { CombinedMesh cm = meshCombiners[i]; if (cm.combinedMesh.targetRenderer == null) { UnityEngine.GameObject go = cm.combinedMesh.buildSceneMeshObject(resultSceneObject, cm.combinedMesh.GetMesh(), true); cm.combinedMesh.targetRenderer = go.GetComponent <UnityEngine.Renderer>(); } else { if (cm.combinedMesh.targetRenderer.transform.parent != resultSceneObject.transform) { Debug.LogError("targetRender objects must be children of resultSceneObject"); return(null); } } if (cm.gosToAdd.Count > 0 || cm.gosToDelete.Count > 0) { cm.combinedMesh.AddDeleteGameObjects(cm.gosToAdd.ToArray(), cm.gosToDelete.ToArray(), disableRendererInSource, textureBakeResults.fixOutOfBoundsUVs); } UnityEngine.Renderer r = cm.combinedMesh.targetRenderer; if (r is MeshRenderer) { MeshFilter mf = r.gameObject.GetComponent <MeshFilter>(); mf.sharedMesh = cm.combinedMesh.GetMesh(); } else { SkinnedMeshRenderer smr = (SkinnedMeshRenderer)r; smr.sharedMesh = cm.combinedMesh.GetMesh(); } } for (int i = 0; i < meshCombiners.Count; i++) { CombinedMesh cm = meshCombiners[i]; for (int j = 0; j < cm.gosToDelete.Count; j++) { obj2MeshCombinerMap.Remove(cm.gosToDelete[j]); if (cm.gosToDelete[j] != null) { // MB2_LOD lod = cm.gosToDelete[j].GetComponent<MB2_LOD>(); // lod.SetStatus(MB2_LODStatus.notInMesh); } } } for (int i = 0; i < meshCombiners.Count; i++) { CombinedMesh cm = meshCombiners[i]; for (int j = 0; j < cm.gosToAdd.Count; j++) { obj2MeshCombinerMap.Add(cm.gosToAdd[j], cm); // MB2_LOD lod = cm.gosToAdd[j].GetComponent<MB2_LOD>(); // lod.SetStatus(MB2_LODStatus.inMesh); } if (cm.gosToAdd.Count > 0 || cm.gosToDelete.Count > 0) { cm.gosToDelete.Clear(); cm.gosToAdd.Clear(); cm.numVertsInListToDelete = 0; cm.numVertsInListToAdd = 0; cm.isDirty = true; } } //Profile.EndProfile("MB2_MultiMeshCombiner.AddDeleteGameObjects3"); if (VERBOSE) { string s = "Meshes in combined:"; for (int i = 0; i < meshCombiners.Count; i++) { s += " mesh" + i + "(" + meshCombiners[i].combinedMesh.GetObjectsInCombined().Count + ")\n"; } s += "children in result: " + resultSceneObject.transform.childCount; Debug.Log(s); } if (meshCombiners.Count > 0) { return(meshCombiners[0].combinedMesh.GetMesh()); } else { return(null); } }
void _distributeAmongBakers(UnityEngine.GameObject[] gos, UnityEngine.GameObject[] deleteGOs) { if (gos == null) { gos = empty; } if (deleteGOs == null) { deleteGOs = empty; } if (resultSceneObject == null) { resultSceneObject = new UnityEngine.GameObject("CombinedMesh-" + name); } //PART 2 ==== calculate which bakers to add objects to for (int i = 0; i < meshCombiners.Count; i++) { meshCombiners[i].extraSpace = _maxVertsInMesh - meshCombiners[i].combinedMesh.GetMesh().vertexCount; } //Profile.EndProfile("MB2_MultiMeshCombiner.AddDeleteGameObjects1"); //Profile.StartProfile("MB2_MultiMeshCombiner.AddDeleteGameObjects2.1"); //first delete game objects from the existing combinedMeshes keep track of free space for (int i = 0; i < deleteGOs.Length; i++) { CombinedMesh c = null; if (obj2MeshCombinerMap.TryGetValue(deleteGOs[i], out c)) { if (VERBOSE) { Debug.Log("Removing " + deleteGOs[i] + " from meshCombiner " + meshCombiners.IndexOf(c)); } c.numVertsInListToDelete += c.combinedMesh.GetNumVerticesFor(deleteGOs[i]); //m.vertexCount; c.gosToDelete.Add(deleteGOs[i]); } else { Debug.LogWarning("UnityEngine.Object " + deleteGOs[i] + " in the list of objects to delete is not in the combined mesh."); } } for (int i = 0; i < gos.Length; i++) { UnityEngine.GameObject go = gos[i]; int numVerts = MB_Utility.GetMesh(go).vertexCount; CombinedMesh cm = null; for (int j = 0; j < meshCombiners.Count; j++) { if (meshCombiners[j].extraSpace + meshCombiners[j].numVertsInListToDelete - meshCombiners[j].numVertsInListToAdd > numVerts) { cm = meshCombiners[j]; if (VERBOSE) { Debug.Log("Added " + gos[i] + " to combinedMesh " + j); } break; } } if (cm == null) { cm = new CombinedMesh(maxVertsInMesh); _setMBValues(cm.combinedMesh); meshCombiners.Add(cm); if (VERBOSE) { Debug.Log("Created new combinedMesh"); } } cm.gosToAdd.Add(go); cm.numVertsInListToAdd += numVerts; // obj2MeshCombinerMap.Add(go,cm); } }
bool _bakeStep1(GameObject[] gos, int[] deleteGOinstanceIDs, bool disableRendererInSource) { //Profile.End//Profile("MB2_MultiMeshCombiner.AddDeleteGameObjects2.2"); //Profile.Start//Profile("MB2_MultiMeshCombiner.AddDeleteGameObjects3"); //PART 3 ==== Add delete meshes from combined for (int i = 0; i < meshCombiners.Count; i++) { CombinedMesh cm = meshCombiners[i]; if (cm.combinedMesh.targetRenderer == null) { cm.combinedMesh.resultSceneObject = _resultSceneObject; cm.combinedMesh.BuildSceneMeshObject(gos, true); if (_LOG_LEVEL >= MB2_LogLevel.debug) { MB2_Log.LogDebug("BuildSO combiner {0} goID {1} targetRenID {2} meshID {3}", i, cm.combinedMesh.targetRenderer.gameObject.GetInstanceID(), cm.combinedMesh.targetRenderer.GetInstanceID(), cm.combinedMesh.GetMesh().GetInstanceID()); } } else { if (cm.combinedMesh.targetRenderer.transform.parent != resultSceneObject.transform) { Debug.LogError("targetRender objects must be children of resultSceneObject"); return(false); } } if (cm.gosToAdd.Count > 0 || cm.gosToDelete.Count > 0) { cm.combinedMesh.AddDeleteGameObjectsByID(cm.gosToAdd.ToArray(), cm.gosToDelete.ToArray(), disableRendererInSource); if (_LOG_LEVEL >= MB2_LogLevel.debug) { MB2_Log.LogDebug("Baked combiner {0} obsAdded {1} objsRemoved {2} goID {3} targetRenID {4} meshID {5}", i, cm.gosToAdd.Count, cm.gosToDelete.Count, cm.combinedMesh.targetRenderer.gameObject.GetInstanceID(), cm.combinedMesh.targetRenderer.GetInstanceID(), cm.combinedMesh.GetMesh().GetInstanceID()); } } Renderer r = cm.combinedMesh.targetRenderer; Mesh m = cm.combinedMesh.GetMesh(); if (r is MeshRenderer) { MeshFilter mf = r.gameObject.GetComponent <MeshFilter>(); mf.sharedMesh = m; } else { SkinnedMeshRenderer smr = (SkinnedMeshRenderer)r; smr.sharedMesh = m; } } for (int i = 0; i < meshCombiners.Count; i++) { CombinedMesh cm = meshCombiners[i]; for (int j = 0; j < cm.gosToDelete.Count; j++) { obj2MeshCombinerMap.Remove(cm.gosToDelete[j]); } } for (int i = 0; i < meshCombiners.Count; i++) { CombinedMesh cm = meshCombiners[i]; for (int j = 0; j < cm.gosToAdd.Count; j++) { obj2MeshCombinerMap.Add(cm.gosToAdd[j].GetInstanceID(), cm); } if (cm.gosToAdd.Count > 0 || cm.gosToDelete.Count > 0) { cm.gosToDelete.Clear(); cm.gosToAdd.Clear(); cm.numVertsInListToDelete = 0; cm.numVertsInListToAdd = 0; cm.isDirty = true; } } //Profile.End//Profile("MB2_MultiMeshCombiner.AddDeleteGameObjects3"); if (LOG_LEVEL >= MB2_LogLevel.debug) { string s = "Meshes in combined:"; for (int i = 0; i < meshCombiners.Count; i++) { s += " mesh" + i + "(" + meshCombiners[i].combinedMesh.GetObjectsInCombined().Count + ")\n"; } s += "children in result: " + resultSceneObject.transform.childCount; MB2_Log.LogDebug(s, LOG_LEVEL); } if (meshCombiners.Count > 0) { return(true); } else { return(false); } }
public Mesh AddDeleteGameObjects(GameObject[] gos, GameObject[] deleteGOs, bool disableRendererInSource, bool fixOutOfBoundUVs) { _validateTextureBakeResults(); if (resultSceneObject == null) { resultSceneObject = new GameObject("CombinedMesh-" + name); } if (gos != null) { for (int i = 0; i < gos.Length; i++) { if (gos[i] == null) { Debug.LogError("The " + i + "th object on the list of objects to combine is 'None'. Use Command-Delete on Mac OS X; Delete or Shift-Delete on Windows to remove this one element."); return(null); } for (int j = i + 1; j < gos.Length; j++) { if (gos[i] == gos[j]) { Debug.LogError("GameObject " + gos[i] + "appears twice in list of game objects to add"); return(null); } } if (obj2MeshCombinerMap.ContainsKey(gos[i])) { Debug.LogError("GameObject " + gos[i] + " is already in the combined mesh"); return(null); } } } if (deleteGOs != null) { for (int i = 0; i < deleteGOs.Length; i++) { if (deleteGOs[i] == null) { Debug.LogError("The " + i + "th object on the list of objects to delete is 'None'."); return(null); } for (int j = i + 1; j < deleteGOs.Length; j++) { if (deleteGOs[i] == deleteGOs[j]) { Debug.LogError("GameObject " + deleteGOs[i] + "appears twice in list of game objects to delete"); return(null); } } if (!obj2MeshCombinerMap.ContainsKey(deleteGOs[i])) { Debug.LogWarning("GameObject " + deleteGOs[i] + " on the list of objects to delete is not in the combined mesh."); } } } if (gos == null) { gos = empty; } if (deleteGOs == null) { deleteGOs = empty; } if (VERBOSE) { Debug.Log("AddDeleteGameObjects adding:" + gos.Length + " deleting:" + deleteGOs.Length + " disableRendererInSource:" + disableRendererInSource + " fixOutOfBoundUVs:" + fixOutOfBoundUVs); } for (int i = 0; i < meshCombiners.Count; i++) { meshCombiners[i].gosToDelete.Clear(); meshCombiners[i].gosToAdd.Clear(); meshCombiners[i].extraSpace = MAX_VERTS_IN_MESH - meshCombiners[i].combinedMesh.GetMesh().vertexCount; } //first delete game objects from the existing combinedMeshes keep track of free space for (int i = 0; i < deleteGOs.Length; i++) { if (obj2MeshCombinerMap.ContainsKey(deleteGOs[i])) { CombinedMesh c = obj2MeshCombinerMap[deleteGOs[i]]; if (VERBOSE) { Debug.Log("Removing " + deleteGOs[i] + " from meshCombiner " + meshCombiners.IndexOf(c)); } Mesh m = MB_Utility.GetMesh(deleteGOs[i]); c.extraSpace += m.vertexCount; c.gosToDelete.Add(deleteGOs[i]); obj2MeshCombinerMap.Remove(deleteGOs[i]); if (c.isEmpty()) { meshCombiners.Remove(c); if (c.combinedMesh.targetRenderer != null) { MB_Utility.Destroy(c.combinedMesh.targetRenderer.gameObject); } c.combinedMesh.DestroyMesh(); if (VERBOSE) { Debug.Log("Combined mesh is empty removing its game object"); } } } else { Debug.LogWarning("Object " + deleteGOs[i] + " in the list of objects to delete is not in the combined mesh."); } } //try to fit gos into free space if possible, otherwise add it to new mesh for (int i = 0; i < gos.Length; i++) { GameObject go = gos[i]; int numVerts = MB_Utility.GetMesh(go).vertexCount; CombinedMesh cm = null; for (int j = 0; j < meshCombiners.Count; j++) { if (meshCombiners[j].extraSpace > numVerts) { cm = meshCombiners[j]; if (VERBOSE) { Debug.Log("Added " + gos[i] + " to combinedMesh " + j); } break; } } if (cm == null) { cm = new CombinedMesh(); _setMBValues(cm.combinedMesh); meshCombiners.Add(cm); if (VERBOSE) { Debug.Log("Created new combinedMesh"); } } cm.gosToAdd.Add(go); cm.extraSpace -= numVerts; obj2MeshCombinerMap.Add(go, cm); } //Add delete meshes from combined for (int i = 0; i < meshCombiners.Count; i++) { CombinedMesh cm = meshCombiners[i]; if (cm.combinedMesh.targetRenderer == null) { GameObject go = MB_Utility.buildSceneMeshObject(resultSceneObject, cm.combinedMesh, cm.combinedMesh.GetMesh(), true); cm.combinedMesh.targetRenderer = go.GetComponent <Renderer>(); } else { if (cm.combinedMesh.targetRenderer.transform.parent != resultSceneObject.transform) { Debug.LogError("targetRender objects must be children of resultSceneObject"); return(null); } } cm.combinedMesh.AddDeleteGameObjects(cm.gosToAdd.ToArray(), cm.gosToDelete.ToArray(), false, textureBakeResults.fixOutOfBoundsUVs); Renderer r = cm.combinedMesh.targetRenderer; if (r is MeshRenderer) { MeshFilter mf = r.gameObject.GetComponent <MeshFilter>(); mf.sharedMesh = cm.combinedMesh.GetMesh(); } else { SkinnedMeshRenderer smr = (SkinnedMeshRenderer)r; smr.sharedMesh = cm.combinedMesh.GetMesh(); } } if (VERBOSE) { string s = "Meshes in combined:"; for (int i = 0; i < meshCombiners.Count; i++) { s += " mesh" + i + "(" + meshCombiners[i].combinedMesh.GetObjectsInCombined().Count + ")\n"; } s += "children in result: " + resultSceneObject.transform.childCount; Debug.Log(s); } if (meshCombiners.Count > 0) { return(meshCombiners[0].combinedMesh.GetMesh()); } else { return(null); } }
public void Separate(CombinedMesh target) { }
private void GenerateMeshes() { /* * Get the set of all meshes to combine. All of this must be done on * the main thread. */ GameObject origObject = m_tile.GameObject.GetComponent <GameObject>(); Observable.Start( () => { Component[] components = origObject.GetComponentsInChildren <MeshFilter>(); foreach (MeshFilter meshFilter in components) { if (m_manager.FilterInfoNodes && meshFilter.name.StartsWith("info Node")) { continue; } SourceMesh sourceMesh = new SourceMesh(); /* * Ignore partial buildings for mesh reduction, we don't * handle these properly. */ var parent = meshFilter.transform.parent; if (parent != null && parent.name.Contains("building:part:yes")) { sourceMesh.type = MeshType.Other; } else { switch (meshFilter.name) { case "water": sourceMesh.type = MeshType.Water; break; case "wall": sourceMesh.type = MeshType.Wall; break; case "floor": sourceMesh.type = MeshType.Floor; break; default: sourceMesh.type = MeshType.Other; break; } } sourceMesh.mesh = meshFilter.mesh; sourceMesh.transform = meshFilter.transform.localToWorldMatrix; sourceMesh.vertexCount = meshFilter.mesh.vertexCount; m_sourceMeshes.Add(sourceMesh); } }, Scheduler.MainThread).Wait(); int vertexReduction = 0; /* * Try to combine all the meshes into smaller meshes. Basic bin * packing problem, use a greedy first-fit algorithm. */ foreach (SourceMesh sourceMesh in m_sourceMeshes) { /* Reduce the complexity of the mesh. */ if (m_manager.EnableMeshReduction) { int vertexCount; sourceMesh.mesh = new MeshReducer().Reduce(sourceMesh.mesh, sourceMesh.type, out vertexCount); vertexReduction += sourceMesh.vertexCount - vertexCount; sourceMesh.vertexCount = vertexCount; } /* Find a mesh that can fit this one. */ CombinedMesh combinedMesh = null; foreach (CombinedMesh existingMesh in m_meshes) { if (existingMesh.type != sourceMesh.type) { continue; } else if (existingMesh.totalVertexCount + sourceMesh.vertexCount > 65534) { continue; } combinedMesh = existingMesh; break; } if (combinedMesh == null) { combinedMesh = new CombinedMesh(); combinedMesh.type = sourceMesh.type; m_meshes.Add(combinedMesh); } CombineInstance combine = new CombineInstance(); combine.mesh = sourceMesh.mesh; combine.transform = sourceMesh.transform; combinedMesh.combines.Add(combine); combinedMesh.totalVertexCount += sourceMesh.vertexCount; } if (m_manager.EnableMeshReduction) { Debug.LogWarning("Reduced total vertex count by " + vertexReduction); } }
void OnEnable() { combined = target as CombinedMesh; }