c++ - sprites - Rotación de OpenGL-Ejes locales vs globales
sfml texture (2)
Así que tengo un objeto que estoy tratando de rotar de acuerdo con un esquema de Yaw, Pitch and Roll, relativo a los ejes locales propios del objeto en lugar de los ejes del espacio global. De acuerdo con esto , necesito realizar las rotaciones en ese orden. Lo he interpretado en el sentido de esto:
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);
Sin embargo, la rotación alrededor de los ejes Y y Z no funciona. La rotación alrededor del eje Y es siempre relativa al espacio global, y la rotación alrededor del eje z funciona de la rotación alrededor del eje X es 0, pero de lo contrario se ensucia.
Solo para estar seguro, intenté el orden inverso también, pero eso tampoco funciona. Creo que he probado todas las otras órdenes también, entonces el problema debe ser algo más. ¿podría ser?
Así es como obtengo las rotaciones:
///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;
}
Luego se agregan a m_Rotation como tal:
//Rotation
m_Rotation.x += Angle.x;
m_Rotation.y += Angle.y;
m_Rotation.z += Angle.z;
(Se pasan a una función interna de la cosa que se mueve, pero no se hace nada más con ellos).
¿Pensamientos? ¿Hay algo más que deba llamar para asegurarme de que todos los ejes que se rotan son ejes locales?
Garrick,
Cuando llamas a glRotate (ángulo, x, y, z), está girando alrededor del vector que estás pasando a glRotate. El vector va de (0,0,0) a (x, y, z).
Si desea rotar un objeto alrededor del eje local del objeto, debe convertir el objeto a origen, realizar su rotación y luego traducirlo de vuelta al lugar de donde proviene.
Aquí hay un ejemplo:
//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();
}
Tu problema es que estás almacenando tus rotaciones x, y, z y agregándolas acumulativamente. Luego, cuando renderizas, estás realizando las rotaciones acumulativas totales en la matriz de identidad (estás realizando todas las rotaciones globalmente). Comente su llamada de identidad desde su ciclo de renderizado. Y asegúrese de establecer la identidad en su función de inicialización. Entonces
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
Como estoy seguro, descubriste después de que aceptaste la respuesta original. El orden de las rotaciones o las traducciones no afecta en qué eje se produce la rotación, sino en el punto en el que se realiza la rotación. por ejemplo, al rotar un planeta 15 grados, lo girará en el eje global 15 grados. Traducirlo del origen y luego girarlo hará que orbite el origen a la distancia traducida (si está en el mismo eje que la rotación, al traducir en el eje x, girar en el eje y no tendría ningún efecto de confusión).