I have created ragdoll and at me with it problems (use Ogre+Bullet). At performance of an update of the physical world, at me connected rigidbody scatter every which way. Here my code:
(Create ragdoll)
Code: Select all
Skeleton* skeleton = (static_cast <Entity *> (parNode-> getAttachedObject (parName)))-> getSkeleton ();
Skeleton:: BoneIterator boneIter = skeleton-> getBoneIterator ();
//the Cycle on bones in a skeleton
while (boneIter.hasMoreElements ())
{
Bone* bone = boneIter.getNext ();
bone-> setManuallyControlled (true);
//World coords
Vector3 bonePos = parNode-> getPosition () + parNode-> getOrientation () * bone-> _ getDerivedPosition () * parNode-> getScale ();
ragdoll.world_pos.push_back (bonePos);
//Rotate
Quaternion boneRot = parNode-> getOrientation () * bone-> _ getDerivedOrientation ();
ragdoll.world_rot.push_back (boneRot);
ragdoll.bones.push_back (bone);
if (bone-> getParent () == 0)
{
continue;
}
else
{
//Distance between two bones
Vector3 posParent = parNode-> getPosition () +
parNode-> getOrientation () * bone-> getParent ()-> _getDerivedPosition () * parNode-> getScale ();
Real dist = posParent.distance (bonePos);
//Create shape
btScalar rad = 10.0;
btCollisionShape* shape = new btCapsuleShape (rad, dist);
//Initial position...
btVector3 ph_pos (posParent.x, posParent.y, posParent.z);
//Rotate
Quaternion qrot = posParent.getRotationTo (bonePos);
btQuaternion ph_rot (qrot.x, qrot.y, qrot.z, qrot.w);
btTransform trans;
trans.setIdentity ();
trans.setOrigin (ph_pos);
trans.setRotation (ph_rot);
btScalar massa = 1.0;
btVector3 inertia (0.0, 0.0, 0.0);
shape-> calculateLocalInertia (massa, inertia);
// Motion state
btDefaultMotionState* mot_state = new btDefaultMotionState (trans);
btRigidBody:: btRigidBodyConstructionInfo rbInfo (massa, mot_state, shape, inertia);
rbInfo.m_additionalDamping = true;
btRigidBody* body = new btRigidBody (rbInfo);
body-> setDamping (0.05, 0.85);
body-> setDeactivationTime (0.8);
body-> setSleepingThresholds (1.6, 2.5);
ragdoll.shapes.push_back (shape);
ragdoll.rbodies.push_back (body);
caps.bone = static_cast <Bone *> (bone-> getParent ());
caps.body = body;
ragdoll.capsules.push_back (caps);
m_dynamicsWorld-> addRigidBody (body);
}
}
Code: Select all
for (unsigned int i = 0; i <ragdoll.capsules.size (); i ++)
{
for (int j = 0; j <ragdoll.capsules.size (); j ++)
{
if (ragdoll.capsules [j].bone-> getParent () == ragdoll.capsules [i].bone)
{
btGeneric6DofConstraint* joint6DOF;
btTransform localA, localB;
bool lineRefFrameA = true;
localA.setIdentity ();
localA.setOrigin (ragdoll.capsules [i].body-> getWorldTransform ().getOrigin ());
localA.setIdentity ();
localA.setOrigin (ragdoll.capsules [j].body-> getWorldTransform ().getOrigin ());
joint6DOF = new btGeneric6DofConstraint (
*ragdoll.capsules [j].body,
*ragdoll.capsules [i].body,
localA, localB, lineRefFrameA);
joint6DOF-> setAngularLowerLimit (btVector3 (-0.942, 0.0,-0.942));
joint6DOF-> setAngularUpperLimit (btVector3 (1.57, 0.0, 0.942));
ragdoll.joints.push_back (joint6DOF);
m_dynamicsWorld-> addConstraint (joint6DOF, true);
}
}
}
m_ragdolls.push_back (ragdoll);
Code: Select all
for (unsigned int j = 0; j <ragdoll.capsules.size (); j ++)
{
btQuaternion rot = ragdoll.capsules [j].body-> getWorldTransform ().getRotation ();
Quaternion brot = Quaternion:: ZERO;
brot.x = rot.x ();
brot.y = rot.y ();
brot.z = rot.z ();
brot.w = rot.w ();
btVector3 pos = ragdoll.capsules [j].body-> getWorldTransform ().getOrigin ();
Vector3 bpos.x = pos.x ();
bpos.y = pos.y ();
bpos.z = pos.z ();
// nn - SceneNode (container Entity <- Skeleton <- Bones)
Vector3 world_bpos = nn-> getPosition () + nn-> getOrientation () * ragdoll.capsules [j].bone-> _ getDerivedPosition () * nn-> getScale ();
Vector3 diff = bpos - world_bpos;
// the bone is transformed already?
boneChanged = false;
for (unsigned int k = 0; k <ragdoll.capsules.size (); k ++)
{
if ((ragdoll.capsules [k].bone == ragdoll.capsules [j].bone) &&
(ragdoll.capsules [k].isChange == true))
{
boneChanged = true;
break;
}
}
if (! boneChanged)
{
LogManager:: getSingleton ().logMessage ("Bone name:" + ragdoll.capsules [j].bone-> getName ());
LogManager:: getSingleton ().logMessage ("Phys coord:" + StringConverter:: toString (bpos));
LogManager:: getSingleton ().logMessage ("Bone coord:" + StringConverter:: toString (world_bpos));
ragdoll.capsules[j].bone->setOrientation(brot);
ragdoll.capsules[j].bone->setPosition(ragdoll.capsules[j].bone->getPosition() + diff);
ragdoll.capsules[j].isChange = true;
}
}
for (unsigned int j = 0; j < ragdoll.capsules.size(); j++)
ragdoll.capsules[j].isChange = false;