[OGRE] 1. From 0, from 2D to 3D

First acquaintance with OGRE : I heard about OGRE a long time ago, when I was learning Qt. At that time, I only knew that Qt can be used with a "game engine" called OGRE. Later, I found out that OGRE cannot be regarded as a game engine. It is a part of a game engine (a game engine includes a physics engine, a network engine, a sound and rendering engine, etc.), OGRE is just the rendering engine, responsible for graphics rendering, while other parts of the other game engines are based on exists in the form of a plugin.

Quaternion: The game engines that I have come into contact with before are all 2D, so I am still a little curious and confused about the 3D world. There are many more things in the world with one more dimension, such as direction, position, and a quaternion. ...(I haven't fully figured it out yet). The most basic thing in OGRE to set the position is the vector Vector3, the variables in it are x, y, z, which can be understood by ordinary people. There is also a quaternion , generally use quaternions to perform rotation operations. The following is a reprinted article about OGRE quaternions. Original text:http://blog.sina.com.cn/s/blog_7fff68b90100w1dj.html

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Before learning about quaternions, let's review the basics of Euler angles, matrix and vector math. In this article and in Ogre, we are using a right-handed coordinate system. This means two things: First, we think that the +X axis points directly to the right of the screen, the +Y axis points directly above the screen, and the +Z axis points vertically to you through the screen. Second, to check how the +45 degree angle is rotated, extend your right thumb along the rotation axis, and the natural bending direction of the remaining fingers is the actual angle rotation direction.
Vector:
In mathematics, a vector describes a directed line segment in 3D space from one point to another. It has direction and distance. This means that it is not a line segment without direction in the general sense (Translator's Note: the line segment has no direction) nor an infinite ray (Translator's Note: the ray has no size). Vectors have the common characteristics of rays and line segments. (Translator's Note: A vector is a quantity with magnitude and direction.)
It takes six parameters to describe two points in 3D space. In Ogre, vectors are stored assuming that the first point is (0,0,0) and the second point is an associated offset. This is a common use of vectors. You can use (0,0,0) as the world root, or set the root in an object's body coordinate system. Just know which coordinate system you are working in when doing transformations. Since a vector has only three parameters, it is often used to define three points.
A vector of length 1 is called a normalized vector. Unit vectors or normalized vectors can be used when we only want to describe one direction. Using normalized limits is a must if you expect the result to be one that needs to pass many precise operations. Don't forget to normalize your vectors!
Common uses of vectors in Ogre are to describe a single point, use a unit vector to define a direction, or to calculate the distance between two points.
Here are some useful vector operations
: Subtract vector A from vector B
to get a vector containing the distance and direction from A to B (in this example, A can be (0,0,0), and the vector representing B can be written as A's own object coordinate system definition, not the world coordinate system).
That is: Bv – Av = Av -> Bv .
· Vector A plus vector B
vector A plus vector B to get vector C. If vector A and vector B are connected end to end, it is as if two arrows point out a path in turn, and vector C points from the tail of vector A to the head of B, forming a triangle.
·Multiply or divide by a scalar
Multiplying or dividing by a scalar does not change the direction of the vector, only the magnitude of the vector. For example, Vector(1,1,1) describes a line (or a 3D point at the default origin) with a positive angle of 45 degrees to the XZ axis plane (upward, and the three axes +X, +Y, +Z) enclosed space), 45 degrees from the XY plane (facing you), and 45 degrees from the YZ plane (to the right). Its length is sqrt(X^2+Y^2+Z^2) or sqrt(3). If we multiply the vector by 2, we get (2,2,2), which constitutes a vector in the same direction. See Vector3::length() of the Ogre API for details.
·Cross product of vectors The cross product of
two vectors yields a vector that is perpendicular to both vectors. This is a very useful operation. If you want to point out a vector that is perpendicular to a polygon, you can cross-multiply two sides of the polygon and you get a vector that is perpendicular to the plane of the polygon. See Vector3 Vector3::crossProduct(Vector3) of Ogre API for details.
·Dot Product of
Vectors Dot product of two vectors yields their angle. The calculation is as follows: DP(V1, V2) = (Cos Th) * Len1 * Len2, where Len1 and Len2 are the sizes of the vectors. Still, you'd better normalize the vectors, which makes them all of size 1. Normalized dot product calculation: Th = ArcCos(V1, V2); Len1=Len2=1. See Real Vector3::dotProduct(Vector3) of the Ogre API for details.
Euler rotation:
Our most common rotation methods should be to use yaw, roll and pitch. yaw is to rotate left and right around the Y axis on the XZ axis plane, and yaw is used when driving. The pitch rotates up and down around the X axis on the YZ axis plane, and the jet is used to pitch up or down when flying or climbing a hill. Roll is a tilt rotation around the Z axis on the XY axis plane. Literally, when you drive your car to make a sharp turn at high speed, your car will have a roll motion: P
Euler rotation is very useful, Ogre API also provides Euler rotation Pull to rotate. However, there is also a problem with rotation. One is that the order of operations cannot be chaotic. If you pitch an object 90 degrees, then yaw 45 degrees, the result is definitely different than yaw 90 degrees and then pitch 45 degrees. The other one is called a gimbal lock. A universal joint is a rotating shaft. This problem occurs when the two rotation axes coincide, and one needs to be deleted at this time.
(Translator's Note: The most famous problem with Euler angles is this: when you yaw 45 degrees and then pitch 90 degrees, it is equivalent to pitching 90 degrees and then rolling 90 degrees. In fact, once you choose ±90 degrees as The pitch angle is limited to only rotate around the vertical axis. In this phenomenon, the second rotation with an angle of ±90 degrees makes the first and third rotation axes the same, becoming a universal lock. In order to eliminate the restriction Euler This aliasing phenomenon of the angle stipulates that the rotation around the vertical axis can only be completed by yaw in the case of a universal lock. That is, if pitch = ±90 degrees, then roll = 0)
In general, the practical application of Euler angles is limited. What I'm referring to here is that using yaw, roll, pitch operations to rotate objects arbitrarily is not very practical. They are useful if you want a camera that can pitch/yaw at will (like many first person shooters). Using the dual scene node trick, you can get a camera that does all the rotation you need with just yaw and pitch operations. Still, when one of your objects is facing one direction, and you want it to be facing an object in an arbitrary position, it's not very good to take the current yaw, roll and pitch values ​​and then calculate the angle difference from the new direction Effective. Likewise, how can I make the rotation smoother? Enter the study of the matrix.
Matrix rotation:
Since using arbitrary three-dimensional Euler rotations results in a large number of operations, it is common to use matrices to store and transform them.
We use three matrices to represent the angular offsets from the X, Y, Z axes, namely pitch (around the X axis), yaw (around the Y axis) and roll (around the Z axis) as we mentioned above. We store it in separate matrices: matRotationX, matRotationY, matRotationZ. When we determine the angle we want to rotate, and store it into a matrix. We can combine a large number of rotation operations into a simple matrix transformation operation through matrix multiplication:
matTransform = matRotationX * matRotationY * matRotationZ;
luckily, Ogre provides the Matrix3 class to operate on 3X3 matrices. This class also contains * operations, so the above statement will work fine in your code. However, to actually rotate an object in Ogre, you can convert it to an axis/angular rotation, store the data into a matrix and do the transformation yourself or convert it to a quaternion.
Note that matrix multiplication is not commutative. A*B != B*A. The order of matrix rotation is very important, just like Euler angles, it cannot be changed arbitrarily. In addition, the Euler angles expressed in matrix form are still affected by the gimbal lock.
Matrices can also be used to manipulate axis/angular rotations. The above matrix uses the concepts of yaw, roll, pitch. Just imagine if these were replaced by rotations around the X, Y and Z axes respectively, this would achieve all axis/angular rotations. By this we avoid the gimbal lock problem (haven't figured it out yet). Ogre does not yet provide conversion between rotation matrices and quaternions. So if you're going to use a rotation matrix, you'll need to manually convert it to a quaternion yourself.
Euler angles have a common problem with matrices and rotation matrices, called matrix offsets, which are described in the next section.
Quaternion rotation:
Quaternions are quite an interesting concept for beginners. As described above, when working with quaternions, I find it easy to stop thinking in terms of yaw, pitch and roll and think in terms of rotation around an axis. For example, we want to simulate the thrusters on a jet with the jet facing the Z axis. In Euler angles, this rotation should be called roll. In quaternions, it is a rotation around a vector pointing to the Z axis or a rotation around Vector3::UNIT_Z.
A quaternion consists of four parts: a vector with x, y, z coordinates and a w rotation component. This is the representation of the axes/angles I mentioned in the matrix section. Quaternion math is pretty tricky, even with assumed parameters. Fortunately, we don't need to use it mathematically or understand why it should be interpreted as a rotation. As a test, first hold up the index finger of your left hand, then hold the end of the pen with your right hand. Now use your wrist and hand in a circular motion, rotating the pen as horizontally as possible, always keeping it perpendicular to the fingers of your left hand and parallel to the ground, as if you were rotating the pen on a table. Think of this as a quaternion rotated around Vector3::UNIT_Y.
At this point we have a vector from (0,0,0) to (1,1,-1). Point to the right with the finger just now, keeping a 45-degree angle to the ground. Now, rotate the pen around your finger, always keeping the pen perpendicular to your finger. Notice how we created a different rotation with the angle and axis selection.
Like matrices, we can also use quaternion multiplication to calculate the angle between them. But quaternion multiplication is still not commutative. Q1*Q2 != Q2*Q1. The order of application still matters. Quaternions also avoid the gimbal lock problem.
Advantages of
Quaternions Quaternions have many advantages that matrices do not have. However, it still follows operations like positive, negative, multiplication or addition like numbers. According to the conclusions obtained in practice, the advantages are as follows:
· Cardan lock is avoided in the axis/angle representation.
·It is easier to modify the rotation.
Suppose we describe a -45 degree axis yaw rotation to the left, create a new quaternion describing a 10 degree axis yaw rotation to the right. Multiplying the two quaternions together, we have a -35 degree axis rotation. This can be used when other objects or multiple identical objects need to achieve the same rotation. The twiddle factor changes depending on the environment.
• Avoids operation-intensive matrix shifts Matrix shifts
occur when a large number of operations are performed on a matrix using the limited point precision in a computer. The rounded-off real numbers gradually increase, which will inevitably corrupt the matrix. Matrix offsets will result in unexpected rotations. The matrix would have to be normalized to reset the rotation, which would be very expensive. Quaternions, on the other hand, have a similarly painful shift, however, from 9 or more parameter operations down to 4, which is far less laborious than normalization.
• Incremental Rotation
When rotating an object, we want the object to rotate smoothly. We often say "Go to this point from your current position. But use 300 frames to do it, moving 1/300 of the full angle each time." It's possible to add value to the matrix, but is it possible otherwise? Quaternions provide two ways of adding value: linear and cubic. Ogre provides three execution methods: slerp, nlerp and square. The percentage that an increment allows between two quaternions is specified. Linear means that the rate of motion is fixed, and if a camera or node is used, it will feel jerky. Both slerp and nlerp are linear, slerp is more accurate but slower. Squad or cubic increments allow four quaternions a, p, q, b to be specified at once. p, q are used to define the value-added curve between points a and b. It allows us to slowly increase the speed, stop, and decrease the speed while adding value.
Ogre uses quaternions
which is why you should read this article

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

目前对于四元数,现在先将其定义为一个可以用来旋转的解决了万向锁的东西就行了,而且他提供了非线性的旋转,这会让视觉更舒服.


面向场景:在这几天对OGRE的学习中深刻感受到什么是面向场景的架构,OGRE有一个SceneManager,用来管理场景中的节点,节点你可以当作树枝,在节点下可以挂载其它的节点,也可以挂载实体(实体指的是可以在场景中渲染的物体,灯光 摄像机 粒子这些就不能当作实体).所以整个OGRE的场景就会像一棵树一样,如果将节点从父节点销毁,OGRE就不会对其进行渲染.

下面是一段节点生成和添加实体的代码:

Ogre::Entity* ogreScene = mSceneManager->createEntity("Head", "mada.mesh");//使用场景管理器生成实体
ogreScene->setMaterialName("Examples/EnvMappedRustySteel");
ogreScene->setCastShadows(true);



  Ogre::SceneNode* headNode = mSceneManager->getRootSceneNode()->createChildSceneNode("headNode");
  headNode->attachObject(ogreScene);//将实体添加到场景下


和之前接触的2D引擎不同,OGRE对物体位置的操作是通过对节点的操作进行的.节点下有setPosition(Ogre::Vector3)函数.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325792651&siteId=291194637