масштабирование перемещает объект - PullRequest
1 голос
/ 30 июня 2019

Видео Ссылка на выпуск.

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 Ответ

3 голосов
/ 01 июля 2019

Объект должен быть ориентирован и расположен следующим образом:

Контрольная точка (pivotx, pivoty, pivotz) - это точка в пространстве объекта.
Объект должен быть масштабирован (scax, scay, scaz) и повернут(rotx, roty, rotz) относительно контрольной точки (pivotx, pivoty, pivotz).
Точка (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;
}
Вращайте масштабированный объект вокруг оси, как в ответе на один из ваших предыдущих вопросов ( Как использовать точку разворота в преобразованиях ):
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;
}
Переместите масштабированный и повернутый объект в конечное положение (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;
...