示例#1
0
        public void Simplify(WMesh inputMesh, WMesh outputMesh, float quality)
        {
            var enableLogging = false;
            int totalTriangleCount;
            var sourceMesh          = ToMeshDecimatorMesh(inputMesh, out totalTriangleCount);
            int targetTriangleCount = Mathf.CeilToInt(totalTriangleCount * quality);

            var algorithm = MeshDecimation.CreateAlgorithm(Algorithm.Default);

            DecimationAlgorithm.StatusReportCallback statusCallback = (iteration, tris, currentTris, targetTris) =>
            {
                Debug.LogFormat("Iteration {0}: tris {1} current {2} target {3}", iteration, tris, currentTris, targetTris);
            };

            if (enableLogging)
            {
                algorithm.StatusReport += statusCallback;
            }

            var destMesh = MeshDecimation.DecimateMesh(algorithm, sourceMesh, targetTriangleCount);

            if (enableLogging)
            {
                algorithm.StatusReport -= statusCallback;
            }

            FromMeshDecimatorMesh(destMesh, false, ref outputMesh);
        }
示例#2
0
 /// <summary>
 /// Decimates an array of meshes, and combines them into one mesh.
 /// </summary>
 /// <param name="meshes">The meshes to decimate.</param>
 /// <param name="transforms">The mesh transforms.</param>
 /// <param name="materials">The mesh materials, including submesh materials.</param>
 /// <param name="quality">The desired quality.</param>
 /// <param name="recalculateNormals">If normals should be recalculated.</param>
 /// <param name="resultMaterials">The resulting materials array.</param>
 /// <param name="statusCallback">The optional status report callback.</param>
 /// <returns>The decimated mesh.</returns>
 public static UMesh DecimateMeshes(UMesh[] meshes, UMatrix[] transforms, UMaterial[][] materials, float quality, bool recalculateNormals, out UMaterial[] resultMaterials, DecimationAlgorithm.StatusReportCallback statusCallback = null)
 {
     UTransform[] mergedBones;
     return(DecimateMeshes(meshes, transforms, materials, null, quality, recalculateNormals, out resultMaterials, out mergedBones, statusCallback));
 }
