c++ - 如何旋转模型以跟随路径

标签 c++ opengl model glm-math

我有一个宇宙飞船模型,我想沿着圆形路径移动。我希望 scapy 始终指向它前进的方向。

这是我现在必须将其移动一圈的代码:

glm::mat4 m = glm::mat4(1.0f);

        //time
        long value_ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::
                                                                                                                                          high_resolution_clock::now())
                                                                                  .time_since_epoch())
                            .count();
        //translate 
        m = glm::translate(m, translate);
        m = glm::translate(m, glm::vec3(-50, 0, -20));
        m = glm::scale(m, glm::vec3(0.025f, 0.025f, 0.025f));
        m = glm::translate(m, glm::vec3(1800, 0, 3000));

        float speed = .002;
        float x = 100 * cos(value_ms * speed); // + 1800;
        float y = 0;
        float z = 100 * sin(value_ms * speed); // + 3000;
        m = glm::translate(m, glm::vec3(x, y, z));

我如何移动它才能使 Nose 始终指向前方?我尝试在将旋转轴设置为 x 或 y 或 z 的情况下执行 glm::rotate,但我无法使其正常工作。

最佳答案

先看Understanding 4x4 homogenous transform matrices因为我正在使用那里的术语和东西......

通常使用物体的变换矩阵来实现导航目的,而不是相反......所以你应该为你的 spaceship 准备一个变换矩阵 M 来表示它的位置和方向在[GCS](全局坐标系)中。最重要的是有时乘以另一个矩阵 M0 将您的 spaceship 网格与第一个矩阵对齐(您知道一些网格不以 (0,0,0) 为中心也不对齐轴...)

现在,当您移动对象时,您只需对 M 执行局部转换,因此向前移动只是将 M 原点位置平移一个正轴基 vector 的倍数。向侧面滑动也是如此(只是使用不同的基础 vector )导致对象始终对齐到它应该在的位置(相对于移动)。轮流也是如此。所以绕圈子只是向前移动并在每个时间迭代步骤(计时器)中以恒定速度转动。

您正在向后执行此操作,首先您计算位置和方向,然后您尝试进行操作以生成会执行相同操作的矩阵...在这种情况下,构造 容易得多矩阵 M 而不是创建将创建它的转换......所以你需要的是:

  • 原点
  • 3 个垂直(最有可能是单位)基 vector

所以原点是您的x,y,z 位置。可以从圆中获得 2 个基 vector ,因此前向是切线(或 position-last_position),朝向圆心的 vector cen 用作(右或左)。第三个 vector 可以通过叉积得到,所以假设:

  • +X轴右
  • +Y 轴向上
  • +Z 轴向前

你得到了:

r=100.0
a=speed*t
pos = (r*cos(a),0.0,r*sin(a))
center = (0.0,0.0,0.0)

所以:

Z = (cos(a-0.5*M_PI),0.0,sin(a-0.5*M_PI))
X = (cos(a),0.0,sin(a))-ceneter
Y = cross(X,Z)
O = pos

规范化:

X /= length(X)
Y /= length(Y)
Z /= length(Z)

现在只需将您的 X,Y,Z,O 提供给您的矩阵(取决于您使用的约定,例如乘法顺序、直接/逆矩阵、行主矩阵或列主矩阵。 ..)

例如像这样:

double M[16]=
 {
 X[0],X[1],X[2],0.0,
 Y[0],Y[1],Y[2],0.0,
 Z[0],Z[1],Z[2],0.0,
 O[0],O[1],O[2],1.0,
 };

或:

double M[16]=
 {
 X[0],Y[0],Z[0],O[0],
 X[1],Y[1],Z[1],O[1],
 X[2],Y[2],Z[2],O[2],
 0.0 ,0.0 ,0.0 ,1.0,
 };

仅此而已……矩阵可能会根据您使用的约定进行转置、反转等。抱歉,我不使用 GLM,但语法应该非常相似……如果行或列可由 vector 加载,矩阵馈送可能会更简单……

关于c++ - 如何旋转模型以跟随路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56763923/

相关文章:

c++ - 如何使用 gflags 为您自己的项目获取 bash 选项卡补全?

c++ - Foo f = Foo();//没有调用 'Foo::Foo(Foo)' 的匹配函数……嗯?

c++ - Windows 10 上的 GetTickCount 值

opengl - 为什么应该使用外部 OpenGL 加载器函数而不是 GLAD 的内置加载器?

c++ - 客户端程序中的 glewInit() 和 GLEW_ARB_xxx_ 失败

c# - 忽略使用 Automapper 映射一个属性

c++ - 在执行 buttonReleased() 之前等待 buttonPressed() 插槽完成

opengl - 如何强制 OpenCL 不重新对齐结构?

java - 无法从 spring mvc portlet 中的 View 检索模型属性

python - 为什么我不能将模型方法用作默认值?无论如何,Python/Django 模型中的 self 是什么?