Mapping user input to rotation without order/gimbol problems
I know this has been addressed before but the past posts seem to be geared toward cameras. So here is exactly what I would like to do and the problem I am having. Any help would be GREATLY appreciated.
I am attempting to apply user control to a spaceship. I am having the well discussed problem of gimbol lock. I want a user to be able to rotate the ship using pitch, roll, and yaw. When the user pitches up, the rotation needs to be in relation to the ship. I understand the problem of rotation order.
I have tried to use Quaternions but of course when I convert from pitch, roll, yaw to the quat, I get the same effects.
How do you map user input to a Quaternion? Or, how do I map the current pitch, roll, and yaw of the ship to the model in a way that allows each axis to relate to it''s peer on the model, effectivly applying xyz rotation simultainiously from an origin.
It is important to my applicaiton to know the exact rotation of the model at all times so simply appying rotations continuosly to a matrix doesn''t work well for that.
I hope you understand what I am asking. I need to map that user input to the object.
Thanks
> How do you map user input to a Quaternion?
Each frame generate a rotation quaternion for each axis in the spaceship''s frame of reference. E.g. for pitch do
QUAT qPitch = qFromAngleAxis(t * angvel, pitchAxis)
t = time step
ang vel = rotational speed in radians per second about axis
pitchAxis = whatever axis you rotate about in your frame of reference when pitching (e.g. if it''s the x axis then use {1, 0, 0}
Repeat this for all rotations taking place, then multiply them to produce the rotation quaternion for the motion. Then multiply the spaceship rotation quaternion by this.
There are two things to watch out for in doing this. First make sure the time step is small enough, so that t * angvel is a small angle. If the angle is too big this becomes inaccurate: very big and you get gimbal-lock type problems. If this is a problem subdivide the interval. E.g. if your time step of 0.1 sec is too big try doing it twice with 0.05 sec instead.
Second for small angles the order the rotations are combined is not important, but the order the combination of them is multiplied with the spaceship rotation is. E.g. you can do
qSpaceship = qSpaceship * qRot
or
qSpaceship = qRot * qSpaceship
but only one is correct. Which depends on the order in which you combine quaternions, and it''s the opposite order of the order of an externally applied rotation. If you are not sure try both and see which works.
> It is important to my applicaiton to know the exact rotation
> of the model at all times so simply appying rotations
> continuosly to a matrix doesn''t work well for that.
I doubt it''s possible. If the rotation were about a single axis you could just sum the angle over time, but if the user is allowed to rotate freely about two or three axes it''s not possible to predict how the rotations will accumulate, unless the user input is very simple (e.g. constant). The only way is to work it out by going through the time steps.
Each frame generate a rotation quaternion for each axis in the spaceship''s frame of reference. E.g. for pitch do
QUAT qPitch = qFromAngleAxis(t * angvel, pitchAxis)
t = time step
ang vel = rotational speed in radians per second about axis
pitchAxis = whatever axis you rotate about in your frame of reference when pitching (e.g. if it''s the x axis then use {1, 0, 0}
Repeat this for all rotations taking place, then multiply them to produce the rotation quaternion for the motion. Then multiply the spaceship rotation quaternion by this.
There are two things to watch out for in doing this. First make sure the time step is small enough, so that t * angvel is a small angle. If the angle is too big this becomes inaccurate: very big and you get gimbal-lock type problems. If this is a problem subdivide the interval. E.g. if your time step of 0.1 sec is too big try doing it twice with 0.05 sec instead.
Second for small angles the order the rotations are combined is not important, but the order the combination of them is multiplied with the spaceship rotation is. E.g. you can do
qSpaceship = qSpaceship * qRot
or
qSpaceship = qRot * qSpaceship
but only one is correct. Which depends on the order in which you combine quaternions, and it''s the opposite order of the order of an externally applied rotation. If you are not sure try both and see which works.
> It is important to my applicaiton to know the exact rotation
> of the model at all times so simply appying rotations
> continuosly to a matrix doesn''t work well for that.
I doubt it''s possible. If the rotation were about a single axis you could just sum the angle over time, but if the user is allowed to rotate freely about two or three axes it''s not possible to predict how the rotations will accumulate, unless the user input is very simple (e.g. constant). The only way is to work it out by going through the time steps.
Thank you very much. That explains MUCH!
Since you seem to understand this stuff well, I''d like to ask an additional question.
I am also attempting to do this rotation via a different method but am having a problem. (I will still probably use the quat but would like to understand)
I have established 3 vectors to represent the three degrees of rotation. They are as follows. forwardv[1, 0, 0] rightv[0,1,0] upv[0,0,1].
I have applied rotation to these vecors as follows.
For an x rotation.
1. Create a rotation matrix with appropriate x rotation delta.(rm)
2. fv = fv(rm)
3. uv = rv -cross- fv
4. rv = uv -cross- fv
This has the effect of keeping the vecors in the correct orientation to each other after rotation. Then I can apply an y or z rotation in the same way and it will be applied correctly reletive to the new ''plane'' of the model.
Question: The vectors rotate perfectly, but I can''t figure out how to take those three vectors and turning them into a matrix that will rotate the model to the correct position in the world..
make sense? I hope so because I''d like to understand this a little better.
Thanks
Since you seem to understand this stuff well, I''d like to ask an additional question.
I am also attempting to do this rotation via a different method but am having a problem. (I will still probably use the quat but would like to understand)
I have established 3 vectors to represent the three degrees of rotation. They are as follows. forwardv[1, 0, 0] rightv[0,1,0] upv[0,0,1].
I have applied rotation to these vecors as follows.
For an x rotation.
1. Create a rotation matrix with appropriate x rotation delta.(rm)
2. fv = fv(rm)
3. uv = rv -cross- fv
4. rv = uv -cross- fv
This has the effect of keeping the vecors in the correct orientation to each other after rotation. Then I can apply an y or z rotation in the same way and it will be applied correctly reletive to the new ''plane'' of the model.
Question: The vectors rotate perfectly, but I can''t figure out how to take those three vectors and turning them into a matrix that will rotate the model to the correct position in the world..
make sense? I hope so because I''d like to understand this a little better.
Thanks
> Question: The vectors rotate perfectly, but I can''t figure
> out how to take those three vectors and turning them into a
> matrix that will rotate the model to the correct position in
> the world..
If I understand you the answer is almost trivial: just write your three rotated vectors into the three columns of a matrix, in the correct order (x then y then z).
Because a rotation matrix should be special orthogonal the three vectors should be unit vectors and perpendicular to each other, but I think your maths ensures this: if not normalise them first.
> out how to take those three vectors and turning them into a
> matrix that will rotate the model to the correct position in
> the world..
If I understand you the answer is almost trivial: just write your three rotated vectors into the three columns of a matrix, in the correct order (x then y then z).
Because a rotation matrix should be special orthogonal the three vectors should be unit vectors and perpendicular to each other, but I think your maths ensures this: if not normalise them first.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement