【问题标题】:Object rotation using keys使用键旋转对象
【发布时间】:2018-04-17 08:22:41
【问题描述】:

我想使用按键旋转立方体。这是代码的一部分。当我按下 LEFT 键时,立方体向左旋转,等等。我的目标是旋转立方体,所以我必须将它旋转 xy 轴,这会导致问题。

我已经定义了mat4 rotation;,并在我按住某个键时使用它来分配旋转。当我按住键时,它正在旋转,例如向左旋转。然后我松开按键,物体回到初始位置(相机回到初始位置,因为物体没有移动)。我认为这个问题导致了在关键功能下方定义的auto rotateMat = rotation; 行。 我做错了什么?

    mat4 rotation; //global 

    if(keysPressed[GLFW_KEY_LEFT]){
                timer -= delta;
                rotation = rotate(mat4{}, timer * 0.5f, {0, 1, 0});
    }

    if(keysPressed[GLFW_KEY_RIGHT]){
                timer += delta;
                rotation = rotate(mat4{}, timer * 0.5f, {0, 1, 0});
    }

   if(keysPressed[GLFW_KEY_UP]){
                timer += delta;
                rotation = rotate(mat4{}, timer * 0.5f, {1, 0, 0});
   }

   if(keysPressed[GLFW_KEY_DOWN]){
                timer -= delta;
                rotation = rotate(mat4{}, timer * 0.5f, {1, 0, 0});
   }

   ...
   program.setUniform("ModelMatrix", rotation* cubeMat); 
   cube.render();

更新:

所以当我使用矩阵变量作为全局变量而不是局部变量时,这个问题就解决了。

【问题讨论】:

  • 如果没有按键被按下,那么旋转将是一个单位矩阵。所以是的,用一个统一矩阵覆盖 rotateMat 会导致你的立方体回到它的初始位置。
  • @BDL 那么我怎么能不覆盖rotateMat?我想当我将rotation 分配给rotateMat 时,它会记住最后一个位置。
  • 例如,您可以计算 ifs 中的相对旋转并将其与当前矩阵相乘。
  • 问题仍然与最初的问题相同:您根本不能只有一个全局矩阵并在每一帧中覆盖它。要么通过乘以相对旋转来累积这些旋转,要么存储两个角度。
  • 请在我创建的新问题中讨论它。

标签: c++ opengl rotation glfw glm-math


【解决方案1】:

有多种方式可以实现这种交互。其中一个更简单的方法是在每一帧中创建相对平移而不是全局平移,并将其添加到当前旋转中:

为此,必须将所有旋转的总和存储在全局变量中

//Global variable
mat4 total_rotate;

并计算每一帧的相对平移:

//In the function
mat4 rotation;

if(keysPressed[GLFW_KEY_LEFT]){
            rotation = rotate(mat4{}, delta, {0, 1, 0});
}

if(keysPressed[GLFW_KEY_RIGHT]){
            rotation = rotate(mat4{}, -delta, {0, 1, 0});
}

if(keysPressed[GLFW_KEY_UP]){
             rotation = rotate(mat4{}, delta, {1, 0, 0});
}

if(keysPressed[GLFW_KEY_DOWN]){
             rotation = rotate(mat4{}, -delta, {1, 0, 0});
}

total_rotate = total_rotate * rotation;
...
program.setUniform("ModelMatrix", total_rotate * cubeMat); 
cube.render();

作为替代方案,您可以存储两个旋转角度并在每一帧中计算矩阵:

//Global variables
float rot_x = 0.0f, rot_y = 0.0f;

//In every frame    
if(keysPressed[GLFW_KEY_LEFT]){
            rot_x += delta;
}

if(keysPressed[GLFW_KEY_RIGHT]){
            rot_x -= delta;
}

//Same for y

auto rotation = rotate(rotate(mat4{}, rot_y, {0, 1, 0}), rot_x, {1, 0, 0}
...
program.setUniform("ModelMatrix", rotation * cubeMat); 
cube.render();

【讨论】:

  • 第一个解决方案对我不起作用。它回到初始位置。
  • 您是否将total_rotate 声明为全局变量?除非您在某处覆盖或重置 total_rotate,否则它不应返回。
  • 它在函数onIdle() override 中,但不应在其中重置。对于第二种解决方案,它想旋转,但它没有,有东西阻碍了运动。所以当我按键移动时,它只是在初始位置“摇晃”。
  • 你的意思是它们是onIdle中的局部变量?然后,每当执行该函数时,所有变量都会被重置。请以它们不是对任何函数本地但全局的方式声明它们。
  • 没关系,它现在正在工作,我没有注意到它仍然不是全局的,我将它放在文件的最顶部。但至于第二个解决方案,您是否看到它“卡住”的问题?
猜你喜欢
  • 1970-01-01
  • 2018-01-30
  • 1970-01-01
  • 1970-01-01
  • 2016-11-30
  • 2014-06-04
  • 2021-09-13
  • 1970-01-01
  • 2013-04-22
相关资源
最近更新 更多