示例#3
0
        /// <summary>
        /// Decimates an array of meshes, and combines them into one mesh.
        /// </summary>
        /// <param name="meshes">The meshes to decimate.</param>
        /// <param name="transforms">The mesh transforms.</param>
        /// <param name="materials">The mesh materials, with submesh materials.</param>
        /// <param name="meshBones">The bones for each mesh.</param>
        /// <param name="quality">The desired quality.</param>
        /// <param name="recalculateNormals">If normals should be recalculated.</param>
        /// <param name="resultMaterials">The resulting materials array.</param>
        /// <param name="mergedBones">The output merged bones.</param>
        /// <param name="statusCallback">The optional status report callback.</param>
        /// <returns>The decimated mesh.</returns>
        public static UMesh DecimateMeshes(UMesh[] meshes, UMatrix[] transforms, UMaterial[][] materials, UTransform[][] meshBones, float quality, bool recalculateNormals, out UMaterial[] resultMaterials, out UTransform[] mergedBones, DecimationAlgorithm.StatusReportCallback statusCallback = null)
        {
            if (meshes == null)
            {
                throw new ArgumentNullException("meshes");
            }
            else if (meshes.Length == 0)
            {
                throw new ArgumentException("You have to simplify at least one mesh.", "meshes");
            }
            else if (transforms == null)
            {
                throw new ArgumentNullException("transforms");
            }
            else if (transforms.Length != meshes.Length)
            {
                throw new ArgumentException("The array of transforms must match the length of the meshes array.", "transforms");
            }
            else if (materials == null)
            {
                throw new ArgumentNullException("materials");
            }
            else if (materials.Length != meshes.Length)
            {
                throw new ArgumentException("If materials are provided, the length of the array must match the length of the meshes array.", "materials");
            }
            else if (meshBones != null && meshBones.Length != meshes.Length)
            {
                throw new ArgumentException("If mesh bones are provided, the length of the array must match the length of the meshes array.", "meshBones");
            }

            int totalVertexCount  = 0;
            int totalSubMeshCount = 0;

            for (int meshIndex = 0; meshIndex < meshes.Length; meshIndex++)
            {
                UMesh mesh = meshes[meshIndex];
                totalVertexCount  += mesh.vertexCount;
                totalSubMeshCount += mesh.subMeshCount;

                var meshMaterials = materials[meshIndex];
                if (meshMaterials == null)
                {
                    throw new ArgumentException(string.Format("The mesh materials for index {0} is null!", meshIndex), "materials");
                }
                else if (meshMaterials.Length != mesh.subMeshCount)
                {
                    throw new ArgumentException(string.Format("The mesh materials at index {0} don't match the submesh count! ({1} != {2})", meshIndex, meshMaterials.Length, mesh.subMeshCount), "materials");
                }

                for (int i = 0; i < meshMaterials.Length; i++)
                {
                    if (meshMaterials[i] == null)
                    {
                        throw new ArgumentException(string.Format("The mesh material index {0} at material array index {1} is null!", i, meshIndex), "materials");
                    }
                }
            }

            int totalTriangleCount = 0;
            var vertices           = new List <Vector3d>(totalVertexCount);
            var indices            = new List <int[]>(totalSubMeshCount);

            List <Vector3>    normals     = null;
            List <Vector4>    tangents    = null;
            List <Vector2>    uv1         = null;
            List <Vector2>    uv2         = null;
            List <Vector2>    uv3         = null;
            List <Vector2>    uv4         = null;
            List <Vector4>    colors      = null;
            List <BoneWeight> boneWeights = null;

            List <UMatrix>              usedBindposes = null;
            List <UTransform>           usedBones     = null;
            List <UMaterial>            usedMaterials = new List <UMaterial>(totalSubMeshCount);
            Dictionary <UMaterial, int> materialMap   = new Dictionary <UMaterial, int>();
            int currentVertexCount = 0;

            for (int meshIndex = 0; meshIndex < meshes.Length; meshIndex++)
            {
                var mesh          = meshes[meshIndex];
                var transform     = transforms[meshIndex];
                var meshMaterials = materials[meshIndex];
                var bones         = (meshBones != null ? meshBones[meshIndex] : null);

                int meshVertexCount = mesh.vertexCount;
                var meshVertices    = mesh.vertices;
                var meshNormals     = mesh.normals;
                var meshTangents    = mesh.tangents;
                var meshUV1         = mesh.uv;
                var meshUV2         = mesh.uv2;
                var meshUV3         = mesh.uv3;
                var meshUV4         = mesh.uv4;
                var meshColors      = mesh.colors;
                var meshBoneWeights = mesh.boneWeights;
                var meshBindposes   = mesh.bindposes;

                if (bones != null && meshBoneWeights != null && meshBoneWeights.Length > 0 && meshBindposes != null && meshBindposes.Length > 0 && bones.Length == meshBindposes.Length)
                {
                    if (usedBindposes == null)
                    {
                        usedBindposes = new List <UMatrix>(meshBindposes);
                        usedBones     = new List <UTransform>(bones);
                    }
                    else
                    {
                        bool  bindPoseMismatch = false;
                        int[] boneIndices      = new int[bones.Length];
                        for (int i = 0; i < bones.Length; i++)
                        {
                            int usedBoneIndex = usedBones.IndexOf(bones[i]);
                            if (usedBoneIndex == -1)
                            {
                                usedBoneIndex = usedBones.Count;
                                usedBones.Add(bones[i]);
                                usedBindposes.Add(meshBindposes[i]);
                            }
                            else
                            {
                                if (meshBindposes[i] != usedBindposes[usedBoneIndex])
                                {
                                    bindPoseMismatch = true;
                                }
                            }
                            boneIndices[i] = usedBoneIndex;
                        }

                        // If any bindpose is mismatching, we correct it first
                        if (bindPoseMismatch)
                        {
                            var correctedBindposes = new UMatrix[meshBindposes.Length];
                            for (int i = 0; i < meshBindposes.Length; i++)
                            {
                                int usedBoneIndex = boneIndices[i];
                                correctedBindposes[i] = usedBindposes[usedBoneIndex];
                            }
                            TransformVertices(meshVertices, meshBoneWeights, meshBindposes, correctedBindposes);
                        }

                        // Then we remap the bones
                        RemapBones(meshBoneWeights, boneIndices);
                    }
                }

                // Transforms the vertices
                TransformVertices(meshVertices, ref transform);

                AddToList(vertices, meshVertices, currentVertexCount, totalVertexCount);
                AddToList(ref normals, meshNormals, currentVertexCount, meshVertexCount, totalVertexCount, new Vector3(1f, 0f, 0f));
                AddToList(ref tangents, meshTangents, currentVertexCount, meshVertexCount, totalVertexCount, new Vector4(0f, 0f, 1f, 1f)); // Is the default value correct?
                AddToList(ref uv1, meshUV1, currentVertexCount, meshVertexCount, totalVertexCount, new Vector2());
                AddToList(ref uv2, meshUV2, currentVertexCount, meshVertexCount, totalVertexCount, new Vector2());
                AddToList(ref uv3, meshUV3, currentVertexCount, meshVertexCount, totalVertexCount, new Vector2());
                AddToList(ref uv4, meshUV4, currentVertexCount, meshVertexCount, totalVertexCount, new Vector2());
                AddToList(ref colors, meshColors, currentVertexCount, meshVertexCount, totalVertexCount);
                AddToList(ref boneWeights, meshBoneWeights, currentVertexCount, meshVertexCount, totalVertexCount);

                int subMeshCount = mesh.subMeshCount;
                for (int subMeshIndex = 0; subMeshIndex < subMeshCount; subMeshIndex++)
                {
                    var   subMeshMaterial = meshMaterials[subMeshIndex];
                    int[] subMeshIndices  = mesh.GetTriangles(subMeshIndex);
                    if (currentVertexCount > 0)
                    {
                        for (int i = 0; i < subMeshIndices.Length; i++)
                        {
                            subMeshIndices[i] += currentVertexCount;
                        }
                    }
                    totalTriangleCount += subMeshIndices.Length / 3;

                    int mergeWithIndex;
                    if (materialMap.TryGetValue(subMeshMaterial, out mergeWithIndex))
                    {
                        int[] currentIndices = indices[mergeWithIndex];
                        indices[mergeWithIndex] = MergeArrays(currentIndices, subMeshIndices);
                    }
                    else
                    {
                        materialMap.Add(subMeshMaterial, indices.Count);
                        usedMaterials.Add(subMeshMaterial);
                        indices.Add(subMeshIndices);
                    }
                }
                currentVertexCount += meshVertices.Length;
            }

            quality = UMath.Clamp01(quality);
            int targetTriangleCount = UMath.CeilToInt(totalTriangleCount * quality);
            var sourceMesh          = new Mesh(vertices.ToArray(), indices.ToArray());

            if (normals != null)
            {
                sourceMesh.Normals = normals.ToArray();
            }
            if (tangents != null)
            {
                sourceMesh.Tangents = tangents.ToArray();
            }
            if (uv1 != null)
            {
                sourceMesh.UV1 = uv1.ToArray();
            }
            if (uv2 != null)
            {
                sourceMesh.UV2 = uv2.ToArray();
            }
            if (uv3 != null)
            {
                sourceMesh.UV3 = uv3.ToArray();
            }
            if (uv4 != null)
            {
                sourceMesh.UV4 = uv4.ToArray();
            }
            if (colors != null)
            {
                sourceMesh.Colors = colors.ToArray();
            }
            if (boneWeights != null)
            {
                sourceMesh.BoneWeights = boneWeights.ToArray();
            }

            var algorithm = MeshDecimation.CreateAlgorithm(Algorithm.Default);

            algorithm.MaxVertexCount = ushort.MaxValue;
            if (statusCallback != null)
            {
                algorithm.StatusReport += statusCallback;
            }

            var destMesh        = MeshDecimation.DecimateMesh(algorithm, sourceMesh, targetTriangleCount);
            var newMeshVertices = FromSimplifyVertices(destMesh.Vertices);

            if (statusCallback != null)
            {
                algorithm.StatusReport -= statusCallback;
            }

            var bindposes = (usedBindposes != null ? usedBindposes.ToArray() : null);

            resultMaterials = usedMaterials.ToArray();
            mergedBones     = (usedBones != null ? usedBones.ToArray() : null);
            return(CreateMesh(bindposes, newMeshVertices, destMesh, recalculateNormals));
        }
