svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r22205:22290
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 #ifdef WIN32
30 #pragma warning (disable : 4786)
31 #endif
32
33 #include "MT_assert.h"
34
35 #include "KX_ConvertPhysicsObject.h"
36 #include "BL_DeformableGameObject.h"
37 #include "RAS_MeshObject.h"
38 #include "KX_Scene.h"
39 #include "SYS_System.h"
40 #include "BL_SkinMeshObject.h"
41 #include "BulletSoftBody/btSoftBody.h"
42
43 #include "PHY_Pro.h" //todo cleanup
44 #include "KX_ClientObjectInfo.h"
45
46 #include "GEN_Map.h"
47 #include "GEN_HashedPtr.h"
48
49 #include "KX_PhysicsEngineEnums.h"
50 #include "PHY_Pro.h"
51
52 #include "KX_MotionState.h" // bridge between motionstate and scenegraph node
53
54 extern "C"{
55         #include "BKE_DerivedMesh.h"
56 }
57
58 #ifdef USE_BULLET
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         class KX_SoftBodyDeformer : public RAS_Deformer
84         {
85                 class RAS_MeshObject*                   m_pMeshObject;
86                 class BL_DeformableGameObject*  m_gameobj;
87
88         public:
89                 KX_SoftBodyDeformer(RAS_MeshObject*     pMeshObject,BL_DeformableGameObject*    gameobj)
90                         :m_pMeshObject(pMeshObject),
91                         m_gameobj(gameobj)
92                 {
93                         //printf("KX_SoftBodyDeformer\n");
94                 };
95
96                 virtual ~KX_SoftBodyDeformer()
97                 {
98                         //printf("~KX_SoftBodyDeformer\n");
99                 };
100                 virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
101                 {
102                         void **h_obj = (*map)[m_gameobj];
103
104                         if (h_obj) {
105                                 m_gameobj = (BL_DeformableGameObject*)(*h_obj);
106                                 m_pMeshObject = m_gameobj->GetMesh(0);
107                         } else {
108                                 m_gameobj = NULL;
109                                 m_pMeshObject = NULL;
110                         }
111                 }
112                 virtual bool Apply(class RAS_IPolyMaterial *polymat)
113                 {
114                         KX_BulletPhysicsController* ctrl = (KX_BulletPhysicsController*) m_gameobj->GetPhysicsController();
115                         if (!ctrl)
116                                 return false;
117
118                         btSoftBody* softBody= ctrl->GetSoftBody();
119                         if (!softBody)
120                                 return false;
121
122                         //printf("apply\n");
123                         RAS_MeshSlot::iterator it;
124                         RAS_MeshMaterial *mmat;
125                         RAS_MeshSlot *slot;
126                         size_t i;
127
128                         // update the vertex in m_transverts
129                         Update();
130
131
132
133                         // The vertex cache can only be updated for this deformer:
134                         // Duplicated objects with more than one ploymaterial (=multiple mesh slot per object)
135                         // share the same mesh (=the same cache). As the rendering is done per polymaterial
136                         // cycling through the objects, the entire mesh cache cannot be updated in one shot.
137                         mmat = m_pMeshObject->GetMeshMaterial(polymat);
138                         if(!mmat->m_slots[(void*)m_gameobj])
139                                 return true;
140
141                         slot = *mmat->m_slots[(void*)m_gameobj];
142
143                         // for each array
144                         for(slot->begin(it); !slot->end(it); slot->next(it)) 
145                         {
146                                 btSoftBody::tNodeArray&   nodes(softBody->m_nodes);
147
148                                 int index = 0;
149                                 for(i=it.startvertex; i<it.endvertex; i++,index++) {
150                                         RAS_TexVert& v = it.vertex[i];
151                                         btAssert(v.getSoftBodyIndex() >= 0);
152
153                                         MT_Point3 pt (
154                                                 nodes[v.getSoftBodyIndex()].m_x.getX(),
155                                                 nodes[v.getSoftBodyIndex()].m_x.getY(),
156                                                 nodes[v.getSoftBodyIndex()].m_x.getZ());
157                                         v.SetXYZ(pt);
158
159                                         MT_Vector3 normal (
160                                                 nodes[v.getSoftBodyIndex()].m_n.getX(),
161                                                 nodes[v.getSoftBodyIndex()].m_n.getY(),
162                                                 nodes[v.getSoftBodyIndex()].m_n.getZ());
163                                         v.SetNormal(normal);
164
165                                 }
166                         }
167                         return true;
168                 }
169                 virtual bool Update(void)
170                 {
171                         //printf("update\n");
172                         m_bDynamic = true;
173                         return true;//??
174                 }
175                 virtual bool UpdateBuckets(void)
176                 {
177                         // this is to update the mesh slots outside the rasterizer, 
178                         // no need to do it for this deformer, it's done in any case in Apply()
179                         return false;
180                 }
181
182                 virtual RAS_Deformer *GetReplica()
183                 {
184                         KX_SoftBodyDeformer* deformer = new KX_SoftBodyDeformer(*this);
185                         deformer->ProcessReplica();
186                         return deformer;
187                 }
188                 virtual void ProcessReplica()
189                 {
190                         // we have two pointers to deal with but we cannot do it now, will be done in Relink
191                         m_bDynamic = false;
192                 }
193                 virtual bool SkipVertexTransform()
194                 {
195                         return true;
196                 }
197
198         protected:
199                 //class RAS_MeshObject  *m_pMesh;
200         };
201
202
203 // forward declarations
204
205 void    KX_ConvertBulletObject( class   KX_GameObject* gameobj,
206         class   RAS_MeshObject* meshobj,
207         struct  DerivedMesh* dm,
208         class   KX_Scene* kxscene,
209         struct  PHY_ShapeProps* shapeprops,
210         struct  PHY_MaterialProps*      smmaterial,
211         struct  KX_ObjectProperties*    objprop)
212 {
213
214         CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
215         assert(env);
216         
217
218         bool isbulletdyna = false;
219         bool isbulletsensor = false;
220         CcdConstructionInfo ci;
221         class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
222         class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo();
223
224         
225         if (!objprop->m_dyna)
226         {
227                 ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
228         }
229         if (objprop->m_ghost)
230         {
231                 ci.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
232         }
233
234         ci.m_MotionState = motionstate;
235         ci.m_gravity = btVector3(0,0,0);
236         ci.m_localInertiaTensor =btVector3(0,0,0);
237         ci.m_mass = objprop->m_dyna ? shapeprops->m_mass : 0.f;
238         ci.m_clamp_vel_min = shapeprops->m_clamp_vel_min;
239         ci.m_clamp_vel_max = shapeprops->m_clamp_vel_max;
240         ci.m_margin = objprop->m_margin;
241         shapeInfo->m_radius = objprop->m_radius;
242         isbulletdyna = objprop->m_dyna;
243         isbulletsensor = objprop->m_sensor;
244         
245         ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f);
246         
247         btCollisionShape* bm = 0;
248
249         switch (objprop->m_boundclass)
250         {
251         case KX_BOUNDSPHERE:
252                 {
253                         //float radius = objprop->m_radius;
254                         //btVector3 inertiaHalfExtents (
255                         //      radius,
256                         //      radius,
257                         //      radius);
258                         
259                         //blender doesn't support multisphere, but for testing:
260
261                         //bm = new MultiSphereShape(inertiaHalfExtents,,&trans.getOrigin(),&radius,1);
262                         shapeInfo->m_shapeType = PHY_SHAPE_SPHERE;
263                         bm = shapeInfo->CreateBulletShape(ci.m_margin);
264                         break;
265                 };
266         case KX_BOUNDBOX:
267                 {
268                         shapeInfo->m_halfExtend.setValue(
269                                 objprop->m_boundobject.box.m_extends[0],
270                                 objprop->m_boundobject.box.m_extends[1],
271                                 objprop->m_boundobject.box.m_extends[2]);
272
273                         shapeInfo->m_halfExtend /= 2.0;
274                         shapeInfo->m_halfExtend = shapeInfo->m_halfExtend.absolute();
275                         shapeInfo->m_shapeType = PHY_SHAPE_BOX;
276                         bm = shapeInfo->CreateBulletShape(ci.m_margin);
277                         break;
278                 };
279         case KX_BOUNDCYLINDER:
280                 {
281                         shapeInfo->m_halfExtend.setValue(
282                                 objprop->m_boundobject.c.m_radius,
283                                 objprop->m_boundobject.c.m_radius,
284                                 objprop->m_boundobject.c.m_height * 0.5f
285                         );
286                         shapeInfo->m_shapeType = PHY_SHAPE_CYLINDER;
287                         bm = shapeInfo->CreateBulletShape(ci.m_margin);
288                         break;
289                 }
290
291         case KX_BOUNDCONE:
292                 {
293                         shapeInfo->m_radius = objprop->m_boundobject.c.m_radius;
294                         shapeInfo->m_height = objprop->m_boundobject.c.m_height;
295                         shapeInfo->m_shapeType = PHY_SHAPE_CONE;
296                         bm = shapeInfo->CreateBulletShape(ci.m_margin);
297                         break;
298                 }
299         case KX_BOUNDPOLYTOPE:
300                 {
301                         shapeInfo->SetMesh(meshobj, dm,true,false);
302                         bm = shapeInfo->CreateBulletShape(ci.m_margin);
303                         break;
304                 }
305         case KX_BOUNDMESH:
306                 {
307                         bool useGimpact = ((ci.m_mass || isbulletsensor) && !objprop->m_softbody);
308
309                         // mesh shapes can be shared, check first if we already have a shape on that mesh
310                         class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, dm, false,useGimpact);
311                         if (sharedShapeInfo != NULL) 
312                         {
313                                 delete shapeInfo;
314                                 shapeInfo = sharedShapeInfo;
315                                 shapeInfo->AddRef();
316                         } else
317                         {
318                                 shapeInfo->SetMesh(meshobj, dm, false,useGimpact);
319                         }
320
321                         // Soft bodies require welding. Only avoid remove doubles for non-soft bodies!
322                         if (objprop->m_softbody)
323                         {
324                                 shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI
325                         }
326
327                         bm = shapeInfo->CreateBulletShape(ci.m_margin);
328                         //should we compute inertia for dynamic shape?
329                         //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
330
331                         break;
332                 }
333         }
334
335
336 //      ci.m_localInertiaTensor.setValue(0.1f,0.1f,0.1f);
337
338         if (!bm)
339         {
340                 delete motionstate;
341                 delete shapeInfo;
342                 return;
343         }
344
345         //bm->setMargin(ci.m_margin);
346
347
348                 if (objprop->m_isCompoundChild)
349                 {
350                         //find parent, compound shape and add to it
351                         //take relative transform into account!
352                         KX_BulletPhysicsController* parentCtrl = (KX_BulletPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController();
353                         assert(parentCtrl);
354                         CcdShapeConstructionInfo* parentShapeInfo = parentCtrl->GetShapeInfo();
355                         btRigidBody* rigidbody = parentCtrl->GetRigidBody();
356                         btCollisionShape* colShape = rigidbody->getCollisionShape();
357                         assert(colShape->isCompound());
358                         btCompoundShape* compoundShape = (btCompoundShape*)colShape;
359
360                         // compute the local transform from parent, this may include several node in the chain
361                         SG_Node* gameNode = gameobj->GetSGNode();
362                         SG_Node* parentNode = objprop->m_dynamic_parent->GetSGNode();
363                         // relative transform
364                         MT_Vector3 parentScale = parentNode->GetWorldScaling();
365                         parentScale[0] = MT_Scalar(1.0)/parentScale[0];
366                         parentScale[1] = MT_Scalar(1.0)/parentScale[1];
367                         parentScale[2] = MT_Scalar(1.0)/parentScale[2];
368                         MT_Vector3 relativeScale = gameNode->GetWorldScaling() * parentScale;
369                         MT_Matrix3x3 parentInvRot = parentNode->GetWorldOrientation().transposed();
370                         MT_Vector3 relativePos = parentInvRot*((gameNode->GetWorldPosition()-parentNode->GetWorldPosition())*parentScale);
371                         MT_Matrix3x3 relativeRot = parentInvRot*gameNode->GetWorldOrientation();
372
373                         shapeInfo->m_childScale.setValue(relativeScale[0],relativeScale[1],relativeScale[2]);
374                         bm->setLocalScaling(shapeInfo->m_childScale);
375                         shapeInfo->m_childTrans.getOrigin().setValue(relativePos[0],relativePos[1],relativePos[2]);
376                         float rot[12];
377                         relativeRot.getValue(rot);
378                         shapeInfo->m_childTrans.getBasis().setFromOpenGLSubMatrix(rot);
379
380                         parentShapeInfo->AddShape(shapeInfo);   
381                         compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
382                         //do some recalc?
383                         //recalc inertia for rigidbody
384                         if (!rigidbody->isStaticOrKinematicObject())
385                         {
386                                 btVector3 localInertia;
387                                 float mass = 1.f/rigidbody->getInvMass();
388                                 compoundShape->calculateLocalInertia(mass,localInertia);
389                                 rigidbody->setMassProps(mass,localInertia);
390                         }
391                         // delete motionstate as it's not used
392                         delete motionstate;
393                         return;
394                 }
395
396                 if (objprop->m_hasCompoundChildren)
397                 {
398                         // create a compound shape info
399                         CcdShapeConstructionInfo *compoundShapeInfo = new CcdShapeConstructionInfo();
400                         compoundShapeInfo->m_shapeType = PHY_SHAPE_COMPOUND;
401                         compoundShapeInfo->AddShape(shapeInfo);
402                         // create the compound shape manually as we already have the child shape
403                         btCompoundShape* compoundShape = new btCompoundShape();
404                         compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
405                         // now replace the shape
406                         bm = compoundShape;
407                         shapeInfo = compoundShapeInfo;
408                 }
409
410
411
412
413
414
415 #ifdef TEST_SIMD_HULL
416         if (bm->IsPolyhedral())
417         {
418                 PolyhedralConvexShape* polyhedron = static_cast<PolyhedralConvexShape*>(bm);
419                 if (!polyhedron->m_optionalHull)
420                 {
421                         //first convert vertices in 'Point3' format
422                         int numPoints = polyhedron->GetNumVertices();
423                         Point3* points = new Point3[numPoints+1];
424                         //first 4 points should not be co-planar, so add central point to satisfy MakeHull
425                         points[0] = Point3(0.f,0.f,0.f);
426                         
427                         btVector3 vertex;
428                         for (int p=0;p<numPoints;p++)
429                         {
430                                 polyhedron->GetVertex(p,vertex);
431                                 points[p+1] = Point3(vertex.getX(),vertex.getY(),vertex.getZ());
432                         }
433
434                         Hull* hull = Hull::MakeHull(numPoints+1,points);
435                         polyhedron->m_optionalHull = hull;
436                 }
437
438         }
439 #endif //TEST_SIMD_HULL
440
441
442         ci.m_collisionShape = bm;
443         ci.m_shapeInfo = shapeInfo;
444         ci.m_friction = smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice
445         ci.m_restitution = smmaterial->m_restitution;
446         ci.m_physicsEnv = env;
447         // drag / damping is inverted
448         ci.m_linearDamping = 1.f - shapeprops->m_lin_drag;
449         ci.m_angularDamping = 1.f - shapeprops->m_ang_drag;
450         //need a bit of damping, else system doesn't behave well
451         ci.m_inertiaFactor = shapeprops->m_inertia/0.4f;//defaults to 0.4, don't want to change behaviour
452         
453         ci.m_do_anisotropic = shapeprops->m_do_anisotropic;
454         ci.m_anisotropicFriction.setValue(shapeprops->m_friction_scaling[0],shapeprops->m_friction_scaling[1],shapeprops->m_friction_scaling[2]);
455
456
457 //////////
458         //do Fh, do Rot Fh
459         ci.m_do_fh = shapeprops->m_do_fh;
460         ci.m_do_rot_fh = shapeprops->m_do_rot_fh ;
461         ci.m_fh_damping = smmaterial->m_fh_damping;
462         ci.m_fh_distance = smmaterial->m_fh_distance;
463         ci.m_fh_normal = smmaterial->m_fh_normal;
464         ci.m_fh_spring = smmaterial->m_fh_spring;
465         ci.m_radius = objprop->m_radius;
466         
467         
468         ///////////////////
469         ci.m_gamesoftFlag = objprop->m_gamesoftFlag;
470         ci.m_soft_linStiff = objprop->m_soft_linStiff;
471         ci.m_soft_angStiff = objprop->m_soft_angStiff;          /* angular stiffness 0..1 */
472         ci.m_soft_volume= objprop->m_soft_volume;                       /* volume preservation 0..1 */
473
474         ci.m_soft_viterations= objprop->m_soft_viterations;             /* Velocities solver iterations */
475         ci.m_soft_piterations= objprop->m_soft_piterations;             /* Positions solver iterations */
476         ci.m_soft_diterations= objprop->m_soft_diterations;             /* Drift solver iterations */
477         ci.m_soft_citerations= objprop->m_soft_citerations;             /* Cluster solver iterations */
478
479         ci.m_soft_kSRHR_CL= objprop->m_soft_kSRHR_CL;           /* Soft vs rigid hardness [0,1] (cluster only) */
480         ci.m_soft_kSKHR_CL= objprop->m_soft_kSKHR_CL;           /* Soft vs kinetic hardness [0,1] (cluster only) */
481         ci.m_soft_kSSHR_CL= objprop->m_soft_kSSHR_CL;           /* Soft vs soft hardness [0,1] (cluster only) */
482         ci.m_soft_kSR_SPLT_CL= objprop->m_soft_kSR_SPLT_CL;     /* Soft vs rigid impulse split [0,1] (cluster only) */
483
484         ci.m_soft_kSK_SPLT_CL= objprop->m_soft_kSK_SPLT_CL;     /* Soft vs rigid impulse split [0,1] (cluster only) */
485         ci.m_soft_kSS_SPLT_CL= objprop->m_soft_kSS_SPLT_CL;     /* Soft vs rigid impulse split [0,1] (cluster only) */
486         ci.m_soft_kVCF= objprop->m_soft_kVCF;                   /* Velocities correction factor (Baumgarte) */
487         ci.m_soft_kDP= objprop->m_soft_kDP;                     /* Damping coefficient [0,1] */
488
489         ci.m_soft_kDG= objprop->m_soft_kDG;                     /* Drag coefficient [0,+inf] */
490         ci.m_soft_kLF= objprop->m_soft_kLF;                     /* Lift coefficient [0,+inf] */
491         ci.m_soft_kPR= objprop->m_soft_kPR;                     /* Pressure coefficient [-inf,+inf] */
492         ci.m_soft_kVC= objprop->m_soft_kVC;                     /* Volume conversation coefficient [0,+inf] */
493
494         ci.m_soft_kDF= objprop->m_soft_kDF;                     /* Dynamic friction coefficient [0,1] */
495         ci.m_soft_kMT= objprop->m_soft_kMT;                     /* Pose matching coefficient [0,1] */
496         ci.m_soft_kCHR= objprop->m_soft_kCHR;                   /* Rigid contacts hardness [0,1] */
497         ci.m_soft_kKHR= objprop->m_soft_kKHR;                   /* Kinetic contacts hardness [0,1] */
498
499         ci.m_soft_kSHR= objprop->m_soft_kSHR;                   /* Soft contacts hardness [0,1] */
500         ci.m_soft_kAHR= objprop->m_soft_kAHR;                   /* Anchors hardness [0,1] */
501         ci.m_soft_collisionflags= objprop->m_soft_collisionflags;       /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */
502         ci.m_soft_numclusteriterations= objprop->m_soft_numclusteriterations;   /* number of iterations to refine collision clusters*/
503
504         ////////////////////
505         ci.m_collisionFilterGroup = 
506                 (isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) :
507                 (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : 
508                 short(CcdConstructionInfo::StaticFilter);
509         ci.m_collisionFilterMask = 
510                 (isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) :
511                 (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : 
512                 short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
513         ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody;
514         
515         ci.m_contactProcessingThreshold = objprop->m_contactProcessingThreshold;//todo: expose this in advanced settings, just like margin, default to 10000 or so
516         ci.m_bSoft = objprop->m_softbody;
517         ci.m_bSensor = isbulletsensor;
518         MT_Vector3 scaling = gameobj->NodeGetWorldScaling();
519         ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]);
520         KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,isbulletsensor,objprop->m_hasCompoundChildren);
521         // shapeInfo is reference counted, decrement now as we don't use it anymore
522         if (shapeInfo)
523                 shapeInfo->Release();
524
525         gameobj->SetPhysicsController(physicscontroller,isbulletdyna);
526         // don't add automatically sensor object, they are added when a collision sensor is registered
527         if (!isbulletsensor && objprop->m_in_active_layer)
528         {
529                 env->addCcdPhysicsController( physicscontroller);
530         }
531         physicscontroller->setNewClientInfo(gameobj->getClientInfo());          
532         {
533                 btRigidBody* rbody = physicscontroller->GetRigidBody();
534
535                 if (rbody)
536                 {
537                         if (objprop->m_angular_rigidbody)
538                         {
539                                 btVector3 linearFactor(
540                                         objprop->m_lockXaxis? 0 : 1,
541                                         objprop->m_lockYaxis? 0 : 1,
542                                         objprop->m_lockZaxis? 0 : 1);
543                                 btVector3 angularFactor(
544                                         objprop->m_lockXRotaxis? 0 : 1,
545                                         objprop->m_lockYRotaxis? 0 : 1,
546                                         objprop->m_lockZRotaxis? 0 : 1);
547                                 rbody->setLinearFactor(linearFactor);
548                                 rbody->setAngularFactor(angularFactor);
549                         }
550
551                         if (rbody && objprop->m_disableSleeping)
552                         {
553                                 rbody->setActivationState(DISABLE_DEACTIVATION);
554                         }
555                 }
556         }
557
558         CcdPhysicsController* parentCtrl = objprop->m_dynamic_parent ? (KX_BulletPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController() : 0;
559         physicscontroller->setParentCtrl(parentCtrl);
560
561         
562         //Now done directly in ci.m_collisionFlags so that it propagates to replica
563         //if (objprop->m_ghost)
564         //{
565         //      rbody->setCollisionFlags(rbody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
566         //}
567         
568         if (objprop->m_dyna && !objprop->m_angular_rigidbody)
569         {
570                 /*
571                 //setting the inertia could achieve similar results to constraint the up
572                 //but it is prone to instability, so use special 'Angular' constraint
573                 btVector3 inertia = physicscontroller->GetRigidBody()->getInvInertiaDiagLocal();
574                 inertia.setX(0.f);
575                 inertia.setZ(0.f);
576
577                 physicscontroller->GetRigidBody()->setInvInertiaDiagLocal(inertia);
578                 physicscontroller->GetRigidBody()->updateInertiaTensor();
579                 */
580
581                 //env->createConstraint(physicscontroller,0,PHY_ANGULAR_CONSTRAINT,0,0,0,0,0,1);
582         
583                 //Now done directly in ci.m_bRigid so that it propagates to replica
584                 //physicscontroller->GetRigidBody()->setAngularFactor(0.f);
585                 ;
586         }
587
588         bool isActor = objprop->m_isactor;
589         gameobj->getClientInfo()->m_type = 
590                 (isbulletsensor) ? ((isActor) ? KX_ClientObjectInfo::OBACTORSENSOR : KX_ClientObjectInfo::OBSENSOR) :
591                 (isActor) ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC;
592         // store materialname in auxinfo, needed for touchsensors
593         if (meshobj)
594         {
595                 const STR_String& matname=meshobj->GetMaterialName(0);
596                 gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL);
597         } else
598         {
599                 gameobj->getClientInfo()->m_auxilary_info = 0;
600         }
601
602
603         gameobj->GetSGNode()->AddSGController(physicscontroller);
604
605         STR_String materialname;
606         if (meshobj)
607                 materialname = meshobj->GetMaterialName(0);
608
609         physicscontroller->SetObject(gameobj->GetSGNode());
610
611
612         ///test for soft bodies
613         if (objprop->m_softbody && physicscontroller)
614         {
615                 btSoftBody* softBody = physicscontroller->GetSoftBody();
616                 if (softBody && gameobj->GetMesh(0))//only the first mesh, if any
617                 {
618                         //should be a mesh then, so add a soft body deformer
619                         KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer( gameobj->GetMesh(0),(BL_DeformableGameObject*)gameobj);
620                         gameobj->SetDeformer(softbodyDeformer);
621                 }
622         }
623
624 }
625
626
627 void    KX_ClearBulletSharedShapes()
628 {
629 }
630
631 /* Refresh the physics object from either an object or a mesh.
632  * gameobj must be valid
633  * from_gameobj and from_meshobj can be NULL
634  * 
635  * when setting the mesh, the following vars get priority
636  * 1) from_meshobj - creates the phys mesh from RAS_MeshObject
637  * 2) from_gameobj - creates the phys mesh from the DerivedMesh where possible, else the RAS_MeshObject
638  * 3) gameobj - update the phys mesh from DerivedMesh or RAS_MeshObject
639  * 
640  * Most of the logic behind this is in shapeInfo->UpdateMesh(...)
641  */
642 bool KX_ReInstanceBulletShapeFromMesh(KX_GameObject *gameobj, KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj)
643 {
644         KX_BulletPhysicsController      *spc= static_cast<KX_BulletPhysicsController*>((gameobj->GetPhysicsController()));
645         CcdShapeConstructionInfo        *shapeInfo;
646
647         /* if this is the child of a compound shape this can happen
648          * dont support compound shapes for now */
649         if(spc==NULL)
650                 return false;
651         
652         shapeInfo = spc->GetShapeInfo();
653         
654         if(shapeInfo->m_shapeType != PHY_SHAPE_MESH || spc->GetSoftBody())
655                 return false;
656         
657         spc->DeleteControllerShape();
658         
659         if(from_gameobj==NULL && from_meshobj==NULL)
660                 from_gameobj= gameobj;
661         
662         /* updates the arrays used for making the new bullet mesh */
663         shapeInfo->UpdateMesh(from_gameobj, from_meshobj);
664
665         /* create the new bullet mesh */
666         btCollisionShape* bm= shapeInfo->CreateBulletShape(spc->getConstructionInfo().m_margin);
667
668         spc->ReplaceControllerShape(bm);
669         return true;
670 }
671 #endif