I've spent a decent chunk of time first playing Payday 2
and then working on a modding tool for it, to convert between GLTF and the game's
native mesh format. However, partly because it was easier and partly because just
didn't remember that line of the spec, I neglected to scale models by a factor of
100, PD2 being done to a 1cm scale, and GLTF mandating a 1m scale.
Unfortunately, Blender also has a slight preference for a 1m scale, so everything
has to have a scale factor applied manually at some point, and/or you have to put
up with objects being uncomfortably big on the Blender side of things, especially
if you happen to be making building-scale objects. Solution: modify the converter
to apply this scale factor manually.
Further problem: The math isn't nice and tidy.
For rotations and translations it is: adjacent ones of the same type can collapse
together, and for every rotation followed by translation, it's possible to create
a translation followed by rotation that has the same effect. Thus we can push the
rotation impelled by Diesel (the PD2 engine) and Blender having different notions
of which axis is up (Y and Z respectively) to wherever we like fairly easily.
For translate-rotate-scale, however, it's not so pleasant: translate-rotate forms
a group, but adding scale to the mix means it's no longer a group (you can make a
shear out of a combination of rotates and non-uniform scales).
Actually, what I want to do here is push a uniform scale down the tree of objects
until it ends up butting against the actual vertex buffers. With that in mind the
obvious approach is creating rules to accomplish this motion in steps. Probably
uniform scale and non-uniform scale behave a bit differently, so let's say there
are four kinds of operation we want to consider: translate, rotate, scale, and
All the operations commute with themselves:
As does uniform scaling with stretching and rotation
Stretches and rotations can't be moved past each other without introducing shears
or additional nodes, which I don't want to do:
But stretches and scales go nicely with translates (here is elementwise multiply):
Since translations and rotations are themselves groups, it should be obvious that
translate-rotate matrices form a group, since the above rules allow arranging for
all the rotating to happen first, then all the translating, and being groups lets
you collapse that down to one of each.
The lack of closure means translate-rotate-scale isn't even a monoid, let alone a
group, but fortunately this isn't a problem here. Most of these rules aren't even
needed here since we're only moving a uniform scale down the object tree.
We can thus do:
which is what we actually need to push scale factors all the way down to the
actual vertex buffers. In addition, is not affected, so the only thing to
worry about in regard to instancing is not to apply it twice (the current
implementation makes instances unique, admittedly).