Esempio n. 1
0
        private void BakeMesh()
        {
            if (bakeObject == null)
            {
                return;
            }

            if (animationClips.Any(clip => clip == null) && !bakeOnlyMesh)
            {
                return;
            }

            // There is a bug in AnimationMode.SampleAnimationClip which crashes
            // Unity if there is no valid controller attached
            Animator animator = bakeObject.GetComponent <Animator>();

            if (animator != null && animator.runtimeAnimatorController == null && !bakeOnlyMesh)
            {
                return;
            }

            //Collect information about gameObject
            List <MeshFilter>          tmpFilters       = bakeObject.GetComponentsInChildren <MeshFilter>().ToList();
            List <SkinnedMeshRenderer> tmpMeshRenderers = new List <SkinnedMeshRenderer>();

            for (int i = 0; i < tmpFilters.Count; i++)
            {
                MeshFilter          filter       = tmpFilters[i];
                SkinnedMeshRenderer meshRenderer = filter.GetComponent <SkinnedMeshRenderer>();

                if (meshRenderer != null)
                {
                    tmpFilters.RemoveAt(i);
                    tmpMeshRenderers.Add(meshRenderer);
                    i--;
                }
            }

            filters        = tmpFilters.ToArray();
            basicRenderers = filters.Select(filter => filter.GetComponent <MeshRenderer>()).ToArray();
            List <Material> _materials = new List <Material>();

            foreach (MeshRenderer renderer in basicRenderers)
            {
                foreach (Material mat in renderer.sharedMaterials)
                {
                    if (!_materials.Contains(mat))
                    {
                        _materials.Add(mat);
                    }
                }
            }

            materials = _materials.ToArray();
            renderers = tmpMeshRenderers.ToArray();

            //Temporarily set position to zero to make matrix math easier
            Vector3 position = bakeObject.transform.position;

            bakeObject.transform.position = Vector3.zero;

            Mesh firstFrame = new Mesh();

            EditorUtility.DisplayProgressBar("Mesh Animation Baker", "Baking", 0f);

            //Now bake
            AnimationMode.StartAnimationMode();
            AnimationMode.BeginSampling();
            int totalFrame = 0;

            int BakeClip(AnimationClip animationClip)
            {
                int clipFrameCount = bakeOnlyMesh ? 1 : GetFramesCount(animationClip);

                for (int frame = 0; frame < clipFrameCount; frame++)
                {
                    EditorUtility.DisplayProgressBar("Mesh Animation Baker", "Baking mesh animations",
                                                     1f * (totalFrame + frame) / frameCount);

                    if (!bakeOnlyMesh)
                    {
                        AnimationMode.SampleAnimationClip(bakeObject, animationClip, frame / frameRate);
                    }
                    Mesh bakedMesh = CombineMeshes(bakeObject);

                    if (!bufferReady)
                    {
                        buffer.Expand(VertType.VNT, bakedMesh.vertexCount, frameCount);
                        frameStride = buffer.vertexSize * buffer.vertexCount;
                        bufferReady = true;
                    }

                    for (int j = 0; j < bakedMesh.vertexCount; j++)
                    {
                        int vertStart       = j * buffer.vertexSize;
                        int globalVertStart = frameStride * (totalFrame + frame) + vertStart;
                        buffer.data[globalVertStart]     = bakedMesh.vertices[j].x;
                        buffer.data[globalVertStart + 1] = bakedMesh.vertices[j].y;
                        buffer.data[globalVertStart + 2] = bakedMesh.vertices[j].z;

                        buffer.data[globalVertStart + 3] = bakedMesh.normals[j].x;
                        buffer.data[globalVertStart + 4] = bakedMesh.normals[j].y;
                        buffer.data[globalVertStart + 5] = bakedMesh.normals[j].z;

                        buffer.data[globalVertStart + 6] = bakedMesh.tangents[j].x;
                        buffer.data[globalVertStart + 7] = bakedMesh.tangents[j].y;
                        buffer.data[globalVertStart + 8] = bakedMesh.tangents[j].z;
                    }

                    if (totalFrame + frame == 0)
                    {
                        firstFrame = bakedMesh;
                    }
                }

                return(bakeOnlyMesh ? 1 : GetFramesCount(animationClip));
            }

            if (!bakeOnlyMesh)
            {
                foreach (AnimationClip clip in animationClips)
                {
                    totalFrame += BakeClip(clip);
                }
            }
            else
            {
                BakeClip(null);
            }

            //Return to original position
            bakeObject.transform.position = position;

            string filePath = Path.Combine(Application.dataPath, vertaPath);

            FileInfo fileInfo = new FileInfo(filePath);

            if (!Directory.Exists(fileInfo.Directory.FullName))
            {
                Directory.CreateDirectory(fileInfo.Directory.FullName);
            }

            filePath += $"/{modelName}.verta";

            if (!bakeOnlyMesh)
            {
                buffer.SaveToFile(filePath);
            }

            if (targetPathObject == null)
            {
                filePath = Path.Combine("Assets", meshDataPath);
            }
            else
            {
                filePath = AssetDatabase.GetAssetPath(targetPathObject);
            }

            fileInfo = new FileInfo(filePath);
            if (!Directory.Exists(fileInfo.Directory.FullName))
            {
                Directory.CreateDirectory(fileInfo.Directory.FullName);
            }

            if (debugMeshOutput)
            {
                AssetDatabase.CreateAsset(firstFrame, filePath + $"/{modelName}-mesh.asset");
            }

            byte[] bytes = MeshDataAssetEditor.saveMeshToMeshAsset(firstFrame);

            MeshDataAsset asset = new MeshDataAsset();

            asset.bytes     = bytes;
            asset.materials = materials.ToArray();

            AssetDatabase.CreateAsset(asset, filePath + $"/{modelName}.asset");

            EditorUtility.ClearProgressBar();

            AnimationMode.EndSampling();
            AnimationMode.StopAnimationMode();
        }
