[Semi-Solved] Bone Pitch problem | Quaternion flipping

Problems building or running the engine, queries about how to use features etc.

[Semi-Solved] Bone Pitch problem | Quaternion flipping

Postby Mind Calamity » Mon Jun 17, 2013 4:13 pm

Hello guys, I've been trying to get my character to look at where the crosshair is pointing, and for that I need to manually control my hips bone, I do so like this:

Code: Select all
      // mDirection is the direction of the character
      Vector3 boneDir = getBoneWorldOrientation(mEntity, mHips) * mDirection;
      // This is the direction of the crosshair
       Vector3 dir = mCameraTrans->_getDerivedDirection();
      Quaternion rot = boneDir.getRotationTo(dir);

      // The code below has been taken from the sinbad character controller and adapted to pitch, instead of yaw
      Real pitchToGoal = rot.getPitch().valueDegrees();
       Real pitchAtSpeed = pitchToGoal / Ogre::Math::Abs(pitchToGoal) * timeSinceLastUpdate * 100.0f;
      if (pitchToGoal < 0) pitchToGoal = std::min<Real>(0, std::max<Real>(pitchToGoal, pitchAtSpeed)); //yawToGoal = Math::Clamp<Real>(yawToGoal, yawAtSpeed, 0);
      else if (pitchToGoal > 0) pitchToGoal = std::max<Real>(0, std::min<Real>(pitchToGoal, pitchAtSpeed)); //yawToGoal = Math::Clamp<Real>(yawToGoal, 0, yawAtSpeed);
       mHips->pitch(Degree(pitchToGoal));


Unfortunately I'm not that good with Vector/Quaternion math, and I get the following bug:

It seems to work properly on +Z, it's shaking a bit on -Z, and it just continues to rotate on +X/-X.

I hope someone can help. :)

EDIT: I've sorta fixed this, see my second post.
Also, I've mirrored my topic to GameDev.net, you can find the topic here: http://www.gamedev.net/topic/644417-vec ... on-vector/
Last edited by Mind Calamity on Wed Jun 19, 2013 12:35 am, edited 2 times in total.
User avatar
Mind Calamity
Ogre Magi
 
Posts: 1207
Kudos: 78
Joined: 25 Dec 2010
Location: Macedonia

Re: Help with Quaternion/Vector math - bone pitch to directi

Postby Daixiwen » Tue Jun 18, 2013 9:53 am

To help debug your code, could you try and printout the contents of the boneDir and dir vectors, to check that they have the expected values? Either by printing something on the hud or have your code regularly print them on the console.
User avatar
Daixiwen
Kobold
 
Posts: 32
Kudos: 6
Joined: 08 Feb 2013
Location: Oslo

Re: Help with Quaternion/Vector math - bone pitch to directi

Postby Syniurge » Tue Jun 18, 2013 6:24 pm

Any reason why you are changing the pitch only and not the yaw?

Something like:
Code: Select all
      // mDirection is the direction of the character
      Vector3 boneDir = getBoneWorldOrientation(mEntity, mHips) * mDirection;
      // This is the direction of the crosshair
      Vector3 dir = mCameraTrans->_getDerivedDirection();
      Quaternion rot = boneDir.getRotationTo(dir);

      Vector3 rotAxis;
      Degree rotAngle, minAngle, maxAngle;
      rot.ToAngleAxis(rotAngle, rotAxis);  // rotAngle is set somewhere between 0 and 360 by ToAngleAxis()
      if (rotAngle.valueDegrees() <= 180.0f) {
        minAngle = 0.0f; maxAngle = rotAngle;
        rotAngle = 1.0f;
      } else {
        minAngle = rotAngle - 360.0f; maxAngle = 0.0f;
        rotAngle = -1.0f;
      }

      rotAngle *= timeSinceLastUpdate * 100.0f;
      mHips->rotate(Quaternion(Radian(Math::Clamp(rotAngle, minAngle, maxAngle)), rotAxis));

should orientate your bone towards dir.
Syniurge
Gnoblar
 
Posts: 23
Kudos: 3
Joined: 30 Aug 2012
Location: France

Re: [Semi-Solved] Bone Pitch problem | Quaternion flipping

Postby Mind Calamity » Wed Jun 19, 2013 12:31 am

Thanks alot for the replies.

Unfortunately, Syniurge your code didn't work, it was just rotating again, except now it was rotating in all directions and not keeping to the proper direction at all.

I've kinda solved this myself by adapting the Camera::setDirection code from OGRE to work for my need:

Now I have the following code:

Code: Select all
   Vector3 boneDir = getBoneWorldOrientation(mEntity, mHips) * Vector3::UNIT_Z; //mDirection;
   Vector3 dir = mCameraTrans->_getDerivedDirection();

   Vector3 zAdjustVec = dir;
   zAdjustVec.normalise();

   Quaternion targetWorldOrientation;

   Vector3 xVec = Vector3::UNIT_Y.crossProduct(zAdjustVec);
   xVec.normalise();

   Vector3 yVec = zAdjustVec.crossProduct(xVec);
   yVec.normalise();

   targetWorldOrientation.FromAxes(xVec, yVec, zAdjustVec);

   // mTransform is basically the SceneNode of the character, I'm multiplying the target orientation with it's inverse orientation to get it to parent/character-space.
   mHips->_setDerivedOrientation(mTransform->_getDerivedOrientation().Inverse() * targetWorldOrientation);


The above code was taken from OgreCamera.cpp, the setDirection function, the part with the fixed yaw axis.
Now, that works... Sorta, I now get this problem at near-90 degree pitch, the orientation kind of flips to the other side, I've made another video to showcase this:



Any ideas on how to fix this ?
User avatar
Mind Calamity
Ogre Magi
 
Posts: 1207
Kudos: 78
Joined: 25 Dec 2010
Location: Macedonia


Return to Help

Who is online

Users browsing this forum: Google [Bot], Google Adsense [Bot] and 18 guests