[solved] Problem with bodies

Eldritch

07-04-2007 15:40:58

I have a large rectangle representing my character. I made it in MAX with the following dimensions:
Height = 2.0 m
Width = 1.0 m
Length = 1.0 m

As it's body, I made an ellipsoid with the size (1, 2, 1).

I also have a couple of small boxes that are of size 0.5 mx0.5 mx0.5 m. For them, I have created box bodies with the size (0.5, 0.5, 0.5).

Now, here comes the funny part. I am noticing that as the Y component of the size for my ellipsoid increases, the character rectangle seems to float above the ground. Even with 1.0 as the size on Y, it is slightly hovering. I am guessing that the body's position is actually at the feet of the character and not at the center, which is quite weird since the SceneNode for the character is clearly at its head...

The boxes are even more weird.. they often fall halfway through the ground, even if I increase their body size by x10... again I am suspecting some form of misplacement of bodies when they are created with Newton.

Code for boxes:

public void SetupPhysBodyBox(CProp refProp, float fSizeX, float fSizeY, float fSizeZ)
{
Entity refEntity = refProp.GetEntity();
SceneNode refNode = refProp.GetSceneNode();

float mass = refEntity.BoundingBox.Volume * 2.5f;
Vector3 size = new Vector3(fSizeX, fSizeY, fSizeZ);
Vector3 inert = MomentOfInertia.CalcBoxSolid(mass, size);

Collision col = new MogreNewt.CollisionPrimitives.Box
(
CPhysicsServer_s.Instance.GetPhysWorld(),
size
);

m_refPhysBody = new Body(CPhysicsServer_s.Instance.GetPhysWorld(), col);
col.Dispose();
m_refPhysBody.attachToNode(refNode);
refNode.ShowBoundingBox = true;
m_refPhysBody.setMassMatrix(mass, inert);
m_refPhysBody.IsGravityEnabled = true;
Vector3 pos = refNode.Position;
m_refPhysBody.setPositionOrientation(pos, refNode.Orientation);
m_refPhysBody.setAutoFreeze(0);
m_refPhysBody.ForceCallback += new ForceCallbackHandler(Prop_ForceCallback);
m_refParentProp = refProp;
}


Code for character:

public void SetupPhysBodyEllipsoid(CCharacter refCharacter, float fSizeX, float fSizeY, float fSizeZ)
{
Entity refEntity = refCharacter.GetEntity();
SceneNode refNode = refCharacter.GetSceneNode();

float mass = refEntity.BoundingBox.Volume * 2.5f;
Vector3 size = new Vector3(fSizeX, fSizeY, fSizeZ);
Vector3 inert = MomentOfInertia.CalcEllipsoidSolid(mass, size);

Collision col = new MogreNewt.CollisionPrimitives.Ellipsoid
(
CPhysicsServer_s.Instance.GetPhysWorld(),
size
);

m_refPhysBody = new Body(CPhysicsServer_s.Instance.GetPhysWorld(), col);
col.Dispose();
m_refPhysBody.attachToNode(refNode);
m_refPhysBody.setMassMatrix(mass, inert);
m_refPhysBody.IsGravityEnabled = true;
m_refPhysBody.setPositionOrientation(refNode.Position, refNode.Orientation);
m_refPhysBody.setAutoFreeze(0);
m_refPhysBody.ForceCallback += new ForceCallbackHandler(Character_ForceCallback);

// Restrict rotation to Y axis only.
MogreNewt.BasicJoints.UpVector uv = new MogreNewt.BasicJoints.UpVector
(
CPhysicsServer_s.Instance.GetPhysWorld(),
m_refPhysBody,
Vector3.UNIT_Y
);

m_refParentCharacter = refCharacter;
}


Do I have build my stuff in MAX so that they have their center at origin (i.e. (0, 0, 0))?? I am totally lost as to why Newton refuses to cooperate with me on this :(

Acid_Gambit

07-04-2007 16:02:31

I think I had the same problem:

Collision body completely offset

And for me aligning the objects in 3ds to the 0,0,0 origin solved the problem. Now my bodies stay aligned even after I scale the nodes.

Langhole

07-04-2007 16:05:55

you're using C#? (sorry I've never coded in C# so I'm not sure if my answer can help you)

I get (most of the time) the same kind of problem... I do, lets say... this:


// vars
Vector3 m_col_pos(m_pos.x, m_pos.y, m_pos.z);
Vector3 size(5, 1.2, 3);
Real mass = ( size.x * size.y * size.z ) * 100;
Vector3 inertia = MomentOfInertia::CalcBoxSolid( mass, size );

// mesh
Entity* ent = mSceneMgr->createEntity(m_name + "_mesh", "box.mesh");
ent->setMaterialName("Examples/BumpyMetal");
ent->setCastShadows(true);
SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(m_name + "_node");
node->attachObject(ent);
node->setScale(size);

// body
Collision* col = new CollisionPrimitives::ConvexHull(mWorld, node, m_orient, m_col_pos);
Body* bod = new Body(mWorld, col);
bod->attachToNode(node);
bod->setPositionOrientation(m_pos, m_orient);
bod->setMassMatrix( mass, inertia );
bod->setStandardForceCallback();

delete col;


Should work just dandy, in fact it does, except that the collision is somehow offset from the mesh ( anything other than 0,0,0 is unpredictable ).

So I found a half-assed fix, which works flawlessly for my project, not sure if it'll work for anyone else but...

Just before you create the collision, change the position var like this:

Vector3 m_col_pos((m_pos.x - m_pos.x), (m_pos.y - m_pos.y), (m_pos.z - m_pos.z));

Now, I'm not sure if you can just put 0,0,0 there instead.. but either way, it works fine..

Eldritch

07-04-2007 18:45:41

Cool!! Moving the models in MAX to origin fixed it all!! Thanks guys!!