c++ - 缩放正在移动对象

标签 c++ opengl glsl glm-math

问题的视频链接。

https://www.youtube.com/watch?v=iqX1RPo4NDE&feature=youtu.be

这就是我想要达到的。

https://www.youtube.com/watch?v=bWwYV0VhXqs

在这里缩放对象后我可以独立移动枢轴,枢轴的位置不会影响对象的位置。

这些是我的矩阵。 当我将轴心点移动到 x 中的一个单位时,如果缩放比例设置为 1,则一切正常。

轴心点移动到一个单位,立方体保持原位。

但是当我第一次将对象缩放到 0.5 然后移动轴心点时,立方体跟随轴心点移动,这不应该是这种情况,因为我只是移动轴心点。

请帮我解决这个问题,我怎样才能将立方体固定到位。

虽然我移动的是轴而不是立方体,所以立方体应该保持在原来的位置。

glm::mat4x4 Container::GetPositionMatrix()
{
    // posx  is the x position of the object.
    // posy  is the y position of the object.
    // posz  is the y position of the object.
    glm::mat4 TransformationPosition = glm::translate(glm::mat4x4(1.0),
    glm::vec3(posx, posy, posz ));
    return TransformationPosition;
}
glm::mat4x4 Container::GetRotationMatrix()
{
    // posx  is the x positon of the object
    // pivotx is the x position on the pivot point
    // rotx is the x rotation of the object
    glm::vec3 pivotVector(posx - pivotx, posy - pivoty, posz - pivotz);
    glm::mat4 TransPivot = glm::translate(glm::mat4x4(1.0f), pivotVector);
    glm::mat4 TransPivotInverse = glm::translate(glm::mat4x4(1.0f), 
    glm::vec3( -pivotVector.x , -pivotVector.y , -pivotVector.z));
    glm::mat4 TransformationRotation(1.0);
    TransformationRotation = glm::rotate(TransformationRotation, 
        glm::radians(rotx), glm::vec3(1.0, 0.0, 0.0));
    TransformationRotation = glm::rotate(TransformationRotation, 
        glm::radians(roty), glm::vec3(0.0, 1.0, 0.0));
    TransformationRotation = glm::rotate(TransformationRotation, 
        glm::radians(rotz ), glm::vec3(0.0, 0.0, 1.0));
    return  TransPivotInverse * TransformationRotation * TransPivot;
}
glm::mat4x4 Container::GetScalingMatrix()
{
    // posx  is the x positon of the object
    // pivotx is the x  position on the pivot point
    // scax is the x scaling of the object
    glm::vec3 pivotVector(posx - pivotx, posy - pivoty, posz - pivotz);
    glm::mat4 TransPivot = glm::translate(glm::mat4x4(1.0f), pivotVector);
    glm::mat4 TransPivotInverse = glm::translate(glm::mat4x4(1.0f),
        glm::vec3(-pivotVector.x, -pivotVector.y, -pivotVector.z));
    glm::mat4 TransformationScale = glm::scale(glm::mat4x4(1.0 ), 
        glm::vec3(scax, scay, scaz));
    return  TransPivotInverse * TransformationScale * TransPivot;
}

对象位置的最终矩阵。

TransformationPosition * TransformationRotation * TransformationScaling

这是我的枢轴点的最终矩阵

 PivotPointPosition = MatrixContainerPosition * MatrixPivotPointPosition * 
 MatrixRotationContainer * MatrixScaleContainer

最佳答案

对象的方向和位置应如下所示:

引用点(pivotx, pivoty, pivotz)是对象空间中的一个点。
对象必须相对于引用点(pivotx、pivoty、pivotz)缩放(scax、scay、scaz)和旋转(rotx、roty、rotz) ).
点 (posx, posy, posz) 定义了对象在场景中的位置,最终要放置引用点的位置。

执行以下步骤:

  1. 相对于引用点将对象缩放到所需大小:
