[Semi-Solved] Bone Pitch problem | Quaternion flipping

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
Mind Calamity
Ogre Magi
Posts: 1255
Joined: Sat Dec 25, 2010 2:55 pm
Location: Macedonia
x 81

[Semi-Solved] Bone Pitch problem | Quaternion flipping

Post by Mind Calamity »

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:
[youtube]IwUpzEE3uwI[/youtube]
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.
BitBucket username changed to iboshkov (from MindCalamity)
Do you need help? What have you tried?
- xavier
---------------------
HkOgre - a Havok Integration for OGRE | Simple SSAO | My Blog | My YouTube | My DeviantArt
User avatar
Daixiwen
Greenskin
Posts: 105
Joined: Fri Feb 08, 2013 11:30 am
Location: Oslo
x 16

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

Post by Daixiwen »

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.
Syniurge
Halfling
Posts: 40
Joined: Thu Aug 30, 2012 1:43 pm
Location: France
x 3

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

Post by Syniurge »

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.
User avatar
Mind Calamity
Ogre Magi
Posts: 1255
Joined: Sat Dec 25, 2010 2:55 pm
Location: Macedonia
x 81

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

Post by Mind Calamity »

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:

[youtube]6bdFhW_vtUs[/youtube]

Any ideas on how to fix this ?
BitBucket username changed to iboshkov (from MindCalamity)
Do you need help? What have you tried?
- xavier
---------------------
HkOgre - a Havok Integration for OGRE | Simple SSAO | My Blog | My YouTube | My DeviantArt
Post Reply