diff --git a/panda/src/ode/odeJoint.h b/panda/src/ode/odeJoint.h index eda2a98b96..47233a9361 100644 --- a/panda/src/ode/odeJoint.h +++ b/panda/src/ode/odeJoint.h @@ -83,7 +83,7 @@ PUBLISHED: INLINE void set_feedback(bool flag = true); INLINE OdeJointFeedback *get_feedback(); - EXTENSION(void attach(const OdeBody *body1, const OdeBody *body2)); + EXTENSION(void attach(PyObject *body1, PyObject *body2)); void attach_bodies(const OdeBody &body1, const OdeBody &body2); void attach_body(const OdeBody &body, int index); void detach(); diff --git a/panda/src/ode/odeJoint_ext.cxx b/panda/src/ode/odeJoint_ext.cxx index 6f284e1213..57669b7644 100644 --- a/panda/src/ode/odeJoint_ext.cxx +++ b/panda/src/ode/odeJoint_ext.cxx @@ -29,6 +29,7 @@ #include "odePlane2dJoint.h" #ifndef CPPPARSER +extern Dtool_PyTypedObject Dtool_OdeBody; extern Dtool_PyTypedObject Dtool_OdeJoint; extern Dtool_PyTypedObject Dtool_OdeBallJoint; extern Dtool_PyTypedObject Dtool_OdeHingeJoint; @@ -48,7 +49,23 @@ extern Dtool_PyTypedObject Dtool_OdePlane2dJoint; * attached to the environment. */ void Extension:: -attach(const OdeBody *body1, const OdeBody *body2) { +attach(PyObject *param1, PyObject *param2) { + const OdeBody *body1 = nullptr; + if (param1 != Py_None) { + body1 = (const OdeBody *)DTOOL_Call_GetPointerThisClass(param1, &Dtool_OdeBody, 1, "OdeJoint.attach", true, true); + if (body1 == nullptr) { + return; + } + } + + const OdeBody *body2 = nullptr; + if (param2 != Py_None) { + body2 = (const OdeBody *)DTOOL_Call_GetPointerThisClass(param2, &Dtool_OdeBody, 2, "OdeJoint.attach", true, true); + if (body2 == nullptr) { + return; + } + } + if (body1 && body2) { _this->attach_bodies(*body1, *body2); diff --git a/panda/src/ode/odeJoint_ext.h b/panda/src/ode/odeJoint_ext.h index b61938506f..84dbf4ac93 100644 --- a/panda/src/ode/odeJoint_ext.h +++ b/panda/src/ode/odeJoint_ext.h @@ -30,7 +30,7 @@ template<> class Extension : public ExtensionBase { public: - void attach(const OdeBody *body1, const OdeBody *body2); + void attach(PyObject *body1, PyObject *body2); PyObject *convert() const; }; diff --git a/tests/ode/conftest.py b/tests/ode/conftest.py new file mode 100644 index 0000000000..289304cf0f --- /dev/null +++ b/tests/ode/conftest.py @@ -0,0 +1,7 @@ +import pytest + + +@pytest.fixture +def world(): + ode = pytest.importorskip("panda3d.ode") + return ode.OdeWorld() diff --git a/tests/ode/test_ode_joints.py b/tests/ode/test_ode_joints.py new file mode 100644 index 0000000000..d1e202412d --- /dev/null +++ b/tests/ode/test_ode_joints.py @@ -0,0 +1,43 @@ +import pytest + + +def test_odejoint_attach_both(world): + from panda3d import ode + + body1 = ode.OdeBody(world) + body2 = ode.OdeBody(world) + + assert len(body1.joints) == 0 + assert len(body2.joints) == 0 + + joint = ode.OdeBallJoint(world) + joint.attach(body1, body2) + + assert tuple(body1.joints) == (joint,) + assert tuple(body2.joints) == (joint,) + + +def test_odejoint_attach_0(world): + from panda3d import ode + + body = ode.OdeBody(world) + + assert len(body.joints) == 0 + + joint = ode.OdeBallJoint(world) + joint.attach(body, None) + + assert tuple(body.joints) == (joint,) + + +def test_odejoint_attach_1(world): + from panda3d import ode + + body = ode.OdeBody(world) + + assert len(body.joints) == 0 + + joint = ode.OdeBallJoint(world) + joint.attach(None, body) + + assert tuple(body.joints) == (joint,)