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();
}