bullet physics ragdoll creation

This topic is 2609 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I'm trying to create ragdoll in directx and with bullet physics. Currently i'm using tiny.x from directx samples. I know the basics of ragdoll physics and how it works, my problem is when i'm creating bounding boxes for bones i give size values so if i use another model i have to change these sizes and definitely i'll use another model later. I'm sure there should be other methods for creating bone bounding boxes that is easier than typing sizes and try to see if it fit. So my question is can you suggest me a better way to create bounding boxes for bones?

And my second question is about updating frame matrices with ragdoll physics. Currently i'm setting frame's combined transformation matrix to bounding boxes world transform if ragdoll is active and this causes some artifacts. So i'm searching for a better way for this too. Also here is the code how i update.

 if(frame->boundingBox) { D3DXVECTOR3 scale, t; D3DXQUATERNION q; D3DXMatrixDecompose(&scale, &q, &t, &frame->CombinedTransformationMatrix); D3DXMATRIX scaleMatrix; D3DXMatrixScaling(&scaleMatrix, scale.x, scale.y, scale.z); D3DXMatrixMultiply(&frame->CombinedTransformationMatrix, &scaleMatrix, &ConvertMatrix_Bullet2DX(frame->boundingBox->rigidBody->getWorldTransform())); } else if(parentMatrix != NULL) D3DXMatrixMultiply(&frame->CombinedTransformationMatrix, &frame->TransformationMatrix, parentMatrix); else frame->CombinedTransformationMatrix = frame->TransformationMatrix; if(frame->pFrameSibling != NULL) { UpdateFrameMatrices(frame->pFrameSibling, parentMatrix); } if(frame->pFrameFirstChild != NULL) { UpdateFrameMatrices(frame->pFrameFirstChild, &frame->CombinedTransformationMatrix); } 

