Ever since I started that “useful links” thread on Alternativa3D forum, I wanned to post some tutorial here focused on simple stuff that people normally do, instead of yet another engine abuse example. But, for some strange reason, out of all choices available, I had to go with rotation tutorial :/ Any way, what’s done is done – it’s here.
In the world of 3D engines, terms “yaw”, “pitch” and “roll” are used to denote rotations around object coordinate axes. In Alternativa3D, rotation of object is represented by three properties, rotationX, rotationY and rotationZ, that are actually Euler angles; this means, in particular, that changing rotationZ property will not always be rolling your object due to effects of other two properties. The question is, therefore, how does one roll in Alternativa3D?
Solution 1 – Nesting objects.
One way to look at Euler angles is, as I just said, to note that two of them are not “pure” rotations around corresponding axes, but “contaminated” with other rotations (that are applied first). The simplest resolution of this problem is, therefore, to “unlink” rotation we want from other two by placing our object into intermediate container, applying those two rotations to container and, finally, applying “pure” axis rotation alone to object itself:
// we wrap the box into dummy object and add to scene var box1papa:Object3D = new Object3D; box1papa.addChild (box1); scene.root.addChild (box1papa); ... // rock and roll, yeah box1papa.rotationY = rotY; box1.rotationZ = roll;
Brevity of their rotation API makes me think that this approach is what they want you to do; and it is probably what you should, in fact, do, because it just can’t get any simpler than that. See it in action, and read the source code for further details.
Solution 2 – Truckloads of math.
Another way to look at Euler angles is to note that object “local” coordinate axes are changed in the process of its rotations, which is why rolling the object using its rotationX/Y/Z properties is pretty much like shooting moving target – it is tricky, but more fun, and helps to develop better understanding of how this pesky 3D math actually works.
If you are still reading this, chances are that you have heared about “transformation matrix”. Transformation matrix is a matrix that you need to multiply some vector coordinates by to obtain their values in different coordinate system. Remember that coordinates of some vector in Descartes coordinate system are the numbers that you need to multiply axes unit vectors so that sum of these products would yield our original vector (you might want to play with this great demo, it may provide you some visual cues to what I am talking about here).
All right, but what does all this crap have to do with Alternativa3D, you think? Let’s take a look at Matrix3D class documentation. It says, among other things, that to transform coordinate
(x, y, z) through the matrix, the following formulas are being used:
According to what I wrote above, we can read this bit another way: in a system with (a, e, i) X axis, (b, f, j) Y axis and (c, g, k) Z axis, coordinates of some vector (x’ – d, y’ – h, z’ – l) are x, y and z. The meaningful part here is, of course, expressions for “local” axes vectors in terms of transformation matrices.
So, we finally have some means to aim at our moving target better. Instead of rotating object container we can now compute corresponding transformation matrix using rotate() method, and use this matrix to construct proper rotation axis for object rolling, as described above. It is straightforward then to use this axis to compute rolling matrix using fromAxisAngle() method, and combine both rotations into one matrix using combine() method. The remaining bit is to convert resulting matrix back to Euler angles using getRotations(), and set object rotationX/Y/Z properties accordingly. You can see this in action here, and read the sources to clear up any confusion.