Recalculated Bounds.

This commit is contained in:
max 2021-02-18 03:19:07 +01:00
parent 2ea76b947e
commit bc8aa08193
3 changed files with 54 additions and 29 deletions

View File

@ -111,15 +111,20 @@ namespace TAO.VertexAnimation.Editor
{ {
AssetDatabaseUtils.RemoveChildAssets(this, new Object[2] { book, material }); AssetDatabaseUtils.RemoveChildAssets(this, new Object[2] { book, material });
foreach (var m in meshes) Bounds bounds = new Bounds
{ {
m.bounds = bakedData.mesh.bounds; max = bakedData.maxBounds,
m.Finalize(); min = bakedData.minBounds
AssetDatabase.AddObjectToAsset(m, this); };
for (int i = 0; i < meshes.Length; i++)
{
meshes[i].bounds = bounds;
meshes[i].Finalize();
AssetDatabase.AddObjectToAsset(meshes[i], this);
} }
AssetDatabase.AddObjectToAsset(positionMap, this); AssetDatabase.AddObjectToAsset(positionMap, this);
AssetDatabase.SaveAssets(); AssetDatabase.SaveAssets();
if (generatePrefab) if (generatePrefab)

View File

@ -11,6 +11,8 @@ namespace TAO.VertexAnimation
public Mesh mesh; public Mesh mesh;
public List<Texture2D> positionMaps; public List<Texture2D> positionMaps;
public int maxFrames; public int maxFrames;
public Vector3 minBounds;
public Vector3 maxBounds;
// Returns main position map. // Returns main position map.
public Texture2D GetPositionMap public Texture2D GetPositionMap
@ -53,12 +55,22 @@ namespace TAO.VertexAnimation
} }
} }
[System.Serializable]
public struct BakedAnimation
{
public Texture2D positionMap;
public Vector3 minBounds;
public Vector3 maxBounds;
}
public static BakedData Bake(this GameObject model, AnimationClip[] animationClips, bool applyRootMotion, int fps, int textureWidth) public static BakedData Bake(this GameObject model, AnimationClip[] animationClips, bool applyRootMotion, int fps, int textureWidth)
{ {
BakedData bakedData = new BakedData() BakedData bakedData = new BakedData()
{ {
mesh = null, mesh = null,
positionMaps = new List<Texture2D>() positionMaps = new List<Texture2D>(),
minBounds = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue),
maxBounds = new Vector3(float.MinValue, float.MinValue, float.MinValue)
}; };
// Calculate what our max frames/time is going to be. // Calculate what our max frames/time is going to be.
@ -79,9 +91,6 @@ namespace TAO.VertexAnimation
// Get the info for the biggest animation. // Get the info for the biggest animation.
AnimationInfo animationInfo = new AnimationInfo(mesh, applyRootMotion, maxFrames, textureWidth, fps); AnimationInfo animationInfo = new AnimationInfo(mesh, applyRootMotion, maxFrames, textureWidth, fps);
// Bounds
Bounds bounds = new Bounds();
foreach (AnimationClip ac in animationClips) foreach (AnimationClip ac in animationClips)
{ {
// Set the frames for this animation. // Set the frames for this animation.
@ -91,12 +100,15 @@ namespace TAO.VertexAnimation
bakedData.mesh = bd.mesh; bakedData.mesh = bd.mesh;
bakedData.positionMaps.AddRange(bd.positionMaps); bakedData.positionMaps.AddRange(bd.positionMaps);
bakedData.maxFrames = maxFrames; bakedData.maxFrames = maxFrames;
bakedData.minBounds = Vector3.Min(bakedData.minBounds, bd.minBounds);
bounds.min = Vector3.Min(bounds.min, mesh.bounds.min); bakedData.maxBounds = Vector3.Max(bakedData.maxBounds, bd.maxBounds);
bounds.max = Vector3.Max(bounds.max, mesh.bounds.max);
} }
bakedData.mesh.bounds = bounds; bakedData.mesh.bounds = new Bounds()
{
max = bakedData.maxBounds,
min = bakedData.minBounds
};
return bakedData; return bakedData;
} }
@ -121,29 +133,34 @@ namespace TAO.VertexAnimation
mesh.uv3 = mesh.BakePositionUVs(animationInfo); mesh.uv3 = mesh.BakePositionUVs(animationInfo);
BakedAnimation bakedAnimation = BakeAnimation(model, animationClip, animationInfo);
BakedData bakedData = new BakedData() BakedData bakedData = new BakedData()
{ {
mesh = mesh, mesh = mesh,
positionMaps = new List<Texture2D>() { BakePositionMap(model, animationClip, animationInfo, out Bounds bounds) }, positionMaps = new List<Texture2D>() { bakedAnimation.positionMap },
maxFrames = animationInfo.maxFrames, maxFrames = animationInfo.maxFrames,
minBounds = bakedAnimation.minBounds,
maxBounds = bakedAnimation.maxBounds
};
mesh.bounds = new Bounds()
{
max = bakedAnimation.maxBounds,
min = bakedAnimation.minBounds
}; };
mesh.bounds = bounds;
return bakedData; return bakedData;
} }
// TODO: Add nicer way to return data/bounds. public static BakedAnimation BakeAnimation(this GameObject model, AnimationClip animationClip, AnimationInfo animationInfo)
public static Texture2D BakePositionMap(this GameObject model, AnimationClip animationClip, AnimationInfo animationInfo, out Bounds bounds)
{ {
// Create positionMap Texture without MipMaps which is Linear and HDR to store values in a bigger range. // Create positionMap Texture without MipMaps which is Linear and HDR to store values in a bigger range.
Texture2D positionMap = new Texture2D(animationInfo.textureWidth, animationInfo.textureHeight, TextureFormat.RGBAHalf, false, true); Texture2D positionMap = new Texture2D(animationInfo.textureWidth, animationInfo.textureHeight, TextureFormat.RGBAHalf, false, true);
// Keep track of min/max bounds. // Keep track of min/max bounds.
bounds = new Bounds Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
{ Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue),
max = new Vector3(float.MinValue, float.MinValue, float.MinValue)
};
// Create instance to sample from. // Create instance to sample from.
GameObject inst = GameObject.Instantiate(model); GameObject inst = GameObject.Instantiate(model);
@ -156,10 +173,6 @@ namespace TAO.VertexAnimation
Mesh sampledMesh = new Mesh(); Mesh sampledMesh = new Mesh();
skinnedMeshRenderer.BakeMesh(sampledMesh); skinnedMeshRenderer.BakeMesh(sampledMesh);
sampledMesh.RecalculateBounds();
bounds.min = Vector3.Min(bounds.min, sampledMesh.bounds.min + bounds.center);
bounds.max = Vector3.Min(bounds.max, sampledMesh.bounds.max + bounds.center);
List<Vector3> verts = new List<Vector3>(); List<Vector3> verts = new List<Vector3>();
sampledMesh.GetVertices(verts); sampledMesh.GetVertices(verts);
@ -169,6 +182,9 @@ namespace TAO.VertexAnimation
int x = 0; int x = 0;
for (int v = 0; v < verts.Count; v++) for (int v = 0; v < verts.Count; v++)
{ {
min = Vector3.Min(min, verts[v]);
max = Vector3.Max(max, verts[v]);
positionMap.SetPixel(x, y, positionMap.SetPixel(x, y,
new Color(verts[v].x, verts[v].y, verts[v].z, new Color(verts[v].x, verts[v].y, verts[v].z,
VectorUtils.EncodeFloat3ToFloat1(normals[v])) VectorUtils.EncodeFloat3ToFloat1(normals[v]))
@ -190,7 +206,12 @@ namespace TAO.VertexAnimation
positionMap.filterMode = FilterMode.Point; positionMap.filterMode = FilterMode.Point;
positionMap.Apply(false, true); positionMap.Apply(false, true);
return positionMap; return new BakedAnimation()
{
positionMap = positionMap,
minBounds = min,
maxBounds = max
};
} }
public static Vector2[] BakePositionUVs(this Mesh mesh, AnimationInfo animationInfo) public static Vector2[] BakePositionUVs(this Mesh mesh, AnimationInfo animationInfo)

View File

@ -16,6 +16,7 @@ namespace TAO.VertexAnimation
normals = mesh.normals, normals = mesh.normals,
tangents = mesh.tangents, tangents = mesh.tangents,
colors = mesh.colors, colors = mesh.colors,
bounds = mesh.bounds,
uv = mesh.uv, uv = mesh.uv,
uv2 = mesh.uv2, uv2 = mesh.uv2,
uv3 = mesh.uv3, uv3 = mesh.uv3,
@ -26,8 +27,6 @@ namespace TAO.VertexAnimation
uv8 = mesh.uv8 uv8 = mesh.uv8
}; };
copy.RecalculateBounds();
return copy; return copy;
} }