When parsing .3ds files I noticed that the points coming in are all already transformed into their final positions.
This was kind of annoying as it messes things up when it comes to performing additional transformations on a mesh or trying to reset it back to its origin. Fortunately the .3ds file also contains a section for each mesh holding its matrix.
http://faydoc.tripod.com/formats/3ds.htm <– a little way down the page you can see the details (its a 3×4 matrix essentially).
Okay, so now we have the matrix the fun can begin
The idea is to reverse engineer the matrix to obtain all the transformations individually, then use that to build an inverse matrix (yes you could just invert the original but that’s less fun) then multiply all the points by that inverse to reset them back to where they should be. Then all that’s left is to set the positions, scales and rotations of the mesh according to what was extracted.
My matrix notation is as follows:
d, h, l, p are not in the .3ds 3×4 matrix but that’s not a problem as we know them to be 0, 0, 0, and 1 respectively.
as m, n and o represent the translation these are the easiest to extract, its a simple copy over from the 3×4 from the .3ds file.
translation.x = m;
translation.y = n;
translation.z = o;
scale is a little trickier
scale.x = sqrt(a*a + b*b + c*c);
scale.y = sqrt(e*e + f*f + g*g);
scale.z = sqrt(i*i + j*j + k*k);
now all we need is rotation
rotation.x = atan2(j/scale.z,k/scale.z)
rotation.y = -arcsin(i/scale.z)
rotation.z = atan2(e/scale.y, a/scale.x)
of course there are reasons for why this works, but this isn’t the time or place to get into that.
so with all that info we can simply
- create a new matrix
- translate it by -translation
- rotate it by -rotation
- scale it by 1/scale
- use it to reset all the points
- then set the x, y, z, scaleX, scaleY, scaleZ, rotationX, rotationY and rotationZ on the mesh and POW…job’s a goodun’
So there you have it