Quaternion nodes provide a convenient way to define a 3D
rotation that can be rotated continually on any axis without gimbal
lock or significant numeric instability.
Example 1
Below is a Quaternion that defines a rotation for the nodes in
its subgraph. Since these are used for rotation in SceneJS, we'll
think of a quaternion in the same terms as the parameters of a
SceneJS.Rotate node. This example's x, y, z and
angle parameters define the base rotation that
this quaternion starts off at, in this case none, then the optional
rotations array defines a sequence of rotations to
apply on top of that. Finally, we apply one more rotation to the
Quaternion node instance through its rotate
method.
var q = new SceneJS.Quaternion({
// Base rotation
x : 0.0, y : 0.0, z : 0.0, angle : 0.0, // No rotation
// Sequence of rotations to apply on top of the base rotation
rotations: [
{ x : 0, y : 0, z : 1, angle : 45 }, // Rotate 45 degrees about Z the axis
{ x : 1, y : 0, z : 0, angle : 20 }, // Rotate 20 degrees about X the axis
{ x : 0, y : 1, z : 0, angle : 90 }, // Rotate 90 degrees about Y the axis
]
},
// .. Child nodes ...
});
// rotate one more time, 15 degrees about the Z axis
q.rotate({ x : 0, y : 0, z : 1, angle : 15 });
Animation
Quaternions are designed to be animated. Typically, we would
dynamically provide rotation updates to them at render time, either
from an interpolator node or human interaction.
Example 2 Below is a Quaternion that is
dynamically configured with a callback that applies rotation
updates that are injected into the scene each time it is rendered.
Note that the callback does not define the base rotation - if it
did, then the Quaternion would reset before each new rotation is
applied, rather than accumulate the rotations as intended. Note
that the rotations could well ge generated by mouse drags to
simulate a trackball.
var exampleScene = new SceneJS.Scene(
// ... sibling nodes
new SceneJS.Quaternion(
function(data) {
return {
rotations: data.get("rotations");
};
},
// ... chld nodes ...
)
//... sibling nodes
);
exampleScene.render({ rotations: [ { x : 0, y : 0, z : 1, angle : 45 } ] });
exampleScene.render({ rotations: [ { x : 1, y : 0, z : 0, angle : 20 } ] });
exampleScene.render({ rotations: [ { x : 0, y : 1, z : 0, angle : 90 } ] });