Jump to content
  • Advertisement
Sign in to follow this  
ekba89

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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!