center of mass not at mesh origin

Post Reply
PaulMartz
Posts: 28
Joined: Mon Jun 02, 2008 7:21 pm

center of mass not at mesh origin

Post by PaulMartz » Tue Jun 03, 2008 4:43 pm

Hello all --

I have a tri mesh, for simplicity let's say it's a cube 2x2x2 units in size, with one corner at the origin. Bullet treats this body as if the center of mass is at the origin corner. I'd like to tell Bullet that the center of mass is at (1,1,1) -- in the center of the 2x2x2 cube-- but so far I haven't been able to accomplish this. btRigidBody::setCenterOfMassOffset doesn't appear to do this; setting btMotionState::m_centerOfMassTransform direcctly also doesn't appear to do this. (In fact, the code seems to be quite confusing regarding the concepts of "ccenter of mass" and "world transform". It almost looks like they are used interchangeably. Very odd.)

If someone could point me to an example that demonstrates how to set a non-origin center of mass in Bullet, I'd appreciate it.

(Sorry if this is a newb question. I did search the forum and the FAQ, to no avail. I also searched the sourrce code, but -- probably due to my own lack of familiarity with the Bullet API -- it wasn't immediatelyt clear to me which examples handled this situation correctly.)

Thanks,
-Paul

DevO
Posts: 95
Joined: Fri Mar 31, 2006 7:13 pm

Re: center of mass not at mesh origin

Post by DevO » Tue Jun 03, 2008 6:08 pm

Hi Paul,

the easiest way would to offset you mesh point for example by (-1,-1,-1) an move origin in the centre of mesh (cube).
Look to ConvexDecompositionDemo.cpp for this.


Another way would be to use CompoundShape like this code from VehicleDemo.cpp

Code: Select all

	btCollisionShape* boxShape = new btBoxShape(btVector3(2.f,2.f, 2.0f));
	btCompoundShape* compound = new btCompoundShape();
	btTransform localTrans;
	localTrans.setIdentity();
	//localTrans effectively shifts the center of mass with respect to the chassis
	localTrans.setOrigin(btVector3(0,0,1));
	compound->addChildShape(localTrans,boxShape);
...
DevO

PaulMartz
Posts: 28
Joined: Mon Jun 02, 2008 7:21 pm

Re: center of mass not at mesh origin

Post by PaulMartz » Tue Jun 03, 2008 8:21 pm

I appreciate your assistance. I have a working solution now. Thanks much.
-Paul

PaulMartz
Posts: 28
Joined: Mon Jun 02, 2008 7:21 pm

Re: center of mass not at mesh origin

Post by PaulMartz » Tue Jun 03, 2008 11:14 pm

Okay, after playing wih this for a while, I'd like to reopen this issue.

Thanks for the help, but both of the solutions provided appear to result in moving the mesh in the world so that it's centered on the origin -- either by offsetting the mesh vertices, or by setting a transform. Neither of the solutions work by actually having Bullet use a different center of mass.

So, unless I've misunderstood something, both of these solutions require me to perform an equivalent operation to my visual scene -- either offset the actual vertices one-by-one, or apply a transformation matrix. If I don't do this, the visual geometry doesn't correspond with the mesh location in the physics simulation.

Unfortunately, this adds a lot of complexity to my application. My app now needs to keep track of the additional matrices in my scene graph so that they can be removed, and the vertices and transforms restored to their original state, when the user saves the model.

Is there really no way to tell Bullet to use a center of mass other than the origin? If not, this is surprising, as I see the phrase "centerofmass" all over the code -- it just doesn't appear to do what I thought that phrase meant.

Thanks, and I appreciate any enlightenment.
-Paul

pico
Posts: 229
Joined: Sun Sep 30, 2007 7:58 am

Re: center of mass not at mesh origin

Post by pico » Wed Jun 04, 2008 5:16 pm

Hi,

i also had to get used to this. However, there is really no other way to set the center of mass. You can go through Bullets OpenGl debug drawer code to see how to get the correct model matrix.

bbangerter
Posts: 6
Joined: Thu Apr 03, 2008 4:45 pm

Re: center of mass not at mesh origin

Post by bbangerter » Wed Jun 04, 2008 7:51 pm

Ultimately if you are rendering an object that is represented in the physics engine, you will (most likely) want your model origin and the physics center of mass to coincide with each other. If they do not you will have to do a center of mass offset translation before doing any rotation/scaling translations as part of your render pipeline. Failing to do so will always result in the the visual representation of your model not being in sync with the physics representation of it's location and orientation.

Consider your box as a scenario. If center of mass is 1, 1, 1 and you rotate it around the z-axis by 90 degrees, then in the physics system your box is taking up the exact same space and volume that it was prior to the rotation - or rather the min/max corners as represented in the physics system in both cases will be (0, 0, 0) - (2, 2, 2). Graphically if you then render based on a rotation of 90 degrees from the model origin (one of the corners) it will go from occupying the min/max corners of (0, 0, 0) - (2, 2, 2) to (-2, 0, 0) - (0, 2, 2) - occupying a completely different volume of space.

That said, I agree it would be nice to be able to set center of mass on an object - but I can't think of any pratical use for doing so when the intent is to render images based off the physics data.

DannyChapman
Posts: 85
Joined: Sun Jan 07, 2007 4:29 pm
Location: Oxford, England
Contact:

Re: center of mass not at mesh origin

Post by DannyChapman » Thu Jun 05, 2008 9:23 am

bbangerter wrote: That said, I agree it would be nice to be able to set center of mass on an object - but I can't think of any pratical use for doing so when the intent is to render images based off the physics data.
There's lots of uses - e.g.

1. Artists may want to set the origin of models at ground level - e.g. level with the bottom of the feet for a table, and it would be nice if the game code didn't have to store the offsets.

2. You may have a car object that has different configurations based on its CoM - i.e. you can have different versions of the car differing only in handling characteristics (including different CoM positions). Again, awkward to absorb the offsets into the game code.

3. A model aircraft flight simulator may want to move the CoM as the plane flies - e.g. as a result of geometry moving (swept wing etc) or the fuel tank emptying, or simply to allow the flight params to be modified whilst flying.

I don't think generally artists will care exactly where the CoM is, or be able to construct the model geometry so that the origin is at the CoM, so there will have to be an offset somewhere in the code. It makes sense to put this offset in the physics engine code rather than game code for any physics engine that wants to support more than just boxes and spheres.

PaulMartz
Posts: 28
Joined: Mon Jun 02, 2008 7:21 pm

Re: center of mass not at mesh origin

Post by PaulMartz » Thu Jun 05, 2008 11:02 pm

Thanks for the input, all. Here's what I have finally done as a solution...

Yes, the Bullet mesh must have center of mass at the origin, and I must do something to make that work, such as applying an offset to each vertex or using a CompiundShape and transform as mentioned earlier.

In addition to that, I have a class derived from btDefaultMotionState, and I override setWorldTransform to drive the position of the geometry in my visual scene. It turns out btDefaultMotionState has a member m_centerOfMassOffset. In my override of setWorldTransform, I first call the base class's setWorldTransform, and this folds the m_centerOfMassOffsset into the m_graphicsEWorldTrans -- and then I just use that to transform my visual scene geometry.

The problem I had up until now was that I had tried both of those (transforming the mesh, and setting the m_centerOfMassOffset) in isolation. Separately, they don't provide a complete solution, But together they resolve the issue.

The nice thing about this is that I can hide the center of mass offset entirely in the code module that glues Bullet together with my rendering code, and it's all managed transparently there.

Thanks again for everyone's input.

peacemoon
Posts: 15
Joined: Wed Sep 03, 2008 12:52 pm

Re: center of mass not at mesh origin

Post by peacemoon » Tue Sep 09, 2008 3:23 pm

Hello Paul,
can you post your working solution. I have the same problem and can't figure out, how i can fix it

Thanks

User avatar
Erwin Coumans
Site Admin
Posts: 4183
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: center of mass not at mesh origin

Post by Erwin Coumans » Tue Sep 09, 2008 4:05 pm

The rigid body world transform is the center of mass.

If your graphics mesh needs an offset, you can use a btCompoundShape to shift the graphics mesh, relative to the center of mass, and use the btDefaultMotionState to apply the inverse shift.

Hope this helps,
Erwin

Heizer
Posts: 1
Joined: Fri May 01, 2009 11:55 pm
Location: Germany
Contact:

Re: center of mass not at mesh origin

Post by Heizer » Sat May 02, 2009 9:11 am

Hello,

In my project Im using Ogre together with btOgre. I have exported a car chassis and 4 wheels from 3dsmax
to Ogre mesh. All this meshs are loading as seperate entitys and are not alligned to orgin.
Without gluing the car to bullet, the position is ok in render.

When I glue it to bullet with btOgre, there is an offset in calculation. The debug-drawer shows that the collision
spere are alligned to the mesh, but the calculation is not.

I try different solutions found here in the forum and look in some demos without success.

Here is my code of creating a wheel body:

Code: Select all

Wheel::Wheel(Model *Model, BTPhysics *Physics, WHEEL_POSITION WheelPosition, std::string path, std::string name)
   {
   m_Model   = Model;
   m_Physics = Physics;
   m_Part    = (MODEL_PARTS)WheelPosition;
   
   m_Node = m_Model->get_Node((MODEL_PARTS)WheelPosition);                        // get scene node
   Ogre::Entity *ent=(Ogre::Entity *)m_Node->getAttachedObject(0);                  // get attached entity
   Ogre::AxisAlignedBox BBox = ent->getBoundingBox();                                      // get bounding box

   m_CylinderShape = new btCylinderShape(Convert::toBullet(BBox.getHalfSize()));  
   m_ColShape       = new btCompoundShape;
   
   btTransform localTransform;
   localTransform.setIdentity();
   // car is facing in -Z direction, rotating cylinder to fit wheel orientation
   localTransform.setRotation(Convert::toBullet(Ogre::Quaternion(Ogre::Degree(-90),Ogre::Vector3::UNIT_Z)));
   // move shape to graphical center
   localTransform.setOrigin(Convert::toBullet(BBox.getCenter()));
   m_ColShape->addChildShape(localTransform,m_CylinderShape);

   btScalar mass(30.0);                                                // 
   btVector3 localInertia(0,0,0);                                     // Is this ok when it is not at orgin ?
   m_ColShape->calculateLocalInertia(mass,localInertia);    //

   btTransform MassTransform;
   MassTransform.setIdentity();
   MassTransform.setOrigin(Convert::toBullet(BBox.getCenter()));
   MassTransform.setRotation(Convert::toBullet(Ogre::Quaternion(Ogre::Degree(-90),Ogre::Vector3::UNIT_Z)));

   localTransform.inverse();      // inverse shift
   MassTransform.inverse();     // inverse massposition

   m_BodyState = new RigidBodyState(localTransform, MassTransform, m_Node); 

   btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,m_BodyState,m_ColShape,localInertia);
   m_WheelBody = new btRigidBody(rbInfo);

   Physics->getWorld()->addRigidBody(m_WheelBody);
   }  
