Getting proper rotations from a rigid body for directx 10

FoxMulder900
Posts: 8
Joined: Mon Oct 27, 2008 6:34 pm

Getting proper rotations from a rigid body for directx 10

Post by FoxMulder900 »

Hello,
I am just starting to integrate Bullet into my directx10 project, I am able to translate my objects using the data retrieved from the rigidBody->getCenterOfMassPosition() function. However I am confused as to how to get the rotation information. The rigidBody->getOrientation() doesn't seem to contain what I need. I have seen examples that go through the rigidBody's motion state to retrieve data. What would be the proper way to retrieve the rotation information so that I can create a D3DXMATRIX rotation matrix? (alternatively I could rotate my object using 3 rotation angles, one for each of the X, Y and Z axis if that would be easier to retrieve)

Any help would be much appreciated!
chunky
Posts: 145
Joined: Tue Oct 30, 2007 9:23 pm

Re: Getting proper rotations from a rigid body for directx 10

Post by chunky »

I don't have experience directly with DirectX, but I can point you in the right direction.

Firstly, use a motionstate to get the positions. It's just a better way to do it. Documentation is on the wiki here:
http://www.bulletphysics.com/mediawiki- ... tionStates

If you look at that page, you'll see setWorldTransform looks like this:
virtual void setWorldTransform(const btTransform &worldTrans)

So to get stuff as a directx rotation matrix, you need to convert the btTransform to something directX understands. Notably, You can build a quaternion and vector3 similarly to the example on that page:

Code: Select all

virtual void setWorldTransform(const btTransform &worldTrans) {
  btQuaternion rot = worldTrans.getRotation();
  D3DXQUATERNION d3drotation(rot.w(), rot.x(), rot.y(), rot.z());
  btVector3 pos = worldTrans.getOrigin();
  D3DXVECTOR3 d3dposition(pos.x(), pos.y(), pos.z());

// Now use d3drotation and d3dposition.
// There's presumably an easy way to make a D3DXMATRIX from these two items...
}
If you really don't want to use a motionstate, you can use btRigidBody::getOrientation() and btRigidBody::getCenterOfMassPosition as you found. [or btRigidBody::getCenterOfMassTransform()]


You wrote this: "The rigidBody->getOrientation() doesn't seem to contain what I need."
I suspect that it does do what you need, but you should read through a short primer on Quaternions. A brief searched turned up this guy: http://gpwiki.org/index.php/OpenGL:Tuto ... t_rotation which seems like a good start.

