【发布时间】:2023-03-25 19:05:01
【问题描述】:
我正在尝试将速度乘以帧之间的时间。我想为四元数做这件事是通过将它们提升到一个幂来完成的。我有代码可以根据鼠标移动来旋转对象。它有一个以一个帧速率运行的主循环和一个以固定帧速率运行的物理循环。这是主循环的相关部分:
glfwPollEvents();
Input::update();
window.clear(0,0,0,1);
rigidBody.angularVelocity *= glm::angleAxis(0.001f * Input::deltaMouse().x, glm::vec3(0,1,0));
rigidBody.angularVelocity *= glm::angleAxis(0.001f * Input::deltaMouse().y, glm::vec3(1,0,0));
if(Input::getKey(Input::KEY_A))
{
rigidBody.velocity -= float(Time::getDelta()) * glm::vec3(1,0,0);
}
if(Input::getKey(Input::KEY_D))
{
rigidBody.velocity += float(Time::getDelta()) * glm::vec3(1,0,0);
}
if(Input::getKey(Input::KEY_W))
{
rigidBody.velocity -= float(Time::getDelta()) * glm::vec3(0,0,1);
}
if(Input::getKey(Input::KEY_S))
{
rigidBody.velocity += float(Time::getDelta()) * glm::vec3(0,0,1);
}
if(Input::getKey(Input::KEY_LCONTROL))
{
rigidBody.velocity -= float(Time::getDelta()) * glm::vec3(0,1,0);
}
if(Input::getKey(Input::KEY_LSHIFT))
{
rigidBody.velocity += float(Time::getDelta()) * glm::vec3(0,1,0);
}
这是物理循环的相关部分:
for(int i = 0; i < *numRigidBodies; i++)
{
rigidBodies[i].transform->getPos() += rigidBodies[i].velocity;
rigidBodies[i].transform->getRot() *= rigidBodies[i].angularVelocity;
}
rigidBodies[0].angularVelocity = glm::quat();
rigidBodies[0].velocity = glm::vec3();
这很好用,但是当我尝试使用 glm::pow 将角速度提高到幂时,对象会随机旋转并且不会跟随我的鼠标。我意识到我可以用这样的一行代码来做到这一点
rigidBodies[i].transform->getRot() *= glm::angleAxis((float)Time::getFixedDelta() * glm::angle(rigidBodies[i].angularVelocity), glm::axis(rigidBodies[i].angularVelocity));
但这对于这项任务来说似乎是不必要的复杂。是什么导致了这个问题,我该如何解决?
【问题讨论】:
-
四元数没有唯一的平方根,也没有旋转的唯一平方根。一个 10 度的旋转可以是两个 5 度的旋转,或者两个 185 度的旋转。两者在组合时都会产生 10 度的旋转。一般来说,k 度旋转的第 n 个根是 x 从 0 到 n-1 的集合 x 360/n + k/n。我不知道你的图书馆是做什么的,我只是指出数学是模棱两可的。