Segfault with collisions

ceacy

18-01-2007 22:27:09

Hi
Sometimes, in my application, a segfault occurs with that message :
ODE INTERNAL ERROR 2: GeomTransform encapsulated object must not be in a space in dCollideTransform()

The code for physics creation is :

/* Physics */
// Based on http://www.ogre3d.org/wiki/index.php/OgreOde_Walking_Character#Creating_the_physics_model
{
const Ogre::Vector3& nodeScale = mNode->getScale();
const Ogre::AxisAlignedBox& aab = mEntity->getBoundingBox();
Ogre::Vector3 min = aab.getMinimum() * nodeScale;
Ogre::Vector3 max = aab.getMaximum() * nodeScale;
Ogre::Vector3 center = aab.getCenter() * nodeScale;
Ogre::Vector3 size( std::fabs( max.x-min.x ), std::fabs( max.y-min.y ), std::fabs( max.z-min.z ) );
float height = size.y;

OgreOde::World* world = PlayState::getSingleton().getPhysicsWorld();
float radius = ( size.x > size.z ) ? size.z/2.0f : size.x/2.0f;

OgreOde::SimpleSpace* dollSpace = new OgreOde::SimpleSpace( world, world->getDefaultSpace() );
dollSpace->setInternalCollisions( false );

/* Feet */
mFeet = new OgreOde::Body( world, mID+"_feet" );
mFeet->setMass( OgreOde::SphereMass( 40, radius ) );
OgreOde::SphereGeometry* feetGeom = new OgreOde::SphereGeometry( radius, world );
OgreOde::TransformGeometry* feetTrans = new OgreOde::TransformGeometry( world, dollSpace );
mModelNode->translate( Ogre::Vector3( 0, -min.y / nodeScale.y, 0 ) ); // The bounding box must have its bottom at the height 0
feetTrans->setBody( mFeet );
feetTrans->setEncapsulatedGeometry( feetGeom );
mNode->attachObject( mFeet );
PlayState::getSingleton().registerBody( mID+"_feet", mFeet );

/* Torso */
mTorso = new OgreOde::Body( world, mID+"_torso" );
mTorso->setMass( OgreOde::CapsuleMass( 40, radius, Ogre::Vector3::UNIT_Y, radius ) );
mTorso->setAffectedByGravity( false );
mTorso->setDamping( 0, 50000 );
OgreOde::TransformGeometry* torsoTrans = new OgreOde::TransformGeometry( world, dollSpace );
OgreOde::CapsuleGeometry* torsoGeom = new OgreOde::CapsuleGeometry( radius, height*nodeScale.y-4*radius, world, dollSpace );
torsoGeom->setPosition( Ogre::Vector3( 0, height/2, 0 ) );
torsoGeom->setOrientation( Ogre::Quaternion( Ogre::Degree(90), Ogre::Vector3::UNIT_X ) );
torsoTrans->setBody( mTorso );
torsoTrans->setEncapsulatedGeometry( torsoGeom );
mNode->attachObject( mTorso );
PlayState::getSingleton().registerBody( mID+"_torso", mTorso );

/* Joint */
OgreOde::BallJoint* joint = new OgreOde::BallJoint( world );
joint->attach( mTorso, mFeet );

mFeet->wake();
mFeet->setPosition( _pos );
}


and collisions :
bool PlayState::collision( OgreOde::Contact* contact )
{
// Check for collisions between things that are connected and ignore them
OgreOde::Geometry * const g1 = contact->getFirstGeometry();
OgreOde::Geometry * const g2 = contact->getSecondGeometry();

if (g1 && g2)
{
const OgreOde::Body * const b1 = g1->getBody();
const OgreOde::Body * const b2 = g2->getBody();
if (b1 && b2 && OgreOde::Joint::areConnected(b1, b2))
return false;
}

// Set the friction at the contact
contact->setCoulombFriction( OgreOde::Utility::Infinity );

contact->setBouncyness( 0.8 );
contact->setCoulombFriction( OgreOde::Utility::Infinity );
contact->setFrictionMode( OgreOde::Contact::Flag_FrictionPyramid );

// Yes, this collision is valid
return true;
}


Do i do something wrong ?

Thanks,
Ceacy.

tuan kuranes

19-01-2007 11:50:56

Check exactly how transfom are created in the Apache (crash) ogreode simplescenes. Your problem comes from that.

ceacy

19-01-2007 19:25:23

Thanks ... with your answer and a look to the ode code, i found the solution :
int dCollideTransform (dxGeom *o1, dxGeom *o2, int flags,
dContactGeom *contact, int skip)
{
dIASSERT (skip >= (int)sizeof(dContactGeom));
dIASSERT (o1->type == dGeomTransformClass);

dxGeomTransform *tr = (dxGeomTransform*) o1;
if (!tr->obj) return 0;
dUASSERT (tr->obj->parent_space==0,
"GeomTransform encapsulated object must not be in a space");
dUASSERT (tr->obj->body==0,
"GeomTransform encapsulated object must not be attached "
"to a body");


The error was :
OgreOde::CapsuleGeometry* torsoGeom = new OgreOde::CapsuleGeometry( radius, height*nodeScale.y-4*radius, world, dollSpace );


(the last parameter had to be "0")