OpenGL - 骨骼动画 - 骨骼围绕原点旋转

Posted

技术标签:

【中文标题】OpenGL - 骨骼动画 - 骨骼围绕原点旋转【英文标题】:OpenGL - skeletal animation - bone rotates around origin 【发布时间】:2019-04-07 10:57:05 【问题描述】:

我正在关注 Youtube (https://www.youtube.com/watch?v=f3Cr8Yx3GGA) 上关于骨骼动画的系列教程,但遇到了一个问题 - 一切正常,除了当我旋转其中一个骨骼(或“关节”)时,它们会围绕场景起源,这意味着它们不会留在原地而是被翻译。下图说明了问题:

我怎样才能避免翻译发生?我已经多次阅读教程系列,但无法确定哪个步骤可以防止这种情况发生。

代码很大,分成十几个文件,我不知道哪个部分可能导致问题,所以我认为在这里发布它没有太大意义(它应该类似于教程中的代码,即使我在他使用 Java 时使用 C++。教​​程代码可以在这里找到:https://github.com/TheThinMatrix/OpenGL-Animation)。如果您可以就骨骼动画中通常如何解决此问题给我提供一般性建议,那么至少应该足以让我确定错误的部分并尝试从那里移开。

【问题讨论】:

你是如何计算骨骼矩阵的?您需要沿着骨架行走并累积您遇到的所有变换。通常,每个骨骼都有一个旋转,然后沿着骨骼平移以到达下一个关节。 @NicoSchertler 这就是我正在做的事情。 【参考方案1】:

旋转矩阵本身只能描述围绕原点的旋转 (Wikipedia)。但是,旋转可以与平移结合使用,以更改原点的位置以获得所需的效果。例如,您可以:

    平移对象,使其以原点为中心 将对象旋转到所需方向 将对象平移回原始位置

或者,用不同但功能相同的方式来表达它:

    将原点移动到对象的位置 将对象旋转到所需方向 将原点重置回其原始位置

相关问题:Rotating an object around a fixed point in opengl

【讨论】:

我知道在正常对象旋转中使用这种方法,但从我在骨骼动画教程中看到的情况来看,这不是通常在那里完成的方式。您将一个矩阵发送到每个骨骼的着色器,然后将顶点(基于它们的权重和分配的骨骼)与之相乘;在任何时候都不会将对象转换为原点。例如,观察这个顶点着色器:github.com/TheThinMatrix/OpenGL-Animation/blob/master/Animation/… 在发送到顶点着色器之前,可以将旋转和平移矩阵相乘成一个通用矩阵。您是通过程序还是其他外部软件编辑模型?我看到的 github 代码似乎直接从输入文件中读取了矩阵。 它们相乘,是的。而且我没有使用任何输入文件,而是在代码本身内部手动创建数据。 好吧,如果您发送的矩阵是旋转矩阵和平移矩阵之间的乘法,我唯一的其他建议可能是切换乘法的顺序。矩阵乘法不可交换,因此rotation * translationtranslation * rotation 不同。看看切换它们是否会产生所需的结果。 嗯,结果改变并围绕不同的点转,但它破坏了翻译(直到现在)。例如,如果父级位于 (3.0, 0.0, 0.0),并且我想旋转子级,如果我希望它保持在同一个位置,我还需要将子级转换为 (3.0, 0.0, 0.0),而不是正确的 (0.0, 0.0, 0.0)(因为孩子的位置应该是相对于父母的)。【参考方案2】:

你只需要注意你正在旋转的东西。

解决此问题的方法:先旋转它,然后再平移它。在对象位于原点时旋转对象,然后将对象平移到您想要的位置。

当整个程序发生变化时,请重复执行此操作。从原点开始对象,进行所需的旋转,然后平移到它的最终静止位置。

【讨论】:

以上是关于OpenGL - 骨骼动画 - 骨骼围绕原点旋转的主要内容,如果未能解决你的问题,请参考以下文章

一步步学OpenGL(38) -《Assimp库实现骨骼蒙皮动画》

带有 Assimp 的 OpenGL (GLSL) 中的骨骼动画

[OpenGL] 骨骼动画混合效果

从中心而不是从左、中旋转

max骨骼脚尖踩不住

android OpenGL渲染带骨骼动画的3D模型