I learned how to properly rotate the quaternion myself. The key was to find the vectors for the axis I want to rotate. They are used to create quaternions along the axis and corner, when the angle is the amount that rotates around the actual axis.
The following code shows what I ended up with. It also allows you to roll the camera, which may be useful for a while.
void Rotate(btVector3 Amount, float Sensitivity) { // fetch current rotation btTransform transform = camera->getWorldTransform(); btQuaternion rotation = transform.getRotation(); // apply mouse sensitivity Amount *= Sensitivity; // create orientation vectors btVector3 up(0, 1, 0); btVector3 lookat = quatRotate(rotation, btVector3(0, 0, 1)); btVector3 forward = btVector3(lookat.getX(), 0, lookat.getZ()).normalize(); btVector3 side = btCross(up, forward); // rotate camera with quaternions created from axis and angle rotation = btQuaternion(up, Amount.getY()) * rotation; rotation = btQuaternion(side, Amount.getX()) * rotation; rotation = btQuaternion(forward, Amount.getZ()) * rotation; // set new rotation transform.setRotation(rotation); camera->setWorldTransform(transform); }
Since I rarely found information on quaternion rotation, I will spend some time further explaining the code above.
The extraction and installation of rotation are specific to the physical engine and are not related to this issue, so I will not dwell on this in detail. The next part, multiplying the number by the sensitivity of the mouse, should be really understandable. Let the direction vectors continue.
- The
up vector depends on your own implementation. Most conveniently, the positive Y axis is directed upward, so we get 0, 1, 0 . - The
lookat vector represents the direction the camera is looking. We simply rotate the unit vector pointing forward using the quaternion of rotation of the camera. Again, the directional vector depends on your agreement. If the Y axis is raised, the positive Z axis can point forward, which is 0, 0, 1 . - Do not mix this with the following vector. It is called
forward , which refers to the rotation of the camera. Therefore, we just need to project the lookat vector lookat the ground. In this case, we just take the lookat vector and ignore the component pointing up. For accuracy, we normalize this vector. - The
side vector points to the left of the camera orientation. Therefore, it is perpendicular to both the up and forward , and we can use the cross-product to calculate it.
Given these vectors, we can correctly rotate the camera quaternion around them. Let's start with Z, Y or Z, depending on the sequence of Euler angles , which, again, differs from application to application. Since I want rotation to be applied in YXZ order, I do the following.
- First, rotate the camera around the
up axis by an amount to rotate Y. This is yaw. - Then rotate around the
side axis, which points to the left, by X. This is a step. - Finally, rotate the Z value around the
forward vector to apply the roll.
To apply these rotations, we need to multiply the quaternions by the axis and angle with the current rotation of the camera. Finally, we apply the reduced quaternion to the body in physical modeling.
danijar
source share