Quaternion based rotation and pivot position

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

   }

It seems to me you take into account the back and forth translation before and after the rotation already. Why that final call of translateTo?

Besides, when you rotate, a pure rotation is always meant around the origin. So if you want a rotation around your pivot point. I'd exptect to translate your pivot point to the origin, then rotate, then translate back to the pivot would be the right thing to do. Therefore, I'd expect your code to look like this:

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

and without the call translateTo(_x, _y, _z); . Also, can you confirm that the rotation part already does what it supposed to? You can check this by comparing rotMat with Glm.rotate(new Mat4(1.0f), angleDegr, axis) . They should be the same for the same rotation.


A quaternion describes only a rotation. As a result how do you want to rotate something around a pivot point with only a quaternion?

The minimum that you need is a R3 vector and a quaternion. With only one level of transformation you first roatate the object and then move it there.

If you want to create a matrix you first create the ration matrix and then add the translation unaltered.

If you want to just call glTranslate and glRotate (or glMultMatrix) you would first call glTranslate and then glRoatate.

Edit:

If you are not rendering and just want to know where each vertex is:

Vector3 newVertex = quat.transform(oldVertex) + translation;
链接地址: http://www.djcxy.com/p/81818.html

上一篇: 触摸结束后旋转iOS OpenGL ES 2.0 GLKit GLKMatrix4

下一篇: 基于四元数的旋转和枢轴位置