- Home /
"Baking" Object scale into mesh
I have a hierarchy of Unity objects, and each object in the hierarchy has a (non-uniform) scale and rotation.
For example, my hierarchy may be A->B->C.
I'm trying to write a script to "bake" the scale of these objects into the meshes in the hierarchy, so from the point of view of the rendering engine, all objects will have a scale of (1,1,1). This will allow batching to work more reliably, and more importantly, should avoid huge spikes I'm getting due to lots of calls to BakeScaledMeshCollisionData. The object hierarchies in question will be used as runtime-prefabs. I've verified this solution works for my needs using simple un-parented objects.
What I need help with, is figuring out how to do this in a hierarchy of objects. In other words - given the hierarchy above, how do I determine for each object what scale to apply?
Basically - how do I recreate the effects of the transforms of all the objects in the hierarchy into a single matrix, that I can then use to transform the verts of the mesh, while setting the localscale of each object in the hierachy to 1.0, to get the same effect?
Well the big thing is getting an accurate scale the whole way down - it sounds like you should probably be using something more accurate than a float - perhaps double or Decimal. You can get an approximation of the scale form lossyScale - but to do it yourself, you just have to Scale through the individual vectors (component wise multiplication) - the all you are doing is the exact same thing to the local position of the mesh renderer and every vertex in the mesh.
Hmm, I don't think component-wise multiplication will be sufficient. The rotation of each object in the hierarchy will affect the way scale is applied to the children, no? For instance, a scale applied to a rotated child becomes a skew...
Are you using none uniform scaling?? Ugh if you are :s
Yep, that's the whole point of doing the baking, as uniformly scaled meshes don't incur these performance issues. What I'm looking for is a general-purpose solution.
Answer by Bunny83 · Apr 22, 2013 at 02:56 PM
I would suggest to simply move the topmost parent to 0,0,0 (world origin) and simply use transform.TransformPoint() on each vertex. The resulting vertices are transformed as you wish. Since you removed the root translation you can simply use the vertices as local coordinates of an object sitting at the world origin with eulerangles 0,0,0 and a scale of 1,1,1. Once the new object is created, just re-add the translation to move it to it's original position.
edit
The solution is actually way simpler than imagined ;)
Vector3 Bake(Transform aOld, Transform aNew, Vector3 aPos)
{
var P = aOld.TransformPoint(aPos);
return aNew.InverseTransformPoint(P);
}
So just create a new object at the same world position / rotation as the nested original object and execute Bake for each vertex ;)
Transform oldObj;
Transform newObj = (new GameObject(oldObj.name + "_Baked")).transform;
newObj.position = oldObj.position;
newObj.rotation = oldObj.rotation;
newObj.localScale = Vector3.one;
for(int i = 0; i < verts.Length,i++)
verts[i] = Bake(oldObj, newObj, verts[i]);
Hmm, so you're suggesting doing this for each object in the hierarchy, using its own transform to translate the verts on the mesh?
Yes, sure ;) The problem is that all 3 things affecting the result: scale, rotation, position except the "outer" position. So in the end you would need the whole matrix stack of your hierarchy, so it's easier to directly use it ;)
Yeah that's what I'm trying to wrap my head around. To complicate things - I won't be zero-ing out the local rotation/translation of each object in the hierarchy, just the scale. So it seems I want to take the total of the parent's effects on each child, $$anonymous$$us the translation, plus the child's local scale, and apply that to the verts.
Oh this is cool. So if I'm understanding the new solution: you're creating a new object at the same point in the hierarchy(but with a scale of 1), then taking each vert in the old object, transfor$$anonymous$$g it to world space, then transfor$$anonymous$$g it into the new local space of the copy object?
Your answer
Follow this Question
Related Questions
How to manually calculate localToWorldMatrix/worldToLocalMatrix? 1 Answer
Are .gameObject and .transform both using GetComponent() in the background? 1 Answer
Why on earth can I not just get and set the Matrix4x4 of a Transform?!? 2 Answers
Transform and "native" components optimization 1 Answer
transform.localScale very slow on device (contrary to Android Remote) 2 Answers