Exemple #1
0
        private void Combine(List <MeshCombineMaterial> meshCombineMaterials, GameObject combinedMeshesParent)
        {
            List <GameObject> allCombinedMeshObjects = new List <GameObject>(100);

            if (combinedMeshesParent == null)
            {
                combinedMeshesParent = new GameObject(GetNameForCombinedMeshesParent());
                UndoEx.RegisterCreatedGameObject(combinedMeshesParent);
            }
            for (int combMaterialIndex = 0; combMaterialIndex < meshCombineMaterials.Count; ++combMaterialIndex)
            {
                MeshCombineMaterial meshCombMaterial = meshCombineMaterials[combMaterialIndex];

                List <GameObject> combineMeshdObjects = Combine(meshCombMaterial, combinedMeshesParent);
                if (_combineSettings.WeldVertexPositions)
                {
                    if (_combineSettings.WeldVertexPositionsOnlyForCommonMaterial)
                    {
                        WeldVertexPositionsForMeshObjects(combineMeshdObjects);
                    }
                    else
                    {
                        allCombinedMeshObjects.AddRange(combineMeshdObjects);
                    }
                }
            }

            if (_combineSettings.WeldVertexPositions && !_combineSettings.WeldVertexPositionsOnlyForCommonMaterial)
            {
                WeldVertexPositionsForMeshObjects(allCombinedMeshObjects);
            }
            if (_combineSettings.CollHandling == MeshCombineSettings.ColliderHandling.Preserve)
            {
                PreserveColliders(meshCombineMaterials, combinedMeshesParent);
            }
        }
Exemple #2
0
        private void PreserveColliders(List <MeshCombineMaterial> meshCombineMaterials, GameObject combinedMeshesParent)
        {
            if (meshCombineMaterials.Count == 0 || _combineSettings.CollHandling != MeshCombineSettings.ColliderHandling.Preserve)
            {
                return;
            }

            GameObject colliderParent          = combinedMeshesParent;
            Transform  colliderParentTransform = colliderParent.transform;

            if (_combineSettings.CollPreserveParent == MeshCombineSettings.ColliderPreserveParent.OneForAll)
            {
                colliderParent = new GameObject(_combineSettings.OneForAllColliderParentName);
                UndoEx.RegisterCreatedGameObject(colliderParent);
                colliderParentTransform        = colliderParent.transform;
                colliderParentTransform.parent = combinedMeshesParent.transform;
            }

            HashSet <GameObject> processedObjects = new HashSet <GameObject>();
            Vector3 positionSum = Vector3.zero;

            for (int cmbMaterialIndex = 0; cmbMaterialIndex < meshCombineMaterials.Count; ++cmbMaterialIndex)
            {
                MeshCombineMaterial meshCmbMaterial = meshCombineMaterials[cmbMaterialIndex];
                EditorUtility.DisplayProgressBar("Collider Handling", "Preserving colliders...", (float)cmbMaterialIndex / meshCombineMaterials.Count);

                List <MeshInstance> meshInstances = meshCmbMaterial.MeshInstances;
                foreach (var meshInstance in meshInstances)
                {
                    GameObject meshObject = meshInstance.MeshTransform.gameObject;

                    if (processedObjects.Contains(meshObject))
                    {
                        continue;
                    }
                    processedObjects.Add(meshObject);

                    positionSum += meshObject.transform.position;

                    BoxCollider[] boxColliders = meshObject.GetComponents <BoxCollider>();
                    foreach (var boxCollider in boxColliders)
                    {
                        string     colliderName   = _combineSettings.CollPreserveName == MeshCombineSettings.ColliderPreserveName.SameAsSource ? meshObject.name : GetDefaultBoxColliderObjectName();
                        GameObject colliderObject = boxCollider.CloneAsNewObject(colliderName).gameObject;
                        UndoEx.RegisterCreatedGameObject(colliderObject);
                        colliderObject.transform.parent = colliderParentTransform;
                    }

                    SphereCollider[] sphereColliders = meshObject.GetComponents <SphereCollider>();
                    foreach (var sphereCollider in sphereColliders)
                    {
                        string     colliderName   = _combineSettings.CollPreserveName == MeshCombineSettings.ColliderPreserveName.SameAsSource ? meshObject.name : GetDefaultSphereColliderObjectName();
                        GameObject colliderObject = sphereCollider.CloneAsNewObject(colliderName).gameObject;
                        UndoEx.RegisterCreatedGameObject(colliderObject);
                        colliderObject.transform.parent = colliderParentTransform;
                    }

                    CapsuleCollider[] capsuleColliders = meshObject.GetComponents <CapsuleCollider>();
                    foreach (var capsuleCollider in capsuleColliders)
                    {
                        string     colliderName   = _combineSettings.CollPreserveName == MeshCombineSettings.ColliderPreserveName.SameAsSource ? meshObject.name : GetDefaultCapsuleColliderObjectName();
                        GameObject colliderObject = capsuleCollider.CloneAsNewObject(colliderName).gameObject;
                        UndoEx.RegisterCreatedGameObject(colliderObject);
                        colliderObject.transform.parent = colliderParentTransform;
                    }

                    MeshCollider[] meshColliders = meshObject.GetComponents <MeshCollider>();
                    foreach (var meshCollider in meshColliders)
                    {
                        string     colliderName   = _combineSettings.CollPreserveName == MeshCombineSettings.ColliderPreserveName.SameAsSource ? meshObject.name : GetDefaultMeshColliderObjectName();
                        GameObject colliderObject = meshCollider.CloneAsNewObject(colliderName).gameObject;
                        UndoEx.RegisterCreatedGameObject(colliderObject);
                        colliderObject.transform.parent = colliderParentTransform;
                    }
                }
            }

            if (_combineSettings.CollPreserveParent == MeshCombineSettings.ColliderPreserveParent.OneForAll)
            {
                colliderParent.SetWorldPosDontAffectChildren(positionSum *= (1.0f / processedObjects.Count));
            }
            if (colliderParent.transform.childCount == 0)
            {
                GameObject.DestroyImmediate(colliderParent);
            }

            EditorUtility.ClearProgressBar();
        }
