The spatial transformation of ogre is a headache for beginners, And the traps are also a pile of traps. Even if I have climbed out of these traps, I still think it is necessary to talk about them.
Translate () this mysterious function. A friend found a trap on the Internet:
The following is an incorrect understanding of a netizen in the Forum:
Certificate ----------------------------------------------------------------------------------------------------------------------------------
This problem has been raised on csdn and gameres, and no one has answered it all the time. I don't know how it works here?
Void createscene (){
... // The first object (coordinate origin)
Entity * head = mscenemgr-> createentity ("object1", "ogrehead. mesh ");
Head-> setmaterialname ("examples/Rockwall ");
Scenenode * node1 = rootnode-> createchildscenenode ();
Node1-> attachobject (head );
// Second object
Head = mscenemgr-> createentity ("object2", "ogrehead. mesh ");
Scenenode * node2 = node1-> createchildscenenode ();
Node2-> attachobject (head );
Node2-> translate (vector3 (50, 0, 0), scenenode: ts_parent );
// Third object
Head = mscenemgr-> createentity ("object3", "ogrehead. mesh ");
Scenenode * node3 = node2-> createchildscenenode ();
Node3-> attachobject (head );
Node3-> translate (vector3 (0, 50, 0), scenenode: ts_world );
Node3-> yaw (degree (90), scenenode: ts_local );
}
According to spatial transformation analysis, the world coordinates of node1 at the origin and node2 are (50, 0, 0), and the world coordinates of node3 are (0, 50, 0 ),
But from the displayed result, node3 is (50, 50, 0 ),
No matter which transformspace value is used, the results are the same: the translate is relative to the parent, and the rotation is in loacal.
My understanding of this parameter is:
Ts_world: No matter where the current node is, its operations are relative to the origin of the world coordinate system.
For example, node3 is under node2, so its initial world coordinates should be (50, 0, 0 ),
If it translate (vector3 (0, 50, 0), scenenode: ts_local), the world coordinates should be (50, 50, 0)
If it translate (vector3 (0, 50, 0), scenenode: ts_world), the coordinates of the world are (0, 50, 0)
Certificate -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The problem this netizen encountered was actually the problem of the translate transformation. Why does he understand it so well? Let's analyze it slowly:
The translate () function is actually relative to the parent node, rather than the absolute movement that the netizen understands.
But if it is relative to the parent node, why do I need to select three reference spaces ???
This is the key. The three reference spaces determine the direction of the relative movement volume, rather than the location where the netizen understands the movement !!!
Why is the result of any change to the Reference Space of the 3rd nodes in his code the same? If it is understood as a direction, it will suddenly become clear.
Because the origin of the world, the parent node, and itself, the orientation of the three nodes is the same (default-z direction), so the relative moving value is the same, all are relatively moving in the Y direction 50
If the origin of the world is located, the parent node is oriented to the positive z direction by default, and the node itself is rotated 90 degrees to the Y direction.
If the local space is translate (vector3 (0, 50, 0), scenenode: ts_local ),
This is because he is moving towards y and 50 to Y in the local space. In the world space, it is actually moving 50 to-Z.
In a word, it is moving 50 units relative to the parent node, and the reference space only determines the direction of moving these 50 units!
So it's right to understand the reference space as orientation.
World Space ---------- determines that the orientation of the world origin is standard. The default value is-Z.
Parent node space ---------- identify parent node orientation as Standard Orientation
Local space ------------ determines that the orientation of the node itself is standard.
The netizen's understanding is actually reasonable. His understanding is actually the following hypothetical function:
Setposition (ts_world );
Setposition (ts_parent );
Setposition (ts_local );
Unfortunately, this is just an assumption. The location setting function does not have reference space ~~~
Why does ogre not set such a function? Because there are already alternative functions:
Setposition () // coordinates of the parent space
Setderivedposition () // absolute coordinate of the World Space
The location setting function of the local space does not need ....
Finally, let's look back at why it is easy to understand translate ()... the reason is that translate (ts_parent) moves relative to the parent space.
If the parent space of the reference space is understood as a direction or location, the results will be exactly the same in two cases, coincidence.
This coincidence hides a trap, which many people think is correct...
Do not believe in source code:
View plaincopy to clipboardprint?
//-----------------------------------------------------------------------
Void node: translate (const vector3 & D, transformspace relativeto)
{
Switch (relativeto)
{
Case ts_local:
// Position is relative to parent so transform downwards
Mposition + = morientation * D;
Break;
Case ts_world:
// Position is relative to parent so transform upwards
If (mparent)
{
Mposition + = (mparent-> _ getderivedorientation (). Inverse () * D)
/Mparent-> _ getderivedscale ();
}
Else
{
Mposition + = D;
}
Break;
Case ts_parent:
Mposition + = D;
Break;
}
Needupdate ();
}
//-----------------------------------------------------------------------
Void node: translate (const vector3 & D, transformspace relativeto)
{
Switch (relativeto)
{
Case ts_local:
// Position is relative to parent so transform downwards
Mposition + = morientation * D;
Break;
Case ts_world:
// Position is relative to parent so transform upwards
If (mparent)
{
Mposition + = (mparent-> _ getderivedorientation (). Inverse () * D)
/Mparent-> _ getderivedscale ();
}
Else
{
Mposition + = D;
}
Break;
Case ts_parent:
Mposition + = D;
Break;
}
Needupdate ();
}
Because the position and direction of mposition relative to the parent node,
Therefore, the calculation results must be converted to the parent space sum.
The local space Moves D toward the orientation of its own node, and changes to the parent space of the mposition, which only needs to rotate to a certain angle,
This angle should be the angle between the node direction and the parent node direction, which is exactly the morientation
Mposition + = morientation * D;
The World Space moves D toward the origin of the world, and the parent space to change to the mposition only needs to rotate a certain angle,
This angle should be the angle between the world origin and the parent node, which is exactly the opposite of the parent node.
(Why is it necessary to take the inverse? We cannot exchange the result of multiplication of two semicolons, because the angle between the world node and the parent node is! = The angle between the parent node and the world node. The opposite is true)
Mposition + = (mparent-> _ getderivedorientation (). Inverse () * D)
/Mparent-> _ getderivedscale ();
Parent node space, which moves D toward the parent node. To change to the mposition, the parent space only needs to rotate to a certain angle,
The conversion of the parent space to the parent space... is actually consistent.
It should be mposition + = quaternion: identity * D;
Equivalent to mposition + = D;
This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/evil_darker/archive/2010/08/21/5826606.aspx