From f840bd4a9f89815ca213d8398c99865fc6d64e4c Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Sun, 4 Nov 2012 20:56:02 +0000 Subject: BGE: This patch adds a character wrapper (similar to the already implemented vehicle wrapper) to control character physics options. Currently supported options are: * jump() -- causes the character to jump * onGround -- specifies whether or not the character is on the ground * gravity -- controls the "gravity" that the character physics uses for the character More options could be added (such as jump speed, step height, make fall speed, max slope, etc). --- source/gameengine/Ketsji/CMakeLists.txt | 2 + source/gameengine/Ketsji/KX_CharacterWrapper.cpp | 94 ++++++++++++++++++++++ source/gameengine/Ketsji/KX_CharacterWrapper.h | 35 ++++++++ .../gameengine/Ketsji/KX_PyConstraintBinding.cpp | 34 ++++++++ source/gameengine/Ketsji/KX_PythonInitTypes.cpp | 2 + .../Physics/Bullet/CcdPhysicsEnvironment.cpp | 40 +++++++++ .../Physics/Bullet/CcdPhysicsEnvironment.h | 2 + .../Physics/Dummy/DummyPhysicsEnvironment.h | 6 ++ source/gameengine/Physics/common/CMakeLists.txt | 1 + source/gameengine/Physics/common/PHY_ICharacter.h | 30 +++++++ .../Physics/common/PHY_IPhysicsEnvironment.h | 4 + 11 files changed, 250 insertions(+) create mode 100644 source/gameengine/Ketsji/KX_CharacterWrapper.cpp create mode 100644 source/gameengine/Ketsji/KX_CharacterWrapper.h create mode 100644 source/gameengine/Physics/common/PHY_ICharacter.h (limited to 'source') diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt index b42c2c27075..4778a6ef9b9 100644 --- a/source/gameengine/Ketsji/CMakeLists.txt +++ b/source/gameengine/Ketsji/CMakeLists.txt @@ -74,6 +74,7 @@ set(SRC KX_Camera.cpp KX_CameraActuator.cpp KX_CameraIpoSGController.cpp + KX_CharacterWrapper.cpp KX_ConstraintActuator.cpp KX_ConstraintWrapper.cpp KX_ConvertPhysicsObjects.cpp @@ -149,6 +150,7 @@ set(SRC KX_Camera.h KX_CameraActuator.h KX_CameraIpoSGController.h + KX_CharacterWrapper.h KX_ClientObjectInfo.h KX_ConstraintActuator.h KX_ConstraintWrapper.h diff --git a/source/gameengine/Ketsji/KX_CharacterWrapper.cpp b/source/gameengine/Ketsji/KX_CharacterWrapper.cpp new file mode 100644 index 00000000000..ce208f3a75f --- /dev/null +++ b/source/gameengine/Ketsji/KX_CharacterWrapper.cpp @@ -0,0 +1,94 @@ +/** \file gameengine/Ketsji/KX_CharacterWrapper.cpp + * \ingroup ketsji + */ + + +#include "KX_CharacterWrapper.h" +#include "PHY_ICharacter.h" + +KX_CharacterWrapper::KX_CharacterWrapper(PHY_ICharacter* character) : + PyObjectPlus(), + m_character(character) +{ +} + +KX_CharacterWrapper::~KX_CharacterWrapper() +{ + if (m_character) + delete m_character; // We're responsible for the character object! +} + +#ifdef WITH_PYTHON + +PyTypeObject KX_CharacterWrapper::Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "KX_CharacterWrapper", + sizeof(PyObjectPlus_Proxy), + 0, + py_base_dealloc, + 0, + 0, + 0, + 0, + py_base_repr, + 0,0,0,0,0,0,0,0,0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + 0,0,0,0,0,0,0, + Methods, + 0, + 0, + &PyObjectPlus::Type, + 0,0,0,0,0,0, + py_base_new +}; + +PyAttributeDef KX_CharacterWrapper::Attributes[] = { + KX_PYATTRIBUTE_RO_FUNCTION("onGround", KX_CharacterWrapper, pyattr_get_onground), + KX_PYATTRIBUTE_RW_FUNCTION("gravity", KX_CharacterWrapper, pyattr_get_gravity, pyattr_set_gravity), + { NULL } //Sentinel +}; + +PyObject *KX_CharacterWrapper::pyattr_get_onground(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_CharacterWrapper* self = static_cast(self_v); + + return PyBool_FromLong(self->m_character->OnGround()); +} + +PyObject *KX_CharacterWrapper::pyattr_get_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) +{ + KX_CharacterWrapper* self = static_cast(self_v); + + return PyFloat_FromDouble(self->m_character->GetGravity()); +} + +int KX_CharacterWrapper::pyattr_set_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value) +{ + KX_CharacterWrapper* self = static_cast(self_v); + double param = PyFloat_AsDouble(value); + + if (param == -1) + { + PyErr_SetString(PyExc_ValueError, "KX_CharacterWrapper.gravity: expected a float"); + return PY_SET_ATTR_FAIL; + } + + self->m_character->SetGravity((float)param); + return PY_SET_ATTR_SUCCESS; +} + +PyMethodDef KX_CharacterWrapper::Methods[] = { + KX_PYMETHODTABLE_NOARGS(KX_CharacterWrapper, jump), + {NULL,NULL} //Sentinel +}; + +KX_PYMETHODDEF_DOC_NOARGS(KX_CharacterWrapper, jump, + "jump()\n" + "makes the character jump.\n") +{ + m_character->Jump(); + + Py_RETURN_NONE; +} + +#endif // WITH_PYTHON diff --git a/source/gameengine/Ketsji/KX_CharacterWrapper.h b/source/gameengine/Ketsji/KX_CharacterWrapper.h new file mode 100644 index 00000000000..cc99aba99f6 --- /dev/null +++ b/source/gameengine/Ketsji/KX_CharacterWrapper.h @@ -0,0 +1,35 @@ + +/** \file KX_CharacterWrapper.h + * \ingroup ketsji + */ + +#ifndef __KX_CHARACTERWRAPPER_H__ +#define __KX_CHARACTERWRAPPER_H__ + +#include "Value.h" +#include "PHY_DynamicTypes.h" +class PHY_ICharacter; + + +///Python interface to character physics +class KX_CharacterWrapper : public PyObjectPlus +{ + Py_Header + +public: + KX_CharacterWrapper(PHY_ICharacter* character); + virtual ~KX_CharacterWrapper(); +#ifdef WITH_PYTHON + KX_PYMETHOD_DOC_NOARGS(KX_CharacterWrapper, jump); + + static PyObject* pyattr_get_onground(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); + + static PyObject* pyattr_get_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static int pyattr_set_gravity(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); +#endif // WITH_PYTHON + +private: + PHY_ICharacter* m_character; +}; + +#endif //__KX_CHARACTERWRAPPER_H__ diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp index 5f3a4879150..4475ac8ec96 100644 --- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp +++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp @@ -33,12 +33,15 @@ #include "PHY_IPhysicsEnvironment.h" #include "KX_ConstraintWrapper.h" #include "KX_VehicleWrapper.h" +#include "KX_CharacterWrapper.h" #include "KX_PhysicsObjectWrapper.h" #include "PHY_IPhysicsController.h" #include "PHY_IVehicle.h" #include "PHY_DynamicTypes.h" #include "MT_Matrix3x3.h" +#include "KX_GameObject.h" // ConvertPythonToGameObject() + #include "PyObjectPlus.h" #ifdef USE_BULLET @@ -81,6 +84,7 @@ static char gPySetSolverType__doc__[] = "setSolverType(int solverType) Very expe static char gPyCreateConstraint__doc__[] = "createConstraint(ob1,ob2,float restLength,float restitution,float damping)"; static char gPyGetVehicleConstraint__doc__[] = "getVehicleConstraint(int constraintId)"; +static char gPyGetCharacter__doc__[] = "getCharacter(KX_GameObject obj)"; static char gPyRemoveConstraint__doc__[] = "removeConstraint(int constraintId)"; static char gPyGetAppliedImpulse__doc__[] = "getAppliedImpulse(int constraintId)"; @@ -402,6 +406,33 @@ static PyObject *gPyGetVehicleConstraint(PyObject *self, Py_RETURN_NONE; } +static PyObject* gPyGetCharacter(PyObject* self, + PyObject* args, + PyObject* kwds) +{ + PyObject* pyob; + KX_GameObject *ob; + + if (!PyArg_ParseTuple(args,"O", &pyob)) + return NULL; + + if (!ConvertPythonToGameObject(pyob, &ob, false, "bge.constraints.getCharacter(value)")) + return NULL; + + if (PHY_GetActiveEnvironment()) + { + + PHY_ICharacter* character= PHY_GetActiveEnvironment()->getCharacterController(ob); + if (character) + { + KX_CharacterWrapper* pyWrapper = new KX_CharacterWrapper(character); + return pyWrapper->NewProxy(true); + } + + } + + Py_RETURN_NONE; +} static PyObject *gPyCreateConstraint(PyObject *self, PyObject *args, @@ -631,6 +662,9 @@ static struct PyMethodDef physicsconstraints_methods[] = { {"getVehicleConstraint",(PyCFunction) gPyGetVehicleConstraint, METH_VARARGS, (const char *)gPyGetVehicleConstraint__doc__}, + {"getCharacter",(PyCFunction) gPyGetCharacter, + METH_VARARGS, (const char *)gPyGetCharacter__doc__}, + {"removeConstraint",(PyCFunction) gPyRemoveConstraint, METH_VARARGS, (const char *)gPyRemoveConstraint__doc__}, {"getAppliedImpulse",(PyCFunction) gPyGetAppliedImpulse, diff --git a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp index d0e3d26f61b..805b9ce2fc2 100644 --- a/source/gameengine/Ketsji/KX_PythonInitTypes.cpp +++ b/source/gameengine/Ketsji/KX_PythonInitTypes.cpp @@ -42,6 +42,7 @@ #include "BL_ArmatureChannel.h" #include "KX_BlenderMaterial.h" #include "KX_CameraActuator.h" +#include "KX_CharacterWrapper.h" #include "KX_ConstraintActuator.h" #include "KX_ConstraintWrapper.h" #include "KX_GameActuator.h" @@ -189,6 +190,7 @@ void initPyTypes(void) PyType_Ready_Attr(dict, KX_BlenderMaterial, init_getset); PyType_Ready_Attr(dict, KX_Camera, init_getset); PyType_Ready_Attr(dict, KX_CameraActuator, init_getset); + PyType_Ready_Attr(dict, KX_CharacterWrapper, init_getset); PyType_Ready_Attr(dict, KX_ConstraintActuator, init_getset); PyType_Ready_Attr(dict, KX_ConstraintWrapper, init_getset); PyType_Ready_Attr(dict, KX_GameActuator, init_getset); diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 687fc116234..486411d7e35 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -37,6 +37,7 @@ subject to the following restrictions: #include "PHY_IMotionState.h" +#include "PHY_ICharacter.h" #include "KX_GameObject.h" #include "RAS_MeshObject.h" #include "RAS_Polygon.h" @@ -266,6 +267,36 @@ public: }; #endif //NEW_BULLET_VEHICLE_SUPPORT +class CharacterWrapper : public PHY_ICharacter +{ +private: + btKinematicCharacterController* m_controller; + +public: + CharacterWrapper(btKinematicCharacterController* cont) + : m_controller(cont) + {} + + virtual void Jump() + { + m_controller->jump(); + } + + virtual bool OnGround() + { + return m_controller->onGround(); + } + + virtual float GetGravity() + { + return m_controller->getGravity(); + } + virtual void SetGravity(float gravity) + { + m_controller->setGravity(gravity); + } +}; + class CcdOverlapFilterCallBack : public btOverlapFilterCallback { private: @@ -2285,6 +2316,15 @@ PHY_IVehicle* CcdPhysicsEnvironment::getVehicleConstraint(int constraintId) #endif //NEW_BULLET_VEHICLE_SUPPORT +PHY_ICharacter* CcdPhysicsEnvironment::getCharacterController(KX_GameObject *ob) +{ + CcdPhysicsController* controller = (CcdPhysicsController*)ob->GetPhysicsController()->GetUserData(); + if (controller->GetCharacterController()) + return new CharacterWrapper(controller->GetCharacterController()); + + return NULL; +} + int currentController = 0; int numController = 0; diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h index 350ecd2588a..18ce0550498 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h @@ -184,6 +184,8 @@ protected: return 0; } #endif /* NEW_BULLET_VEHICLE_SUPPORT */ + // Character physics wrapper + virtual PHY_ICharacter* getCharacterController(class KX_GameObject* ob); btTypedConstraint* getConstraintById(int constraintId); diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h index 70de9c25553..233c4412d9e 100644 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h +++ b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h @@ -68,6 +68,12 @@ public: //complex constraint for vehicles virtual PHY_IVehicle* getVehicleConstraint(int constraintId) + { + return 0; + } + + // Character physics wrapper + virtual PHY_ICharacter* getCharacterController(class KX_GameObject* ob) { return 0; } diff --git a/source/gameengine/Physics/common/CMakeLists.txt b/source/gameengine/Physics/common/CMakeLists.txt index ceb7a8ba548..400e475f8a2 100644 --- a/source/gameengine/Physics/common/CMakeLists.txt +++ b/source/gameengine/Physics/common/CMakeLists.txt @@ -41,6 +41,7 @@ set(SRC PHY_IVehicle.cpp PHY_DynamicTypes.h + PHY_ICharacter.h PHY_IController.h PHY_IGraphicController.h PHY_IMotionState.h diff --git a/source/gameengine/Physics/common/PHY_ICharacter.h b/source/gameengine/Physics/common/PHY_ICharacter.h new file mode 100644 index 00000000000..e2fc5e45125 --- /dev/null +++ b/source/gameengine/Physics/common/PHY_ICharacter.h @@ -0,0 +1,30 @@ + +/** \file PHY_ICharacter.h + * \ingroup phys + */ + +#ifndef __PHY_ICHARACTER_H__ +#define __PHY_ICHARACTER_H__ + +//PHY_ICharacter provides a generic interface for "character" controllers + +#ifdef WITH_CXX_GUARDEDALLOC +#include "MEM_guardedalloc.h" +#endif + +class PHY_ICharacter +{ +public: + + virtual void Jump()= 0; + virtual bool OnGround()= 0; + + virtual float GetGravity()= 0; + virtual void SetGravity(float gravity)= 0; + +#ifdef WITH_CXX_GUARDEDALLOC + MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_ICharacter") +#endif +}; + +#endif //__PHY_ICHARACTER_H__ diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h index 66ca037aa47..077d225903c 100644 --- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h +++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h @@ -40,6 +40,7 @@ #endif class PHY_IVehicle; +class PHY_ICharacter; class RAS_MeshObject; class PHY_IPhysicsController; @@ -156,6 +157,9 @@ class PHY_IPhysicsEnvironment //complex constraint for vehicles virtual PHY_IVehicle* getVehicleConstraint(int constraintId) =0; + // Character physics wrapper + virtual PHY_ICharacter* getCharacterController(class KX_GameObject* ob) =0; + virtual PHY_IPhysicsController* rayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ)=0; //culling based on physical broad phase -- cgit v1.2.3