示例#4
0
        /// <summary>
        /// Decimates a mesh.
        /// </summary>
        /// <param name="mesh">The mesh to decimate.</param>
        /// <param name="transform">The mesh transform.</param>
        /// <param name="quality">The desired quality.</param>
        /// <param name="recalculateNormals">If normals should be recalculated.</param>
        /// <param name="statusCallback">The optional status report callback.</param>
        /// <returns>The decimated mesh.</returns>
        public static UMesh DecimateMesh(UMesh mesh, UMatrix transform, float quality, bool recalculateNormals, DecimationAlgorithm.StatusReportCallback statusCallback = null)
        {
            if (mesh == null)
            {
                throw new ArgumentNullException("mesh");
            }

            int subMeshCount    = mesh.subMeshCount;
            var meshVertices    = mesh.vertices;
            var meshNormals     = mesh.normals;
            var meshTangents    = mesh.tangents;
            var meshUV1         = mesh.uv;
            var meshUV2         = mesh.uv2;
            var meshUV3         = mesh.uv3;
            var meshUV4         = mesh.uv4;
            var meshColors      = mesh.colors;
            var meshBoneWeights = mesh.boneWeights;
            var meshBindposes   = mesh.bindposes;

            int totalTriangleCount = 0;
            var meshIndices        = new int[subMeshCount][];

            for (int i = 0; i < subMeshCount; i++)
            {
                meshIndices[i]      = mesh.GetTriangles(i);
                totalTriangleCount += meshIndices[i].Length / 3;
            }

            // Transforms the vertices
            TransformVertices(meshVertices, ref transform);

            var vertices = ToSimplifyVertices(meshVertices);

            quality = UMath.Clamp01(quality);
            int targetTriangleCount = UMath.CeilToInt(totalTriangleCount * quality);
            var sourceMesh          = new Mesh(vertices, meshIndices);

            if (meshNormals != null && meshNormals.Length > 0)
            {
                sourceMesh.Normals = ToSimplifyVec(meshNormals);
            }
            if (meshTangents != null && meshTangents.Length > 0)
            {
                sourceMesh.Tangents = ToSimplifyVec(meshTangents);
            }
            if (meshUV1 != null && meshUV1.Length > 0)
            {
                sourceMesh.UV1 = ToSimplifyVec(meshUV1);
            }
            if (meshUV2 != null && meshUV2.Length > 0)
            {
                sourceMesh.UV2 = ToSimplifyVec(meshUV2);
            }
            if (meshUV3 != null && meshUV3.Length > 0)
            {
                sourceMesh.UV3 = ToSimplifyVec(meshUV3);
            }
            if (meshUV4 != null && meshUV4.Length > 0)
            {
                sourceMesh.UV4 = ToSimplifyVec(meshUV4);
            }
            if (meshColors != null && meshColors.Length > 0)
            {
                sourceMesh.Colors = ToSimplifyVec(meshColors);
            }
            if (meshBoneWeights != null && meshBoneWeights.Length > 0)
            {
                sourceMesh.BoneWeights = ToSimplifyBoneWeights(meshBoneWeights);
            }

            var algorithm = MeshDecimation.CreateAlgorithm(Algorithm.Default);

            algorithm.MaxVertexCount = ushort.MaxValue;
            if (statusCallback != null)
            {
                algorithm.StatusReport += statusCallback;
            }

            //var destMesh = MeshDecimation.DecimateMeshLossless( sourceMesh);
            var destMesh        = MeshDecimation.DecimateMesh(algorithm, sourceMesh, targetTriangleCount);
            var newMeshVertices = FromSimplifyVertices(destMesh.Vertices);

            if (statusCallback != null)
            {
                algorithm.StatusReport -= statusCallback;
            }

            return(CreateMesh(meshBindposes, newMeshVertices, destMesh, recalculateNormals));
        }
