Set orientation (up vector) to normal vector of ground below

Senzin

19-12-2012 11:14:55

I want to orient and object so that it's standing flat on the surface it's standing on, regardless of the orientation of that surface. Basically, imagine an astronaut in space walking up a wall, they would appear horizontal to someone standing on the floor. Or imagine someone walking down a hill, their shoes would be rotated to rest flat against the hill. That's what I'm trying to achieve.

Here is what I have at the moment. You'll notice I'm using a mix of Ogre and NxOgre objects. This is because the Ogre versions have some functions that I need. I'd love to know their equivalents in NxOgre.

I'm trying to do this by doing a Raycast through the object's Down vector. The Raycast will hit whatever the object is standing on and return with the Normal. That Normal is what I want to be the object's new Up vector. So I get the object's currect Forward vector and cross it with the Normal vector to get the new Right vector. Then I create a Quaternion from that. I then simply set the objects orientation to that Quaternion.


NxOgre::Quat q1 = mBody->getGlobalOrientationQuat();
Ogre::Quaternion q2(q1.w, q1.x, q1.y, q1.z);
NxOgre::Ray ray;
ray.mOrigin = mBody->getGlobalPosition();
ray.mDirection = q2 * Vector3::NEGATIVE_UNIT_Y;
NxOgre::RaycastHit hit = mScene->raycastClosestShape(ray, NxOgre::Enums::ShapesType_Static);
Ogre::Vector3 forward = q2.zAxis();
Ogre::Vector3 up(hit.mWorldNormal.x, hit.mWorldNormal.y, hit.mWorldNormal.z);
Ogre::Vector3 right = forward.crossProduct(up);
Ogre::Quaternion quat(right, up, forward);
mBoxy->setGlobalOrientation(NxOgre::Quat(quat));


Normal (-0.276, 0.961, 0.000)
Forward (0.000, 0.000, 1.000)
Up (-0.276, 0.961, 0.000)
Right (-0.961, -0.276, 0.000)
Quaternion (0.707, 0.000, 0.000, 0.000)

Here you can see the values when the object is on a ramp which slopes up as it goes in the positive x direction. The Normal is clearly pointing mostly up and a little to the negative x. Forward is pointing in the positive z. Up is the same as the Normal. And Right is pointing mostly to the negative x and a little to the negative y. Those all look correct.

The Quaternion, however, is unchanged from when it was on the ground plane or any other surface. No matter what I put it on, it just stays like that.

So why doesn't the Quaternion change? And is there a better way to do this (I hope, I hope)?

Edit: It just occurred to me that even if that code worked, it still isn't quite right. The Forward vector isn't being affected by the Up vector, which of course is wrong if the object was facing the ramp instead of looking sideways from it. So I'm back to "is there a better way to do this (I hope, I hope)?"

Senzin

28-12-2012 10:38:56

See solution on main forums: http://www.ogre3d.org/forums/viewtopic.php?f=5&t=75861