Well, I've finally managed to do it but that was painful. And to be honest I still don't understand everything.
The code that worked was:
var scale = 2000;
quat.multiply(Q, Q, [Math.sin(Pitch/scale), 0, 0, Math.cos(Pitch/scale)]);
quat.multiply(Q, Q, [ 0, Math.sin(Yaw/scale), 0, Math.cos(Yaw/scale)]);
quat.multiply(Q, Q, [ 0, 0, Math.sin(Roll/scale), Math.cos(Roll/scale)]);
mat4.fromRotationTranslation(mvMatrix, Q, [0.0, 0.0, 200.0]);
That was after I realized I should store the orientation of the ship in a global quaternion variable.
Before that I tried something which I thought was the same :
var scale = 2000;
quat.multiply(Q, Q, [Math.sin(Pitch/scale), 0, 0, Math.cos(Pitch/scale)]);
quat.multiply(Q, Q, [ 0, Math.sin(Yaw/scale), 0, Math.cos(Yaw/scale)]);
quat.multiply(Q, Q, [ 0, 0, Math.sin(Roll/scale), Math.cos(Roll/scale)]);
mat4.fromQuat(mvMatrix, Q);
mat4.translate(mvMatrix, [0.0, 0.0, 0.0, 200.0];
But no, apparently it's different. The center of rotation keeps being the origin, not the ship.