示例#5
0
        public static UMesh DecimateMeshBasic(Mesh sourceMesh, UMatrix transform, float quality, bool recalculateNormals, DecimationAlgorithm.StatusReportCallback statusCallback = null)
        {
            var algorithm = MeshDecimation.CreateAlgorithm(Algorithm.FastQuadraticMesh);

            algorithm.MaxVertexCount = ushort.MaxValue;
            if (statusCallback != null)
            {
                algorithm.StatusReport += statusCallback;
            }

            int totalTriangleCount  = sourceMesh.Indices.Length / 3;
            int targetTriangleCount = UMath.CeilToInt(totalTriangleCount * quality);

            //var destMesh = MeshDecimation.DecimateMeshLossless( sourceMesh);
            var destMesh = MeshDecimation.DecimateMesh(algorithm, sourceMesh, targetTriangleCount);

            var newMeshVertices = FromSimplifyVertices(destMesh.Vertices);

            if (statusCallback != null)
            {
                algorithm.StatusReport -= statusCallback;
            }

            return(CreateMesh(null, newMeshVertices, destMesh, recalculateNormals));
        }
示例#6
0
        /// <summary>
        /// Generates the LODs and sets up a LOD Group for the specified game object.
        /// </summary>
        /// <param name="gameObj">The game object to set up.</param>
        /// <param name="levels">The LOD levels.</param>
        /// <param name="statusCallback">The optional status report callback.</param>
        public static void GenerateLODs(GameObject gameObj, LODSettings[] levels, LODStatusReportCallback statusCallback = null)
        {
            DestroyLODs(gameObj);

            var transform        = gameObj.transform;
            var meshRenderers    = gameObj.GetComponentsInChildren <MeshRenderer>();
            var skinnedRenderers = gameObj.GetComponentsInChildren <SkinnedMeshRenderer>();

            // Check if there's anything to do
            if (meshRenderers.Length == 0 && skinnedRenderers.Length == 0)
            {
                return;
            }

            var lodsParentObj = new GameObject(ParentGameObjectName);
            var lodsParent    = lodsParentObj.transform;

            lodsParent.parent        = transform;
            lodsParent.localPosition = Vector3.zero;
            lodsParent.localRotation = Quaternion.identity;
            lodsParent.localScale    = Vector3.one;

            var lodGroup = gameObj.GetComponent <LODGroup>();

            if (lodGroup == null)
            {
                lodGroup = gameObj.AddComponent <LODGroup>();
            }

            float screenRelativeTransitionHeight = 0.5f;

            LOD[] lodLevels           = new LOD[levels.Length + 1];
            var   firstLevelRenderers = CombineRenderers(meshRenderers, skinnedRenderers);

            lodLevels[0] = new LOD(screenRelativeTransitionHeight, firstLevelRenderers);
            screenRelativeTransitionHeight *= 0.5f;

            float minimumQuality = 1f;

            for (int levelIndex = 0; levelIndex < levels.Length; levelIndex++)
            {
                var   level   = levels[levelIndex];
                float quality = Mathf.Clamp(level.quality, 0.01f, minimumQuality);
                screenRelativeTransitionHeight *= quality * quality;
                GameObject lodObj    = new GameObject(string.Format("Level{0}", levelIndex));
                var        lodParent = lodObj.transform;
                lodParent.parent        = lodsParent;
                lodParent.localPosition = Vector3.zero;
                lodParent.localRotation = Quaternion.identity;
                lodParent.localScale    = Vector3.one;

                DecimationAlgorithm.StatusReportCallback levelStatusCallback = null;
                if (statusCallback != null)
                {
                    levelStatusCallback = (iteration, originalTris, currentTris, targetTris) =>
                    {
                        statusCallback.Invoke(levelIndex, iteration, originalTris, currentTris, targetTris);
                    };
                }

                GameObject staticLodObj     = lodObj;
                GameObject skinnedLodObj    = lodObj;
                Transform  staticLodParent  = lodParent;
                Transform  skinnedLodParent = lodParent;
                if (meshRenderers.Length > 0 && skinnedRenderers.Length > 0)
                {
                    staticLodObj                  = new GameObject("Static", typeof(MeshFilter), typeof(MeshRenderer));
                    staticLodParent               = staticLodObj.transform;
                    staticLodParent.parent        = lodParent;
                    staticLodParent.localPosition = Vector3.zero;
                    staticLodParent.localRotation = Quaternion.identity;
                    staticLodParent.localScale    = Vector3.one;

                    skinnedLodObj                  = new GameObject("Skinned", typeof(SkinnedMeshRenderer));
                    skinnedLodParent               = skinnedLodObj.transform;
                    skinnedLodParent.parent        = lodParent;
                    skinnedLodParent.localPosition = Vector3.zero;
                    skinnedLodParent.localRotation = Quaternion.identity;
                    skinnedLodParent.localScale    = Vector3.one;
                }

                Renderer[] staticLodRenderers  = null;
                Renderer[] skinnedLodRenderers = null;
                if (meshRenderers.Length > 0)
                {
                    if (level.combineMeshes)
                    {
                        Material[] materials;
                        Mesh       lodMesh = GenerateStaticLOD(transform, meshRenderers, quality, out materials, levelStatusCallback);
                        lodMesh.name = string.Format("{0}_static{1}", gameObj.name, levelIndex);
                        var meshFilter = staticLodObj.AddComponent <MeshFilter>();
                        meshFilter.sharedMesh = lodMesh;
                        var lodRenderer = staticLodObj.AddComponent <MeshRenderer>();
                        lodRenderer.sharedMaterials = materials;
                        SetupLODRenderer(lodRenderer, level);
                        staticLodRenderers = new Renderer[] { lodRenderer };
                    }
                    else
                    {
                        staticLodRenderers = new Renderer[meshRenderers.Length];

                        Material[] materials;
                        for (int rendererIndex = 0; rendererIndex < meshRenderers.Length; rendererIndex++)
                        {
                            var  renderer = meshRenderers[rendererIndex];
                            Mesh lodMesh  = GenerateStaticLOD(transform, renderer, quality, out materials, levelStatusCallback);
                            lodMesh.name = string.Format("{0}_static{1}_{2}", gameObj.name, levelIndex, rendererIndex);

                            var rendererLodObj = new GameObject(renderer.name, typeof(MeshFilter), typeof(MeshRenderer));
                            rendererLodObj.transform.parent        = staticLodParent;
                            rendererLodObj.transform.localPosition = Vector3.zero;
                            rendererLodObj.transform.localRotation = Quaternion.identity;
                            rendererLodObj.transform.localScale    = Vector3.one;
                            var meshFilter = rendererLodObj.GetComponent <MeshFilter>();
                            meshFilter.sharedMesh = lodMesh;
                            var lodRenderer = rendererLodObj.GetComponent <MeshRenderer>();
                            lodRenderer.sharedMaterials = materials;
                            SetupLODRenderer(lodRenderer, level);
                            staticLodRenderers[rendererIndex] = lodRenderer;
                        }
                    }
                }

                if (skinnedRenderers.Length > 0)
                {
                    if (level.combineMeshes)
                    {
                        Transform[] bones;
                        Material[]  materials;
                        Mesh        lodMesh = GenerateSkinnedLOD(transform, skinnedRenderers, quality, out materials, out bones, levelStatusCallback);
                        lodMesh.name = string.Format("{0}_skinned{1}", gameObj.name, levelIndex);
                        Transform rootBone = FindRootBone(transform, bones);

                        var lodRenderer = skinnedLodObj.AddComponent <SkinnedMeshRenderer>();
                        lodRenderer.sharedMesh      = lodMesh;
                        lodRenderer.sharedMaterials = materials;
                        lodRenderer.rootBone        = rootBone;
                        lodRenderer.bones           = bones;
                        SetupLODRenderer(lodRenderer, level);
                        skinnedLodRenderers = new Renderer[] { lodRenderer };
                    }
                    else
                    {
                        skinnedLodRenderers = new Renderer[skinnedRenderers.Length];

                        Transform[] bones;
                        Material[]  materials;
                        for (int rendererIndex = 0; rendererIndex < skinnedRenderers.Length; rendererIndex++)
                        {
                            var  renderer = skinnedRenderers[rendererIndex];
                            Mesh lodMesh  = GenerateSkinnedLOD(transform, renderer, quality, out materials, out bones, levelStatusCallback);
                            lodMesh.name = string.Format("{0}_skinned{1}_{2}", gameObj.name, levelIndex, rendererIndex);
                            Transform rootBone = FindRootBone(transform, bones);

                            var rendererLodObj = new GameObject(renderer.name, typeof(SkinnedMeshRenderer));
                            rendererLodObj.transform.parent        = skinnedLodParent;
                            rendererLodObj.transform.localPosition = Vector3.zero;
                            rendererLodObj.transform.localRotation = Quaternion.identity;
                            rendererLodObj.transform.localScale    = Vector3.one;
                            var lodRenderer = rendererLodObj.GetComponent <SkinnedMeshRenderer>();
                            lodRenderer.sharedMesh      = lodMesh;
                            lodRenderer.sharedMaterials = materials;
                            lodRenderer.rootBone        = rootBone;
                            lodRenderer.bones           = bones;
                            SetupLODRenderer(lodRenderer, level);
                            skinnedLodRenderers[rendererIndex] = lodRenderer;
                        }
                    }
                }

                Renderer[] lodRenderers;
                if (staticLodRenderers != null && skinnedLodRenderers != null)
                {
                    lodRenderers = staticLodRenderers.Concat <Renderer>(skinnedLodRenderers).ToArray();
                }
                else if (staticLodRenderers != null)
                {
                    lodRenderers = staticLodRenderers;
                }
                else if (skinnedLodRenderers != null)
                {
                    lodRenderers = skinnedLodRenderers;
                }
                else
                {
                    lodRenderers = new Renderer[0];
                }

                minimumQuality            = quality;
                lodLevels[levelIndex + 1] = new LOD(screenRelativeTransitionHeight, lodRenderers);
            }

            lodGroup.SetLODs(lodLevels);
        }
