Page 1 of 2

Getting proper rotations from a rigid body for directx 10

Posted: Mon Oct 27, 2008 6:59 pm
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!

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

Posted: Mon Oct 27, 2008 7:56 pm
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 (-;

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

Posted: Mon Oct 27, 2008 8:47 pm
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.

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

Posted: Tue Oct 28, 2008 3:50 am
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!

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

Posted: Tue Oct 28, 2008 4:37 am
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 (-;

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

Posted: Tue Oct 28, 2008 8:19 pm
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!

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

Posted: Wed Oct 29, 2008 7:21 am
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.

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

Posted: Wed Oct 29, 2008 6:35 pm
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!

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

Posted: Mon Nov 03, 2008 2:37 pm
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!

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

Posted: Mon Nov 03, 2008 4:43 pm
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 (-;

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

Posted: Mon Nov 03, 2008 9:08 pm
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?

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

Posted: Mon Nov 03, 2008 10:26 pm
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);

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

Posted: Wed Nov 05, 2008 1:13 am
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.

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

Posted: Wed Nov 05, 2008 1:29 am
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

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

Posted: Sun Sep 25, 2011 8:14 pm
by llefler
I am having the same problem with not being able to get any rotation, have you solved this problem yet? Thanks!