Gary (-;
sparkprime
Posts: 508
Joined: Fri May 30, 2008 2:51 am
Location: Ossining, New York
Contact:

Re: Getting proper rotations from a rigid body for directx 10

Post by sparkprime »

Might be worth making a wiki page explaining how scalar, basis, vector, quaternion, matrix, transform etc are used in bullet, and links to other resources related to those concepts. Then every page that mentions them can link to it.
FoxMulder900
Posts: 8
Joined: Mon Oct 27, 2008 6:34 pm

Re: Getting proper rotations from a rigid body for directx 10

Post by FoxMulder900 »

Ok great! those are excellent resources. The motion states make a lot of sense now. However I am still a little stuck on converting a btMatrix3x3 to a D3DXMATRIX - I wrote the following helper function but it doesn't seem to work properly, any ideas on what I have mixed around?

Code: Select all

D3DXMATRIX toD3DXMATRIX(btMatrix3x3 inMatrix)
{
	D3DXMATRIX outMatrix = D3DXMATRIX();

	outMatrix._11 = inMatrix[0][0];
	outMatrix._12 = inMatrix[1][0];
	outMatrix._13 = inMatrix[2][0];

	outMatrix._21 = inMatrix[0][1];
	outMatrix._22 = inMatrix[1][1];
	outMatrix._23 = inMatrix[2][1];

	outMatrix._31 = inMatrix[0][2];
	outMatrix._32 = inMatrix[1][2];
	outMatrix._33 = inMatrix[2][2];

	return outMatrix;
}
Thanks again!
chunky
Posts: 145
Joined: Tue Oct 30, 2007 9:23 pm

Re: Getting proper rotations from a rigid body for directx 10

Post by chunky »

D3DXMATRIX is 4x4. a btMatrix3x3 isn't going to map onto it neatly. I suggest looking for how to take a D3DXVECTOR3 and a D3DXQUATERNION onto a D3DXMATRIX. In fact, what would be even better would be if you could apply the vector3 and a quaternion directly to your object [eg, d3dobject->setRotation(quaternion); d3dobject->setPosition(vector3)]

Gary (-;
FoxMulder900
Posts: 8
Joined: Mon Oct 27, 2008 6:34 pm

Re: Getting proper rotations from a rigid body for directx 10

Post by FoxMulder900 »

Thank you very much, You're suggestions are helping quite a bit in keeping my project clean.

I now have a motionstate implemented and I have the following code:

Code: Select all

void BasicObject::setWorldTransform(const btTransform &worldTrans)
{
	setPosition(worldTrans.getOrigin());
	cout << worldTrans.getRotation().x() << worldTrans.getRotation().y() << worldTrans.getRotation().z() << endl;
	setRotation(worldTrans.getRotation());
}
the position is getting set properly however my objects are never rotating, the x y and z of the rotation are always 0. Is there something that I should be doing to ensure rotations occur? Thanks again for all you're help!
mickey
Posts: 107
Joined: Fri Sep 19, 2008 6:08 pm

Re: Getting proper rotations from a rigid body for directx 10

Post by mickey »

Hi Fox

I have this convert function that converts a btTransform into a D3DXMatrix, might help.

Code: Select all

D3DXMATRIX ConvertMatrix( btTransform &trn ) 
{
	btVector3 R = trn.getBasis().getColumn(0);
	btVector3 U = trn.getBasis().getColumn(1);
	btVector3 L = trn.getBasis().getColumn(2);
	btVector3 P = trn.getOrigin();

	D3DXVECTOR3 vR, vU, vL, vP;
	vR.x = R.x();vR.y = R.y();vR.z = R.z();
	vU.x = U.x();vU.y = U.y();vU.z = U.z();
	vL.x = L.x();vL.y = L.y();vL.z = L.z();
	vP.x = P.x();vP.y = P.y();vP.z = P.z();

	D3DXMATRIX matOutput;
	matOutput._11 = vR.x;matOutput._12 = vR.y;matOutput._13 = vR.z;matOutput._14 = 0.f;
	matOutput._21 = vU.x;matOutput._22 = vU.y;matOutput._23 = vU.z;matOutput._24 = 0.f;
	matOutput._31 = vL.x;matOutput._32 = vL.y;matOutput._33 = vL.z;matOutput._34 = 0.f;
	matOutput._41 = vP.x;matOutput._42 = vP.y;matOutput._43 = vP.z;matOutput._44 = 1.f;

	return matOutput;
}
the whole btTransform contains the scaling, rotation and translation values of a rigid body, you can get that information from the rigid body itself (eg, motion states).

Actually I may have fond this snippet somewhere here in the forum too!

Hope that helps.
FoxMulder900
Posts: 8
Joined: Mon Oct 27, 2008 6:34 pm

Re: Getting proper rotations from a rigid body for directx 10

Post by FoxMulder900 »

That is a very helpful function, however I seem to having the same problems with it.
I altered the middle section to include a cout statement like so:

Code: Select all

  D3DXVECTOR3 vR, vU, vL, vP;
   vR.x = R.x();vR.y = R.y();vR.z = R.z();
   vU.x = U.x();vU.y = U.y();vU.z = U.z();
   cout << vU.x << vU.y << vU.z << endl;      /////<< new line
   vL.x = L.x();vL.y = L.y();vL.z = L.z();
   vP.x = P.x();vP.y = P.y();vP.z = P.z();
and this always prints 010, meaning that the up vector of all of my objects is always pointing straight up the Y axis although my objects should definitely be rotating.

Here is an example of my simulation, I am dropping 4 objects onto a hill in my world, the result should be the objects tumbling in various directions, however they always stay aligned with the axis - see pictures below.

Image
Image
Image

As you can see these objects should clearly not stack on top of each other as they do, they should rotate and fall off of each other.

I have no idea what i am missing, it is probably something simple that I am overlooking!
Thanks again for all your help!
FoxMulder900
Posts: 8
Joined: Mon Oct 27, 2008 6:34 pm

Re: Getting proper rotations from a rigid body for directx 10

Post by FoxMulder900 »

Sorry to bump my own post, but has no-one else ran into this problem? I'm sure it is something simple I am missing!
chunky
Posts: 145
Joined: Tue Oct 30, 2007 9:23 pm

Re: Getting proper rotations from a rigid body for directx 10

Post by chunky »

When you create the body, are you correctly setting the localinertia? It's one of the things you put into the btRigidBodyConstructionInfo

Gary (-;
FoxMulder900
Posts: 8
Joined: Mon Oct 27, 2008 6:34 pm

Re: Getting proper rotations from a rigid body for directx 10

Post by FoxMulder900 »

Great! that solved my problem, I was using the default value of (0,0,0). I changed it to (0.5, 0.5, 0.5) and it seems to work well, but out of curiosity how would you determine a good value to use?
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Getting proper rotations from a rigid body for directx 10

Post by Erwin Coumans »

See http://www.bulletphysics.com/mediawiki- ... ello_World

Code: Select all

btScalar mass = 1;
btVector3 inertia(0,0,0);
shape->calculateLocalInertia(mass,inertia);
FoxMulder900
Posts: 8
Joined: Mon Oct 27, 2008 6:34 pm

Re: Getting proper rotations from a rigid body for directx 10

Post by FoxMulder900 »

Once again, thank you for all of your help and your patience with me through this problem.

When I use these 2 lines:

Code: Select all

collisionShape->calculateLocalInertia(1, btVector3(0,0,0));
rigidBody = new btRigidBody(1, motionState, collisionShape);
I do not get any rotations at all, however if I just use the following line (which i'm sure isnt proper since it is arbitrary values), i get rotations but my objects fall right through my ground.

Code: Select all

rigidBody = new btRigidBody(1, motionState, collisionShape, btVector3(.5,.5,.5));
I went through the tutorial that you linked and my code is nearly identical except for the fact that I am inheriting from the motionState and using my own class (which my get and set functions now work properly) I am just not getting any rotations returned from bullet.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: Getting proper rotations from a rigid body for directx 10

Post by Erwin Coumans »

Don't pass in constant values into the calculateLocalInertia or btRigidBody constructor:

Use this code without modification.

Code: Select all

btScalar mass = 1;
btVector3 inertia(0,0,0);
shape->calculateLocalInertia(mass,inertia);
rigidBody = new btRigidBody(mass, motionState, collisionShape,inertia);
You might want to learn a bit more about C++ development before using Bullet.

Hope this helps,
Erwin
llefler
Posts: 17
Joined: Sun Sep 25, 2011 8:13 pm

Re: Getting proper rotations from a rigid body for directx 1

Post by llefler »

I am having the same problem with not being able to get any rotation, have you solved this problem yet? Thanks!
Post Reply