REFERENCE: QUATERNIONS/ Ogre Transformations
Overview Most of this lecture will be about (Ogre) SceneNodes What are they? How do we set up a scene graph? How do we transform a scene node?
SceneGraph Made up of SceneNodes Goals: Frustrum calling Limit the number of material swaps Hierarchical Transformations
SceneNodes can hold MoveableObject’s Lots of things are derived from MoveableObject: Entities Lights ParticleEmitters Billboards …… SceneManager::create___ Optional unique name (string) SceneManager::get____ SceneManager::destroy___ Don’t forget SceneNode::detach before doing this. MoveableObject::getParentSceneNode()
SceneNode class Attributes: Pointer to parent and children scene nodes. Pointers to attached objects A 3x4 transformation matrix: from the parent. Rendering the graph Depth-first traversal Matrix concatenation Override with SceneNode::setInheritXXX(bool) (orientation or scale) Set up the scene graph with: SceneNode::createChildSceneNode SceneNode::addChild(Node *) SceneNode::removeChild(Node *) To set / modify a scene node's matrix, you normally call methods. Translation and scaling are pretty easy Rotations (and orientations) require Quaternions… …so let's get this out of the way.
Quaternions Discovered by Hamilton in 1843 Originally to visualize complex numbers (a 2d plane), but we can extend it to 3d. (in Dublin, Ireland)
Complex numbers If you want to solve x^2 + 1 = 0, you’ll attempt to take the square root of a negative number. Not possible! …but mathematicians invented a fictional quantity I i^2 = -1 A complex number is of the form z = a + bi Real numbers have b = 0 Imaginary numbers have a = 0
Complex numbers operations Adding complex numbers (a + bi) + (c + di) = (a + c) + (b + d)i Subtracting complex numbers (a + bi) – (c + di) = (a – c) + (b – d)i Complex * scalar k (a + bi) = ka + kbi Complex * Complex (a + bi) (c + di) = (ac – bd) + (ad + bc)i Complex 2 (a + bi) * (a + bi) = (a 2 – b 2 ) + 2abi Complex Conjugate (a + bi)* = (a – bi) (a + bi) (a + bi)* = a 2 + b 2
Powers of i … i -5 = -i i -4 = 1 i -3 = i i -2 = -1 i -1 = -i i 0 = 1 i 1 = i i 2 = -1 i 3 = -i i 4 = 1 i 5 = i i 6 = -1 … See a pattern? i n = rot(90 0 * n) on the real / imaginary plane …extending that… Taking a point on the complex plane and multiplying by i rotates it 90 degrees. Real Imaginary
An example Real Imaginary
Arbitrary Rotations
Now to 3D!
Quaternion Operations
A Quaternion "rotation"
Quaternion rotation
SLERP-ing
Comparison to other rotation methods Rotation Matrices Not very easy to interpolate Euler angles A series of rotations about the cardinal (world) axes Can lead to gimbal lock Hard to visualize, but happens in games – the camera is rotating smoothly, but suddenly flips. We can convert each of these back & forth between quaternions.
Quaternions in Ogre Several constructors. The main one: Quaternion(Radian r, Vector3 axis); e.g Quaternion(Radian(3.14), Vector3(0,1,0)); Quaternion(Degree(45), Vector3(0,1,0)); Slerping: Quaternion::slerp(Real t, const Quaternion & Q, const Quaternion & P, bool shortest_path=false); Useful methods: Use * operator for multiplication. Quaternion UnitInverse() const Vector3 xAxis() Real normalise();
Transformation methods (of Node class) Adjusting translate(const Vector3 & offset, Node::TransformSpace space) space can be one of: Node::TS_LOCAL, Node::TS_PARENT, Node::TS_WORLD. rotate(const Quaternion & q, Node::TransformSpace space) Also, pitch, yaw, and roll methods. scale(const Vector3 & factor); Setting (all are relative to parent setPosition(const Vector3 & pos); setScale(const Vector3 & factor) setOrientation(const Quaternion & q); Conversion Quaternion convertLocalToWorldOrientation(const Quaternion & local); Quaternion convertWorldToLocalOrientation(const Quaternion & world); // Similar functions for Position (but not scale).
Some interesting scene node setups Gimbals: e.g. for our camera control [Describe] [more to be added later]