diff --git a/panda/src/ode/odeSpace.cxx b/panda/src/ode/odeSpace.cxx index f31519f4e7..84c8279eb4 100755 --- a/panda/src/ode/odeSpace.cxx +++ b/panda/src/ode/odeSpace.cxx @@ -15,6 +15,13 @@ #include "config_ode.h" #include "odeSpace.h" +#ifdef HAVE_PYTHON + #include "py_panda.h" + #include "typedReferenceCount.h" + #ifndef CPPPARSER + extern EXPCL_PANDAODE Dtool_PyTypedObject Dtool_OdeGeom; + #endif +#endif TypeHandle OdeSpace::_type_handle; // this data is used in auto_collide @@ -25,6 +32,9 @@ dJointGroupID OdeSpace::_collide_joint_group; int OdeSpace::contactCount = 0; double OdeSpace::contact_data[192]; int OdeSpace::contact_ids[128]; +#ifdef HAVE_PYTHON +PyObject* OdeSpace::_python_callback = NULL; +#endif OdeSpace:: OdeSpace(dSpaceID id) : @@ -103,7 +113,7 @@ set_auto_collide_joint_group(OdeJointGroup &joint_group) } int OdeSpace:: -autoCollide() +auto_collide() { if (my_world == NULL) { odespace_cat.error() << "No collide world has been set!\n"; @@ -112,7 +122,7 @@ autoCollide() OdeSpace::contactCount = 0; _collide_space = this; _collide_world = my_world; - dSpaceCollide(_id, this, &autoCallback); + dSpaceCollide(_id, this, &auto_callback); return OdeSpace::contactCount; } } @@ -144,11 +154,8 @@ get_contact_id(int data_index, int first) } } - - - void OdeSpace:: -autoCallback(void *data, dGeomID o1, dGeomID o2) +auto_callback(void *data, dGeomID o1, dGeomID o2) // uses data stored on the world to resolve collisions so you don't have to use near_callbacks in python { int i; @@ -210,6 +217,37 @@ autoCallback(void *data, dGeomID o1, dGeomID o2) } +#ifdef HAVE_PYTHON +int OdeSpace:: +collide(PyObject* arg, PyObject* callback) { + nassertr(callback != NULL, -1); + if (!PyCallable_Check(callback)) { + PyErr_Format(PyExc_TypeError, "'%s' object is not callable", callback->ob_type->tp_name); + return -1; + } else { + OdeSpace::_python_callback = (PyObject*) callback; + Py_XINCREF(OdeSpace::_python_callback); + dSpaceCollide(_id, (void*) arg, &near_callback); + Py_XDECREF(OdeSpace::_python_callback); + return 0; + } +} + +void OdeSpace:: +near_callback(void *data, dGeomID o1, dGeomID o2) { + odespace_cat.spam() << "near_callback called, data: " << data << ", dGeomID1: " << o1 << ", dGeomID2: " << o2 << "\n"; + OdeGeom g1 (o1); + OdeGeom g2 (o2); + PyObject* p1 = DTool_CreatePyInstanceTyped(&g1, Dtool_OdeGeom, true, false, g1.get_type_index()); + PyObject* p2 = DTool_CreatePyInstanceTyped(&g2, Dtool_OdeGeom, true, false, g2.get_type_index()); + PyObject* result = PyEval_CallFunction(_python_callback, "OOO", (PyObject*) data, p1, p2); + if (!result) { + odespace_cat.error() << "An error occurred while calling python function!\n"; + PyErr_Print(); + } +} +#endif + OdeSimpleSpace OdeSpace:: convert_to_simple_space() const { nassertr(_id != 0, OdeSimpleSpace((dSpaceID)0)); diff --git a/panda/src/ode/odeSpace.h b/panda/src/ode/odeSpace.h index cc48309e73..56ee768fcb 100755 --- a/panda/src/ode/odeSpace.h +++ b/panda/src/ode/odeSpace.h @@ -26,6 +26,11 @@ #include "ode_includes.h" +#ifdef HAVE_PYTHON + #include "py_panda.h" + #include "Python.h" +#endif + class OdeGeom; class OdeTriMeshGeom; class OdeSimpleSpace; @@ -85,11 +90,15 @@ PUBLISHED: OdeHashSpace convert_to_hash_space() const; OdeQuadTreeSpace convert_to_quad_tree_space() const; - int autoCollide(); - static void autoCallback(void*, dGeomID, dGeomID); + int auto_collide(); + static void auto_callback(void*, dGeomID, dGeomID); +#ifdef HAVE_PYTHON + int collide(PyObject* arg, PyObject* near_callback); + static void near_callback(void*, dGeomID, dGeomID); +#endif static double get_contact_data(int data_index); int get_contact_id(int data_index, int first = 0); - int set_collide_id( int collide_id, dGeomID id); + int set_collide_id(int collide_id, dGeomID id); int set_collide_id(OdeGeom& geom, int collide_id); void set_surface_type( int surface_type, dGeomID id); void set_surface_type(OdeGeom& geom, int surface_type); @@ -104,6 +113,9 @@ public: static OdeWorld* _collide_world; static OdeSpace* _collide_space; static dJointGroupID _collide_joint_group; +#ifdef HAVE_PYTHON + static PyObject* _python_callback; +#endif static int contactCount; static double contact_data[192]; // 64 times three