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.