Matching origins between bullet body and graphic object

User avatar
SynapticBytes
Posts: 74
Joined: Thu Feb 10, 2011 8:27 pm

Matching origins between bullet body and graphic object

Post by SynapticBytes »

Hi All,

I'm still working on my Bullet plugin for Shiva. I'm having a few problems trying to keep the origins aligned between a RigidBody in Bullet, and the graphic model created in Shiva.

The example is a cylinder, both any object where origins don't match between the two is a problem. In Shiva, a standard cylinder origin Y-axis aligned is on the bottom circle face, on the middle of the circle. The Bullet cylinder origin is the centre of the body.

I went through my createCylinderBody API and transformed the body creation to match the graphic object by putting specific tests for cylinders in my generic "setupBody" function, which I think I've got working. But now I've realised my MotionState, which in it's generic form sets the graphic object translation to the Bullet worldTransform, is resetting the work I did in the body setup.

I don't want to have to write a whole bunch of custom code in the setWorldTransform member function for every case where the origins of the body & graphic object don't meet, to try and align them properly. Surely there must be some way to alter the origin of the body? Shiva doesn't allow altering the origin of it's standard shapes from what I can see. If all models were done in a DCC tool which allowed origin changes, then it'd be fine, but this needs to work with any object Shiva users can create, and without control over built-in shapes, I'm stuck.

Can anyone provide any advice on how I might keep the origins aligned, or how I can keep my setWorldTransform function clean to set my graphic object to match the Bullet world transform?

Thanks. Russell.
User avatar
SynapticBytes
Posts: 74
Joined: Thu Feb 10, 2011 8:27 pm

Re: Matching origins between bullet body and graphic object

Post by SynapticBytes »

OK I think I might have figured my own way around it.

I added an origin_offset vector at my motionState call constructor, and then after I've matched my graphic object translate to the world transform, I just set the translation in local space to the origin_offset value. So far it's working anyway. I'm sure there'll be a gotcha somewhere along the way...
Ripiz
Posts: 47
Joined: Mon Aug 16, 2010 10:43 am

Re: Matching origins between bullet body and graphic object

Post by Ripiz »

I'm using DirectX, but maybe it'll help you.

Code: Select all

// get cylinder's rotation, and convert values into Euler
Vector3 rotation = QuatToEuler(&body->getWorldTransform().getRotation());
// set rotation for my object
model->SetRotation(rotation);

// negative cylinder's half extend (only Y axis), in other words, model's offset
Vector4 offset(0, -0.38621816f, 0, 0);
// rotate offset by same rotation which we got earlier (rotationX, rotationY, rotationZ are Matrices generated inside SetRotation() from Euler rotational values)
D3DXVec3Transform(&offset, (Vector3*)&offset, &Matrix(model->rotationX * model->rotationY * model->rotationZ));

// get cylinder's position
position = Vector3(body->getWorldTransform().getOrigin().m_floats);
// set objects position
model->SetPosition(position + (Vector3)offset);
It perfectly matches, however you don't really have to convert Quaternion into Euler, I did this just to understand myself what's going on.
User avatar
SynapticBytes
Posts: 74
Joined: Thu Feb 10, 2011 8:27 pm

Re: Matching origins between bullet body and graphic object

Post by SynapticBytes »

Thanks.

A little different to my method, but I think the end result is the same. My offset varies with the cylinder extents. Anyway, if there's any issues I'll see if your code helps.
Kanttori
Posts: 38
Joined: Thu Jul 08, 2010 12:52 am

Re: Matching origins between bullet body and graphic object

Post by Kanttori »

I'm using the same motionState when flipping objects between being "animated" as in kinematic objects and when they are being simulated by bullet so I take the offset into account in both the get and set functions. Here's my spin on it using center_offset_ and negative_center_offset_ vectors.

Code: Select all

void LinkMotionState::getWorldTransform(btTransform& worldTrans) const
{
  Matrix4x4 temp = object_->globmat;
  Vector3 loc;

  MultiVec(temp, center_offset_, loc);

  temp.setLoc(loc);

  worldTrans.setFromOpenGLMatrix(&temp[0]);
}

Code: Select all

void LinkMotionState::setWorldTransform(const btTransform& worldTrans) const
{
  worldTrans.getOpenGLMatrix(&object_->globmat[0]);

  Vector3 loc;
  MultiVec(object_->globmat, negative_center_offset_, loc);
  object_->globmat.setLoc(loc);
}