public List <GameObject> CombineToMeshes(List <MeshRenderer> meshRenderers, List <SkinnedMeshRenderer> skinnedMeshRenderers, Transform parent, int combinedIndex) { // The list of Meshes created List <GameObject> combinedMeshes = new List <GameObject>(); // The list of _combineInstances CombineInstanceID combineInstances = new CombineInstanceID(); int verticesCount = 0; int combinedGameObjectCount = 0; // Process meshes for combine process for (int i = 0; i < meshRenderers.Count; i++) { for (int j = 0; j < meshRenderers[i].GetComponent <MeshFilter>().sharedMesh.subMeshCount; j++) { // Get a copy of the submesh at index j Mesh newMesh = SubmeshSplitter.ExtractSubmesh(meshRenderers[i].GetComponent <MeshFilter>().sharedMesh, j); verticesCount += newMesh.vertexCount; if (verticesCount > _maxVerticesCount) { combinedMeshes.Add(CreateCombinedMeshGameObject(combineInstances, parent, combinedGameObjectCount, combinedIndex)); combineInstances.Clear(); combinedGameObjectCount++; verticesCount = newMesh.vertexCount; } // Create the list of CombineInstance for this mesh Matrix4x4 matrix = parent.transform.worldToLocalMatrix * meshRenderers[i].transform.localToWorldMatrix; combineInstances.AddRange(CreateCombinedInstances(newMesh, new Material[] { meshRenderers[i].sharedMaterials[j] }, meshRenderers[i].gameObject.GetInstanceID(), meshRenderers[i].gameObject.name, matrix, combinedIndex)); } } for (int i = 0; i < skinnedMeshRenderers.Count; i++) { for (int j = 0; j < meshRenderers[i].GetComponent <MeshFilter>().sharedMesh.subMeshCount; j++) { // Get a snapshot of the sub skinnedMesh renderer at index j Mesh newMesh = SubmeshSplitter.ExtractSubmesh(skinnedMeshRenderers[i].sharedMesh, j); _vertexOffset += newMesh.vertexCount; verticesCount += newMesh.vertexCount; if (verticesCount > _maxVerticesCount && combineInstances.Count() > 0) { combinedMeshes.Add(CreateCombinedMeshGameObject(combineInstances, parent, combinedGameObjectCount, combinedIndex)); combineInstances.Clear(); combinedGameObjectCount++; verticesCount = newMesh.vertexCount; } // Create the list of CombineInstance for this skinnedMesh Matrix4x4 matrix = parent.transform.worldToLocalMatrix * skinnedMeshRenderers[i].transform.localToWorldMatrix; combineInstances.AddRange(CreateCombinedInstances(newMesh, new Material[] { skinnedMeshRenderers[i].sharedMaterials[j] }, skinnedMeshRenderers[i].GetInstanceID(), skinnedMeshRenderers[i].gameObject.name, matrix, combinedIndex)); } } if (combineInstances.Count() > 0) { // Create the combined GameObject which contains the combined meshes combinedMeshes.Add(CreateCombinedMeshGameObject(combineInstances, parent, combinedGameObjectCount, combinedIndex)); } return(combinedMeshes); }
public List <GameObject> CombineToSkinnedMeshes(List <MeshRenderer> meshRenderers, List <SkinnedMeshRenderer> skinnedMeshRenderers, Transform parent, int combinedIndex) { // The list of Meshes created List <GameObject> combinedMeshes = new List <GameObject>(); // The list of _combineInstances CombineInstanceID combineInstances = new CombineInstanceID(); int verticesCount = 0; int combinedGameObjectCount = 0; /* * / Skinned mesh parameters */ // List of bone weight List <BoneWeight> boneWeights = new List <BoneWeight>(); // List of bones List <Transform> bones = new List <Transform>(); // List of bindposes List <Matrix4x4> bindposes = new List <Matrix4x4>(); // List of original bones mapped to their instanceId Dictionary <int, Transform> originalBones = new Dictionary <int, Transform>(); // Link original bone instanceId to the new created bones Dictionary <int, Transform> originToNewBoneMap = new Dictionary <int, Transform>(); // The vertices count int boneOffset = 0; // Get bones hierarchies from all skinned mesh for (int i = 0; i < skinnedMeshRenderers.Count; i++) { foreach (Transform t in skinnedMeshRenderers[i].bones) { if (!originalBones.ContainsKey(t.GetInstanceID())) { originalBones.Add(t.GetInstanceID(), t); } } } // Find the root bones Transform[] rootBones = FindRootBone(originalBones); for (int i = 0; i < rootBones.Length; i++) { // Instantiate the GameObject parent for this rootBone GameObject rootBoneParent = new GameObject("rootBone" + i); rootBoneParent.transform.position = rootBones[i].position; rootBoneParent.transform.parent = parent; rootBoneParent.transform.localPosition -= rootBones[i].localPosition; rootBoneParent.transform.localRotation = Quaternion.identity; // Instanciate a copy of the root bone GameObject newRootBone = InstantiateCopy(rootBones[i].gameObject); newRootBone.transform.position = rootBones[i].position; newRootBone.transform.rotation = rootBones[i].rotation; newRootBone.transform.parent = rootBoneParent.transform; newRootBone.AddComponent <MeshRenderer>(); // Get the correspondancy map between original bones and new bones GetOrignialToNewBonesCorrespondancy(rootBones[i], newRootBone.transform, originToNewBoneMap); } // Copy Animator Controllers to new Combined GameObject foreach (Animator anim in parent.parent.GetComponentsInChildren <Animator>()) { Transform[] children = anim.GetComponentsInChildren <Transform>(); // Find the transform into which a copy of the Animator component will be added Transform t = FindTransformForAnimator(children, rootBones, anim); if (t != null) { CopyAnimator(anim, originToNewBoneMap[t.GetInstanceID()].parent.gameObject); } } for (int i = 0; i < skinnedMeshRenderers.Count; i++) { // Get a snapshot of the skinnedMesh renderer Mesh mesh = copyMesh(skinnedMeshRenderers[i].sharedMesh, skinnedMeshRenderers[i].GetInstanceID().ToString()); _vertexOffset += mesh.vertexCount; verticesCount += skinnedMeshRenderers[i].sharedMesh.vertexCount; if (verticesCount > _maxVerticesCount && combineInstances.Count() > 0) { // Create the new GameObject GameObject combinedGameObject = CreateCombinedSkinnedMeshGameObject(combineInstances, parent, combinedGameObjectCount, combinedIndex); // Assign skinnedMesh parameters values SkinnedMeshRenderer sk = combinedGameObject.GetComponent <SkinnedMeshRenderer>(); AssignParametersToSkinnedMesh(sk, bones, boneWeights, bindposes); combinedMeshes.Add(combinedGameObject); boneOffset = 0; combineInstances.Clear(); combinedGameObjectCount++; verticesCount = skinnedMeshRenderers[i].sharedMesh.vertexCount; } // Copy bone weights BoneWeight[] meshBoneweight = skinnedMeshRenderers[i].sharedMesh.boneWeights; foreach (BoneWeight bw in meshBoneweight) { BoneWeight bWeight = bw; bWeight.boneIndex0 += boneOffset; bWeight.boneIndex1 += boneOffset; bWeight.boneIndex2 += boneOffset; bWeight.boneIndex3 += boneOffset; boneWeights.Add(bWeight); } boneOffset += skinnedMeshRenderers[i].bones.Length; // Copy bones and bindposes Transform[] meshBones = skinnedMeshRenderers[i].bones; foreach (Transform bone in meshBones) { bones.Add(originToNewBoneMap[bone.GetInstanceID()]); bindposes.Add(bone.worldToLocalMatrix * parent.transform.localToWorldMatrix); } // Create the list of CombineInstance for this skinnedMesh Matrix4x4 matrix = parent.transform.worldToLocalMatrix * skinnedMeshRenderers[i].transform.localToWorldMatrix; combineInstances.AddRange(CreateCombinedInstances(mesh, skinnedMeshRenderers[i].sharedMaterials, skinnedMeshRenderers[i].GetInstanceID(), skinnedMeshRenderers[i].gameObject.name, matrix, combinedIndex)); } if (combineInstances.Count() > 0) { // Create the combined GameObject which contains the combined meshes // Create the new GameObject GameObject combinedGameObject = CreateCombinedSkinnedMeshGameObject(combineInstances, parent, combinedGameObjectCount, combinedIndex); // Assign skinnedMesh parameters values SkinnedMeshRenderer sk = combinedGameObject.GetComponent <SkinnedMeshRenderer>(); AssignParametersToSkinnedMesh(sk, bones, boneWeights, bindposes); combinedMeshes.Add(combinedGameObject); } return(combinedMeshes); }