示例#7
0
 private static Mesh GenerateSkinnedLOD(Transform transform, SkinnedMeshRenderer[] renderers, float quality, out Material[] materials, out Transform[] mergedBones, DecimationAlgorithm.StatusReportCallback statusCallback)
 {
     if (renderers.Length == 1)
     {
         return(GenerateSkinnedLOD(transform, renderers[0], quality, out materials, out mergedBones, statusCallback));
     }
     else
     {
         var sourceMeshes  = new Mesh[renderers.Length];
         var transforms    = new Matrix4x4[renderers.Length];
         var meshMaterials = new Material[renderers.Length][];
         var meshBones     = new Transform[renderers.Length][];
         for (int i = 0; i < renderers.Length; i++)
         {
             var renderer          = renderers[i];
             var rendererTransform = renderer.transform;
             sourceMeshes[i]  = renderer.sharedMesh;
             transforms[i]    = transform.worldToLocalMatrix * rendererTransform.localToWorldMatrix;
             meshMaterials[i] = renderer.sharedMaterials;
             meshBones[i]     = renderer.bones;
         }
         return(MeshDecimatorUtility.DecimateMeshes(sourceMeshes, transforms, meshMaterials, meshBones, quality, false, out materials, out mergedBones, statusCallback));
     }
 }
