Rotating an object about local angles/axes
Revision as of 19:53, 2 June 2011 by imported>ThePhilanthropy
The functions SetAngle and Rotate rotate objects about the world axes. In order to apply local rotations, the angles need to be derived first. It is possible to rotate an object about local angles by first specifying the local angles, then extracting the world angles from the local rotation and applying those to the object.
Example
These declarations are needed:
;the object one wishes to rotate ref myObject ;the local angles float localAngX float localAngY float localAngZ ;the world angles float worldAngX float worldAngY float worldAngZ ;sine and cosine of local x, y, z angles float sx float cx float sy float cy float sz float cz ;temporary arguments for trigonometric functions float arg1 float arg2
The actual rotation code:
;sine and cosine of local x, y, z angles set sx to sin localAngX set cx to cos localAngX set sy to sin localAngY set cy to cos localAngY set sz to sin localAngZ set cz to cos localAngZ ;extraction of world x angle set arg1 to -( cx * -sy * cz + sx * sz) set arg2 to ( cy * cz) set worldAngX to atan2 arg1 arg2 ;extraction of world y angle set arg1 to -(-sx * -sy * cz + cx * sz) set worldAngY to asin arg1 ;extraction of world z angle set arg1 to -(-sx * cy) set arg2 to (-sx * -sy * -sz + cx * cz) set worldAngZ to atan2 arg1 arg2 ;apply extracted rotation myObject.setAngle x worldAngX myObject.setAngle y worldAngY myObject.setAngle z worldAngZ
Special Note
This code has been tested ingame and works reliably well. It is advised to experiment with the order of the local angles to get the desired result.
E.g. this...
set localAngX to 0 set localAngY to player.getangle y set localAngZ to player.getangle z
...will result in a different rotation than this:
set localAngX to player.getangle z set localAngY to player.getangle x set localAngZ to 0
Notes
- Some types of object, specifically Actors, do not allow for rotation about all three axes. Other objects, such as activators have all three degrees of freedom.
- The equations were determined via matrix multiplication of standard rotation matrices in X*Y*Z axis order. Unused matrix elements are omitted in the code.
- Gimbal Lock will occur when (-sx * -sy * cz + cx * sz) equals 1 or -1. No reliable solution is implemented yet.
- It is not certain to the author whether Oblivion actually uses an axis order of XYZ, but it is assumed. Falsification / Verification of this claim is hereby requested.
- For a more in-depth discussion of the math behind this, see wikipedia.org and euclideanspace.com.