glm::mat4 GetScalingMatrix()
{
    glm::vec3 refVector(pivotx, pivoty, pivotz);

    glm::mat4 TransRefToOrigin   = glm::translate(glm::mat4(1.0f), -refVector);
    glm::mat4 TransRefFromOrigin = glm::translate(glm::mat4(1.0f),  refVector);

    glm::vec3 scale = glm::vec3(scax, scay, scaz);
    glm::mat4 TransformationScale = glm::scale(glm::mat4(1.0), scale);
    return TransRefFromOrigin * TransformationScale * TransRefToOrigin;
}
  1. 围绕轴心旋转缩放对象,就像在回答您之前的一个问题 (How to use Pivot Point in Transformations) 时一样:
glm::mat4 GetRotationMatrix()
{
    glm::vec3 pivotVector(pivotx, pivoty, pivotz);

    glm::mat4 TransPivotToOrigin   = glm::translate(glm::mat4(1.0f), -pivotVector);
    glm::mat4 TransPivotFromOrigin = glm::translate(glm::mat4(1.0f),  pivotVector);

    glm::mat4 TransformationRotation(1.0);
    TransformationRotation = glm::rotate(TransformationRotation, 
        glm::radians(rotx), glm::vec3(1.0, 0.0, 0.0));
    TransformationRotation = glm::rotate(TransformationRotation, 
        glm::radians(roty), glm::vec3(0.0, 1.0, 0.0));
    TransformationRotation = glm::rotate(TransformationRotation, 
        glm::radians(rotz), glm::vec3(0.0, 0.0, 1.0));

    return  TransPivotFromOrigin * TransformationRotation * TransPivotToOrigin;
}
  1. 将缩放和旋转的对象移动到其最终位置(posx, posy, posz)。
glm::mat4 GetPositionMatrix()
{
    glm::vec3 trans = glm::vec3(posx-pivotx, posy-pivoty, posz-pivotz);
    glm::mat4 TransformationPosition = glm::translate(glm::mat4(1.0), trans);
    return TransformationPosition;
}

顺序很重要:

glm::mat4 model = GetPositionMatrix() * GetRotationMatrix() * GetScalingMatrix(); 

所有这些都可以简化:

// translate "pivot" to origin 
glm::mat4 ref2originM = glm::translate(glm::mat4(1.0f), -glm::vec3(pivotx, pivoty, pivotz));        

// scale
glm::mat4 scaleM = glm::scale(glm::mat4(1.0), glm::vec3(scax, scay, scaz));

// rotate
glm::mat4 rotationM(1.0);
rotationM = glm::rotate(rotationM, glm::radians(rotx), glm::vec3(1.0, 0.0, 0.0));
rotationM = glm::rotate(rotationM, glm::radians(roty), glm::vec3(0.0, 1.0, 0.0));
rotationM = glm::rotate(rotationM, glm::radians(rotz), glm::vec3(0.0, 0.0, 1.0));

// translate to "pos"
glm::mat4 origin2posM = glm::translate(glm::mat4(1.0), glm::vec3(posx, posy, posz));

// concatenate matrices
glm::mat4 model = origin2posM * rotationM * scaleM * ref2originM;

关于c++ - 缩放正在移动对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56824983/

相关文章:

c++ - 在 C++11 中将(1 元组到 10 元组)参数转换为 n 元组参数

python - 如何在运行时覆盖 C 函数(如 LD_PRELOAD)?

c++ - 试图引用已删除的函数

c++ - 矩阵类 : error: expected primary-expression before ')' token

javascript - 在 WebGL 着色器中使用 UInt8Array 数据

c++ - OpenGL 3.1 使用索引绘图发布渲染纹理

c++ - 优化 C++ 模板执行

c++ - OpenGL:旋转 90 度后圆柱体变形

python - python 中的 Kivy 模块

android - GLSL ES 局部变量崩溃?