First, let's take a look at the two commonly used camera models in the game: the Euler's camera model and the uvn camera model.
1. Euler's camera model
Euler angles is a method used to describe the direction of a rigid body in a three-dimensional Euclidean space) describes the direction of an object.
Notes:
1) undo
Assume that the angle transformation sequence applied to an object is Pyr. To restore the original direction of the object, the transformation sequence to be applied is: (-R) (-y) (-P ).
2) Universal Joint lock (gimbal lock)
When the two rotating axes are re-formed, a universal joint is displayed. At this time, you need to delete one. Once you select the plus or minus 90 degrees as the pitch angle, it is limited to only rotating around the vertical axis. This phenomenon, the second rotation with an angle of ± 90 degrees makes the first and third rotation axes the same and become a universal lock. In order to eliminate this alias that limits the ouarla corner, it is stipulated that only the yaw can rotate the vertical axis in the case of a universal lock. That is, if Pitch = + 90 degrees, roll = 0
2. uvn camera model
Unlike the Euler's camera model, the uvn camera model uses vectors to describe the orientation of the camera. N indicates the orientation of the camera. V indicates the upper vector, and u indicates the right vector.
Notes:
Because U, V, and n are linearly independent, after changing N, You need to recalculate the values of V and N:
V = n × U
U = n × V
3. Summary
From the data description of the two camera models, we can see that both of them are centered around the camera itself and all rotate around the camera. Therefore, it is suitable for camera control in the first-person scenario. For the code implementation of these two models, refer to the ogre Camera class.
Many software programs need to rotate around the observed objects, such as the view rotation of the objects in CAD software. What kind of camera model is suitable for this application?
Arcball is a model of a camera that rotates around the center. The principle is quite simple: Imagine a model as a ball, and the camera moves on the ball.
If you use the mouse to control the rotation of the camera, you need to map the screen coordinates (x, y) to the spherical surface (x1, Y1, Z1 ). To simplify the operation, we can assume that the radius of the ball is 1 and the center of the ball is the center of the screen (currently, only the x. y axis is considered ),
Assuming that the radius of the largest circle on the screen is R, it is not difficult to convert (x, y) to (x1, Y1 ):
X1 = x/R * 2-1;
Y1 = 1-y/R * 2
Because the ball radius is 1, there are:
Z1 * z1 = 1-X1 * x1-Y1 * Y1.
If the starting coordinate of the mouse movement is (x1, Y1) and the ending coordinate is (X2, Y2), two vectors V1, V2, from V1, v2 can calculate the rotation axis and rotation angle.
Therefore, the key idea of the entire algorithm is to convert the points on the screen to the imaginary sphere.
Arcball Based on the direct3d mathematical library is as follows:
Class program cball { Public: Repeated cball (){} ~ Repeated cball (){}Void setrect (rect) { M_rect = rect; } Void start (int x, int y) { Maptosphere (X, Y, & m_vstart ); } Void rotateto (int x, int y) { Maptosphere (X, Y, & m_vend ); // Compute the angle Float fdot = d3dxvec3dot (& m_vstart, & m_vend ); Float angle = ACO (fdot ); // Axis D3dxvector3 vaxis; D3dxvec3cross (& vaxis, & m_vstart, & m_vend ); M_qcurrent = d3dxquaternion (vaxis. X, vaxis. Y, vaxis. Z, angle ); } Void getrotationmatrix (d3dxmatrix * pmatrot) { D3dxmatrixrotationquaternion (pmatrot, & m_qcurrent ); }; PRIVATE: Void maptosphere (int x, int y, d3dxvector3 * PVEC) { Int nradius = (m_rect.width ()> m_rect.height ())? M_rect.width (): m_rect.height (); // Translate to [0... 2] Float PTX = float (X)/nradius * 2; Float Pty = float (y)/nradius * 2; // Move [0, 0] to the center PTx = PTX-1; Pty = 1-Pty; // Get Z Float Z2 = 1-PTX * PTX-Pty * Pty; Float PTZ = Z2> 0? SQRT (Z2): 0; * PVEC = d3dxvector3 (PTX, Pty, PTZ ); D3dxvec3normalize (PVEC, PVEC ); }
PRIVATE: Crect m_rect; D3dxvector3 m_vstart; D3dxvector3 m_vend; D3dxquaternion m_qcurrent; // current one }; |