Blender  V2.59
KX_PyConstraintBinding.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: KX_PyConstraintBinding.cpp 38880 2011-07-31 11:21:48Z dfelinto $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  */
00029 
00034 #include "KX_PyConstraintBinding.h"
00035 #include "PHY_IPhysicsEnvironment.h"
00036 #include "KX_ConstraintWrapper.h"
00037 #include "KX_VehicleWrapper.h"
00038 #include "KX_PhysicsObjectWrapper.h"
00039 #include "PHY_IPhysicsController.h"
00040 #include "PHY_IVehicle.h"
00041 #include "PHY_DynamicTypes.h"
00042 #include "MT_Matrix3x3.h"
00043 
00044 #include "PyObjectPlus.h" 
00045 
00046 #ifdef USE_BULLET
00047 #  include "LinearMath/btIDebugDraw.h"
00048 #endif
00049 
00050 #ifdef WITH_PYTHON
00051 
00052 // macro copied from KX_PythonInit.cpp
00053 #define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyLong_FromSsize_t(name2)); Py_DECREF(item)
00054 
00055 // nasty glob variable to connect scripting language
00056 // if there is a better way (without global), please do so!
00057 static PHY_IPhysicsEnvironment* g_CurrentActivePhysicsEnvironment = NULL;
00058 
00059 static char PhysicsConstraints_module_documentation[] =
00060 "This is the Python API for the Physics Constraints";
00061 
00062 
00063 static char gPySetGravity__doc__[] = "setGravity(float x,float y,float z)";
00064 static char gPySetDebugMode__doc__[] = "setDebugMode(int mode)";
00065 
00066 static char gPySetNumIterations__doc__[] = "setNumIterations(int numiter) This sets the number of iterations for an iterative constraint solver";
00067 static char gPySetNumTimeSubSteps__doc__[] = "setNumTimeSubSteps(int numsubstep) This sets the number of substeps for each physics proceed. Tradeoff quality for performance.";
00068 
00069 
00070 static char gPySetDeactivationTime__doc__[] = "setDeactivationTime(float time) This sets the time after which a resting rigidbody gets deactived";
00071 static char gPySetDeactivationLinearTreshold__doc__[] = "setDeactivationLinearTreshold(float linearTreshold)";
00072 static char gPySetDeactivationAngularTreshold__doc__[] = "setDeactivationAngularTreshold(float angularTreshold)";
00073 static char gPySetContactBreakingTreshold__doc__[] = "setContactBreakingTreshold(float breakingTreshold) Reasonable default is 0.02 (if units are meters)";
00074 
00075 static char gPySetCcdMode__doc__[] = "setCcdMode(int ccdMode) Very experimental, not recommended";
00076 static char gPySetSorConstant__doc__[] = "setSorConstant(float sor) Very experimental, not recommended";
00077 static char gPySetSolverTau__doc__[] = "setTau(float tau) Very experimental, not recommended";
00078 static char gPySetSolverDamping__doc__[] = "setDamping(float damping) Very experimental, not recommended";
00079 static char gPySetLinearAirDamping__doc__[] = "setLinearAirDamping(float damping) Very experimental, not recommended";
00080 static char gPySetUseEpa__doc__[] = "setUseEpa(int epa) Very experimental, not recommended";
00081 static char gPySetSolverType__doc__[] = "setSolverType(int solverType) Very experimental, not recommended";
00082 
00083 
00084 static char gPyCreateConstraint__doc__[] = "createConstraint(ob1,ob2,float restLength,float restitution,float damping)";
00085 static char gPyGetVehicleConstraint__doc__[] = "getVehicleConstraint(int constraintId)";
00086 static char gPyRemoveConstraint__doc__[] = "removeConstraint(int constraintId)";
00087 static char gPyGetAppliedImpulse__doc__[] = "getAppliedImpulse(int constraintId)";
00088 
00089 
00090 
00091 
00092 
00093 
00094 static PyObject* gPySetGravity(PyObject* self,
00095                                PyObject* args,
00096                                PyObject* kwds)
00097 {
00098         float x,y,z;
00099         if (PyArg_ParseTuple(args,"fff",&x,&y,&z))
00100         {
00101                 if (PHY_GetActiveEnvironment())
00102                         PHY_GetActiveEnvironment()->setGravity(x,y,z);
00103         }
00104         else {
00105                 return NULL;
00106         }
00107         
00108         Py_RETURN_NONE;
00109 }
00110 
00111 static PyObject* gPySetDebugMode(PyObject* self,
00112                                  PyObject* args,
00113                                  PyObject* kwds)
00114 {
00115         int mode;
00116         if (PyArg_ParseTuple(args,"i",&mode))
00117         {
00118                 if (PHY_GetActiveEnvironment())
00119                 {
00120                         PHY_GetActiveEnvironment()->setDebugMode(mode);
00121                         
00122                 }
00123                 
00124         }
00125         else {
00126                 return NULL;
00127         }
00128         
00129         Py_RETURN_NONE;
00130 }
00131 
00132 
00133 
00134 static PyObject* gPySetNumTimeSubSteps(PyObject* self,
00135                                        PyObject* args,
00136                                        PyObject* kwds)
00137 {
00138         int substep;
00139         if (PyArg_ParseTuple(args,"i",&substep))
00140         {
00141                 if (PHY_GetActiveEnvironment())
00142                 {
00143                         PHY_GetActiveEnvironment()->setNumTimeSubSteps(substep);
00144                 }
00145         }
00146         else {
00147                 return NULL;
00148         }
00149         Py_RETURN_NONE;
00150 }
00151 
00152 
00153 static PyObject* gPySetNumIterations(PyObject* self,
00154                                      PyObject* args,
00155                                      PyObject* kwds)
00156 {
00157         int iter;
00158         if (PyArg_ParseTuple(args,"i",&iter))
00159         {
00160                 if (PHY_GetActiveEnvironment())
00161                 {
00162                         PHY_GetActiveEnvironment()->setNumIterations(iter);
00163                 }
00164         }
00165         else {
00166                 return NULL;
00167         }
00168         Py_RETURN_NONE;
00169 }
00170 
00171 
00172 static PyObject* gPySetDeactivationTime(PyObject* self,
00173                                         PyObject* args,
00174                                         PyObject* kwds)
00175 {
00176         float deactive_time;
00177         if (PyArg_ParseTuple(args,"f",&deactive_time))
00178         {
00179                 if (PHY_GetActiveEnvironment())
00180                 {
00181                         PHY_GetActiveEnvironment()->setDeactivationTime(deactive_time);
00182                 }
00183         }
00184         else {
00185                 return NULL;
00186         }
00187         Py_RETURN_NONE;
00188 }
00189 
00190 
00191 static PyObject* gPySetDeactivationLinearTreshold(PyObject* self,
00192                                                   PyObject* args,
00193                                                   PyObject* kwds)
00194 {
00195         float linearDeactivationTreshold;
00196         if (PyArg_ParseTuple(args,"f",&linearDeactivationTreshold))
00197         {
00198                 if (PHY_GetActiveEnvironment())
00199                 {
00200                         PHY_GetActiveEnvironment()->setDeactivationLinearTreshold( linearDeactivationTreshold);
00201                 }
00202         }
00203         else {
00204                 return NULL;
00205         }
00206         Py_RETURN_NONE;
00207 }
00208 
00209 
00210 static PyObject* gPySetDeactivationAngularTreshold(PyObject* self,
00211                                                    PyObject* args,
00212                                                    PyObject* kwds)
00213 {
00214         float angularDeactivationTreshold;
00215         if (PyArg_ParseTuple(args,"f",&angularDeactivationTreshold))
00216         {
00217                 if (PHY_GetActiveEnvironment())
00218                 {
00219                         PHY_GetActiveEnvironment()->setDeactivationAngularTreshold( angularDeactivationTreshold);
00220                 }
00221         }
00222         else {
00223                 return NULL;
00224         }
00225         Py_RETURN_NONE;
00226 }
00227 
00228 static PyObject* gPySetContactBreakingTreshold(PyObject* self,
00229                                                PyObject* args,
00230                                                PyObject* kwds)
00231 {
00232         float contactBreakingTreshold;
00233         if (PyArg_ParseTuple(args,"f",&contactBreakingTreshold))
00234         {
00235                 if (PHY_GetActiveEnvironment())
00236                 {
00237                         PHY_GetActiveEnvironment()->setContactBreakingTreshold( contactBreakingTreshold);
00238                 }
00239         }
00240         else {
00241                 return NULL;
00242         }
00243         Py_RETURN_NONE;
00244 }
00245 
00246 
00247 static PyObject* gPySetCcdMode(PyObject* self,
00248                                PyObject* args,
00249                                PyObject* kwds)
00250 {
00251         float ccdMode;
00252         if (PyArg_ParseTuple(args,"f",&ccdMode))
00253         {
00254                 if (PHY_GetActiveEnvironment())
00255                 {
00256                         PHY_GetActiveEnvironment()->setCcdMode( ccdMode);
00257                 }
00258         }
00259         else {
00260                 return NULL;
00261         }
00262         Py_RETURN_NONE;
00263 }
00264 
00265 static PyObject* gPySetSorConstant(PyObject* self,
00266                                    PyObject* args,
00267                                    PyObject* kwds)
00268 {
00269         float sor;
00270         if (PyArg_ParseTuple(args,"f",&sor))
00271         {
00272                 if (PHY_GetActiveEnvironment())
00273                 {
00274                         PHY_GetActiveEnvironment()->setSolverSorConstant( sor);
00275                 }
00276         }
00277         else {
00278                 return NULL;
00279         }
00280         Py_RETURN_NONE;
00281 }
00282 
00283 static PyObject* gPySetSolverTau(PyObject* self,
00284                                  PyObject* args,
00285                                  PyObject* kwds)
00286 {
00287         float tau;
00288         if (PyArg_ParseTuple(args,"f",&tau))
00289         {
00290                 if (PHY_GetActiveEnvironment())
00291                 {
00292                         PHY_GetActiveEnvironment()->setSolverTau( tau);
00293                 }
00294         }
00295         else {
00296                 return NULL;
00297         }
00298         Py_RETURN_NONE;
00299 }
00300 
00301 
00302 static PyObject* gPySetSolverDamping(PyObject* self,
00303                                      PyObject* args,
00304                                      PyObject* kwds)
00305 {
00306         float damping;
00307         if (PyArg_ParseTuple(args,"f",&damping))
00308         {
00309                 if (PHY_GetActiveEnvironment())
00310                 {
00311                         PHY_GetActiveEnvironment()->setSolverDamping( damping);
00312                 }
00313         }
00314         else {
00315                 return NULL;
00316         }
00317         Py_RETURN_NONE;
00318 }
00319 
00320 static PyObject* gPySetLinearAirDamping(PyObject* self,
00321                                         PyObject* args,
00322                                         PyObject* kwds)
00323 {
00324         float damping;
00325         if (PyArg_ParseTuple(args,"f",&damping))
00326         {
00327                 if (PHY_GetActiveEnvironment())
00328                 {
00329                         PHY_GetActiveEnvironment()->setLinearAirDamping( damping);
00330                 }
00331         }
00332         else {
00333                 return NULL;
00334         }
00335         Py_RETURN_NONE;
00336 }
00337 
00338 
00339 static PyObject* gPySetUseEpa(PyObject* self,
00340                               PyObject* args,
00341                               PyObject* kwds)
00342 {
00343         int     epa;
00344         if (PyArg_ParseTuple(args,"i",&epa))
00345         {
00346                 if (PHY_GetActiveEnvironment())
00347                 {
00348                         PHY_GetActiveEnvironment()->setUseEpa(epa);
00349                 }
00350         }
00351         else {
00352                 return NULL;
00353         }
00354         Py_RETURN_NONE;
00355 }
00356 static PyObject* gPySetSolverType(PyObject* self,
00357                                   PyObject* args,
00358                                   PyObject* kwds)
00359 {
00360         int     solverType;
00361         if (PyArg_ParseTuple(args,"i",&solverType))
00362         {
00363                 if (PHY_GetActiveEnvironment())
00364                 {
00365                         PHY_GetActiveEnvironment()->setSolverType(solverType);
00366                 }
00367         }
00368         else {
00369                 return NULL;
00370         }
00371         Py_RETURN_NONE;
00372 }
00373 
00374 
00375 
00376 static PyObject* gPyGetVehicleConstraint(PyObject* self,
00377                                          PyObject* args,
00378                                          PyObject* kwds)
00379 {
00380 #if defined(_WIN64)
00381         __int64 constraintid;
00382         if (PyArg_ParseTuple(args,"L",&constraintid))
00383 #else
00384         long constraintid;
00385         if (PyArg_ParseTuple(args,"l",&constraintid))
00386 #endif
00387         {
00388                 if (PHY_GetActiveEnvironment())
00389                 {
00390                         
00391                         PHY_IVehicle* vehicle = PHY_GetActiveEnvironment()->getVehicleConstraint(constraintid);
00392                         if (vehicle)
00393                         {
00394                                 KX_VehicleWrapper* pyWrapper = new KX_VehicleWrapper(vehicle,PHY_GetActiveEnvironment());
00395                                 return pyWrapper->NewProxy(true);
00396                         }
00397 
00398                 }
00399         }
00400         else {
00401                 return NULL;
00402         }
00403 
00404         Py_RETURN_NONE;
00405 }
00406 
00407 
00408 static PyObject* gPyCreateConstraint(PyObject* self,
00409                                                                                  PyObject* args, 
00410                                                                                  PyObject* kwds)
00411 {
00412         /* FIXME - physicsid is a long being cast to a pointer, should at least use PyCapsule */
00413 #if defined(_WIN64)
00414         __int64 physicsid=0,physicsid2 = 0;
00415 #else
00416         long physicsid=0,physicsid2 = 0;
00417 #endif
00418         int constrainttype=0, extrainfo=0;
00419         int len = PyTuple_Size(args);
00420         int success = 1;
00421         int flag = 0;
00422 
00423         float pivotX=1,pivotY=1,pivotZ=1,axisX=0,axisY=0,axisZ=1;
00424         if (len == 3)
00425         {
00426 #if defined(_WIN64)
00427                 success = PyArg_ParseTuple(args,"LLi",&physicsid,&physicsid2,&constrainttype);
00428 #else
00429                 success = PyArg_ParseTuple(args,"lli",&physicsid,&physicsid2,&constrainttype);
00430 #endif
00431         }
00432         else if (len == 6)
00433         {
00434 #if defined(_WIN64)
00435                 success = PyArg_ParseTuple(args,"LLifff",&physicsid,&physicsid2,&constrainttype,
00436                                            &pivotX,&pivotY,&pivotZ);
00437 #else
00438                 success = PyArg_ParseTuple(args,"llifff",&physicsid,&physicsid2,&constrainttype,
00439                                            &pivotX,&pivotY,&pivotZ);
00440 #endif  
00441         }
00442         else if (len == 9)
00443         {
00444 #if defined(_WIN64)
00445                 success = PyArg_ParseTuple(args,"LLiffffff",&physicsid,&physicsid2,&constrainttype,
00446                                            &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ);
00447 #else
00448                 success = PyArg_ParseTuple(args,"lliffffff",&physicsid,&physicsid2,&constrainttype,
00449                                            &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ);
00450 #endif
00451         }
00452         else if (len == 10)
00453         {
00454 #if defined(_WIN64)
00455                 success = PyArg_ParseTuple(args,"LLiffffffi",&physicsid,&physicsid2,&constrainttype,
00456                                            &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ,&flag);
00457 #else
00458                 success = PyArg_ParseTuple(args,"lliffffffi",&physicsid,&physicsid2,&constrainttype,
00459                                            &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ,&flag);
00460 #endif
00461         }
00462 
00463         /* XXX extrainfo seems to be nothing implemented. right now it works as a pivot with [X,0,0] */
00464         else if (len == 4)
00465         {
00466 #if defined(_WIN64)
00467                 success = PyArg_ParseTuple(args,"LLii",&physicsid,&physicsid2,&constrainttype,&extrainfo);
00468 #else
00469                 success = PyArg_ParseTuple(args,"llii",&physicsid,&physicsid2,&constrainttype,&extrainfo);
00470 #endif
00471                 pivotX=extrainfo;
00472         }
00473 
00474         if (success)
00475         {
00476                 if (PHY_GetActiveEnvironment())
00477                 {
00478                         
00479                         PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) physicsid;
00480                         PHY_IPhysicsController* physctrl2 = (PHY_IPhysicsController*) physicsid2;
00481                         if (physctrl) //TODO:check for existence of this pointer!
00482                         {
00483                                 PHY_ConstraintType ct = (PHY_ConstraintType) constrainttype;
00484                                 int constraintid =0;
00485 
00486                                 if (ct == PHY_GENERIC_6DOF_CONSTRAINT)
00487                                 {
00488                                         //convert from euler angle into axis
00489                                         float radsPerDeg = 6.283185307179586232f / 360.f;
00490 
00491                                         //we need to pass a full constraint frame, not just axis
00492                                         //localConstraintFrameBasis
00493                                         MT_Matrix3x3 localCFrame(MT_Vector3(radsPerDeg*axisX,radsPerDeg*axisY,radsPerDeg*axisZ));
00494                                         MT_Vector3 axis0 = localCFrame.getColumn(0);
00495                                         MT_Vector3 axis1 = localCFrame.getColumn(1);
00496                                         MT_Vector3 axis2 = localCFrame.getColumn(2);
00497 
00498                                         constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,
00499                                                                                                     pivotX,pivotY,pivotZ,
00500                                                                                                     (float)axis0.x(),(float)axis0.y(),(float)axis0.z(),
00501                                                                                                     (float)axis1.x(),(float)axis1.y(),(float)axis1.z(),
00502                                                                                                     (float)axis2.x(),(float)axis2.y(),(float)axis2.z(),flag);
00503                                 }
00504                                 else {
00505                                         constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,pivotX,pivotY,pivotZ,axisX,axisY,axisZ,0);
00506                                 }
00507                                 
00508                                 KX_ConstraintWrapper* wrap = new KX_ConstraintWrapper((enum PHY_ConstraintType)constrainttype,constraintid,PHY_GetActiveEnvironment());
00509 
00510                                 return wrap->NewProxy(true);
00511                         }
00512                         
00513                         
00514                 }
00515         }
00516         else {
00517                 return NULL;
00518         }
00519 
00520         Py_RETURN_NONE;
00521 }
00522 
00523 
00524 
00525 
00526 static PyObject* gPyGetAppliedImpulse(PyObject* self,
00527                                       PyObject* args,
00528                                       PyObject* kwds)
00529 {
00530         float   appliedImpulse = 0.f;
00531 
00532 #if defined(_WIN64)
00533         __int64 constraintid;
00534         if (PyArg_ParseTuple(args,"L",&constraintid))
00535 #else
00536         long constraintid;
00537         if (PyArg_ParseTuple(args,"l",&constraintid))
00538 #endif
00539         {
00540                 if (PHY_GetActiveEnvironment())
00541                 {
00542                         appliedImpulse = PHY_GetActiveEnvironment()->getAppliedImpulse(constraintid);
00543                 }
00544         }
00545         else {
00546                 return NULL;
00547         }
00548 
00549         return PyFloat_FromDouble(appliedImpulse);
00550 }
00551 
00552 
00553 static PyObject* gPyRemoveConstraint(PyObject* self,
00554                                      PyObject* args,
00555                                      PyObject* kwds)
00556 {
00557 #if defined(_WIN64)
00558         __int64 constraintid;
00559         if (PyArg_ParseTuple(args,"L",&constraintid))
00560 #else
00561         long constraintid;
00562         if (PyArg_ParseTuple(args,"l",&constraintid))
00563 #endif
00564         {
00565                 if (PHY_GetActiveEnvironment())
00566                 {
00567                         PHY_GetActiveEnvironment()->removeConstraint(constraintid);
00568                 }
00569         }
00570         else {
00571                 return NULL;
00572         }
00573         
00574         Py_RETURN_NONE;
00575 }
00576 
00577 static PyObject* gPyExportBulletFile(PyObject*, PyObject* args)
00578 {
00579         char* filename;
00580         if (!PyArg_ParseTuple(args,"s:exportBulletFile",&filename))
00581                 return NULL;
00582 
00583         if (PHY_GetActiveEnvironment())
00584         {
00585                 PHY_GetActiveEnvironment()->exportFile(filename);
00586         }
00587         Py_RETURN_NONE;
00588 }
00589 
00590 static struct PyMethodDef physicsconstraints_methods[] = {
00591         {"setGravity",(PyCFunction) gPySetGravity,
00592          METH_VARARGS, (const char*)gPySetGravity__doc__},
00593         {"setDebugMode",(PyCFunction) gPySetDebugMode,
00594          METH_VARARGS, (const char *)gPySetDebugMode__doc__},
00595 
00597         {"setNumIterations",(PyCFunction) gPySetNumIterations,
00598          METH_VARARGS, (const char *)gPySetNumIterations__doc__},
00599 
00600         {"setNumTimeSubSteps",(PyCFunction) gPySetNumTimeSubSteps,
00601          METH_VARARGS, (const char *)gPySetNumTimeSubSteps__doc__},
00602 
00603         {"setDeactivationTime",(PyCFunction) gPySetDeactivationTime,
00604          METH_VARARGS, (const char *)gPySetDeactivationTime__doc__},
00605 
00606         {"setDeactivationLinearTreshold",(PyCFunction) gPySetDeactivationLinearTreshold,
00607          METH_VARARGS, (const char *)gPySetDeactivationLinearTreshold__doc__},
00608         {"setDeactivationAngularTreshold",(PyCFunction) gPySetDeactivationAngularTreshold,
00609          METH_VARARGS, (const char *)gPySetDeactivationAngularTreshold__doc__},
00610 
00611         {"setContactBreakingTreshold",(PyCFunction) gPySetContactBreakingTreshold,
00612          METH_VARARGS, (const char *)gPySetContactBreakingTreshold__doc__},
00613         {"setCcdMode",(PyCFunction) gPySetCcdMode,
00614          METH_VARARGS, (const char *)gPySetCcdMode__doc__},
00615         {"setSorConstant",(PyCFunction) gPySetSorConstant,
00616          METH_VARARGS, (const char *)gPySetSorConstant__doc__},
00617         {"setSolverTau",(PyCFunction) gPySetSolverTau,
00618          METH_VARARGS, (const char *)gPySetSolverTau__doc__},
00619         {"setSolverDamping",(PyCFunction) gPySetSolverDamping,
00620          METH_VARARGS, (const char *)gPySetSolverDamping__doc__},
00621 
00622         {"setLinearAirDamping",(PyCFunction) gPySetLinearAirDamping,
00623          METH_VARARGS, (const char *)gPySetLinearAirDamping__doc__},
00624 
00625         {"setUseEpa",(PyCFunction) gPySetUseEpa,
00626          METH_VARARGS, (const char *)gPySetUseEpa__doc__},
00627         {"setSolverType",(PyCFunction) gPySetSolverType,
00628          METH_VARARGS, (const char *)gPySetSolverType__doc__},
00629 
00630 
00631         {"createConstraint",(PyCFunction) gPyCreateConstraint,
00632          METH_VARARGS, (const char *)gPyCreateConstraint__doc__},
00633         {"getVehicleConstraint",(PyCFunction) gPyGetVehicleConstraint,
00634          METH_VARARGS, (const char *)gPyGetVehicleConstraint__doc__},
00635 
00636         {"removeConstraint",(PyCFunction) gPyRemoveConstraint,
00637          METH_VARARGS, (const char *)gPyRemoveConstraint__doc__},
00638         {"getAppliedImpulse",(PyCFunction) gPyGetAppliedImpulse,
00639          METH_VARARGS, (const char *)gPyGetAppliedImpulse__doc__},
00640 
00641         {"exportBulletFile",(PyCFunction)gPyExportBulletFile,
00642          METH_VARARGS, "export a .bullet file"},
00643 
00644         //sentinel
00645         { NULL, (PyCFunction) NULL, 0, NULL }
00646 };
00647 
00648 static struct PyModuleDef PhysicsConstraints_module_def = {
00649         {}, /* m_base */
00650         "PhysicsConstraints",  /* m_name */
00651         PhysicsConstraints_module_documentation,  /* m_doc */
00652         0,  /* m_size */
00653         physicsconstraints_methods,  /* m_methods */
00654         0,  /* m_reload */
00655         0,  /* m_traverse */
00656         0,  /* m_clear */
00657         0,  /* m_free */
00658 };
00659 
00660 PyObject* initPythonConstraintBinding()
00661 {
00662 
00663         PyObject* ErrorObject;
00664         PyObject* m;
00665         PyObject* d;
00666         PyObject* item;
00667 
00668         /* Use existing module where possible
00669          * be careful not to init any runtime vars after this */
00670         m = PyImport_ImportModule( "PhysicsConstraints" );
00671         if(m) {
00672                 Py_DECREF(m);
00673                 return m;
00674         }
00675         else {
00676                 PyErr_Clear();
00677                 
00678                 m = PyModule_Create(&PhysicsConstraints_module_def);
00679                 PyDict_SetItemString(PySys_GetObject("modules"), PhysicsConstraints_module_def.m_name, m);
00680         }
00681 
00682         // Add some symbolic constants to the module
00683         d = PyModule_GetDict(m);
00684         ErrorObject = PyUnicode_FromString("PhysicsConstraints.error");
00685         PyDict_SetItemString(d, "error", ErrorObject);
00686         Py_DECREF(ErrorObject);
00687 
00688 #ifdef USE_BULLET
00689         //Debug Modes constants to be used with setDebugMode() python function
00690         KX_MACRO_addTypesToDict(d, DBG_NODEBUG, btIDebugDraw::DBG_NoDebug);
00691         KX_MACRO_addTypesToDict(d, DBG_DRAWWIREFRAME, btIDebugDraw::DBG_DrawWireframe);
00692         KX_MACRO_addTypesToDict(d, DBG_DRAWAABB, btIDebugDraw::DBG_DrawAabb);
00693         KX_MACRO_addTypesToDict(d, DBG_DRAWFREATURESTEXT, btIDebugDraw::DBG_DrawFeaturesText);
00694         KX_MACRO_addTypesToDict(d, DBG_DRAWCONTACTPOINTS, btIDebugDraw::DBG_DrawContactPoints);
00695         KX_MACRO_addTypesToDict(d, DBG_NOHELPTEXT, btIDebugDraw::DBG_NoHelpText);
00696         KX_MACRO_addTypesToDict(d, DBG_DRAWTEXT, btIDebugDraw::DBG_DrawText);
00697         KX_MACRO_addTypesToDict(d, DBG_PROFILETIMINGS, btIDebugDraw::DBG_ProfileTimings);
00698         KX_MACRO_addTypesToDict(d, DBG_ENABLESATCOMPARISION, btIDebugDraw::DBG_EnableSatComparison);
00699         KX_MACRO_addTypesToDict(d, DBG_DISABLEBULLETLCP, btIDebugDraw::DBG_DisableBulletLCP);
00700         KX_MACRO_addTypesToDict(d, DBG_ENABLECDD, btIDebugDraw::DBG_EnableCCD);
00701         KX_MACRO_addTypesToDict(d, DBG_DRAWCONSTRAINTS, btIDebugDraw::DBG_DrawConstraints);
00702         KX_MACRO_addTypesToDict(d, DBG_DRAWCONSTRAINTLIMITS, btIDebugDraw::DBG_DrawConstraintLimits);
00703         KX_MACRO_addTypesToDict(d, DBG_FASTWIREFRAME, btIDebugDraw::DBG_FastWireframe);
00704 #endif // USE_BULLET
00705 
00706         //Constraint types to be used with createConstraint() python function
00707         KX_MACRO_addTypesToDict(d, POINTTOPOINT_CONSTRAINT, PHY_POINT2POINT_CONSTRAINT);
00708         KX_MACRO_addTypesToDict(d, LINEHINGE_CONSTRAINT, PHY_LINEHINGE_CONSTRAINT);
00709         KX_MACRO_addTypesToDict(d, ANGULAR_CONSTRAINT, PHY_ANGULAR_CONSTRAINT);
00710         KX_MACRO_addTypesToDict(d, CONETWIST_CONSTRAINT, PHY_CONE_TWIST_CONSTRAINT);
00711         KX_MACRO_addTypesToDict(d, VEHICLE_CONSTRAINT, PHY_VEHICLE_CONSTRAINT);
00712 
00713         // Check for errors
00714         if (PyErr_Occurred()) {
00715                 Py_FatalError("can't initialize module PhysicsConstraints");
00716         }
00717 
00718         return d;
00719 }
00720 
00721 
00722 void    KX_RemovePythonConstraintBinding()
00723 {
00724 }
00725 
00726 void    PHY_SetActiveEnvironment(class  PHY_IPhysicsEnvironment* env)
00727 {
00728         g_CurrentActivePhysicsEnvironment = env;
00729 }
00730 
00731 PHY_IPhysicsEnvironment*        PHY_GetActiveEnvironment()
00732 {
00733         return g_CurrentActivePhysicsEnvironment;
00734 }
00735 
00736 #endif // WITH_PYTHON