forked from bartvdbraak/blender
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).
This commit is contained in:
parent
cc77001416
commit
f840bd4a9f
@ -78,6 +78,14 @@ Physics Constraints (bge.constraints)
|
||||
|
||||
:return: a vehicle constraint object.
|
||||
:rtype: :class:`bge.types.KX_VehicleWrapper`
|
||||
|
||||
.. function:: getCharacter(gameobj)
|
||||
|
||||
:arg gameobj: The game object with the character physics.
|
||||
:type gameobj: :class:`bge.types.KX_GameObject`
|
||||
|
||||
:return: character wrapper
|
||||
:rtype: :class:`bge.types.KX_CharacterWrapper`
|
||||
|
||||
.. function:: removeConstraint(constraintId)
|
||||
|
||||
|
@ -3464,6 +3464,26 @@ Types
|
||||
:arg wheelIndex: the wheel index
|
||||
:type wheelIndex: integer
|
||||
|
||||
.. class:: KX_CharacterWrapper(PyObjectPlus)
|
||||
|
||||
A wrapper to expose character physics options.
|
||||
|
||||
.. attribute:: onGround
|
||||
|
||||
Whether or not the character is on the ground. (read-only)
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. attribute:: gravity
|
||||
|
||||
The gravity value used for the character.
|
||||
|
||||
:type: float
|
||||
|
||||
.. method:: jump()
|
||||
|
||||
The character jumps based on it's jump speed.
|
||||
|
||||
.. class:: KX_VertexProxy(SCA_IObject)
|
||||
|
||||
A vertex holds position, UV, color and normal information.
|
||||
|
@ -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
|
||||
|
94
source/gameengine/Ketsji/KX_CharacterWrapper.cpp
Normal file
94
source/gameengine/Ketsji/KX_CharacterWrapper.cpp
Normal file
@ -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<KX_CharacterWrapper*>(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<KX_CharacterWrapper*>(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<KX_CharacterWrapper*>(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
|
35
source/gameengine/Ketsji/KX_CharacterWrapper.h
Normal file
35
source/gameengine/Ketsji/KX_CharacterWrapper.h
Normal file
@ -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__
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ set(SRC
|
||||
PHY_IVehicle.cpp
|
||||
|
||||
PHY_DynamicTypes.h
|
||||
PHY_ICharacter.h
|
||||
PHY_IController.h
|
||||
PHY_IGraphicController.h
|
||||
PHY_IMotionState.h
|
||||
|
30
source/gameengine/Physics/common/PHY_ICharacter.h
Normal file
30
source/gameengine/Physics/common/PHY_ICharacter.h
Normal file
@ -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__
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user