Offsetting collision shapes.

Post Reply
Starfox
Posts: 37
Joined: Wed Jul 27, 2011 12:01 am

Offsetting collision shapes.

Post by Starfox »

How do I change the origin of a collision shape? Let's say I have a cube with its origin around (0,0,0) - it works great with a box shape since in this case both the model and collision shape origins match. Now let's say I have another cube mesh where (0,0,0) in object space is at the center of the bottom face of the cube, for easier placement. How do I build a collision shape for it? I basically want to offset the collision shape by -.5 * cubeSideDimension in the Y direction.
Jonathan
Posts: 36
Joined: Sun Feb 10, 2013 6:52 pm

Re: Offsetting collision shapes.

Post by Jonathan »

I believe the answer in the past has been to use a btCompoundShape since you can control the individual offset of each sub-shape.
Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Re: Offsetting collision shapes.

Post by Flix »

For convex shapes (like a cuboid), you can also just use a plain btConvexHullShape passing to it the 6 vertices of the cuboid (which are not centered in the origin).

However the btCompoundShape wrapper is the default way to do it, maybe because the localAABB (used for broadphase culling) of an off-center btConvexHullShape is not optimal (just guessing: I don't master the Bullet internals).

However both approaches do work.
Starfox
Posts: 37
Joined: Wed Jul 27, 2011 12:01 am

Re: Offsetting collision shapes.

Post by Starfox »

How would the moment of inertia vectors be affected by both methods? I'm not sure how it would work in the former but I think the latter would enable me to use Bullet's built-in inertia calculation - am I correct?
Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Re: Offsetting collision shapes.

Post by Flix »

Starfox wrote:How would the moment of inertia vectors be affected by both methods? I'm not sure how it would work in the former but I think the latter would enable me to use Bullet's built-in inertia calculation - am I correct?
I don't know exacly how Bullet computes the local inertia for btCompoundShapes and btConvexHullShapes in general, so you may be right, but I can't be completely sure.

However for most shapes I just use the local inertia Bullet provides.
Lehooo
Posts: 1
Joined: Tue Nov 19, 2013 4:02 pm

Re: Offsetting collision shapes.

Post by Lehooo »

This is an old topic but I'm going to reply anyway (perhaps someone will find it useful). I was just struggling with the exact same problem before I found this post. After reading the previous replies, I took some time to think about it. I came up with a solution that seems to work perfectly (and please point out any problems that I've overlooked, I may be missing something important).

The way I approached the problem was to calculate the actual offset based on the rotation (the offset relative to the orientation of the body/mesh) and take that into consideration when calculating the position. In getWorldTransform I take the position, rotation and offset, calculate the final offset by multiplying the offset by the rotation, add the final offset to the position, and use this to set the origin of the btTransform:

Code: Select all

void getWorldTransform( btTransform& worldTrans ) const
{
  btTransform transform;

  transform.setIdentity();

  vec3 position = // Get the position from my engine
  quat rotation = // Get the rotation from my engine
  vec3 offset = // Get the offset from my engine

  vec3 finalOffset = rotation * offset;

  transform.setOrigin( btVector3( position.x + finalOffset.x, position.y + finalOffset.y, position.z + finalOffset.z ) );

  transform.setRotation( btQuaternion( rotation.x, rotation.y, rotation.z, rotation.w ) );

  worldTrans = transform;
}
Then in setWorldTransform, I calculate the final offset in the same way, but instead subtract it from the position:

Code: Select all

void setWorldTransform( const btTransform& worldTrans )
{
  btVector3 btPosition = worldTrans.getOrigin();
  btQuaternion btRotation = worldTrans.getRotation();

  vec3 offset = // Get the offset from my engine
  quat rotation = quat( btRotation.w(), btRotation.x(), btRotation.y(), btRotation.z() );
  vec3 finalOffset = rotation * offset;

  vec3 position = vec3( float( btPosition.x() ) - finalOffset.x,
                        float( btPosition.y() ) - finalOffset.y,
                        float( btPosition.z() ) - finalOffset.z );

  // Finally, set the position and rotation for the rendering engine, this part is left out as it will be different for everyone.
}
Post Reply