缩放正在移动对象

时间:2019-06-30 12:51:26

标签: 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

1 个答案:

答案 0 :(得分:3)

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

参考点(pivotx, pivoty, pivotz)是对象空间中的点。
必须相对于参考点(scax, scay, scaz)缩放(rotx, roty, rotz)和旋转(pivotx, pivoty, pivotz)对象。
点(posxposyposz)定义了对象在场景中最终要放置参考点的位置。

执行以下步骤:

  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;