doxygen: prevent GPL license block from being parsed as doxygen comment.
[blender.git] / source / gameengine / Ketsji / KX_ConvertPhysicsObjects.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29 #if defined(WIN32) && !defined(FREE_WINDOWS)
30 #pragma warning (disable : 4786)
31 #endif
32
33 #include "MT_assert.h"
34
35 #include "KX_SoftBodyDeformer.h"
36 #include "KX_ConvertPhysicsObject.h"
37 #include "BL_DeformableGameObject.h"
38 #include "RAS_MeshObject.h"
39 #include "KX_Scene.h"
40 #include "SYS_System.h"
41
42 #include "PHY_Pro.h" //todo cleanup
43 #include "KX_ClientObjectInfo.h"
44
45 #include "GEN_Map.h"
46 #include "GEN_HashedPtr.h"
47
48 #include "KX_PhysicsEngineEnums.h"
49 #include "PHY_Pro.h"
50
51 #include "KX_MotionState.h" // bridge between motionstate and scenegraph node
52
53 extern "C"{
54         #include "BKE_DerivedMesh.h"
55 }
56
57 #ifdef USE_BULLET
58 #include "BulletSoftBody/btSoftBody.h"
59
60 #include "CcdPhysicsEnvironment.h"
61 #include "CcdPhysicsController.h"
62 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
63
64 #include "KX_BulletPhysicsController.h"
65 #include "btBulletDynamicsCommon.h"
66
67                                                         #ifdef WIN32
68 #if _MSC_VER >= 1310
69 //only use SIMD Hull code under Win32
70 //#define TEST_HULL 1
71 #ifdef TEST_HULL
72 #define USE_HULL 1
73 //#define TEST_SIMD_HULL 1
74
75 #include "NarrowPhaseCollision/Hull.h"
76 #endif //#ifdef TEST_HULL
77
78 #endif //_MSC_VER 
79 #endif //WIN32
80
81
82
83 // forward declarations
84
85 void    KX_ConvertBulletObject( class   KX_GameObject* gameobj,
86         class   RAS_MeshObject* meshobj,
87         struct  DerivedMesh* dm,
88         class   KX_Scene* kxscene,
89         struct  PHY_ShapeProps* shapeprops,
90         struct  PHY_MaterialProps*      smmaterial,
91         struct  KX_ObjectProperties*    objprop)
92 {
93
94         CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
95         assert(env);
96         
97
98         bool isbulletdyna = false;
99         bool isbulletsensor = false;
100         bool useGimpact = false;
101         CcdConstructionInfo ci;
102         class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
103         class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo();
104
105         
106         if (!objprop->m_dyna)
107         {
108                 ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
109         }
110         if (objprop->m_ghost)
111         {
112                 ci.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
113         }
114
115         ci.m_MotionState = motionstate;
116         ci.m_gravity = btVector3(0,0,0);
117         ci.m_localInertiaTensor =btVector3(0,0,0);
118         ci.m_mass = objprop->m_dyna ? shapeprops->m_mass : 0.f;
119         ci.m_clamp_vel_min = shapeprops->m_clamp_vel_min;
120         ci.m_clamp_vel_max = shapeprops->m_clamp_vel_max;
121         ci.m_margin = objprop->m_margin;
122         shapeInfo->m_radius = objprop->m_radius;
123         isbulletdyna = objprop->m_dyna;
124         isbulletsensor = objprop->m_sensor;
125         useGimpact = ((isbulletdyna || isbulletsensor) && !objprop->m_softbody);
126
127         ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f);
128         
129         btCollisionShape* bm = 0;
130
131         switch (objprop->m_boundclass)
132         {
133         case KX_BOUNDSPHERE:
134                 {
135                         //float radius = objprop->m_radius;
136                         //btVector3 inertiaHalfExtents (
137                         //      radius,
138                         //      radius,
139                         //      radius);
140                         
141                         //blender doesn't support multisphere, but for testing:
142
143                         //bm = new MultiSphereShape(inertiaHalfExtents,,&trans.getOrigin(),&radius,1);
144                         shapeInfo->m_shapeType = PHY_SHAPE_SPHERE;
145                         bm = shapeInfo->CreateBulletShape(ci.m_margin);
146                         break;
147                 };
148         case KX_BOUNDBOX:
149                 {
150                         shapeInfo->m_halfExtend.setValue(
151                                 objprop->m_boundobject.box.m_extends[0],
152                                 objprop->m_boundobject.box.m_extends[1],
153                                 objprop->m_boundobject.box.m_extends[2]);
154
155                         shapeInfo->m_halfExtend /= 2.0;
156                         shapeInfo->m_halfExtend = shapeInfo->m_halfExtend.absolute();
157                         shapeInfo->m_shapeType = PHY_SHAPE_BOX;
158                         bm = shapeInfo->CreateBulletShape(ci.m_margin);
159                         break;
160                 };
161         case KX_BOUNDCYLINDER:
162                 {
163                         shapeInfo->m_halfExtend.setValue(
164                                 objprop->m_boundobject.c.m_radius,
165                                 objprop->m_boundobject.c.m_radius,
166                                 objprop->m_boundobject.c.m_height * 0.5f
167                         );
168                         shapeInfo->m_shapeType = PHY_SHAPE_CYLINDER;
169                         bm = shapeInfo->CreateBulletShape(ci.m_margin);
170                         break;
171                 }
172
173         case KX_BOUNDCONE:
174                 {
175                         shapeInfo->m_radius = objprop->m_boundobject.c.m_radius;
176                         shapeInfo->m_height = objprop->m_boundobject.c.m_height;
177                         shapeInfo->m_shapeType = PHY_SHAPE_CONE;
178                         bm = shapeInfo->CreateBulletShape(ci.m_margin);
179                         break;
180                 }
181         case KX_BOUNDPOLYTOPE:
182                 {
183                         shapeInfo->SetMesh(meshobj, dm,true);
184                         bm = shapeInfo->CreateBulletShape(ci.m_margin);
185                         break;
186                 }
187         case KX_BOUNDCAPSULE:
188                 {
189                         shapeInfo->m_radius = objprop->m_boundobject.c.m_radius;
190                         shapeInfo->m_height = objprop->m_boundobject.c.m_height;
191                         shapeInfo->m_shapeType = PHY_SHAPE_CAPSULE;
192                         bm = shapeInfo->CreateBulletShape(ci.m_margin);
193                         break;
194                 }
195         case KX_BOUNDMESH:
196                 {
197                         // mesh shapes can be shared, check first if we already have a shape on that mesh
198                         class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, dm, false);
199                         if (sharedShapeInfo != NULL) 
200                         {
201                                 shapeInfo->Release();
202                                 shapeInfo = sharedShapeInfo;
203                                 shapeInfo->AddRef();
204                         } else
205                         {
206                                 shapeInfo->SetMesh(meshobj, dm, false);
207                         }
208
209                         // Soft bodies require welding. Only avoid remove doubles for non-soft bodies!
210                         if (objprop->m_softbody)
211                         {
212                                 shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI
213                         }
214
215                         bm = shapeInfo->CreateBulletShape(ci.m_margin, useGimpact, !objprop->m_softbody);
216                         //should we compute inertia for dynamic shape?
217                         //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
218
219                         break;
220                 }
221         case KX_BOUND_DYN_MESH:
222                 /* do nothing */
223                 break;
224         }
225
226
227 //      ci.m_localInertiaTensor.setValue(0.1f,0.1f,0.1f);
228
229         if (!bm)
230         {
231                 delete motionstate;
232                 shapeInfo->Release();
233                 return;
234         }
235
236         //bm->setMargin(ci.m_margin);
237
238
239                 if (objprop->m_isCompoundChild)
240                 {
241                         //find parent, compound shape and add to it
242                         //take relative transform into account!
243                         KX_BulletPhysicsController* parentCtrl = (KX_BulletPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController();
244                         assert(parentCtrl);
245                         CcdShapeConstructionInfo* parentShapeInfo = parentCtrl->GetShapeInfo();
246                         btRigidBody* rigidbody = parentCtrl->GetRigidBody();
247                         btCollisionShape* colShape = rigidbody->getCollisionShape();
248                         assert(colShape->isCompound());
249                         btCompoundShape* compoundShape = (btCompoundShape*)colShape;
250
251                         // compute the local transform from parent, this may include several node in the chain
252                         SG_Node* gameNode = gameobj->GetSGNode();
253                         SG_Node* parentNode = objprop->m_dynamic_parent->GetSGNode();
254                         // relative transform
255                         MT_Vector3 parentScale = parentNode->GetWorldScaling();
256                         parentScale[0] = MT_Scalar(1.0)/parentScale[0];
257                         parentScale[1] = MT_Scalar(1.0)/parentScale[1];
258                         parentScale[2] = MT_Scalar(1.0)/parentScale[2];
259                         MT_Vector3 relativeScale = gameNode->GetWorldScaling() * parentScale;
260                         MT_Matrix3x3 parentInvRot = parentNode->GetWorldOrientation().transposed();
261                         MT_Vector3 relativePos = parentInvRot*((gameNode->GetWorldPosition()-parentNode->GetWorldPosition())*parentScale);
262                         MT_Matrix3x3 relativeRot = parentInvRot*gameNode->GetWorldOrientation();
263
264                         shapeInfo->m_childScale.setValue(relativeScale[0],relativeScale[1],relativeScale[2]);
265                         bm->setLocalScaling(shapeInfo->m_childScale);
266                         shapeInfo->m_childTrans.getOrigin().setValue(relativePos[0],relativePos[1],relativePos[2]);
267                         float rot[12];
268                         relativeRot.getValue(rot);
269                         shapeInfo->m_childTrans.getBasis().setFromOpenGLSubMatrix(rot);
270
271                         parentShapeInfo->AddShape(shapeInfo);   
272                         compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
273                         //do some recalc?
274                         //recalc inertia for rigidbody
275                         if (!rigidbody->isStaticOrKinematicObject())
276                         {
277                                 btVector3 localInertia;
278                                 float mass = 1.f/rigidbody->getInvMass();
279                                 compoundShape->calculateLocalInertia(mass,localInertia);
280                                 rigidbody->setMassProps(mass,localInertia);
281                         }
282                         shapeInfo->Release();
283                         // delete motionstate as it's not used
284                         delete motionstate;
285                         return;
286                 }
287
288                 if (objprop->m_hasCompoundChildren)
289                 {
290                         // create a compound shape info
291                         CcdShapeConstructionInfo *compoundShapeInfo = new CcdShapeConstructionInfo();
292                         compoundShapeInfo->m_shapeType = PHY_SHAPE_COMPOUND;
293                         compoundShapeInfo->AddShape(shapeInfo);
294                         // create the compound shape manually as we already have the child shape
295                         btCompoundShape* compoundShape = new btCompoundShape();
296                         compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
297                         // now replace the shape
298                         bm = compoundShape;
299                         shapeInfo->Release();
300                         shapeInfo = compoundShapeInfo;
301                 }
302
303
304
305
306
307
308 #ifdef TEST_SIMD_HULL
309         if (bm->IsPolyhedral())
310         {
311                 PolyhedralConvexShape* polyhedron = static_cast<PolyhedralConvexShape*>(bm);
312                 if (!polyhedron->m_optionalHull)
313                 {
314                         //first convert vertices in 'Point3' format
315                         int numPoints = polyhedron->GetNumVertices();
316                         Point3* points = new Point3[numPoints+1];
317                         //first 4 points should not be co-planar, so add central point to satisfy MakeHull
318                         points[0] = Point3(0.f,0.f,0.f);
319                         
320                         btVector3 vertex;
321                         for (int p=0;p<numPoints;p++)
322                         {
323                                 polyhedron->GetVertex(p,vertex);
324                                 points[p+1] = Point3(vertex.getX(),vertex.getY(),vertex.getZ());
325                         }
326
327                         Hull* hull = Hull::MakeHull(numPoints+1,points);
328                         polyhedron->m_optionalHull = hull;
329                 }
330
331         }
332 #endif //TEST_SIMD_HULL
333
334
335         ci.m_collisionShape = bm;
336         ci.m_shapeInfo = shapeInfo;
337         ci.m_friction = smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice
338         ci.m_restitution = smmaterial->m_restitution;
339         ci.m_physicsEnv = env;
340         // drag / damping is inverted
341         ci.m_linearDamping = 1.f - shapeprops->m_lin_drag;
342         ci.m_angularDamping = 1.f - shapeprops->m_ang_drag;
343         //need a bit of damping, else system doesn't behave well
344         ci.m_inertiaFactor = shapeprops->m_inertia/0.4f;//defaults to 0.4, don't want to change behaviour
345         
346         ci.m_do_anisotropic = shapeprops->m_do_anisotropic;
347         ci.m_anisotropicFriction.setValue(shapeprops->m_friction_scaling[0],shapeprops->m_friction_scaling[1],shapeprops->m_friction_scaling[2]);
348
349
350 //////////
351         //do Fh, do Rot Fh
352         ci.m_do_fh = shapeprops->m_do_fh;
353         ci.m_do_rot_fh = shapeprops->m_do_rot_fh ;
354         ci.m_fh_damping = smmaterial->m_fh_damping;
355         ci.m_fh_distance = smmaterial->m_fh_distance;
356         ci.m_fh_normal = smmaterial->m_fh_normal;
357         ci.m_fh_spring = smmaterial->m_fh_spring;
358         ci.m_radius = objprop->m_radius;
359         
360         
361         ///////////////////
362         ci.m_gamesoftFlag = objprop->m_gamesoftFlag;
363         ci.m_soft_linStiff = objprop->m_soft_linStiff;
364         ci.m_soft_angStiff = objprop->m_soft_angStiff;          /* angular stiffness 0..1 */
365         ci.m_soft_volume= objprop->m_soft_volume;                       /* volume preservation 0..1 */
366
367         ci.m_soft_viterations= objprop->m_soft_viterations;             /* Velocities solver iterations */
368         ci.m_soft_piterations= objprop->m_soft_piterations;             /* Positions solver iterations */
369         ci.m_soft_diterations= objprop->m_soft_diterations;             /* Drift solver iterations */
370         ci.m_soft_citerations= objprop->m_soft_citerations;             /* Cluster solver iterations */
371
372         ci.m_soft_kSRHR_CL= objprop->m_soft_kSRHR_CL;           /* Soft vs rigid hardness [0,1] (cluster only) */
373         ci.m_soft_kSKHR_CL= objprop->m_soft_kSKHR_CL;           /* Soft vs kinetic hardness [0,1] (cluster only) */
374         ci.m_soft_kSSHR_CL= objprop->m_soft_kSSHR_CL;           /* Soft vs soft hardness [0,1] (cluster only) */
375         ci.m_soft_kSR_SPLT_CL= objprop->m_soft_kSR_SPLT_CL;     /* Soft vs rigid impulse split [0,1] (cluster only) */
376
377         ci.m_soft_kSK_SPLT_CL= objprop->m_soft_kSK_SPLT_CL;     /* Soft vs rigid impulse split [0,1] (cluster only) */
378         ci.m_soft_kSS_SPLT_CL= objprop->m_soft_kSS_SPLT_CL;     /* Soft vs rigid impulse split [0,1] (cluster only) */
379         ci.m_soft_kVCF= objprop->m_soft_kVCF;                   /* Velocities correction factor (Baumgarte) */
380         ci.m_soft_kDP= objprop->m_soft_kDP;                     /* Damping coefficient [0,1] */
381
382         ci.m_soft_kDG= objprop->m_soft_kDG;                     /* Drag coefficient [0,+inf] */
383         ci.m_soft_kLF= objprop->m_soft_kLF;                     /* Lift coefficient [0,+inf] */
384         ci.m_soft_kPR= objprop->m_soft_kPR;                     /* Pressure coefficient [-inf,+inf] */
385         ci.m_soft_kVC= objprop->m_soft_kVC;                     /* Volume conversation coefficient [0,+inf] */
386
387         ci.m_soft_kDF= objprop->m_soft_kDF;                     /* Dynamic friction coefficient [0,1] */
388         ci.m_soft_kMT= objprop->m_soft_kMT;                     /* Pose matching coefficient [0,1] */
389         ci.m_soft_kCHR= objprop->m_soft_kCHR;                   /* Rigid contacts hardness [0,1] */
390         ci.m_soft_kKHR= objprop->m_soft_kKHR;                   /* Kinetic contacts hardness [0,1] */
391
392         ci.m_soft_kSHR= objprop->m_soft_kSHR;                   /* Soft contacts hardness [0,1] */
393         ci.m_soft_kAHR= objprop->m_soft_kAHR;                   /* Anchors hardness [0,1] */
394         ci.m_soft_collisionflags= objprop->m_soft_collisionflags;       /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */
395         ci.m_soft_numclusteriterations= objprop->m_soft_numclusteriterations;   /* number of iterations to refine collision clusters*/
396
397         ////////////////////
398         ci.m_collisionFilterGroup = 
399                 (isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) :
400                 (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : 
401                 short(CcdConstructionInfo::StaticFilter);
402         ci.m_collisionFilterMask = 
403                 (isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) :
404                 (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : 
405                 short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
406         ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody;
407         
408         ci.m_contactProcessingThreshold = objprop->m_contactProcessingThreshold;//todo: expose this in advanced settings, just like margin, default to 10000 or so
409         ci.m_bSoft = objprop->m_softbody;
410         ci.m_bSensor = isbulletsensor;
411         ci.m_bGimpact = useGimpact;
412         MT_Vector3 scaling = gameobj->NodeGetWorldScaling();
413         ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]);
414         KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,isbulletsensor,objprop->m_hasCompoundChildren);
415         // shapeInfo is reference counted, decrement now as we don't use it anymore
416         if (shapeInfo)
417                 shapeInfo->Release();
418
419         gameobj->SetPhysicsController(physicscontroller,isbulletdyna);
420         // don't add automatically sensor object, they are added when a collision sensor is registered
421         if (!isbulletsensor && objprop->m_in_active_layer)
422         {
423                 env->addCcdPhysicsController( physicscontroller);
424         }
425         physicscontroller->setNewClientInfo(gameobj->getClientInfo());          
426         {
427                 btRigidBody* rbody = physicscontroller->GetRigidBody();
428
429                 if (rbody)
430                 {
431                         if (objprop->m_angular_rigidbody)
432                         {
433                                 btVector3 linearFactor(
434                                         objprop->m_lockXaxis? 0 : 1,
435                                         objprop->m_lockYaxis? 0 : 1,
436                                         objprop->m_lockZaxis? 0 : 1);
437                                 btVector3 angularFactor(
438                                         objprop->m_lockXRotaxis? 0 : 1,
439                                         objprop->m_lockYRotaxis? 0 : 1,
440                                         objprop->m_lockZRotaxis? 0 : 1);
441                                 rbody->setLinearFactor(linearFactor);
442                                 rbody->setAngularFactor(angularFactor);
443                         }
444
445                         if (rbody && objprop->m_disableSleeping)
446                         {
447                                 rbody->setActivationState(DISABLE_DEACTIVATION);
448                         }
449                 }
450         }
451
452         CcdPhysicsController* parentCtrl = objprop->m_dynamic_parent ? (KX_BulletPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController() : 0;
453         physicscontroller->setParentCtrl(parentCtrl);
454
455         
456         //Now done directly in ci.m_collisionFlags so that it propagates to replica
457         //if (objprop->m_ghost)
458         //{
459         //      rbody->setCollisionFlags(rbody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
460         //}
461         
462         if (objprop->m_dyna && !objprop->m_angular_rigidbody)
463         {
464                 /*
465                 //setting the inertia could achieve similar results to constraint the up
466                 //but it is prone to instability, so use special 'Angular' constraint
467                 btVector3 inertia = physicscontroller->GetRigidBody()->getInvInertiaDiagLocal();
468                 inertia.setX(0.f);
469                 inertia.setZ(0.f);
470
471                 physicscontroller->GetRigidBody()->setInvInertiaDiagLocal(inertia);
472                 physicscontroller->GetRigidBody()->updateInertiaTensor();
473                 */
474
475                 //env->createConstraint(physicscontroller,0,PHY_ANGULAR_CONSTRAINT,0,0,0,0,0,1);
476         
477                 //Now done directly in ci.m_bRigid so that it propagates to replica
478                 //physicscontroller->GetRigidBody()->setAngularFactor(0.f);
479                 ;
480         }
481
482         bool isActor = objprop->m_isactor;
483         gameobj->getClientInfo()->m_type = 
484                 (isbulletsensor) ? ((isActor) ? KX_ClientObjectInfo::OBACTORSENSOR : KX_ClientObjectInfo::OBSENSOR) :
485                 (isActor) ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC;
486         // store materialname in auxinfo, needed for touchsensors
487         if (meshobj)
488         {
489                 const STR_String& matname=meshobj->GetMaterialName(0);
490                 gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL);
491         } else
492         {
493                 gameobj->getClientInfo()->m_auxilary_info = 0;
494         }
495
496
497         gameobj->GetSGNode()->AddSGController(physicscontroller);
498
499         STR_String materialname;
500         if (meshobj)
501                 materialname = meshobj->GetMaterialName(0);
502
503         physicscontroller->SetObject(gameobj->GetSGNode());
504
505 #if 0
506         ///test for soft bodies
507         if (objprop->m_softbody && physicscontroller)
508         {
509                 btSoftBody* softBody = physicscontroller->GetSoftBody();
510                 if (softBody && gameobj->GetMesh(0))//only the first mesh, if any
511                 {
512                         //should be a mesh then, so add a soft body deformer
513                         KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer( gameobj->GetMesh(0),(BL_DeformableGameObject*)gameobj);
514                         gameobj->SetDeformer(softbodyDeformer);
515                 }
516         }
517 #endif
518
519 }
520
521
522 void    KX_ClearBulletSharedShapes()
523 {
524 }
525
526 /* Refresh the physics object from either an object or a mesh.
527  * gameobj must be valid
528  * from_gameobj and from_meshobj can be NULL
529  * 
530  * when setting the mesh, the following vars get priority
531  * 1) from_meshobj - creates the phys mesh from RAS_MeshObject
532  * 2) from_gameobj - creates the phys mesh from the DerivedMesh where possible, else the RAS_MeshObject
533  * 3) gameobj - update the phys mesh from DerivedMesh or RAS_MeshObject
534  * 
535  * Most of the logic behind this is in shapeInfo->UpdateMesh(...)
536  */
537 bool KX_ReInstanceBulletShapeFromMesh(KX_GameObject *gameobj, KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj)
538 {
539         KX_BulletPhysicsController      *spc= static_cast<KX_BulletPhysicsController*>((gameobj->GetPhysicsController()));
540         CcdShapeConstructionInfo        *shapeInfo;
541
542         /* if this is the child of a compound shape this can happen
543          * dont support compound shapes for now */
544         if(spc==NULL)
545                 return false;
546         
547         shapeInfo = spc->GetShapeInfo();
548         
549         if(shapeInfo->m_shapeType != PHY_SHAPE_MESH/* || spc->GetSoftBody()*/)
550                 return false;
551         
552         spc->DeleteControllerShape();
553         
554         if(from_gameobj==NULL && from_meshobj==NULL)
555                 from_gameobj= gameobj;
556         
557         /* updates the arrays used for making the new bullet mesh */
558         shapeInfo->UpdateMesh(from_gameobj, from_meshobj);
559
560         /* create the new bullet mesh */
561         CcdConstructionInfo& cci = spc->getConstructionInfo();
562         btCollisionShape* bm= shapeInfo->CreateBulletShape(cci.m_margin, cci.m_bGimpact, !cci.m_bSoft);
563
564         spc->ReplaceControllerShape(bm);
565         return true;
566 }
567 #endif // USE_BULLET