Jump to content
  • Advertisement
Sign in to follow this  
lexington

Help with Quaternion rotation (6DOF)

This topic is 848 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I am currently trying to create a space combat game and am currently working on the players movement (as well as the camera) but I have run into a problem with doing the rotation for the player.

 

The main goal is to have 6 degrees of freedom for the player but I am currently just working on yaw and pitch. I am using the mouse to control the rotation with mouse up and down changing pitch and mouse left and right controlling yaw. For this I have been trying to understand Quaternion and am currently using the axis angle method (with the glm library)  but I have hit a problem.

 

I'm not sure if this is to do with a lack of understanding or some other factor,

 

Currently I can just change the pitch and yaw of the ship perfectly fine but say for example I was to have a pitch change of 90 degrees (so the ship was looking up) and was the to try and change the yaw of the ship, what would happen is the roll of the ship would change instead. the opposite would happen with the yaw being 90 degrees and then changing the pitch. 

 

It feels like I'm not understanding something or maybe my code is incorrect. Any help with the problem or understanding more about Quaternion would be very appreciated.

 

code for creating the axis change

 ynewquat = glm::quat();
 xnewquat = glm::quat();


    if(currentmouse.x < 540)
     {
       int rotate = -(540 - currentmouse.x);
       glm::quat tempquad = glm::angleAxis((rotate * 0.002f) * deltaTs,glm::vec3(0,1,0));
       xnewquat = tempquad;
     }
     if(currentmouse.x > 740)
     {
       int rotate = (currentmouse.x - 740);
        glm::quat tempquad = glm::angleAxis((rotate * 0.002f) * deltaTs,glm::vec3(0,1,0));
        xnewquat = tempquad;
     }
     if(currentmouse.y > 400)
     {
        int rotate = (currentmouse.y - 400);
        glm::quat tempquad = glm::angleAxis((rotate * 0.005f) * deltaTs,glm::vec3(1,0,0));
        ynewquat = tempquad;
        std::cout<<rotate<<'\n';
     }
     if(currentmouse.y < 320)
     {
       int rotate = -(320 - currentmouse.y);
       glm::quat tempquad = glm::angleAxis((rotate * 0.005f) * deltaTs,glm::vec3(1,0,0));
       ynewquat = tempquad;
       std::cout<<rotate<<'\n';
     }

     newquat = xnewquat * ynewquat;
		
     player->Update(deltaTs,newquat);

Then in the player update function

void Gamemodelimported::Update(float deltaTs, glm::quat rotation)
{

  currentrotation = rotation * currentrotation;

  temp = currentrotation * direction;

   glm::vec3 tempvel = temp * speed * deltaTs;
  position += tempvel * deltaTs;

  glm::mat4 RotationMatrix = glm::toMat4(currentrotation);
   glm::mat4 translationmatrix = glm::translate(glm::mat4(1.0f), position);

   _modelMatrix = translationmatrix * RotationMatrix;

}

Share this post


Link to post
Share on other sites
Advertisement
I am not sure what the difference is between roll and yaw when the ship is looking straight up.

There are two common situations when people try to program 3D rotations for the first time:
* They mess up the order in which rotations are applied.
* They think their code doesn't work, but it's really their understanding of 3D rotations that has issues.

I suspect you are in the latter category, but I am not sure.

Share this post


Link to post
Share on other sites

I am not sure what the difference is between roll and yaw when the ship is looking straight up.

 

ill try to give a deeper explanation of what I mean

 

say for this example the camera is looking down at a pyramid

 

if I was to change the yaw of the shape (in other words construct a quad with an axis of (0,1,0) by an angle and times it to my objects quad) it will turn to look left and right (depending what side my mouse is on).

 

Then say I have applied a quad to the objects orientation (with an angle of 90 around axit (1,0,0)) so it is looking at the camera. so now if i was to apply a quad with an angle in the y axis (0,1,0) it will twirl rather then rotate left of right

 

 

Is this me misunderstanding how applying axis of rotation works or is there something else going wrong?

Share this post


Link to post
Share on other sites
Yes, I think there is some misunderstanding. A sequence of rotations around the X axis and the Y axis can result in a rotation around the Z axis, and this is surprising to a lot of people.

If you want your code to control pitch and yaw, keep track of pitch and yaw separately and then build your rotation from them every frame.

Share this post


Link to post
Share on other sites

If you want your code to control pitch and yaw, keep track of pitch and yaw separately and then build your rotation from them every frame.

 

so rather then continuously applying new quaternions to the objects quaternions, it would be best to store the rotation (in say a vec3) and then construct a new quad each time.

 

I have added this change (i believe) but now the object is twitching a lot, am I missing a component to make it sleeker

 

new code

 if(currentmouse.x < 540)
     {
       rotation.y += -(540 - currentmouse.x);
     }
     if(currentmouse.x > 740)
     {
       rotation.y += -(540 - currentmouse.x);
     }
     if(currentmouse.y > 400)
     {
        rotation.x += (currentmouse.y - 400);
     }
     if(currentmouse.y < 320)
     {
       rotation.x += -(320 - currentmouse.y);
     }
		
     player->Update(deltaTs,rotation);
void Gamemodelimported::Update(float deltaTs, glm::vec3 rotation)
{
	
  //glm::quat tempquad = glm::angleAxis((-300.0f * 0.005f) * deltaTs,glm::vec3(0,1,0));
  //glm::quat tempquad2 = glm::angleAxis((-500.0f * 0.001f) * deltaTs,glm::vec3(1,0,0));



  glm::quat xrotation = glm::angleAxis((rotation.x * 0.005f) * deltaTs,glm::vec3(1,0,0));
  glm::quat yrotation = glm::angleAxis((rotation.y * 0.002f) * deltaTs,glm::vec3(0,1,0));


  currentrotation = glm::quat();
  currentrotation = xrotation * yrotation;

  temp = currentrotation * direction;

   glm::vec3 tempvel = temp * speed * deltaTs;
  position += tempvel * deltaTs;

  glm::mat4 RotationMatrix = glm::toMat4(currentrotation);
   glm::mat4 translationmatrix = glm::translate(glm::mat4(1.0f), position);

   _modelMatrix = translationmatrix * RotationMatrix;

 
}
Edited by lexington

Share this post


Link to post
Share on other sites

I do still have a problem though, it seems that i have fix the fail where if u face the camera then rotate by y axis then it rolls but the other way does not work.

 

If i switch the order around so instead of 

 

  currentrotation = xrotation * yrotation;

 

i do

 

  currentrotation = yrotation * xrotation;

 

it just leads to the opposite problem 

 

Im confused on how i build a rotation off theses that does not lead to one of these problems?

 

Currently doing 

glm::quat xrotation = glm::angleAxis((rotation.x),glm::vec3(1,0,0));
glm::quat yrotation = glm::angleAxis((rotation.y),glm::vec3(0,1,0));

currentrotation = xrotation * yrotation;
Edited by lexington

Share this post


Link to post
Share on other sites
Your code seems correct now, and I don't quite understand what you mean by "but the other way doesn't work" or by "the opposite problem".

Share this post


Link to post
Share on other sites

arr i seem to have got this working by doing

 

currentrotation = currentrotation  * xrotation * yrotation;

 

 

Rotating about global axes is rarely a good idea when it comes to spaceships. Are you sure you shouldn't be rotating about the ship's local axes instead?I

 

I thought the fact that i construct the rotation matrix first and apply it in the correct order means i had done a local rotation on the ships axes, is this incorrect?

Edited by lexington

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!