Ragdoll problem

whiplash
Posts: 16
Joined: Sun Dec 13, 2009 3:21 pm

Ragdoll problem

Post by whiplash »

Hello!

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);
		}
	}
(Add constraints)

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);
(Update rigidbody & bone's position)

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;
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Ragdoll problem

Post by Erwin Coumans »

There is currently not an easy way for us to help you (we don't look at code).

Please compare your setup with the Bullet ragdoll demos (Bullet/Demos/RagdollDemo or Bullet/Demos/GenericJointDemo).

Thanks,
Erwin
whiplash
Posts: 16
Joined: Sun Dec 13, 2009 3:21 pm

Re: Ragdoll problem

Post by whiplash »

Thanx :(