Share on other sites
I'm still trying to make it work but no success. I added some more code and some screenshots maybe they help you to understand what's going on. First screenshot shows how bounding boxes are created and second screenshot is what happens when i simulate boxes with physics engine. I really appreciate any help. Thanks.

 void Player::AddBoundingBoxToBone(string boneName, D3DXVECTOR3 size, LPDIRECT3DDEVICE9 device, PhysicalWorld* world) { D3DXFRAME_EXTENDED *frame = entity->GetFrame(boneName.c_str()); if(!frame) { return; } D3DXMATRIX m = frame->exCombinedTransformationMatrix; D3DXVECTOR3 s, t; D3DXQUATERNION q; D3DXMatrixDecompose(&s, &q, &t, &m); D3DXMATRIX m; D3DXMatrixRotationQuaternion(&m, &q); OrientedBoundingBox* bb = new OrientedBoundingBox(t, size, q); bb->CreateBBMesh(device); //create mesh for debug frame1->boundingBox = bb; world->AddBody(bb->rigidBody); } 

 void Player::AddHingeConstraintToBones(string boneName1, string boneName2, D3DXVECTOR3 hinge_axis, float min_limit, float max_limit, bool ignoreCollision, PhysicalWorld *world) { D3DXFRAME_EXTENDED *frame1 = entity->GetFrame(boneName1.c_str()); D3DXFRAME_EXTENDED *frame2 = entity->GetFrame(boneName2.c_str()); if(!frame1 || !frame2) { return; } btRigidBody* body1 = frame1->boundingBox->rigidBody; btRigidBody* body2 = frame2->boundingBox->rigidBody; if(!body1 || !body2) { return; } D3DXMATRIX worldMat = frame2->exCombinedTransformationMatrix; D3DXVECTOR3 hingePos(worldMat(3, 0), worldMat(3, 1), worldMat(3, 2)); btTransform b1Trans, b2Trans; body1->getMotionState()->getWorldTransform(b1Trans); body2->getMotionState()->getWorldTransform(b2Trans); D3DXMATRIX world1 = BT2DX_MATRIX(b1Trans); D3DXMATRIX world2 = BT2DX_MATRIX(b2Trans); D3DXVECTOR3 off1, off2; D3DXMatrixInverse(&world1, NULL, &world1); D3DXMatrixInverse(&world2, NULL, &world2); D3DXVec3TransformCoord(&off1, &hingePos, &world1); D3DXVec3TransformCoord(&off2, &hingePos, &world2); btVector3 offset1(off1.x, off1.y, off1.z); btVector3 offset2(off2.x, off2.y, off2.z); b1Trans.setIdentity(); b1Trans.setOrigin(offset1); b1Trans.getBasis().setEulerZYX(hinge_axis.x, hinge_axis.y, hinge_axis.y); b2Trans.setIdentity(); b2Trans.setOrigin(offset2); b2Trans.getBasis().setEulerZYX(hinge_axis.x, hinge_axis.y, hinge_axis.y); btHingeConstraint *constraint = new btHingeConstraint(*body1, *body2, b1Trans, b2Trans); constraint->setLimit(min_limit, max_limit); world->AddConstraint(constraint, ignoreCollision); } 

 //head and neck player->AddBoundingBoxToBone("Bip01_Neck", D3DXVECTOR3(0.1f, 0.1f, 0.1f), dxDevice->GetDevice(), physicalWorld); //arms player->AddBoundingBoxToBone("Bip01_L_UpperArm", D3DXVECTOR3(0.3f, 0.2f, 0.15f), dxDevice->GetDevice(), physicalWorld); player->AddBoundingBoxToBone("Bip01_L_Forearm", D3DXVECTOR3(0.3f, 0.2f, 0.15f), dxDevice->GetDevice(), physicalWorld); player->AddBoundingBoxToBone("Bip01_R_UpperArm", D3DXVECTOR3(0.3f, 0.2f, 0.15f), dxDevice->GetDevice(), physicalWorld); player->AddBoundingBoxToBone("Bip01_R_Forearm", D3DXVECTOR3(0.3f, 0.2f, 0.15f), dxDevice->GetDevice(), physicalWorld); //legs player->AddBoundingBoxToBone("Bip01_Pelvis", D3DXVECTOR3(0.3f, 0.3f, 0.3f), dxDevice->GetDevice(), physicalWorld); player->AddBoundingBoxToBone("Bip01_L_Thigh", D3DXVECTOR3(0.4f, 0.2f, 0.25f), dxDevice->GetDevice(), physicalWorld); player->AddBoundingBoxToBone("Bip01_L_Calf", D3DXVECTOR3(0.4f, 0.2f, 0.25f), dxDevice->GetDevice(), physicalWorld); player->AddBoundingBoxToBone("Bip01_R_Thigh", D3DXVECTOR3(0.4f, 0.2f, 0.25f), dxDevice->GetDevice(), physicalWorld); player->AddBoundingBoxToBone("Bip01_R_Calf", D3DXVECTOR3(0.4f, 0.2f, 0.25f), dxDevice->GetDevice(), physicalWorld); //body player->AddBoundingBoxToBone("Bip01_Spine", D3DXVECTOR3(0.1f, 0.3f, 0.4f), dxDevice->GetDevice(), physicalWorld); player->AddBoundingBoxToBone("Bip01_Spine1", D3DXVECTOR3(0.1f, 0.3f, 0.4f), dxDevice->GetDevice(), physicalWorld); player->AddBoundingBoxToBone("Bip01_Spine2", D3DXVECTOR3(0.1f, 0.3f, 0.4f), dxDevice->GetDevice(), physicalWorld); player->AddBoundingBoxToBone("Bip01_Spine3", D3DXVECTOR3(0.1f, 0.3f, 0.4f), dxDevice->GetDevice(), physicalWorld); //constraints player->AddHingeConstraintToBones("Bip01_Neck", "Bip01_Spine",D3DXVECTOR3(0, 0, D3DX_PI/2.0f), 0, 0, true, physicalWorld); player->AddHingeConstraintToBones("Bip01_Spine", "Bip01_L_UpperArm", D3DXVECTOR3(0, D3DX_PI/2.0f, 0), -D3DX_PI, D3DX_PI, true, physicalWorld); player->AddHingeConstraintToBones("Bip01_Spine", "Bip01_R_UpperArm", D3DXVECTOR3(0, D3DX_PI/2.0f, 0), -D3DX_PI, D3DX_PI, true, physicalWorld); player->AddHingeConstraintToBones("Bip01_L_UpperArm", "Bip01_L_Forearm", D3DXVECTOR3(0, 0, D3DX_PI/2.0f), 0, 0.4f, true, physicalWorld); player->AddHingeConstraintToBones("Bip01_R_UpperArm", "Bip01_R_Forearm", D3DXVECTOR3(0, 0, D3DX_PI/2.0f), 0, 0.4f, true, physicalWorld); player->AddHingeConstraintToBones("Bip01_Pelvis", "Bip01_R_Thigh", D3DXVECTOR3(0, 0, D3DX_PI/2.0f), 0, 0, true, physicalWorld); player->AddHingeConstraintToBones("Bip01_Pelvis", "Bip01_L_Thigh", D3DXVECTOR3(0, 0, D3DX_PI/2.0f), 0, 0, true, physicalWorld); player->AddHingeConstraintToBones("Bip01_R_Thigh", "Bip01_R_Calf", D3DXVECTOR3(0, 0, D3DX_PI/2.0f), -D3DX_PI/2, 0, true, physicalWorld); player->AddHingeConstraintToBones("Bip01_L_Thigh", "Bip01_L_Calf", D3DXVECTOR3(0, 0, D3DX_PI/2.0f), -D3DX_PI/2, 0, true, physicalWorld); player->AddHingeConstraintToBones("Bip01_Spine", "Bip01_Spine1",D3DXVECTOR3(0, 0, 0), 0, 0, true, physicalWorld); player->AddHingeConstraintToBones("Bip01_Spine1", "Bip01_Spine2",D3DXVECTOR3(0, 0, 0), 0, 0, true, physicalWorld); player->AddHingeConstraintToBones("Bip01_Spine2", "Bip01_Spine3",D3DXVECTOR3(0, 0, 0), 0, 0, true, physicalWorld); player->AddHingeConstraintToBones("Bip01_Spine3", "Bip01_Pelvis",D3DXVECTOR3(0, 0, 0), 0, 0, true, physicalWorld); 

Share on other sites
I suggest adding in controls to allow you to add, remove and manipulate rigid bodies and constraints in your demo at runtime (ie. using your mouse and keyboard as you would in Maya/Max). It is a bit of work, but will be a lot easier in the long run than trying to code them in by hand. I had a similar setup when I was implementing ragdolls using Bullet and it worked really well. You can then save the ragdoll out to file for later use; no need for hardcoding

Alternatively you could create and export the ragdoll using your DCC software.

Share on other sites
Thanks for reply. I know it's not good to use hardcoding but there are some things that i don't understand. Now i'm creating rigid bodies when character dies so rigid bodies have the same orientation with bones and then i set bones' combined transform matrix to rigid bodies transform matrix. But if i create rigid bodies when i load the model after i animate model bones have different orientation so rigid bodies won't work.

Share on other sites

Thanks for reply. I know it's not good to use hardcoding but there are some things that i don't understand. Now i'm creating rigid bodies when character dies so rigid bodies have the same orientation with bones and then i set bones' combined transform matrix to rigid bodies transform matrix. But if i create rigid bodies when i load the model after i animate model bones have different orientation so rigid bodies won't work.

You will have to calculate the local transforms (relative to linked joint) for each of your rigid bodies/constraints ... then you can easily fit the ragdoll to your animated model, no matter what pose the animated model is in. You could also animate the ragdoll along with your model then, if you wanted to, enabling it in Bullet only when you need to.
If there is more that you don't understand then let us know.

Share on other sites
Thanks i'll try that and tell you about results.

1. 1
Rutin
37
2. 2
3. 3
4. 4
5. 5

• 9
• 12
• 14
• 9
• 9
• Forum Statistics

• Total Topics
633348
• Total Posts
3011459
• Who's Online (See full list)

There are no registered users currently online

×