Exemple #3
0
        private List <GameObject> Combine(MeshCombineMaterial meshCombineMaterial, GameObject combinedMeshesParent)
        {
            List <MeshInstance> meshInstances = meshCombineMaterial.MeshInstances;

            if (meshInstances.Count == 0)
            {
                return(new List <GameObject>());
            }

            int       maxNumMeshVerts      = GetMaxNumberOfMeshVerts();
            const int numVertsPerMeshGuess = 500;
            int       totalNumVertsGuess   = meshCombineMaterial.MeshInstances.Count * numVertsPerMeshGuess;
            var       combinedMeshData     = new CombinedMeshData(totalNumVertsGuess);

            List <GameObject> combinedMeshObjects = new List <GameObject>(100);

            for (int meshInstanceIndex = 0; meshInstanceIndex < meshInstances.Count; ++meshInstanceIndex)
            {
                MeshInstance meshInstance = meshInstances[meshInstanceIndex];
                Mesh         mesh         = meshInstance.SourceMesh;
                if (mesh.vertexCount == 0)
                {
                    continue;
                }

                EditorUtility.DisplayProgressBar("Combining Meshes", "Processing material: " + meshCombineMaterial.Material.name, (float)meshInstanceIndex / meshInstances.Count);

                Matrix4x4 worldMatrix           = meshInstance.MeshTransform.localToWorldMatrix;
                Matrix4x4 worldInverseTranspose = worldMatrix.inverse.transpose;

                int     numNegativeScaleComps = 0;
                Vector3 worldScale            = meshInstance.MeshTransform.lossyScale;
                if (worldScale[0] < 0.0f)
                {
                    ++numNegativeScaleComps;
                }
                if (worldScale[1] < 0.0f)
                {
                    ++numNegativeScaleComps;
                }
                if (worldScale[2] < 0.0f)
                {
                    ++numNegativeScaleComps;
                }
                bool reverseVertexWindingOrder = (numNegativeScaleComps % 2 != 0);

                int[] submeshVertIndices = mesh.GetTriangles(meshInstance.SubmeshIndex);
                if (submeshVertIndices.Length == 0)
                {
                    continue;
                }

                Vector4[] vertTangents  = mesh.tangents;
                Vector3[] vertPositions = mesh.vertices;
                Vector3[] vertNormals   = mesh.normals;
                Vector2[] vertUV1       = mesh.uv;
                Vector2[] vertUV2       = mesh.uv2;
                Vector2[] vertUV3       = mesh.uv3;
                Vector2[] vertUV4       = mesh.uv4;
                Color[]   vertColors    = mesh.colors;

                foreach (var vertIndex in submeshVertIndices)
                {
                    if (vertTangents.Length != 0)
                    {
                        Vector3 transformedTangent = new Vector3(vertTangents[vertIndex].x, vertTangents[vertIndex].y, vertTangents[vertIndex].z);
                        transformedTangent = worldInverseTranspose.MultiplyVector(transformedTangent);
                        transformedTangent.Normalize();

                        combinedMeshData.VertTangents.Add(new Vector4(transformedTangent.x, transformedTangent.y, transformedTangent.z, vertTangents[vertIndex].w));
                    }

                    if (vertNormals.Length != 0)
                    {
                        Vector3 transformedNormal = worldInverseTranspose.MultiplyVector(vertNormals[vertIndex]);
                        transformedNormal.Normalize();

                        combinedMeshData.VertNormals.Add(transformedNormal);
                    }

                    if (vertPositions.Length != 0)
                    {
                        combinedMeshData.VertPositions.Add(worldMatrix.MultiplyPoint(vertPositions[vertIndex]));
                    }
                    if (vertColors.Length != 0)
                    {
                        combinedMeshData.VertColors.Add(vertColors[vertIndex]);
                    }
                    if (vertUV1.Length != 0)
                    {
                        combinedMeshData.VertUV1.Add(vertUV1[vertIndex]);
                    }
                    if (vertUV3.Length != 0)
                    {
                        combinedMeshData.VertUV2.Add(vertUV3[vertIndex]);
                    }
                    if (vertUV4.Length != 0)
                    {
                        combinedMeshData.VertUV3.Add(vertUV4[vertIndex]);
                    }
                    if (vertUV2.Length != 0 && !_combineSettings.GenerateLightmapUVs)
                    {
                        combinedMeshData.VertUV2.Add(vertUV2[vertIndex]);
                    }

                    combinedMeshData.AddCurrentVertIndex();

                    int numIndices = combinedMeshData.VertIndices.Count;
                    if (reverseVertexWindingOrder && numIndices % 3 == 0)
                    {
                        combinedMeshData.ReverseWindingOrderForLastTriangle();
                    }

                    int numMeshVerts = combinedMeshData.VertPositions.Count;
                    if (combinedMeshData.VertIndices.Count % 3 == 0 && (maxNumMeshVerts - numMeshVerts) < 3)
                    {
                        combinedMeshObjects.Add(CreateCombinedMeshObject(combinedMeshData, meshCombineMaterial.Material, combinedMeshesParent));
                        combinedMeshData.Reset();
                    }
                }
            }

            combinedMeshObjects.Add(CreateCombinedMeshObject(combinedMeshData, meshCombineMaterial.Material, combinedMeshesParent));
            EditorUtility.ClearProgressBar();

            return(combinedMeshObjects);
        }