The code I use to set the wheel to a specific position

Code: Select all

void Wheel::set_Position(Ogre::Vector3 Position)
   {
   btTransform transform; 
   transform.setIdentity();                                                
   transform.setOrigin(Convert::toBullet(Position));                
   m_WheelBody->setWorldTransform(transform);                  
   }
What is the right way to setup a rigid body which is not orgin alligned ?
I have not found a working solution withing the last 7 days and I realy tryed everyting
found in forum and demos.

I need your help guys.

( sorry for my bad english )

Bigpet
Posts: 10
Joined: Fri Oct 28, 2011 5:14 am

Re: center of mass not at mesh origin

Post by Bigpet » Fri Nov 18, 2011 7:06 am

Sorry for necroing this thread but I thought that this would fit nicely in here.
So, I know that for the translation of objects a btCompoundShape has been recommended in multiple threads. btCompoundShape may have a negligible overhead if you wrap a single complex shape into it but using it to offset the center of gravity of a lot of simple shapes (like btBoxShapes in my example) does produce a significant overhead.

basically I created a huge stack of cubes and let the tower fall. When using btCompoundShapes around the btBoxShapes I had spikes of over 100ms while the spikes of using simple btBoxShapes were in the range of 25-35ms. For this use-case (offsetting the center of mass of a lot of simple shapes) btCompoundShape seems unfit. I am currently looking into writing a "btTransformShape" that just hosts one child shape and applies a transformation to it (an equivalent to the ode GeomOffsets). If something like this already exists, please let me know.

here's the demo Video:
http://www.youtube.com/watch?v=KLDDExjgosk

User avatar
majestik666
Posts: 66
Joined: Tue Mar 02, 2010 6:13 am

Re: center of mass not at mesh origin

Post by majestik666 » Sun Nov 20, 2011 10:05 pm

I do this kind of things a lot because of the meshes we get from maya
are basically never centered around their pivot.
Instead of adding a transform I transform the vertices of the shape
so that the vertices are centered around the pivot, and no need for a top transform,
once that is done I apply an invert offset on the transform to move the object back
into the correct position.

User avatar
Erwin Coumans
Site Admin
Posts: 4183
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA
Contact:

Re: center of mass not at mesh origin

Post by Erwin Coumans » Mon Nov 21, 2011 6:15 pm

#BigPet, there is no btTransformShape right now, but if you need it for simple convex shapes (btBoxShape etc) you can create it indeed
(you will need to create a new collision algorithm too, not sure if it will be much more efficient than a btCompoundShape)

We'll have a more efficient method for Bullet 3.x (see the Physics Effects code in https://github.com/erwincoumans/experiments )
Thanks,
Erwin

Post Reply