OpenGL - glm平移和缩放组合

3
我有一个程序,在其中显示一个对象。 首先我从文件中加载位置p.x,p.y,p.z和比例s.x,s.y,s.z。 然后我将它们应用于4x4 ModelMatrix,并对其执行许多平移和缩放操作。
当我第一次加载对象时,我使用p和s的值:
modelMatrix = glm::mat4(1.0));

/*Translations*/
modelMatrix = glm::translate(modelMatrix, glm::vec3(p.x, p.y, p.z));
modelMatrix = glm::scale(modelMatrix, glm::vec3(s.x, s.y, s,z));

在程序中,我进行了缩放和平移操作,然后将p和s值保存回文件。

void Display::Translate( double x, double y, double z)
{
    modelMatrix = glm::translate(modelMatrix, glm::vec3(x,y,z));
    p.x += x;   //that way p is composition of all translations
    p.y += y;
    p.z += z;
} 

void Display::Scale( double x, double y, double z)
{
    modelMatrix = glm::scale(modelMatrix, glm::vec3(x,y,z));
    s.x *= x;    //that way s is composition of all scalings
    s.y *= y;
    s.z *= z;
}

现在的问题是,重新加载程序后,对象不会出现在我保存它们的位置,而是一些随机的位置。(特别是翻译) 我是否错误地组合了变换 (在平移中添加x、y、z,在缩放中乘以)?

2
我不确定你到底是在保存什么并从文件中加载,因为你没有告诉我们 - 很有可能你的错误就在那里 - 但也值得指出的是,变换不是可交换的 - 如果你先进行平移再进行缩放,结果通常会与先进行缩放再进行平移的结果不同。如果你想将变换保存到文件中,请保存完整的变换矩阵,而不是所有平移的总和和所有缩放的总和。 - Cubic
1个回答

3

我在组合变换时是不是用错了方法(在平移中加上x、y、z,在缩放中乘以)?

是的,这是错误的,因为您的平移实际上也被缩放了。更好的方法是从模型矩阵中提取比例和平移。平移可以在w列(最右侧列)中找到,而比例可以在左上角的3×3子矩阵中找到;平凡的情况只是对角线元素,但如果应用了旋转,则必须确定主轴(https://en.wikipedia.org/wiki/Principal_axis_theorem),或者只需通过获取列向量的长度来确定比例。


是的,还有旋转。我想我只需要存储modelMatrix(16个数字而不是10个/包括比例、位移和四元数旋转)即可。 - Yurkee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接