Imagine the process of moving an object in a 3D space. This object will inevitably involve rotation. For example, a monster's movement direction changes. To change its direction, you only need to rotate it.
There are roughly three rotation methods: Euler rotation, Matrix Rotation, and Quaternary rotation.
Here, I will briefly record my current understanding of the rotation of the Quaternary element. I don't care about the mathematics and the principle of the element. I just need to learn how to use it.
No matter which type of rotation, the relative position between the object and the local coordinate system of the object will not change. Therefore, when performing two partial rotations (relative to the local coordinate system), note that the results may not be as expected.
For Euler's rotation, ogre provides interfaces such as yaw, pitch, and roll for scenenode. These interfaces are rotated by reference to the local coordinate system by default, and can be specified by the second parameter, for example, yaw (degree (90), scenenode: ts_world );
The quaternion class in ogre is used for the processing of four elements. This class (which can be said to be the Quaternary element itself) has four members: X, Y, Z, and W. What are the four numbers?
On the Ogre forum, I found some information that can be easily understood:
Quaternions can seem pretty daunting because of the use of 'imaginary 'numbers. it's much easier to understand if you just ignore this concept completely. the basic formula for creating a quaternion from Angle/axis is:
Q = cos (angle/2) + I (x * sin (A/2) + J (y * sin (A/2 )) + K (z * sin (A/2 ))
Or
Code:
Q. W = cos (angle/2)
Q. x = axis. x * sin (angle/2)
Q. Y = axis. y * sin (angle/2)
Q. z = axis. z * sin (angle/2)
Ignore the concepts such as the plural, and use the angle/axis method to create the four element formula:
Q = cos (angle/2) + I (x * sin (A/2) + J (y * sin (A/2 )) + K (z * sin (A/2 ))
CorrespondingCodeIs:
Q. W = cos (angle/2)
Q. x = axis. x * sin (angle/2)
Q. Y = axis. y * sin (angle/2)
Q. z = axis. z * sin (angle/2)
Let's take a look at a quaternion function in ogre to construct a quaternary element.Source code:
Void quaternion: fromangleaxis (const radian & rfangle,
Const vector3 & rkaxis)
{
// Assert: Axis [] is unit length
//
// The quaternion representing the rotation is
// Q = cos (A/2) + sin (A/2) * (x * I + y * j + z * K)
Radian fhalfangle (0.5 * rfangle );
Real FSIN = Math: sin (fhalfangle );
W = Math: cos (fhalfangle );
X = FSIN * rkaxis. X;
Y = FSIN * rkaxis. Y;
Z = FSIN * rkaxis. Z;
}
Although W represents the number of rotations, x, y, and z represent the corresponding axes, this is not all correct. As we can see, for data such as the actual rotation volume, we need to perform some formula transformation before we can get the W, X, Y, Z.
However, even so, we can simply construct a quaternary element for rotation:
Quaternion Q (degree (-90), vector3: unit_x );
The first parameter of the constructor specifies the rotation angle, and the second parameter specifies the rotation axis (which may not be). The Code above indicates that the X axis (positive x direction) and the rotation is-90 degrees. Use this element to rotate a scene node:
Scenenode-> rotate (Q );
This node can rotate the X axis to 90 degrees.
Let's take a look at a piece of code in ogre Tutorial:
Vector3 src = mnode-> getorientation () * vector3: unit_x;
Ogre: quaternion quat = SRC. getrotationto (mdirection );
Mnode-> rotate (quat );
The getorientation of scenenode obtains the orientation of the node, which is expressed by a quaternary element. What is orientation? I don't know here, but for a quaternary element, it represents a rotation offset, which is offset from the initial orientation.
On the Ogre Forum, there is a saying:
The reason there's no other way to convert a quaternion to a vector is because a quaternion is relative. It has no direction.
With a ction (like a vector) You cocould say "face north east ".
But with a quaternion, you say "face 45 degrees clockwise from whatever direction you are already facing" (very simplified example ). without knowing which way the object is already facing, a quaternion is always Ally meaningless with respect to orientation. so we just default it to some initial direction, like unit Z, and make all orientations relative to that.
Then, what does getorientation () * vector3: uint_x get? I can tell you that the overall function of the first code is to obtain the current orientation of the object. For how to multiply a quaternary element by a vector ,:
As we can see, the Quaternary element represents a rotation offset, Which is multiplied by a vector to obtain another vector. The result vector represents the direction determined by the rotation offset.
So why should we multiply unit_x In the first code? This indicates that the initial orientation of the object is positive X.
In the second sentence, a four-element is constructed by a vector, which indicates a four-element required to rotate from the current orientation to the target orientation. In the third sentence, use the Z to rotate the node. But sometimes it seems that the rotation is incorrect (in my experiment, the initial orientation of the model I used is negative y, during initialization, I rotated the X axis for a negative 90 degrees, but it was not correct when it was rotated). This can be corrected through rotate (Q, scenenode: ts_world. (So it is estimated that it is a mistake caused by previous rotation) (sometimes I wonder why the rotation and other transformations of all objects do not directly refer to the world coordinate system? Because what we finally see is in the world coordinate system .)
Note: When the rotation angle is 180 degrees, an error occurs here. To prevent this error, you can do this:
Vector3 src = mnode-> getorientation () * vector3: unit_x;
If (1.0f + SRC. dotproduct (mdirection) <0.0001f)
{
Mnode-> yaw (degree (180 ));
}
Else
{
Ogre: quaternion quat = SRC. getrotationto (mdirection );
Mnode-> rotate (quat );
} // Else