Allow for near callbacks in python

This commit is contained in:
rdb 2008-11-05 15:46:19 +00:00
parent 54477b4129
commit 32ec0dd1c6
2 changed files with 59 additions and 9 deletions

View File

@ -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));

View File

@ -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