public bool VerifyNumOfVertices(BaseMaterialsAgainstDependencies BaseMat, MeshFilter meshFilterToAdd) // Checks if the subMesh will have too many Vertices. { float currentNumOfVertices = 0; foreach (MeshFilter localFilter in BaseMat.MeshFiltersThatRequireBaseMaterial) { currentNumOfVertices += localFilter.sharedMesh.vertexCount; } int numOfVerticesToAdd = meshFilterToAdd.sharedMesh.vertexCount; // Ensures that there are not too many vertices. // If there are too many Split it if (currentNumOfVertices + numOfVerticesToAdd > maxNumberOfVerticesForSubMeshes) { return(false); } return(true); }
public void MyOwnAdvancedMeshCombinder() { BaseMaterialsRequired.Clear(); List <GameObject> objectsToMerge = new List <GameObject>(); Debug.Log("Number of objects wanted to Merge: " + GameObjectsToMerge.Count); // Iterate through every object that should be merged. // Getting a reference to all their mesh filters. ( unless they are supposed to be ignored ) foreach (Transform ObjToMerge in GameObjectsToMerge) { foreach (MeshFilter filter in ObjToMerge.GetComponentsInChildren <MeshFilter>(false)) // Loops through every MeshFilter that is active on its children. { // Ensures any objects that have the ignore merge tag or this object from being merged. if (filter.transform.tag != "IgnoreFromMeshMerge" && filter.transform != transform) { objectsToMerge.Add(filter.gameObject); } } } // Now that we know what to merge. if (isDebugging) { Debug.Log("Number of objects ready to merge: " + objectsToMerge.Count); } // Now split the objects mesh filters into lists based on their Material. int localMatSubIndex = 0; foreach (GameObject obj in objectsToMerge) { // Get all the materials on this object. Material[] localMaterials = obj.GetComponent <Renderer>().sharedMaterials; // Usually only one material. localMatSubIndex = 0; // Loop through all the local materials, to check if you need to add another material. foreach (Material localMat in localMaterials) { bool isTheMaterialAlreadySetUP = false; // If the locally required material is already defined. Then don't worry about it. Otherwise add it. foreach (BaseMaterialsAgainstDependencies baseMat in BaseMaterialsRequired) { //Debug.Log("baseMat " + localMat); if (baseMat.BaseMaterial == localMat) { // This material already has a dependency set up, soo add its mesh filter. // But first check their wont be too many vertices. MeshFilter localMaterialsFilter = obj.GetComponent <MeshFilter>(); if (VerifyNumOfVertices(baseMat, localMaterialsFilter)) // If there is enough vertices spare to add the mesh. // If it is not verified then The materialAlreadySetUp will stay false. { // Causing another sub mesh to be generated. baseMat.MeshFiltersThatRequireBaseMaterial.Add(localMaterialsFilter); baseMat.MeshFilterSubIndex.Add(localMatSubIndex); isTheMaterialAlreadySetUP = true; break; } } } if (!isTheMaterialAlreadySetUP) // The material has not been set up as a dependancy { // Create a new BaseMaterial // Set its base material BaseMaterialsAgainstDependencies newBaseMat = new BaseMaterialsAgainstDependencies(); newBaseMat.BaseMaterial = localMat; // Add the material that relies on it's mesh filter. MeshFilter localMaterialsFilter = obj.GetComponent <MeshFilter>(); newBaseMat.MeshFiltersThatRequireBaseMaterial.Add(localMaterialsFilter); newBaseMat.MeshFilterSubIndex.Add(localMatSubIndex); // Finally add it as a new base material. BaseMaterialsRequired.Add(newBaseMat); } localMatSubIndex++; } } // Now that we have a 2d array of the Mesh filters against their required Material. We should Squish them down into a submesh per Material. int index; foreach (BaseMaterialsAgainstDependencies baseMat in BaseMaterialsRequired) { if (isDebugging) { Debug.Log("Material " + baseMat.BaseMaterial + " Has " + baseMat.MeshFiltersThatRequireBaseMaterial.Count + "Dependencies."); } // Create a list of CombineInstances to store all of the info we need for each filter within this current material to combine into one. List <CombineInstance> combinersForEachFilterPerMaterial = new List <CombineInstance>(); index = 0; foreach (MeshFilter filter in baseMat.MeshFiltersThatRequireBaseMaterial) { CombineInstance Ci = new CombineInstance(); if (!filter.sharedMesh.isReadable) { Debug.Log(filter.transform.parent.transform.name + " - Is not readable!!!"); } Ci.mesh = filter.sharedMesh; Ci.subMeshIndex = baseMat.MeshFilterSubIndex[index]; Ci.transform = filter.transform.localToWorldMatrix; combinersForEachFilterPerMaterial.Add(Ci); index++; } // Creates a new mesh that is a combination of all the meshes that require this material. Mesh newMesh = new Mesh(); newMesh.CombineMeshes(combinersForEachFilterPerMaterial.ToArray(), true); baseMat.SubMesh = newMesh; if (isDebugging) { Debug.Log("This Submesh has: " + baseMat.SubMesh.vertexCount + " Vertices"); } } // Finally combine all the meshes. List <CombineInstance> finalCombiners = new List <CombineInstance>(); List <Material> currentMaterialsRequired = new List <Material>(); int currentVertices = 0; for (int baseMaterialIndex = 0; baseMaterialIndex < BaseMaterialsRequired.Count; baseMaterialIndex++) { CombineInstance ci = new CombineInstance(); BaseMaterialsAgainstDependencies baseMat = BaseMaterialsRequired[baseMaterialIndex]; ci.mesh = baseMat.SubMesh; ci.transform = transform.worldToLocalMatrix; ci.subMeshIndex = 0; if (isDebugging) { Debug.Log("Adding " + baseMat.BaseMaterial + " with " + ci.mesh.vertexCount); } int verticesInMesh = ci.mesh.vertexCount; if (currentVertices + verticesInMesh > maxNumberOfVerticesForMeshes) // Need to create a new mesh, Over the Mesh Vertex limit. { // Create Mesh for last. CreateNewMesh(finalCombiners.ToArray(), currentMaterialsRequired.ToArray()); // Clear everything. currentMaterialsRequired.Clear(); currentVertices = 0; finalCombiners.Clear(); // Set up for next mesh. finalCombiners.Add(ci); currentMaterialsRequired.Add(baseMat.BaseMaterial); currentVertices += verticesInMesh; // On the odd Chance that this is also the last run. if (baseMaterialIndex == BaseMaterialsRequired.Count - 1) { // Create new mesh. CreateNewMesh(finalCombiners.ToArray(), currentMaterialsRequired.ToArray()); // Clear for next use. currentMaterialsRequired.Clear(); currentVertices = 0; finalCombiners.Clear(); if (isDebugging) { Debug.Log("Mesh - Fnished Generating Mesh"); } /// Do whatever after gen is finished \\\ } } else if (baseMaterialIndex == BaseMaterialsRequired.Count - 1) // This is the final run. So finish up and create the new mesh. { // Make up for final run finalCombiners.Add(ci); currentMaterialsRequired.Add(baseMat.BaseMaterial); // Create new mesh. CreateNewMesh(finalCombiners.ToArray(), currentMaterialsRequired.ToArray()); // Clear for next use. currentMaterialsRequired.Clear(); currentVertices = 0; finalCombiners.Clear(); if (isDebugging) { Debug.Log("Mesh - Fnished Generating Mesh"); } } else // Keep Looping. { currentVertices += verticesInMesh; finalCombiners.Add(ci); currentMaterialsRequired.Add(baseMat.BaseMaterial); } } // Hide the original meshes. foreach (Transform objToMerge in GameObjectsToMerge) { SetActiveAllChildren(objToMerge, false); } }