Rotating Objects Using Quaternions
This has the dual benefit of providing smooth camera rotations and making players feel as though the game responded instantly to their input.
This allows you to piggyback1 on the calculations that the game already makes when the character moves within the game world.
Note that I do not recommend using quaternion interpolation for first-person action games since these games typically require instant response to player actions, and 球面線形補間はちょっと計算コストが高い。
However, we can use it for some special scenes.
For instance, assume that you're writing a tank simulation.
Every tank has a scope or similar targeting mechanism,
and you'd like to simulate it as realistically as possible.
The scoping mechanism and the tank's barrel are controlled by a series of motors that players control.
Depending on the zoom power of the scope and the distance to a target object,
even a small movement of a motor could cause a large change in the viewing angle,
resulting in a series of huge, seemingly disconnected jumps between individual frames.
To eliminate this unwanted effect, you could interpolate the orientation according to the zoom and distance of object.
This type of interpolation between two positions over several frames helps dampen the rapid movement and keeps players from becoming disoriented.
Another useful application of quaternions is for prerecorded (but not prerendered) animations.
Instead of recording camera movements by playing the game (as many games do today),
you could prerecord camera movements and rotations using a commercial package such as Softimage 3D or 3D Studio MAX.
Then, using an SDK, export all of the keyframed camera/object quaternion rotations.
This would save both space and rendering time.
Then you could just play the keyframed camera motions whenever the script calls for cinematic scenes.
Vec3 targetPosition = this.getTargetPosition(); Quaternion tmpQuaternion = new Quaternion (); //回転軸 回転角 180度回転する tmpQuaternion.setFromAxisAngle(new Vec3(0, 1, 0), 180 * (Math['PI'] / 180)); Matrix targetRotation = this.getTargetRotation(); targetRotation.multiplySelf(tmpQuaternion); targetRotation.quaternion.normalize(); Quaternion qm = new Quaternion(); Quaternion.slerp(this.camera.quaternion, targetRotation, qm, 0.07); this.camera.quaternion = qm; this.camera.quaternion.normalize();