2
\$\begingroup\$

I can't figure out how to perform matrix rotation using Quaternion while taking into account pivot position in OpenGL.What I am currently getting is rotation of the object around some point in the space and not a local pivot which is what I want. Here is the code [Using Java]

Quaternion rotation method:

  public void rotateTo3(float xr, float yr, float zr) {

    _rotation.x = xr;
    _rotation.y = yr;
    _rotation.z = zr;

    Quaternion xrotQ = Glm.angleAxis((xr), Vec3.X_AXIS);
    Quaternion yrotQ = Glm.angleAxis((yr), Vec3.Y_AXIS);
    Quaternion zrotQ = Glm.angleAxis((zr), Vec3.Z_AXIS);
    xrotQ = Glm.normalize(xrotQ);
    yrotQ = Glm.normalize(yrotQ);
    zrotQ = Glm.normalize(zrotQ);

    Quaternion acumQuat;
    acumQuat = Quaternion.mul(xrotQ, yrotQ);
    acumQuat = Quaternion.mul(acumQuat, zrotQ);



    Mat4 rotMat = Glm.matCast(acumQuat);

    _model = new Mat4(1);

   scaleTo(_scaleX, _scaleY, _scaleZ);

    _model = Glm.translate(_model, new Vec3(_pivot.x, _pivot.y, 0));

    _model =rotMat.mul(_model);//_model.mul(rotMat); //rotMat.mul(_model);

    _model = Glm.translate(_model, new Vec3(-_pivot.x, -_pivot.y, 0));


   translateTo(_x, _y, _z);

    notifyTranformChange();
   }

Model matrix scale method: public void scaleTo(float x, float y, float z) {

    _model.set(0, x);
    _model.set(5, y);
    _model.set(10, z);

    _scaleX = x;
    _scaleY = y;
    _scaleZ = z;

    notifyTranformChange();
  }

Translate method: public void translateTo(float x, float y, float z) {

    _x = x - _pivot.x;
    _y = y - _pivot.y;
    _z = z;
    _position.x = _x;
    _position.y = _y;
    _position.z = _z;

    _model.set(12, _x);
    _model.set(13, _y);
    _model.set(14, _z);

    notifyTranformChange();
   }

But this method in which I don't use Quaternion works fine:

  public void rotate(Vec3 axis, float angleDegr) {
    _rotation.add(axis.scale(angleDegr));
    //  change to GLM:
    Mat4 backTr = new Mat4(1.0f);

    backTr = Glm.translate(backTr, new Vec3(_pivot.x, _pivot.y, 0));

    backTr = Glm.rotate(backTr, angleDegr, axis);


    backTr = Glm.translate(backTr, new Vec3(-_pivot.x, -_pivot.y, 0));

    _model =_model.mul(backTr);///backTr.mul(_model);
    notifyTranformChange();

   }
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

The above is the implementation of the world rotation matrix using OpenTK.

Matrix4    m_worldMatrix;
Quaternion m_rotation;
Vector3    m_scale;
Vector3    m_translation;

void RotateBy(float radians, Vector3 rotation_axis)
{
    GL.MatrixMode(ModelView);

    m_rotation = Quaternion.FromAxisAngle(rotation_axis, radians) * m_rotation;   

    m_worldMatrix = Matrix4.Scale(m_scale) *
                    Matrix4.Rotate(m_rotation) *
                    Matrix4.CreateTranslation(m_translation); 

    GL.MultMatrix(ref m_worldMatrix); 
}

Notice that you must always multiply the world matrix in this order: Scale * Rotate * Translate. I hope this helps.

\$\endgroup\$
0
\$\begingroup\$

Is the point in space that is used for the rotation known to you? Or can you find out what point it is?

If you can find this point do a translation from that point to your local point, then do the rotation and after that do a translation back.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .