So I've got an object I'm trying to rotate according to a Yaw, Pitch and Roll scheme, relative to the object's own local axes rather than the global space's axes. According to this, I need to perform the rotations in that order. I've interpreted that to mean this:
所以我有一个物体,我试着根据偏航,俯仰和滚动的方式,相对于物体本身的局部轴,而不是全局空间的轴。根据这个,我需要按照这个顺序进行旋转。我把它解释为:
glRotatef(m_Rotation.y, 0.0, 1.0, 0.0);
glRotatef(m_Rotation.z, 0.0, 0.0, 1.0);
glRotatef(m_Rotation.x, 1.0, 0.0, 0.0);
However, rotation around the Y and Z axes don't work. Rotation around the Y axis is always relative to the global space, and rotation around the z axis works of the rotation around the X axis is 0, but otherwise messes up.
然而,绕Y轴和Z轴旋转不起作用。绕Y轴旋转总是相对于全局空间,绕着X轴旋转的z轴旋转的工作是0,否则就会弄乱。
Just to be sure, I tried the reverse order as well, but that doesn't work either. I think I've tried all the other orders as well, so the problem must be something else. might it be?
当然,我也试过相反的顺序,但那也不行。我想我也试过了所有其他的订单,所以问题肯定是别的。它会是什么?
This is how I obtain the rotations:
这就是我得到旋转的方法:
///ROTATIONS
sf::Vector3<float> Rotation;
Rotation.x = 0;
Rotation.y = 0;
Rotation.z = 0;
//ROLL
if (m_pApp->GetInput().IsKeyDown(sf::Key::Up) == true)
{
Rotation.x -= TurnSpeed;
}
if (m_pApp->GetInput().IsKeyDown(sf::Key::Down) == true)
{
Rotation.x += TurnSpeed;
}
//YAW
if (m_pApp->GetInput().IsKeyDown(sf::Key::Left) == true)
{
Rotation.y -= TurnSpeed;
}
if (m_pApp->GetInput().IsKeyDown(sf::Key::Right) == true)
{
Rotation.y += TurnSpeed;
}
//PITCH
if (m_pApp->GetInput().IsKeyDown(sf::Key::Q) == true)
{
Rotation.z -= TurnSpeed;
}
if (m_pApp->GetInput().IsKeyDown(sf::Key::E) == true)
{
Rotation.z += TurnSpeed;
}
They are then added to m_Rotation as such:
然后将它们加到m_Rotation中:
//Rotation
m_Rotation.x += Angle.x;
m_Rotation.y += Angle.y;
m_Rotation.z += Angle.z;
(They are passed to a function internal to the thing being moved around, but nothing else is done with them).
(它们被传递给一个内部的函数,但是没有其他的操作)。
Thoughts? Is there something else I should call to make sure all the axes being rotated around are local axes?
想法吗?我还需要调用什么来确保旋转的所有轴都是局部轴吗?
2 个解决方案
#1
1
Garrick,
灰吕,
When you call glRotate(angle, x, y, z), it is rotating around the vector that you are passing into glRotate. The vector goes from (0,0,0) to (x,y,z).
当你调用glRotate(角度,x, y, z)时,它围绕着你进入glRotate的矢量旋转。向量从(0,0,0)到(x,y,z)
If you want to rotate an object around the object's local axis, you need to glTranslate the object to origin, perform your rotation, and then translate it back to where it came from.
如果你想在对象的局部轴上旋转一个对象,你需要将该对象转换为原点,执行你的旋转,然后将它转换回原来的位置。
Here is an example:
这是一个例子:
//Assume your object has the following properties
sf::Vector3<float> m_rotation;
sf::Vector3<float> m_center;
//Here would be the rotate method
public void DrawRotated(sf::Vector<float> degrees) {
//Store our current matrix
glPushMatrix();
//Everything will happen in the reverse order...
//Step 3: Translate back to where this object came from
glTranslatef(m_center.x, m_center.y, m_center.z);
//Step 2: Rotate this object about it's local axis
glRotatef(degrees.y, 0, 1.0, 0);
glRotatef(degrees.z, 0, 0, 1.0);
glRotatef(degrees.x, 1.0, 0, 0);
//Step 1: Translate this object to the origin
glTranslatef(-1*m_center.x, -1*m_center.y, -1*m_center.z);
//Render this object rotated by degrees
Render();
//Pop this matrix so that everything we render after this
// is not also rotated
glPopMatrix();
}
#2
0
Your problem is that you are storing your x, y, z rotations and adding to them cumulatively. Then when you render you are performing the total cumulative rotations upon the identity matrix(you are performing all rotations globally). Comment out your identity call from your render loop. And make sure you set identity at your initialize function. Then
你的问题是,你在存储你的x, y, z旋转,并累积起来。然后,当你渲染你的时候,你正在对单位矩阵执行总的累积旋转(你在全球执行所有旋转)。在渲染循环中注释掉你的身份调用。确保在初始化函数中设置了标识。然后
rotate as normal
m_Rotation.x = m_Rotation.y = m_Rotation.z = 0.0f;
//clear your rotations you don't want them to accumulate between frames
glpush
translate as normal
(all other stuff)
glpop
//you should be back to just the rotations
//glclear and start next frame as usual
As I'm sure you found out after you accepted the original answer. The order of rotations or translations does not affect which axis the rotation occurs on, rather the point at which the rotation is performed. eg rotating a planet 15 degrees will rotate it on the global axis 15 degrees. Translating it away from origin and then rotating it will cause it to orbit the origin at the distance translated (if on the same axis as the rotation, translating on the x axis then rotating on the y axis would not have any confounding effects).
我相信你在接受了最初的答案后就知道了。旋转或平移的顺序不会影响旋转发生在哪个轴上,而不是旋转的位置。旋转一个行星15度将使它在全球轴上旋转15度。把它从原点平移,然后旋转它就会使它绕着原点旋转(如果在同一个轴上旋转,在x轴上平移,然后在y轴上旋转不会有任何混淆的效果)。
#1
1
Garrick,
灰吕,
When you call glRotate(angle, x, y, z), it is rotating around the vector that you are passing into glRotate. The vector goes from (0,0,0) to (x,y,z).
当你调用glRotate(角度,x, y, z)时,它围绕着你进入glRotate的矢量旋转。向量从(0,0,0)到(x,y,z)
If you want to rotate an object around the object's local axis, you need to glTranslate the object to origin, perform your rotation, and then translate it back to where it came from.
如果你想在对象的局部轴上旋转一个对象,你需要将该对象转换为原点,执行你的旋转,然后将它转换回原来的位置。
Here is an example:
这是一个例子:
//Assume your object has the following properties
sf::Vector3<float> m_rotation;
sf::Vector3<float> m_center;
//Here would be the rotate method
public void DrawRotated(sf::Vector<float> degrees) {
//Store our current matrix
glPushMatrix();
//Everything will happen in the reverse order...
//Step 3: Translate back to where this object came from
glTranslatef(m_center.x, m_center.y, m_center.z);
//Step 2: Rotate this object about it's local axis
glRotatef(degrees.y, 0, 1.0, 0);
glRotatef(degrees.z, 0, 0, 1.0);
glRotatef(degrees.x, 1.0, 0, 0);
//Step 1: Translate this object to the origin
glTranslatef(-1*m_center.x, -1*m_center.y, -1*m_center.z);
//Render this object rotated by degrees
Render();
//Pop this matrix so that everything we render after this
// is not also rotated
glPopMatrix();
}
#2
0
Your problem is that you are storing your x, y, z rotations and adding to them cumulatively. Then when you render you are performing the total cumulative rotations upon the identity matrix(you are performing all rotations globally). Comment out your identity call from your render loop. And make sure you set identity at your initialize function. Then
你的问题是,你在存储你的x, y, z旋转,并累积起来。然后,当你渲染你的时候,你正在对单位矩阵执行总的累积旋转(你在全球执行所有旋转)。在渲染循环中注释掉你的身份调用。确保在初始化函数中设置了标识。然后
rotate as normal
m_Rotation.x = m_Rotation.y = m_Rotation.z = 0.0f;
//clear your rotations you don't want them to accumulate between frames
glpush
translate as normal
(all other stuff)
glpop
//you should be back to just the rotations
//glclear and start next frame as usual
As I'm sure you found out after you accepted the original answer. The order of rotations or translations does not affect which axis the rotation occurs on, rather the point at which the rotation is performed. eg rotating a planet 15 degrees will rotate it on the global axis 15 degrees. Translating it away from origin and then rotating it will cause it to orbit the origin at the distance translated (if on the same axis as the rotation, translating on the x axis then rotating on the y axis would not have any confounding effects).
我相信你在接受了最初的答案后就知道了。旋转或平移的顺序不会影响旋转发生在哪个轴上,而不是旋转的位置。旋转一个行星15度将使它在全球轴上旋转15度。把它从原点平移,然后旋转它就会使它绕着原点旋转(如果在同一个轴上旋转,在x轴上平移,然后在y轴上旋转不会有任何混淆的效果)。