Esempio n. 2
0
        private void BakeMesh()
        {
            if (bakeObject == null)
            {
                return;
            }

            if (animationClip == null)
            {
                return;
            }

            // There is a bug in AnimationMode.SampleAnimationClip which crashes
            // Unity if there is no valid controller attached
            Animator animator = bakeObject.GetComponent <Animator>();

            if (animator != null && animator.runtimeAnimatorController == null)
            {
                return;
            }

            //Collect information about gameObject
            List <MeshFilter>          tmpFilters       = bakeObject.GetComponentsInChildren <MeshFilter>().ToList();
            List <SkinnedMeshRenderer> tmpMeshRenderers = new List <SkinnedMeshRenderer>();

            for (int i = 0; i < tmpFilters.Count; i++)
            {
                MeshFilter          filter       = tmpFilters[i];
                SkinnedMeshRenderer meshRenderer = filter.GetComponent <SkinnedMeshRenderer>();

                if (meshRenderer != null)
                {
                    tmpFilters.RemoveAt(i);
                    tmpMeshRenderers.Add(meshRenderer);
                    i--;
                }
            }

            filters   = tmpFilters.ToArray();
            renderers = tmpMeshRenderers.ToArray();

            Mesh firstFrame = new Mesh();

            EditorUtility.DisplayProgressBar("Mesh Animation Baker", "Baking", 0f);

            //Now bake
            AnimationMode.StartAnimationMode();
            AnimationMode.BeginSampling();

            for (int frame = 0; frame < frameCount; frame++)
            {
                EditorUtility.DisplayProgressBar("Mesh Animation Baker", "Baking mesh animations", 1f * frame / frameCount);

                AnimationMode.SampleAnimationClip(bakeObject, animationClip, frame / frameRate);
                Mesh bakedMesh = CombineMeshes(bakeObject);

                if (!bufferReady)
                {
                    buffer.Expand(VertType.VNT, bakedMesh.vertexCount, frameCount);
                    frameStride = buffer.vertexSize * buffer.vertexCount;
                    bufferReady = true;
                }

                for (int i = 0; i < bakedMesh.vertexCount; i++)
                {
                    int vertStart       = i * buffer.vertexSize;
                    int globalVertStart = frameStride * frame + vertStart;
                    buffer.data[globalVertStart]     = bakedMesh.vertices[i].x;
                    buffer.data[globalVertStart + 1] = bakedMesh.vertices[i].y;
                    buffer.data[globalVertStart + 2] = bakedMesh.vertices[i].z;

                    buffer.data[globalVertStart + 3] = bakedMesh.normals[i].x;
                    buffer.data[globalVertStart + 4] = bakedMesh.normals[i].y;
                    buffer.data[globalVertStart + 5] = bakedMesh.normals[i].z;

                    buffer.data[globalVertStart + 6] = bakedMesh.tangents[i].x;
                    buffer.data[globalVertStart + 7] = bakedMesh.tangents[i].y;
                    buffer.data[globalVertStart + 8] = bakedMesh.tangents[i].z;
                }

                if (frame == 0)
                {
                    firstFrame = bakedMesh;
                }
            }

            string filePath = Path.Combine(Application.dataPath, vertaPath);

            FileInfo fileInfo = new FileInfo(filePath);

            if (!Directory.Exists(fileInfo.Directory.FullName))
            {
                Directory.CreateDirectory(fileInfo.Directory.FullName);
            }

            filePath += $"/{modelName}.verta";

            buffer.SaveToFile(filePath);

            filePath = Path.Combine("Assets", meshDataPath);

            fileInfo = new FileInfo(filePath);
            if (!Directory.Exists(fileInfo.Directory.FullName))
            {
                Directory.CreateDirectory(fileInfo.Directory.FullName);
            }

            filePath += $"/{modelName}.asset";

            byte[] bytes = MeshDataAssetEditor.saveMeshToMeshAsset(firstFrame);

            MeshDataAsset asset = new MeshDataAsset();

            asset.bytes = bytes;

            AssetDatabase.CreateAsset(asset, filePath);

            EditorUtility.ClearProgressBar();

            AnimationMode.EndSampling();
            AnimationMode.StopAnimationMode();
        }