Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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();

   }
share|improve this question

2 Answers 2

up vote 2 down vote accepted

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.

share|improve this answer

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.