2011-02-23 10:52:22 +00:00
/*
2008-04-16 22:40:48 +00:00
* * * * * * BEGIN GPL LICENSE BLOCK * * * * *
2002-10-12 11:37:38 +00:00
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
2008-04-16 22:40:48 +00:00
* of the License , or ( at your option ) any later version .
2002-10-12 11:37:38 +00:00
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software Foundation ,
2010-02-12 13:34:04 +00:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
2002-10-12 11:37:38 +00:00
*
* The Original Code is Copyright ( C ) 2001 - 2002 by NaN Holding BV .
* All rights reserved .
*
* The Original Code is : all of this file .
*
* Contributor ( s ) : none yet .
*
2008-04-16 22:40:48 +00:00
* * * * * * END GPL LICENSE BLOCK * * * * *
2002-10-12 11:37:38 +00:00
*/
2011-02-25 13:35:59 +00:00
/** \file gameengine/Ketsji/KX_PyConstraintBinding.cpp
* \ ingroup ketsji
*/
2002-10-12 11:37:38 +00:00
# include "KX_PyConstraintBinding.h"
# include "PHY_IPhysicsEnvironment.h"
# include "KX_ConstraintWrapper.h"
2006-01-30 20:33:59 +00:00
# include "KX_VehicleWrapper.h"
2002-10-12 11:37:38 +00:00
# include "KX_PhysicsObjectWrapper.h"
# include "PHY_IPhysicsController.h"
2006-01-30 20:33:59 +00:00
# include "PHY_IVehicle.h"
2011-07-30 23:16:22 +00:00
# include "PHY_DynamicTypes.h"
2009-05-24 00:42:40 +00:00
# include "MT_Matrix3x3.h"
2002-10-12 11:37:38 +00:00
2008-09-06 14:13:31 +00:00
# include "PyObjectPlus.h"
2008-09-06 02:46:11 +00:00
2011-07-31 07:45:54 +00:00
# ifdef USE_BULLET
# include "LinearMath / btIDebugDraw.h"
# endif
2011-07-30 23:16:22 +00:00
2010-10-31 04:11:39 +00:00
# ifdef WITH_PYTHON
2009-09-29 21:42:40 +00:00
2011-07-30 23:16:22 +00:00
// macro copied from KX_PythonInit.cpp
# define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyLong_FromSsize_t(name2)); Py_DECREF(item)
2002-10-12 11:37:38 +00:00
// nasty glob variable to connect scripting language
// if there is a better way (without global), please do so!
2005-03-25 10:33:39 +00:00
static PHY_IPhysicsEnvironment * g_CurrentActivePhysicsEnvironment = NULL ;
2002-10-12 11:37:38 +00:00
static char PhysicsConstraints_module_documentation [ ] =
" This is the Python API for the Physics Constraints " ;
static char gPySetGravity__doc__ [ ] = " setGravity(float x,float y,float z) " ;
2005-08-02 14:59:49 +00:00
static char gPySetDebugMode__doc__ [ ] = " setDebugMode(int mode) " ;
2005-08-03 18:22:30 +00:00
static char gPySetNumIterations__doc__ [ ] = " setNumIterations(int numiter) This sets the number of iterations for an iterative constraint solver " ;
2006-05-22 21:03:43 +00:00
static char gPySetNumTimeSubSteps__doc__ [ ] = " setNumTimeSubSteps(int numsubstep) This sets the number of substeps for each physics proceed. Tradeoff quality for performance. " ;
2005-08-03 18:22:30 +00:00
static char gPySetDeactivationTime__doc__ [ ] = " setDeactivationTime(float time) This sets the time after which a resting rigidbody gets deactived " ;
static char gPySetDeactivationLinearTreshold__doc__ [ ] = " setDeactivationLinearTreshold(float linearTreshold) " ;
static char gPySetDeactivationAngularTreshold__doc__ [ ] = " setDeactivationAngularTreshold(float angularTreshold) " ;
static char gPySetContactBreakingTreshold__doc__ [ ] = " setContactBreakingTreshold(float breakingTreshold) Reasonable default is 0.02 (if units are meters) " ;
2005-08-04 19:07:39 +00:00
static char gPySetCcdMode__doc__ [ ] = " setCcdMode(int ccdMode) Very experimental, not recommended " ;
2005-08-03 18:22:30 +00:00
static char gPySetSorConstant__doc__ [ ] = " setSorConstant(float sor) Very experimental, not recommended " ;
2005-08-04 19:07:39 +00:00
static char gPySetSolverTau__doc__ [ ] = " setTau(float tau) Very experimental, not recommended " ;
static char gPySetSolverDamping__doc__ [ ] = " setDamping(float damping) Very experimental, not recommended " ;
static char gPySetLinearAirDamping__doc__ [ ] = " setLinearAirDamping(float damping) Very experimental, not recommended " ;
static char gPySetUseEpa__doc__ [ ] = " setUseEpa(int epa) Very experimental, not recommended " ;
static char gPySetSolverType__doc__ [ ] = " setSolverType(int solverType) Very experimental, not recommended " ;
2005-08-03 18:22:30 +00:00
2002-10-12 11:37:38 +00:00
static char gPyCreateConstraint__doc__ [ ] = " createConstraint(ob1,ob2,float restLength,float restitution,float damping) " ;
2006-01-30 20:33:59 +00:00
static char gPyGetVehicleConstraint__doc__ [ ] = " getVehicleConstraint(int constraintId) " ;
static char gPyRemoveConstraint__doc__ [ ] = " removeConstraint(int constraintId) " ;
2006-07-03 05:58:23 +00:00
static char gPyGetAppliedImpulse__doc__ [ ] = " getAppliedImpulse(int constraintId) " ;
2002-10-12 11:37:38 +00:00
2005-08-02 14:59:49 +00:00
2005-08-03 18:22:30 +00:00
2002-10-12 11:37:38 +00:00
static PyObject * gPySetGravity ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2002-10-12 11:37:38 +00:00
{
float x , y , z ;
2008-07-01 16:43:46 +00:00
if ( PyArg_ParseTuple ( args , " fff " , & x , & y , & z ) )
2002-10-12 11:37:38 +00:00
{
2005-03-25 10:33:39 +00:00
if ( PHY_GetActiveEnvironment ( ) )
PHY_GetActiveEnvironment ( ) - > setGravity ( x , y , z ) ;
2002-10-12 11:37:38 +00:00
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2002-10-12 11:37:38 +00:00
}
2005-08-02 14:59:49 +00:00
static PyObject * gPySetDebugMode ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2005-08-02 14:59:49 +00:00
{
int mode ;
if ( PyArg_ParseTuple ( args , " i " , & mode ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_GetActiveEnvironment ( ) - > setDebugMode ( mode ) ;
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2005-08-03 18:22:30 +00:00
}
2005-08-02 14:59:49 +00:00
2006-05-22 21:03:43 +00:00
static PyObject * gPySetNumTimeSubSteps ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2006-05-22 21:03:43 +00:00
{
int substep ;
if ( PyArg_ParseTuple ( args , " i " , & substep ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_GetActiveEnvironment ( ) - > setNumTimeSubSteps ( substep ) ;
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2006-05-22 21:03:43 +00:00
}
2005-08-03 18:22:30 +00:00
static PyObject * gPySetNumIterations ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2005-08-03 18:22:30 +00:00
{
int iter ;
if ( PyArg_ParseTuple ( args , " i " , & iter ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_GetActiveEnvironment ( ) - > setNumIterations ( iter ) ;
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2005-08-02 14:59:49 +00:00
}
2005-08-03 18:22:30 +00:00
static PyObject * gPySetDeactivationTime ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2005-08-03 18:22:30 +00:00
{
float deactive_time ;
if ( PyArg_ParseTuple ( args , " f " , & deactive_time ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_GetActiveEnvironment ( ) - > setDeactivationTime ( deactive_time ) ;
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2005-08-03 18:22:30 +00:00
}
static PyObject * gPySetDeactivationLinearTreshold ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2005-08-03 18:22:30 +00:00
{
float linearDeactivationTreshold ;
if ( PyArg_ParseTuple ( args , " f " , & linearDeactivationTreshold ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_GetActiveEnvironment ( ) - > setDeactivationLinearTreshold ( linearDeactivationTreshold ) ;
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2005-08-03 18:22:30 +00:00
}
static PyObject * gPySetDeactivationAngularTreshold ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2005-08-03 18:22:30 +00:00
{
float angularDeactivationTreshold ;
if ( PyArg_ParseTuple ( args , " f " , & angularDeactivationTreshold ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_GetActiveEnvironment ( ) - > setDeactivationAngularTreshold ( angularDeactivationTreshold ) ;
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2005-08-03 18:22:30 +00:00
}
static PyObject * gPySetContactBreakingTreshold ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2005-08-03 18:22:30 +00:00
{
float contactBreakingTreshold ;
if ( PyArg_ParseTuple ( args , " f " , & contactBreakingTreshold ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_GetActiveEnvironment ( ) - > setContactBreakingTreshold ( contactBreakingTreshold ) ;
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2005-08-03 18:22:30 +00:00
}
static PyObject * gPySetCcdMode ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2005-08-03 18:22:30 +00:00
{
float ccdMode ;
if ( PyArg_ParseTuple ( args , " f " , & ccdMode ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_GetActiveEnvironment ( ) - > setCcdMode ( ccdMode ) ;
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2005-08-03 18:22:30 +00:00
}
static PyObject * gPySetSorConstant ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2005-08-03 18:22:30 +00:00
{
float sor ;
if ( PyArg_ParseTuple ( args , " f " , & sor ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_GetActiveEnvironment ( ) - > setSolverSorConstant ( sor ) ;
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2005-08-03 18:22:30 +00:00
}
2005-08-04 19:07:39 +00:00
static PyObject * gPySetSolverTau ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2005-08-03 18:22:30 +00:00
{
float tau ;
if ( PyArg_ParseTuple ( args , " f " , & tau ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
2005-08-04 19:07:39 +00:00
PHY_GetActiveEnvironment ( ) - > setSolverTau ( tau ) ;
2005-08-03 18:22:30 +00:00
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2005-08-03 18:22:30 +00:00
}
2005-08-04 19:07:39 +00:00
static PyObject * gPySetSolverDamping ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2005-08-03 18:22:30 +00:00
{
float damping ;
if ( PyArg_ParseTuple ( args , " f " , & damping ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
2005-08-04 19:07:39 +00:00
PHY_GetActiveEnvironment ( ) - > setSolverDamping ( damping ) ;
2005-08-03 18:22:30 +00:00
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2005-08-03 18:22:30 +00:00
}
2002-10-12 11:37:38 +00:00
2005-08-04 19:07:39 +00:00
static PyObject * gPySetLinearAirDamping ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2005-08-04 19:07:39 +00:00
{
float damping ;
if ( PyArg_ParseTuple ( args , " f " , & damping ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_GetActiveEnvironment ( ) - > setLinearAirDamping ( damping ) ;
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2005-08-04 19:07:39 +00:00
}
static PyObject * gPySetUseEpa ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2005-08-04 19:07:39 +00:00
{
int epa ;
if ( PyArg_ParseTuple ( args , " i " , & epa ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_GetActiveEnvironment ( ) - > setUseEpa ( epa ) ;
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2005-08-04 19:07:39 +00:00
}
static PyObject * gPySetSolverType ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2005-08-04 19:07:39 +00:00
{
int solverType ;
if ( PyArg_ParseTuple ( args , " i " , & solverType ) )
{
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_GetActiveEnvironment ( ) - > setSolverType ( solverType ) ;
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2005-08-04 19:07:39 +00:00
}
2006-01-30 20:33:59 +00:00
static PyObject * gPyGetVehicleConstraint ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2006-01-30 20:33:59 +00:00
{
# if defined(_WIN64)
__int64 constraintid ;
if ( PyArg_ParseTuple ( args , " L " , & constraintid ) )
# else
long constraintid ;
if ( PyArg_ParseTuple ( args , " l " , & constraintid ) )
# endif
{
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_IVehicle * vehicle = PHY_GetActiveEnvironment ( ) - > getVehicleConstraint ( constraintid ) ;
if ( vehicle )
{
KX_VehicleWrapper * pyWrapper = new KX_VehicleWrapper ( vehicle , PHY_GetActiveEnvironment ( ) ) ;
2009-04-19 12:46:39 +00:00
return pyWrapper - > NewProxy ( true ) ;
2006-01-30 20:33:59 +00:00
}
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2006-01-30 20:33:59 +00:00
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2006-01-30 20:33:59 +00:00
}
2002-10-12 11:37:38 +00:00
static PyObject * gPyCreateConstraint ( PyObject * self ,
PyObject * args ,
PyObject * kwds )
{
2011-05-28 08:16:34 +00:00
/* FIXME - physicsid is a long being cast to a pointer, should at least use PyCapsule */
# if defined(_WIN64)
__int64 physicsid = 0 , physicsid2 = 0 ;
# else
long physicsid = 0 , physicsid2 = 0 ;
# endif
int constrainttype = 0 , extrainfo = 0 ;
2002-10-12 11:37:38 +00:00
int len = PyTuple_Size ( args ) ;
int success = 1 ;
PhysicsConstraints.createConstraint:
allow to dynamically create rigid body constraints while disable collision detection between connected bodies, pass as 10th argument the flag 128
PhysiPython KX_ConstraintWrapper, setParam
export setParam(paramIndex,paramValue0,paramValue1) for Physics constraints
paramIndex 0,1,2 are linear limits, 3,4,5 are angular limits, 6,7,8 are linear motors, 9,10,11 are angular motors
For example:
disableConnectedBodies=128
cons = PhysicsConstraints.createConstraint(oid,rid,generic6dof,pivotInAx,pivotInAy,pivotInAz,angleX,angleY,angleZ,disableConnectedBodies)
#params 0,1,2 are linear limits, low,high value. if low > high then disable limit
cons.setParam(0,0,0)
I will provide an example .blend for Blender 2.49
2009-05-24 01:55:24 +00:00
int flag = 0 ;
2002-10-12 11:37:38 +00:00
float pivotX = 1 , pivotY = 1 , pivotZ = 1 , axisX = 0 , axisY = 0 , axisZ = 1 ;
if ( len = = 3 )
{
2011-05-28 08:16:34 +00:00
# if defined(_WIN64)
success = PyArg_ParseTuple ( args , " LLi " , & physicsid , & physicsid2 , & constrainttype ) ;
# else
success = PyArg_ParseTuple ( args , " lli " , & physicsid , & physicsid2 , & constrainttype ) ;
# endif
2002-10-12 11:37:38 +00:00
}
2011-07-31 11:21:48 +00:00
else if ( len = = 6 )
{
2011-05-28 08:16:34 +00:00
# if defined(_WIN64)
2011-07-31 11:21:48 +00:00
success = PyArg_ParseTuple ( args , " LLifff " , & physicsid , & physicsid2 , & constrainttype ,
& pivotX , & pivotY , & pivotZ ) ;
2011-05-28 08:16:34 +00:00
# else
2011-07-31 11:21:48 +00:00
success = PyArg_ParseTuple ( args , " llifff " , & physicsid , & physicsid2 , & constrainttype ,
& pivotX , & pivotY , & pivotZ ) ;
2011-05-28 08:16:34 +00:00
# endif
2011-07-31 11:21:48 +00:00
}
else if ( len = = 9 )
{
2011-05-28 08:16:34 +00:00
# if defined(_WIN64)
2011-07-31 11:21:48 +00:00
success = PyArg_ParseTuple ( args , " LLiffffff " , & physicsid , & physicsid2 , & constrainttype ,
& pivotX , & pivotY , & pivotZ , & axisX , & axisY , & axisZ ) ;
2011-05-28 08:16:34 +00:00
# else
2011-07-31 11:21:48 +00:00
success = PyArg_ParseTuple ( args , " lliffffff " , & physicsid , & physicsid2 , & constrainttype ,
& pivotX , & pivotY , & pivotZ , & axisX , & axisY , & axisZ ) ;
2011-05-28 08:16:34 +00:00
# endif
2011-07-31 11:21:48 +00:00
}
else if ( len = = 10 )
{
2011-05-28 08:16:34 +00:00
# if defined(_WIN64)
2011-07-31 11:21:48 +00:00
success = PyArg_ParseTuple ( args , " LLiffffffi " , & physicsid , & physicsid2 , & constrainttype ,
& pivotX , & pivotY , & pivotZ , & axisX , & axisY , & axisZ , & flag ) ;
2011-05-28 08:16:34 +00:00
# else
2011-07-31 11:21:48 +00:00
success = PyArg_ParseTuple ( args , " lliffffffi " , & physicsid , & physicsid2 , & constrainttype ,
& pivotX , & pivotY , & pivotZ , & axisX , & axisY , & axisZ , & flag ) ;
2011-05-28 08:16:34 +00:00
# endif
2011-07-31 11:21:48 +00:00
}
/* XXX extrainfo seems to be nothing implemented. right now it works as a pivot with [X,0,0] */
else if ( len = = 4 )
{
2011-05-28 08:16:34 +00:00
# if defined(_WIN64)
2011-07-31 11:21:48 +00:00
success = PyArg_ParseTuple ( args , " LLii " , & physicsid , & physicsid2 , & constrainttype , & extrainfo ) ;
2011-05-28 08:16:34 +00:00
# else
2011-07-31 11:21:48 +00:00
success = PyArg_ParseTuple ( args , " llii " , & physicsid , & physicsid2 , & constrainttype , & extrainfo ) ;
2011-05-28 08:16:34 +00:00
# endif
2011-07-31 11:21:48 +00:00
pivotX = extrainfo ;
2002-10-12 11:37:38 +00:00
}
2011-07-31 07:54:24 +00:00
2002-10-12 11:37:38 +00:00
if ( success )
{
2005-03-25 10:33:39 +00:00
if ( PHY_GetActiveEnvironment ( ) )
2002-10-12 11:37:38 +00:00
{
PHY_IPhysicsController * physctrl = ( PHY_IPhysicsController * ) physicsid ;
PHY_IPhysicsController * physctrl2 = ( PHY_IPhysicsController * ) physicsid2 ;
2010-01-14 10:59:42 +00:00
if ( physctrl ) //TODO:check for existence of this pointer!
2002-10-12 11:37:38 +00:00
{
2009-05-24 00:42:40 +00:00
PHY_ConstraintType ct = ( PHY_ConstraintType ) constrainttype ;
int constraintid = 0 ;
if ( ct = = PHY_GENERIC_6DOF_CONSTRAINT )
{
//convert from euler angle into axis
float radsPerDeg = 6.283185307179586232f / 360.f ;
//we need to pass a full constraint frame, not just axis
//localConstraintFrameBasis
MT_Matrix3x3 localCFrame ( MT_Vector3 ( radsPerDeg * axisX , radsPerDeg * axisY , radsPerDeg * axisZ ) ) ;
MT_Vector3 axis0 = localCFrame . getColumn ( 0 ) ;
MT_Vector3 axis1 = localCFrame . getColumn ( 1 ) ;
MT_Vector3 axis2 = localCFrame . getColumn ( 2 ) ;
2011-07-31 07:54:24 +00:00
constraintid = PHY_GetActiveEnvironment ( ) - > createConstraint ( physctrl , physctrl2 , ( enum PHY_ConstraintType ) constrainttype ,
pivotX , pivotY , pivotZ ,
( float ) axis0 . x ( ) , ( float ) axis0 . y ( ) , ( float ) axis0 . z ( ) ,
( float ) axis1 . x ( ) , ( float ) axis1 . y ( ) , ( float ) axis1 . z ( ) ,
( float ) axis2 . x ( ) , ( float ) axis2 . y ( ) , ( float ) axis2 . z ( ) , flag ) ;
}
else {
2009-05-24 00:42:40 +00:00
constraintid = PHY_GetActiveEnvironment ( ) - > createConstraint ( physctrl , physctrl2 , ( enum PHY_ConstraintType ) constrainttype , pivotX , pivotY , pivotZ , axisX , axisY , axisZ , 0 ) ;
}
2002-10-12 11:37:38 +00:00
2005-03-25 10:33:39 +00:00
KX_ConstraintWrapper * wrap = new KX_ConstraintWrapper ( ( enum PHY_ConstraintType ) constrainttype , constraintid , PHY_GetActiveEnvironment ( ) ) ;
2002-10-12 11:37:38 +00:00
2009-04-19 12:46:39 +00:00
return wrap - > NewProxy ( true ) ;
2002-10-12 11:37:38 +00:00
}
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2002-10-12 11:37:38 +00:00
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2002-10-12 11:37:38 +00:00
}
2006-07-03 05:58:23 +00:00
static PyObject * gPyGetAppliedImpulse ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2006-07-03 05:58:23 +00:00
{
float appliedImpulse = 0.f ;
# if defined(_WIN64)
__int64 constraintid ;
if ( PyArg_ParseTuple ( args , " L " , & constraintid ) )
# else
long constraintid ;
if ( PyArg_ParseTuple ( args , " l " , & constraintid ) )
# endif
{
if ( PHY_GetActiveEnvironment ( ) )
{
appliedImpulse = PHY_GetActiveEnvironment ( ) - > getAppliedImpulse ( constraintid ) ;
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2006-07-03 05:58:23 +00:00
return PyFloat_FromDouble ( appliedImpulse ) ;
}
2002-10-12 11:37:38 +00:00
static PyObject * gPyRemoveConstraint ( PyObject * self ,
2011-07-31 07:54:24 +00:00
PyObject * args ,
PyObject * kwds )
2002-10-12 11:37:38 +00:00
{
2005-11-28 06:51:54 +00:00
# if defined(_WIN64)
__int64 constraintid ;
if ( PyArg_ParseTuple ( args , " L " , & constraintid ) )
# else
long constraintid ;
if ( PyArg_ParseTuple ( args , " l " , & constraintid ) )
# endif
2002-10-12 11:37:38 +00:00
{
2005-03-25 10:33:39 +00:00
if ( PHY_GetActiveEnvironment ( ) )
2002-10-12 11:37:38 +00:00
{
2006-01-15 11:34:55 +00:00
PHY_GetActiveEnvironment ( ) - > removeConstraint ( constraintid ) ;
2002-10-12 11:37:38 +00:00
}
}
2008-07-01 16:43:46 +00:00
else {
return NULL ;
}
2008-08-14 03:23:36 +00:00
Py_RETURN_NONE ;
2002-10-12 11:37:38 +00:00
}
2011-03-12 20:34:17 +00:00
static PyObject * gPyExportBulletFile ( PyObject * , PyObject * args )
{
char * filename ;
if ( ! PyArg_ParseTuple ( args , " s:exportBulletFile " , & filename ) )
return NULL ;
2011-07-31 07:54:24 +00:00
2011-03-12 20:34:17 +00:00
if ( PHY_GetActiveEnvironment ( ) )
{
PHY_GetActiveEnvironment ( ) - > exportFile ( filename ) ;
}
Py_RETURN_NONE ;
}
2002-10-12 11:37:38 +00:00
static struct PyMethodDef physicsconstraints_methods [ ] = {
2011-07-31 07:54:24 +00:00
{ " setGravity " , ( PyCFunction ) gPySetGravity ,
METH_VARARGS , ( const char * ) gPySetGravity__doc__ } ,
{ " setDebugMode " , ( PyCFunction ) gPySetDebugMode ,
METH_VARARGS , ( const char * ) gPySetDebugMode__doc__ } ,
/// settings that influence quality of the rigidbody dynamics
{ " setNumIterations " , ( PyCFunction ) gPySetNumIterations ,
METH_VARARGS , ( const char * ) gPySetNumIterations__doc__ } ,
{ " setNumTimeSubSteps " , ( PyCFunction ) gPySetNumTimeSubSteps ,
METH_VARARGS , ( const char * ) gPySetNumTimeSubSteps__doc__ } ,
{ " setDeactivationTime " , ( PyCFunction ) gPySetDeactivationTime ,
METH_VARARGS , ( const char * ) gPySetDeactivationTime__doc__ } ,
{ " setDeactivationLinearTreshold " , ( PyCFunction ) gPySetDeactivationLinearTreshold ,
METH_VARARGS , ( const char * ) gPySetDeactivationLinearTreshold__doc__ } ,
{ " setDeactivationAngularTreshold " , ( PyCFunction ) gPySetDeactivationAngularTreshold ,
METH_VARARGS , ( const char * ) gPySetDeactivationAngularTreshold__doc__ } ,
{ " setContactBreakingTreshold " , ( PyCFunction ) gPySetContactBreakingTreshold ,
METH_VARARGS , ( const char * ) gPySetContactBreakingTreshold__doc__ } ,
{ " setCcdMode " , ( PyCFunction ) gPySetCcdMode ,
METH_VARARGS , ( const char * ) gPySetCcdMode__doc__ } ,
{ " setSorConstant " , ( PyCFunction ) gPySetSorConstant ,
METH_VARARGS , ( const char * ) gPySetSorConstant__doc__ } ,
{ " setSolverTau " , ( PyCFunction ) gPySetSolverTau ,
METH_VARARGS , ( const char * ) gPySetSolverTau__doc__ } ,
{ " setSolverDamping " , ( PyCFunction ) gPySetSolverDamping ,
METH_VARARGS , ( const char * ) gPySetSolverDamping__doc__ } ,
{ " setLinearAirDamping " , ( PyCFunction ) gPySetLinearAirDamping ,
METH_VARARGS , ( const char * ) gPySetLinearAirDamping__doc__ } ,
{ " setUseEpa " , ( PyCFunction ) gPySetUseEpa ,
METH_VARARGS , ( const char * ) gPySetUseEpa__doc__ } ,
2005-08-04 19:07:39 +00:00
{ " setSolverType " , ( PyCFunction ) gPySetSolverType ,
2011-07-31 07:54:24 +00:00
METH_VARARGS , ( const char * ) gPySetSolverType__doc__ } ,
2005-08-03 18:22:30 +00:00
2011-07-31 07:54:24 +00:00
{ " createConstraint " , ( PyCFunction ) gPyCreateConstraint ,
METH_VARARGS , ( const char * ) gPyCreateConstraint__doc__ } ,
{ " getVehicleConstraint " , ( PyCFunction ) gPyGetVehicleConstraint ,
METH_VARARGS , ( const char * ) gPyGetVehicleConstraint__doc__ } ,
2006-01-30 20:33:59 +00:00
2011-07-31 07:54:24 +00:00
{ " removeConstraint " , ( PyCFunction ) gPyRemoveConstraint ,
METH_VARARGS , ( const char * ) gPyRemoveConstraint__doc__ } ,
2006-07-03 05:58:23 +00:00
{ " getAppliedImpulse " , ( PyCFunction ) gPyGetAppliedImpulse ,
2011-07-31 07:54:24 +00:00
METH_VARARGS , ( const char * ) gPyGetAppliedImpulse__doc__ } ,
2011-03-12 20:34:17 +00:00
2011-07-31 07:54:24 +00:00
{ " exportBulletFile " , ( PyCFunction ) gPyExportBulletFile ,
METH_VARARGS , " export a .bullet file " } ,
2002-10-12 11:37:38 +00:00
2011-07-31 07:54:24 +00:00
//sentinel
{ NULL , ( PyCFunction ) NULL , 0 , NULL }
2002-10-12 11:37:38 +00:00
} ;
2009-04-29 16:54:45 +00:00
static struct PyModuleDef PhysicsConstraints_module_def = {
{ } , /* m_base */
" PhysicsConstraints " , /* m_name */
PhysicsConstraints_module_documentation , /* m_doc */
0 , /* m_size */
physicsconstraints_methods , /* m_methods */
0 , /* m_reload */
0 , /* m_traverse */
0 , /* m_clear */
0 , /* m_free */
} ;
2002-10-12 11:37:38 +00:00
2011-07-31 07:54:24 +00:00
PyObject * initPythonConstraintBinding ( )
2002-10-12 11:37:38 +00:00
{
2011-07-31 07:54:24 +00:00
PyObject * ErrorObject ;
PyObject * m ;
PyObject * d ;
PyObject * item ;
2002-10-12 11:37:38 +00:00
2009-04-29 23:39:27 +00:00
/* Use existing module where possible
* be careful not to init any runtime vars after this */
m = PyImport_ImportModule ( " PhysicsConstraints " ) ;
if ( m ) {
Py_DECREF ( m ) ;
return m ;
}
else {
PyErr_Clear ( ) ;
2009-08-10 00:07:34 +00:00
2009-04-29 23:39:27 +00:00
m = PyModule_Create ( & PhysicsConstraints_module_def ) ;
2009-06-16 07:16:51 +00:00
PyDict_SetItemString ( PySys_GetObject ( " modules " ) , PhysicsConstraints_module_def . m_name , m ) ;
2009-04-29 23:39:27 +00:00
}
2002-10-12 11:37:38 +00:00
2011-07-31 07:54:24 +00:00
// Add some symbolic constants to the module
d = PyModule_GetDict ( m ) ;
ErrorObject = PyUnicode_FromString ( " PhysicsConstraints.error " ) ;
PyDict_SetItemString ( d , " error " , ErrorObject ) ;
Py_DECREF ( ErrorObject ) ;
2002-10-12 11:37:38 +00:00
2011-07-31 07:45:54 +00:00
# ifdef USE_BULLET
2011-07-31 07:54:24 +00:00
//Debug Modes constants to be used with setDebugMode() python function
KX_MACRO_addTypesToDict ( d , DBG_NODEBUG , btIDebugDraw : : DBG_NoDebug ) ;
KX_MACRO_addTypesToDict ( d , DBG_DRAWWIREFRAME , btIDebugDraw : : DBG_DrawWireframe ) ;
KX_MACRO_addTypesToDict ( d , DBG_DRAWAABB , btIDebugDraw : : DBG_DrawAabb ) ;
KX_MACRO_addTypesToDict ( d , DBG_DRAWFREATURESTEXT , btIDebugDraw : : DBG_DrawFeaturesText ) ;
KX_MACRO_addTypesToDict ( d , DBG_DRAWCONTACTPOINTS , btIDebugDraw : : DBG_DrawContactPoints ) ;
KX_MACRO_addTypesToDict ( d , DBG_NOHELPTEXT , btIDebugDraw : : DBG_NoHelpText ) ;
KX_MACRO_addTypesToDict ( d , DBG_DRAWTEXT , btIDebugDraw : : DBG_DrawText ) ;
KX_MACRO_addTypesToDict ( d , DBG_PROFILETIMINGS , btIDebugDraw : : DBG_ProfileTimings ) ;
KX_MACRO_addTypesToDict ( d , DBG_ENABLESATCOMPARISION , btIDebugDraw : : DBG_EnableSatComparison ) ;
KX_MACRO_addTypesToDict ( d , DBG_DISABLEBULLETLCP , btIDebugDraw : : DBG_DisableBulletLCP ) ;
KX_MACRO_addTypesToDict ( d , DBG_ENABLECDD , btIDebugDraw : : DBG_EnableCCD ) ;
KX_MACRO_addTypesToDict ( d , DBG_DRAWCONSTRAINTS , btIDebugDraw : : DBG_DrawConstraints ) ;
KX_MACRO_addTypesToDict ( d , DBG_DRAWCONSTRAINTLIMITS , btIDebugDraw : : DBG_DrawConstraintLimits ) ;
KX_MACRO_addTypesToDict ( d , DBG_FASTWIREFRAME , btIDebugDraw : : DBG_FastWireframe ) ;
2011-07-31 07:45:54 +00:00
# endif // USE_BULLET
2011-07-30 23:16:22 +00:00
2011-07-31 07:54:24 +00:00
//Constraint types to be used with createConstraint() python function
KX_MACRO_addTypesToDict ( d , POINTTOPOINT_CONSTRAINT , PHY_POINT2POINT_CONSTRAINT ) ;
KX_MACRO_addTypesToDict ( d , LINEHINGE_CONSTRAINT , PHY_LINEHINGE_CONSTRAINT ) ;
KX_MACRO_addTypesToDict ( d , ANGULAR_CONSTRAINT , PHY_ANGULAR_CONSTRAINT ) ;
KX_MACRO_addTypesToDict ( d , CONETWIST_CONSTRAINT , PHY_CONE_TWIST_CONSTRAINT ) ;
KX_MACRO_addTypesToDict ( d , VEHICLE_CONSTRAINT , PHY_VEHICLE_CONSTRAINT ) ;
2002-10-12 11:37:38 +00:00
2011-07-31 07:54:24 +00:00
// Check for errors
if ( PyErr_Occurred ( ) ) {
Py_FatalError ( " can't initialize module PhysicsConstraints " ) ;
}
2002-10-12 11:37:38 +00:00
2011-07-31 07:54:24 +00:00
return d ;
2002-10-12 11:37:38 +00:00
}
void KX_RemovePythonConstraintBinding ( )
{
}
void PHY_SetActiveEnvironment ( class PHY_IPhysicsEnvironment * env )
{
2005-03-25 10:33:39 +00:00
g_CurrentActivePhysicsEnvironment = env ;
2002-10-12 11:37:38 +00:00
}
2005-03-25 10:33:39 +00:00
PHY_IPhysicsEnvironment * PHY_GetActiveEnvironment ( )
{
return g_CurrentActivePhysicsEnvironment ;
}
2010-10-31 04:11:39 +00:00
# endif // WITH_PYTHON