示例#8
0
        private static Mesh GenerateSkinnedLOD(Transform transform, SkinnedMeshRenderer renderer, float quality, out Material[] materials, out Transform[] mergedBones, DecimationAlgorithm.StatusReportCallback statusCallback)
        {
            var rendererTransform = renderer.transform;
            var mesh          = renderer.sharedMesh;
            var meshTransform = transform.worldToLocalMatrix * rendererTransform.localToWorldMatrix;

            materials   = renderer.sharedMaterials;
            mergedBones = renderer.bones;
            return(MeshDecimatorUtility.DecimateMesh(mesh, meshTransform, quality, false, statusCallback));
        }
示例#9
0
        private static Mesh GenerateStaticLOD(Transform transform, MeshRenderer renderer, float quality, out Material[] materials, DecimationAlgorithm.StatusReportCallback statusCallback)
        {
            var rendererTransform = renderer.transform;
            var meshFilter        = renderer.GetComponent <MeshFilter>();
            var mesh          = meshFilter.sharedMesh;
            var meshTransform = transform.worldToLocalMatrix * rendererTransform.localToWorldMatrix;

            materials = renderer.sharedMaterials;
            return(MeshDecimatorUtility.DecimateMesh(mesh, meshTransform, quality, false, statusCallback));
        }
