How to apply / search for global / local transformations in OpenGL

5

I'm programming a simple Game Engine using the OpenGL graphics API. But I have a problem that I can not solve. The problem is that the transformations in the world (world) do not work correctly. The scale transformations are normal, but the translation and rotation are the problem.

For example, if I move the camera locally and then rotate it globally on the Y axis (axis pointing up) and locally on the X axis (a simple mouse look), the camera starts rotating as a pivot having the its center of origin where it was created.

Each object / entity in the Engine has a base class HTransform , which serves to rotate / move / scale global / local (local, along its own axis).  And it has a function to update the transformation matrix. After doing the transformations I apply the array m_WorldTransform . In the camera array I use glLoadMatrixf , and on glMultMatrixf objects.

// C++ - Resumo da classe HTransform

void setWorldPosition(const HVec3f& pos);
Hvec3f getWorldPosition() const;
// Ect......

HVec3f m_WorldPosition;
HQuaternion m_WorldOrientation;
HVec3f m_WorldScaling;

HVec3f m_LocalPosition;
HQuaternion m_LocalOrientation;
HVec3f m_LocalScaling;

HMatrix4 m_WorldTransform;
HMatrix4 m_LocalTransform;

void HTransform::updateTransform()
{
    m_WorldTransform.setRotationAxis(m_WorldOrientation.getAngle(), m_WorldOrientation.getAxis());
    m_WorldTransform.translate(m_WorldPosition);
    m_WorldTransform.scale(m_WorldScaling);

    m_LocalTransform.setRotationAxis(m_LocalOrientation.getAngle(), m_LocalOrientation.getAxis());
    m_LocalTransform.translate(m_LocalPosition);
    m_LocalTransform.scale(m_LocalScaling);

    m_WorldTransform = m_WorldTransform * m_LocalTransform;// * m_WorldTransform.getInverse();

    m_NeedTransformUpdate = false;
}

The camera also has the base class HTransform .

// C++ - Resumo da classe HCamera
HMatrix4 m_MatView;
HMatrix4 m_MatProjection;

void HeCamera::updateViewMatrix()
{
    //this->updateTransform();

    m_WorldTransform.setRotationAxis(m_WorldOrientation.getAngle(), m_WorldOrientation.getAxis());
    m_WorldTransform.translate(m_WorldPosition);
    m_WorldTransform.scale(m_WorldScaling);

    m_LocalTransform.setRotationAxis(m_LocalOrientation.getAngle(), m_LocalOrientation.getAxis());
    m_LocalTransform.translate(m_LocalPosition);
    m_LocalTransform.scale(m_LocalScaling);

    m_WorldTransform = m_WorldTransform * m_LocalTransform;

    m_MatView = m_WorldTransform.invert();
    m_NeedTransformUpdate = false;
}

As you can see, each object will use two arrays, one for global transformations and one for local transformations. But I just wanted to use one, but I do not know how to do it.

upload a demo to better visualize the problem. The controls are W, A, S, D, Q, and E for the movements and the mouse to control the orientation of the camera (a MouseLook).

The demo contains a script_test.lua file that, from line 75, is the part that controls the orientation / rotation of the camera.

What am I doing wrong?

    
asked by anonymous 20.04.2014 / 15:00

1 answer

2

At first glance, there is a particularity in the order in which you are applying two transformations:

  

m_WorldTransform.translate (m_WorldPosition);

     

m_WorldTransform.scale (m_WorldScaling);

If you move first, and resize later, the translation will be affected by resizing. For example, if you move +10 on the X-axis, and then resize the X-axis by 0.5, you have effectively reduced the size of the X-object to half, and moved only +5 in the X- / p>

This is because all transformations are based on the origin of the space (0, 0, 0). The same thing happens with rotation, and all other linear transformations.

If you want to test these transformations, and you have a browser that supports WebGL, you can use an online interactive material that I make available to my college students: WebGL - Matrices and Linear Transformations Home .

Take the following test:

Create a translation (10, 0, 0), then add a resize (50%, 100% 100%). Select the last item in the list and click "Animate step by step". Then reverse the order of translation and resizing, select the last item in the list and click "Animate step by step".

With this you can feel the difference visually.

    
05.05.2014 / 16:24