I'm using this code to create the bodies:
- Code: Select all
NewtonBody* CPhysicsInterface::addBody(NewtonCollision* shape,float mass,CBody* entity){
NewtonBody* body;
XMFLOAT3 pos=entity->getPosition();
XMFLOAT4 rot=entity->getQuaternion();
dMatrix world;
world=dMatrix(dQuaternion(rot.x,rot.y,rot.z,rot.w),dVector(pos.x,pos.y,pos.z,1.0f));
body=NewtonCreateBody(pWorld,shape,&world[0][0]);
NewtonBodySetDestructorCallback(body,CPhysicsInterface::DestroyBodyCallback);
NewtonBodySetUserData(body,entity);
dVector origin;
dVector inertia;
NewtonConvexCollisionCalculateInertialMatrix(shape,&inertia[0],&origin[0]);
NewtonBodySetMassMatrix (body,mass,mass*inertia.m_x, mass * inertia.m_y, mass * inertia.m_z);
NewtonBodySetCentreOfMass(body,&origin[0]);
NewtonBodySetForceAndTorqueCallback (body, ApplyForceAndTorqueCallback);
NewtonBodySetTransformCallback (body, SetTransformCallback);
return body;
}
NewtonBody* CPhysicsInterface::addBodyBox(float dx,float dy,float dz,float mass,CBody* entity,NewtonCollision* &shapeOut){
NewtonCollision* shape;
XMFLOAT3 o=entity->getOrigin();
dMatrix offset(GetIdentityMatrix());
offset.m_posit=dVector(o.x,o.y,o.z);
shape=NewtonCreateBox(pWorld,dx,dy,dz,0,&offset[0][0]);
shapeOut=shape;
NewtonBody* body=addBody(shape,mass,entity);
NewtonReleaseCollision(pWorld,shape);
return body;
}
NewtonBody* CPhysicsInterface::addBodyStaticMesh(CBody* entity,vector<float> &vertices,NewtonCollision* &shapeOut){
assert(vertices.size()%9==0);
NewtonCollision* shape=NewtonCreateTreeCollision(pWorld,0);
NewtonTreeCollisionBeginBuild(shape);
int vertexCount=vertices.size()/3;
int faceCount=vertexCount/3;
for(int i=0; i<faceCount; i++){
dVector vertex[3];
for(int v=0; v<3; v++){
vertex[v].m_x=vertices[i*9+3*v];
vertex[v].m_y=vertices[i*9+3*v+1];
vertex[v].m_z=vertices[i*9+3*v+2];
}
NewtonTreeCollisionAddFace(shape,3,&vertex[0].m_x,sizeof(dVector),i+1);
}
NewtonTreeCollisionEndBuild(shape,1);
NewtonBody* body=addBody(shape,0,entity);
NewtonReleaseCollision(pWorld,shape);
return body;
}
To test this, I created a box in my modeler that was offset by quite a bit. I gave it a mass of 5.
I also created a box to act as the ground, which I placed in my modeler at about (0,-5,0).
When I load the ground model and set it's mass to 0, it acts like the ground is centered at 0 rather than -5. The same thing happens whether I call addBodyBox or addBodyStaticMesh. If I edit the model to be centered at 0,0,0 then everything works as normal. What's really confusing me is why the collisiontree is doing this. Is my addBody method doing something to recenter the model?
Edit:
It looks like the model is getting inverted in at least the y direction. I tried negating the y coordinates that were getting passed into the collisiontree, but that created even worse behavior.