SFAOK
10-05-2007 22:14:30
So I've got this skeleton that I have imported from 3DS Max.

I am trying to convert the skeleton into an articulated one, using OgreNewt Custom Joints. Simple right?
I've spent a week+ trying to get this to work, I get the feeling I'm going round in circles!

Above you can see that I've sort of got it working. The joints hinge along the Z-axis (red), with X-axis being blue and Y-axis green. It works very well.
However, the system only behaves as it should when the imported skeleton is aligned like the first screenshot here:

If I rotate it, like the second image, the joints don't orientate properly!
Can anyone help me here (oh god please)? I've been staring at the ragdoll and prebuilt custom joint examples for hours, but I just can't see an obvious problem!
Here's how I create the bones + joints :
The CustomJoint constructor :
And the contents of submitConstraint() :
I am trying to convert the skeleton into an articulated one, using OgreNewt Custom Joints. Simple right?
I've spent a week+ trying to get this to work, I get the feeling I'm going round in circles!
Above you can see that I've sort of got it working. The joints hinge along the Z-axis (red), with X-axis being blue and Y-axis green. It works very well.
However, the system only behaves as it should when the imported skeleton is aligned like the first screenshot here:
If I rotate it, like the second image, the joints don't orientate properly!
Can anyone help me here (oh god please)? I've been staring at the ragdoll and prebuilt custom joint examples for hours, but I just can't see an obvious problem!
Here's how I create the bones + joints :
for (int x=1;x<numBones-1;x++)
{
//Get parent and child Positions
Vector3 curr = mLegBones[x]->_getDerivedPosition() * mLegScale;
Vector3 next = mLegBones[x+1]->_getDerivedPosition() * mLegScale;
//get vector difference between parent and child
Vector3 difference = next-curr;
Vector3 forward = difference.normalisedCopy();
//Get bone Orientation and re-align
Quaternion new_orient = mLegBones[x]->getWorldOrientation();
//length of bone
size = Vector3(difference.length(), 1, 1);
//mid point of bone
pos = curr + (forward * (difference.length() * 0.5));
// make the next box.
child[x] = makeSimpleBox(size, pos, new_orient);
child[x]->setCustomForceAndTorqueCallback<OgreNewtonApplication>(&OgreNewtonApplication::defaultCallback, this );
// make the joint right between the bodies...
Vector3 axis = new_orient.zAxis();
joint[x] = new myCustomJoint(mSceneMgr, child[x], parent, curr, axis);
joint[x]->setCollisionState(0);
// save the last body for the next loop!
parent = child[x];
}
The CustomJoint constructor :
myCustomJoint::myCustomJoint(OgreNewt::Body* child, OgreNewt::Body* parent, Ogre::Vector3 point, Ogre::Vector3 pin) : OgreNewt::CustomJoint( 6, child, parent)
{
pinAndDirToLocal(point, pin, mLocalOrient0, mLocalPos0, mLocalOrient1, mLocalPos1 );
}
And the contents of submitConstraint() :
// get globals.
Ogre::Vector3 globalPos0, globalPos1;
Ogre::Quaternion globalOrient0, globalOrient1;
localToGlobal( mLocalOrient0, mLocalPos0, globalOrient0, globalPos0, 0 );
localToGlobal( mLocalOrient1, mLocalPos1, globalOrient1, globalPos1, 1 );
// apply the constraints!
addLinearRow( globalPos0, globalPos1, globalOrient0 * Ogre::Vector3::UNIT_X );
addLinearRow( globalPos0, globalPos1, globalOrient0 * Ogre::Vector3::UNIT_Y );
addLinearRow( globalPos0, globalPos1, globalOrient0 * Ogre::Vector3::UNIT_Z );
// now find a point off 10 units away.
globalPos0 = globalPos0 + (globalOrient0 * (Ogre::Vector3::UNIT_X * 10.0f));
globalPos1 = globalPos1 + (globalOrient1 * (Ogre::Vector3::UNIT_X * 10.0f));
// apply the constraints!
addLinearRow( globalPos0, globalPos1, globalOrient0 * Ogre::Vector3::UNIT_Y );
addLinearRow( globalPos0, globalPos1, globalOrient0 * Ogre::Vector3::UNIT_Z );
// Now for hinge rotations
Ogre::Vector3 bod0X = globalOrient0 * Ogre::Vector3(Ogre::Vector3::UNIT_X );
if (mAngle != 0.0f)
{
addAngularRow(Radian(mAngle), bod0X );
setRowStiffness( 1.0f );
}