Exemple #4
0
        private List <MeshCombineMaterial> GetMeshCombineMaterials(List <GameObject> meshObjects, GameObject sourceParent)
        {
            var meshCombineMaterialsMap = new Dictionary <Material, MeshCombineMaterial>();
            var meshCombineMaterials    = new List <MeshCombineMaterial>();

            Transform sourceParentTransform = sourceParent != null ? sourceParent.transform : null;

            foreach (var meshObject in meshObjects)
            {
                Transform meshTransform = meshObject.transform;
                if (_combineSettings.IgnoreObjectsInHierarchies)
                {
                    if (sourceParentTransform != null)
                    {
                        if (meshTransform.parent != sourceParentTransform || meshTransform.childCount != 0)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (meshTransform.parent != null || meshTransform.childCount != 0)
                        {
                            continue;
                        }
                    }
                }

                if (!_combineSettings.CombineStaticMeshes && meshTransform.gameObject.isStatic)
                {
                    continue;
                }
                if (!_combineSettings.CombineDynamicMeshes && !meshTransform.gameObject.isStatic)
                {
                    continue;
                }

                MeshFilter meshFilter = meshObject.GetComponent <MeshFilter>();
                if (meshFilter == null || meshFilter.sharedMesh == null)
                {
                    continue;
                }

                MeshRenderer meshRenderer = meshObject.GetComponent <MeshRenderer>();
                if (meshRenderer == null)
                {
                    continue;
                }

                Mesh sharedMesh = meshFilter.sharedMesh;
                for (int submeshIndex = 0; submeshIndex < sharedMesh.subMeshCount; ++submeshIndex)
                {
                    Material            subMeshMaterial     = meshRenderer.sharedMaterials[submeshIndex];
                    MeshCombineMaterial meshCombineMaterial = null;

                    if (!meshCombineMaterialsMap.ContainsKey(subMeshMaterial))
                    {
                        meshCombineMaterial          = new MeshCombineMaterial();
                        meshCombineMaterial.Material = subMeshMaterial;

                        meshCombineMaterialsMap.Add(subMeshMaterial, meshCombineMaterial);
                        meshCombineMaterials.Add(meshCombineMaterial);
                    }
                    else
                    {
                        meshCombineMaterial = meshCombineMaterialsMap[subMeshMaterial];
                    }

                    var meshInstance = new MeshInstance();
                    meshInstance.SourceMesh    = sharedMesh;
                    meshInstance.SubmeshIndex  = submeshIndex;
                    meshInstance.MeshTransform = meshTransform;
                    meshCombineMaterial.MeshInstances.Add(meshInstance);
                }
            }

            return(meshCombineMaterials);
        }