I am creating a graphical scene with OpenGL and SDL, and I'm running into a problem in regards to translating an object in its rotation direction.
Each of the graphical objects in the scene has a Transform
object, which contains the object position, rotation, and scale. The following code in the Transform
calculate the model for the object:
inline glm::mat4 GetModel() const
{
glm::mat4 matx;
matx = glm::translate(matx, m_translateV);
matx = glm::rotate(matx, m_rotateV.x, glm::vec3(1.0, 0.0, 0.0));
matx = glm::rotate(matx, m_rotateV.y, glm::vec3(0.0, 1.0, 0.0));
matx = glm::rotate(matx, m_rotateV.z, glm::vec3(0.0, 0.0, 1.0));
matx = glm::scale(matx, m_scaleV);
return matx;
}
Additionally it has getters which return a pointer to each vec3
, so that I can modify it when I request it (not too important for my issue, just giving you a background).
inline glm::vec3* GetPos() { return &m_translateV; }
inline glm::vec3* GetRot() { return &m_rotateV; }
inline glm::vec3* GetScale() { return &m_scaleV; }
The following code is called from my main game loop to process key inputs:
SDL_Event event;
std::shared_ptr<ENGINE::RenderObject> ro = m_renderer.GetRenderObject(0);
ENGINE::Transform t = ro->GetTransform();
if (SDL_PollEvent(&event))
{
if (event.type == SDL_KEYDOWN)
{
if (event.key.keysym.sym == SDLK_ESCAPE)
{
m_gameState = GameState::EXIT;
}
if (event.key.keysym.sym == SDLK_w)
{
t.GetPos()->x -= glm::sin(glm::radians(t.GetRot()->y)) * 0.5;
t.GetPos()->z -= glm::cos(glm::radians(t.GetRot()->y)) * 0.5;
}
if (event.key.keysym.sym == SDLK_s)
{
t.GetPos()->x += glm::sin(glm::radians(t.GetRot()->y)) * 0.5;
t.GetPos()->z += glm::cos(glm::radians(t.GetRot()->y)) * 0.5;
}
if (event.key.keysym.sym == SDLK_a)
{
t.GetRot()->y += 0.1;
}
if (event.key.keysym.sym == SDLK_d)
{
t.GetRot()->y -= 0.1;
}
}
}
ro->SetTransform(t);
The problem I'm having is that even if I rotate my object, it keeps translating in the same direction (forward on the z-axis). The following two images should explain what I mean (the object of interest is the rotated one):
Image 1 : With rotation before translation (before pressing w):
Image 2 : With rotation and translation:
As you can see, even though I have rotated the object using a and d
, when I press w or s
to translate the object, it keeps translating in the same direction.
I have tried another case, where I create some rotation values, but I don't actually rotate the object. What happens in this case is that even though when I press a or d
the object doesn't actually appear to rotate, however it will translate in the correct direction when I press w or s
. The following is the code change that I tried:
if (SDL_PollEvent(&event))
{
if (event.type == SDL_KEYDOWN)
{
if (event.key.keysym.sym == SDLK_ESCAPE)
{
m_gameState = GameState::EXIT;
}
if (event.key.keysym.sym == SDLK_w)
{
t.GetPos()->x -= glm::sin(glm::radians((float)direction)) * 0.5;
t.GetPos()->z -= glm::cos(glm::radians((float)direction)) * 0.5;
}
if (event.key.keysym.sym == SDLK_s)
{
t.GetPos()->x += glm::sin(glm::radians((float)direction)) * 0.5;
t.GetPos()->z += glm::cos(glm::radians((float)direction)) * 0.5;
}
if (event.key.keysym.sym == SDLK_a)
{
direction += 5; // new line
}
if (event.key.keysym.sym == SDLK_d)
{
direction -= 5; // new line
}
}
}
ro->SetTransform(t);
I can't seem to figure out why exactly the object doesn't translate in the correct direction when I apply rotation to it, but it does when I don't apply rotation and instead use some other value in the calculation for the x and z
values. I am uploading the model matrix normally to the vertex shader.
Hope the question/issue is clear. I will provide any additional code if needed.
Thanks