示例#10
0
 private static Mesh GenerateStaticLOD(Transform transform, MeshRenderer[] renderers, float quality, out Material[] materials, DecimationAlgorithm.StatusReportCallback statusCallback)
 {
     if (renderers.Length == 1)
     {
         var renderer          = renderers[0];
         var rendererTransform = renderer.transform;
         var meshFilter        = renderer.GetComponent <MeshFilter>();
         var mesh          = meshFilter.sharedMesh;
         var meshTransform = transform.worldToLocalMatrix * rendererTransform.localToWorldMatrix;
         materials = renderer.sharedMaterials;
         return(MeshDecimatorUtility.DecimateMesh(mesh, meshTransform, quality, false, statusCallback));
     }
     else
     {
         var sourceMeshes  = new Mesh[renderers.Length];
         var transforms    = new Matrix4x4[renderers.Length];
         var meshMaterials = new Material[renderers.Length][];
         for (int i = 0; i < renderers.Length; i++)
         {
             var renderer          = renderers[i];
             var rendererTransform = renderer.transform;
             var meshFilter        = renderer.GetComponent <MeshFilter>();
             sourceMeshes[i]  = meshFilter.sharedMesh;
             transforms[i]    = transform.worldToLocalMatrix * rendererTransform.localToWorldMatrix;
             meshMaterials[i] = renderer.sharedMaterials;
         }
         return(MeshDecimatorUtility.DecimateMeshes(sourceMeshes, transforms, meshMaterials, quality, false, out materials, statusCallback));
     }
 }