Need help with ODE collision

I’m trying to catch ODE collision events, but i cannot seem to get it right. I’m using panda 1.7.0.

My setup code looks like this:

framework.define_key("ode-collision", "ode-collision", &(ODEWorld::onCollision), (void*)this);

The event function looks like this:

void ODEWorld::onCollision(const Event* event, void* data)
	const OdeCollisionEntry* entry = (const OdeCollisionEntry*)(event->get_parameter(0).get_ptr());
	ODEWorld* obj = (ODEWorld*)data;
void ODEWorld::handleCollision(const OdeCollisionEntry* entry)
	const OdeGeom geom1 = entry->get_geom1();
	const OdeGeom geom2 = entry->get_geom2();
	dGeomID geom1ID = geom1.get_id();
	dGeomID geom2ID = geom2.get_id();
	std::cout << "Geom1 = " << geom1ID << " , Geom2 = " << geom2ID << std::endl;

In the simulation loop I do this:

// set pos of nodepaths from ode

The ID for geom1 is 0 the whole time + I don’t get collisions reported for all objects.
Am I doing something wrong here?

Don’t know if it will make a difference, but I call autoCollide before quickStep (in Python).

When I replaced this line:

const OdeCollisionEntry* entry = (const OdeCollisionEntry*)(event->get_parameter(0).get_ptr());

… with this line:

const OdeCollisionEntry* entry = (const OdeCollisionEntry*)(event->get_parameter(0).get_typed_ref_count_value());

… it worked!

I wish the C++ documentation was as good as the Python documentation.

Note that it’s a good idea to use the DCAST macro, instead of static casting, to protect you from mistakes like this in the future:

const OdeCollisionEntry* entry = DCAST(OdeCollisionEntry, event->get_parameter(0).get_ptr()); 

or the equivalent:

const OdeCollisionEntry* entry;
DCAST_INTO_V(entry, event->get_parameter(0).get_ptr());

This will ensure that the pointer you are casting actually is of the type you are casting it to, or it will raise an assertion error otherwise. That would have caught the incorrect-type error from your first attempt. :slight_smile:


The code doesn’t work:

const OdeCollisionEntry* entry = DCAST(OdeCollisionEntry, event->get_parameter(0).get_ptr());

… but this works:

const OdeCollisionEntry* entry = DCAST(OdeCollisionEntry, event->get_parameter(0).get_typed_ref_count_value());

Right, that’s what I mean. The result of get_ptr() isn’t an OdeCollisionEntry, and shouldn’t be cast to one. If you just use a static cast, it will crash mysteriously. If you use the DCAST macro, it should at least tell you that you’re casting a pointer to the wrong type before it crashes mysteriously.


The weird thing is that I didn’t get any crash when doing it the wrong way… my pgm run normally, I just got totally wrong collision results reported back to me.

Well, that’s just the luck of the draw. When you miscast a pointer in C++, you get technically “undefined behavior”, which often means a crash, but it might just mean weird behavior.