07fdc8ec41b61aa0a352c1715eb29a4d83331557
[blender-staging.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 // defines USE_ODE to choose physics engine
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 #include "BL_SkinMeshObject.h"
42 #include "BulletSoftBody/btSoftBody.h"
43
44 #include "PHY_Pro.h" //todo cleanup
45 #include "KX_ClientObjectInfo.h"
46
47 #include "GEN_Map.h"
48 #include "GEN_HashedPtr.h"
49
50 #include "KX_PhysicsEngineEnums.h"
51 #include "PHY_Pro.h"
52
53 #include "KX_MotionState.h" // bridge between motionstate and scenegraph node
54
55 #ifdef USE_ODE
56
57 #include "KX_OdePhysicsController.h"
58 #include "OdePhysicsEnvironment.h"
59 #endif //USE_ODE
60
61
62 // USE_SUMO_SOLID is defined in headerfile KX_ConvertPhysicsObject.h
63 #ifdef USE_SUMO_SOLID
64
65
66 #include "SumoPhysicsEnvironment.h"
67 #include "KX_SumoPhysicsController.h"
68
69
70 // sumo physics specific
71 #include "SM_Object.h"
72 #include "SM_FhObject.h"
73 #include "SM_Scene.h"
74 #include "SM_ClientObjectInfo.h"
75
76 #include "KX_SumoPhysicsController.h"
77
78 struct KX_PhysicsInstance
79 {
80         DT_VertexBaseHandle     m_vertexbase;
81         RAS_DisplayArray*       m_darray;
82         RAS_IPolyMaterial*      m_material;
83
84         KX_PhysicsInstance(DT_VertexBaseHandle vertex_base, RAS_DisplayArray *darray, RAS_IPolyMaterial* mat)
85                 : m_vertexbase(vertex_base),
86                 m_darray(darray),
87                 m_material(mat)
88         {
89         }
90
91         ~KX_PhysicsInstance()
92         {
93                 DT_DeleteVertexBase(m_vertexbase);
94         }
95 };
96
97 static GEN_Map<GEN_HashedPtr,DT_ShapeHandle> map_gamemesh_to_sumoshape;
98 static GEN_Map<GEN_HashedPtr, KX_PhysicsInstance*> map_gamemesh_to_instance;
99
100 // forward declarations
101 static void     BL_RegisterSumoObject(KX_GameObject* gameobj,class SM_Scene* sumoScene,class SM_Object* sumoObj,const STR_String& matname,bool isDynamic,bool isActor);
102 static DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj, bool polytope);
103
104 void    KX_ConvertSumoObject(   KX_GameObject* gameobj,
105                 RAS_MeshObject* meshobj,
106                 KX_Scene* kxscene,
107                 PHY_ShapeProps* kxshapeprops,
108                 PHY_MaterialProps*      kxmaterial,
109                 struct  KX_ObjectProperties*    objprop)
110
111
112 {
113         SM_ShapeProps* smprop = new SM_ShapeProps;
114
115         smprop->m_ang_drag = kxshapeprops->m_ang_drag;
116         smprop->m_do_anisotropic = kxshapeprops->m_do_anisotropic;
117         smprop->m_do_fh = kxshapeprops->m_do_fh;
118         smprop->m_do_rot_fh = kxshapeprops->m_do_rot_fh ;
119         smprop->m_friction_scaling[0]  = kxshapeprops->m_friction_scaling[0];
120         smprop->m_friction_scaling[1]  = kxshapeprops->m_friction_scaling[1];
121         smprop->m_friction_scaling[2]  = kxshapeprops->m_friction_scaling[2];
122         smprop->m_inertia = MT_Vector3(1., 1., 1.) * kxshapeprops->m_inertia;
123         smprop->m_lin_drag = kxshapeprops->m_lin_drag;
124         smprop->m_mass = kxshapeprops->m_mass;
125         smprop->m_radius = objprop->m_radius;
126
127
128         SM_MaterialProps* smmaterial = new SM_MaterialProps;
129
130         smmaterial->m_fh_damping = kxmaterial->m_fh_damping;
131         smmaterial->m_fh_distance = kxmaterial->m_fh_distance;
132         smmaterial->m_fh_normal = kxmaterial->m_fh_normal;
133         smmaterial->m_fh_spring = kxmaterial->m_fh_spring;
134         smmaterial->m_friction = kxmaterial->m_friction;
135         smmaterial->m_restitution = kxmaterial->m_restitution;
136
137         SumoPhysicsEnvironment* sumoEnv =
138                 (SumoPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
139
140         SM_Scene*       sceneptr = sumoEnv->GetSumoScene();
141
142         SM_Object*      sumoObj=NULL;
143
144         if (objprop->m_dyna && objprop->m_isactor)
145         {
146                 DT_ShapeHandle shape = NULL;
147                 bool polytope = false;
148                 switch (objprop->m_boundclass)
149                 {
150                         case KX_BOUNDBOX:
151                                 shape = DT_NewBox(objprop->m_boundobject.box.m_extends[0], 
152                                                 objprop->m_boundobject.box.m_extends[1], 
153                                                 objprop->m_boundobject.box.m_extends[2]);
154                                 smprop->m_inertia.scale(objprop->m_boundobject.box.m_extends[0]*objprop->m_boundobject.box.m_extends[0],
155                                                 objprop->m_boundobject.box.m_extends[1]*objprop->m_boundobject.box.m_extends[1],
156                                                 objprop->m_boundobject.box.m_extends[2]*objprop->m_boundobject.box.m_extends[2]);
157                                 smprop->m_inertia *= smprop->m_mass/MT_Vector3(objprop->m_boundobject.box.m_extends).length();
158                                 break;
159                         case KX_BOUNDCYLINDER:
160                                 shape = DT_NewCylinder(smprop->m_radius, objprop->m_boundobject.c.m_height);
161                                 smprop->m_inertia.scale(smprop->m_mass*smprop->m_radius*smprop->m_radius,
162                                                 smprop->m_mass*smprop->m_radius*smprop->m_radius,
163                                                 smprop->m_mass*objprop->m_boundobject.c.m_height*objprop->m_boundobject.c.m_height);
164                                 break;
165                         case KX_BOUNDCONE:
166                                 shape = DT_NewCone(objprop->m_radius, objprop->m_boundobject.c.m_height);
167                                 smprop->m_inertia.scale(smprop->m_mass*smprop->m_radius*smprop->m_radius,
168                                                 smprop->m_mass*smprop->m_radius*smprop->m_radius,
169                                                 smprop->m_mass*objprop->m_boundobject.c.m_height*objprop->m_boundobject.c.m_height);
170                                 break;
171                                 /* Dynamic mesh objects.  WARNING! slow. */
172                         case KX_BOUNDPOLYTOPE:
173                                 polytope = true;
174                                 // fall through
175                         case KX_BOUNDMESH:
176                                 if (meshobj && meshobj->NumPolygons() > 0)
177                                 {
178                                         if ((shape = CreateShapeFromMesh(meshobj, polytope)))
179                                         {
180                                                 // TODO: calculate proper inertia
181                                                 smprop->m_inertia *= smprop->m_mass*smprop->m_radius*smprop->m_radius;
182                                                 break;
183                                         }
184                                 }
185                                 /* If CreateShapeFromMesh fails, fall through and use sphere */
186                         default:
187                         case KX_BOUNDSPHERE:
188                                 shape = DT_NewSphere(objprop->m_radius);
189                                 smprop->m_inertia *= smprop->m_mass*smprop->m_radius*smprop->m_radius;
190                                 break;
191
192                 }
193
194                 sumoObj = new SM_Object(shape, !objprop->m_ghost?smmaterial:NULL,smprop,NULL);
195
196                 sumoObj->setRigidBody(objprop->m_angular_rigidbody?true:false);
197
198                 BL_RegisterSumoObject(gameobj,sceneptr,sumoObj,"",true, true);
199
200         } 
201         else {
202                 // non physics object
203                 if (meshobj)
204                 {
205                         int numpolys = meshobj->NumPolygons();
206                         {
207
208                                 DT_ShapeHandle complexshape=0;
209                                 bool polytope = false;
210
211                                 switch (objprop->m_boundclass)
212                                 {
213                                         case KX_BOUNDBOX:
214                                                 complexshape = DT_NewBox(objprop->m_boundobject.box.m_extends[0], objprop->m_boundobject.box.m_extends[1], objprop->m_boundobject.box.m_extends[2]);
215                                                 break;
216                                         case KX_BOUNDSPHERE:
217                                                 complexshape = DT_NewSphere(objprop->m_boundobject.c.m_radius);
218                                                 break;
219                                         case KX_BOUNDCYLINDER:
220                                                 complexshape = DT_NewCylinder(objprop->m_boundobject.c.m_radius, objprop->m_boundobject.c.m_height);
221                                                 break;
222                                         case KX_BOUNDCONE:
223                                                 complexshape = DT_NewCone(objprop->m_boundobject.c.m_radius, objprop->m_boundobject.c.m_height);
224                                                 break;
225                                         case KX_BOUNDPOLYTOPE:
226                                                 polytope = true;
227                                                 // fall through
228                                         default:
229                                         case KX_BOUNDMESH:
230                                                 if (numpolys>0)
231                                                 {
232                                                         complexshape = CreateShapeFromMesh(meshobj, polytope);
233                                                         //std::cout << "Convert Physics Mesh: " << meshobj->GetName() << std::endl;
234 /*                                                      if (!complexshape) 
235                                                         {
236                                                                 // Something has to be done here - if the object has no polygons, it will not be able to have
237                                                                 //   sensors attached to it. 
238                                                                 DT_Vector3 pt = {0., 0., 0.};
239                                                                 complexshape = DT_NewSphere(1.0);
240                                                                 objprop->m_ghost = evilObject = true;
241                                                         } */
242                                                 }
243                                                 break;
244                                 }
245                                 
246                                 if (complexshape)
247                                 {
248                                         SM_Object *dynamicParent = NULL;
249
250                                         if (objprop->m_dynamic_parent)
251                                         {
252                                                 // problem is how to find the dynamic parent
253                                                 // in the scenegraph
254                                                 KX_SumoPhysicsController* sumoctrl = 
255                                                 (KX_SumoPhysicsController*)
256                                                         objprop->m_dynamic_parent->GetPhysicsController();
257
258                                                 if (sumoctrl)
259                                                 {
260                                                         dynamicParent = sumoctrl->GetSumoObject();
261                                                 }
262
263                                                 MT_assert(dynamicParent);
264                                         }
265                                 
266                                         
267                                         sumoObj = new SM_Object(complexshape,!objprop->m_ghost?smmaterial:NULL,NULL, dynamicParent);    
268                                         const STR_String& matname=meshobj->GetMaterialName(0);
269
270                                         
271                                         BL_RegisterSumoObject(gameobj,sceneptr,
272                                                 sumoObj,
273                                                 matname,
274                                                 objprop->m_dyna,
275                                                 objprop->m_isactor);
276                                 }
277                         }
278                 }
279         }
280
281         // physics object get updated here !
282
283         
284         // lazy evaluation because we might not support scaling !gameobj->UpdateTransform();
285
286         if (objprop->m_in_active_layer && sumoObj)
287         {
288                 sceneptr->add(*sumoObj);
289         }
290
291 }
292
293
294
295 static void     BL_RegisterSumoObject(
296         KX_GameObject* gameobj,
297         class SM_Scene* sumoScene,
298         class SM_Object* sumoObj,
299         const STR_String& matname,
300         bool isDynamic,
301         bool isActor) 
302 {
303                 PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
304
305                 // need easy access, not via 'node' etc.
306                 KX_SumoPhysicsController* physicscontroller = new KX_SumoPhysicsController(sumoScene,sumoObj,motionstate,isDynamic);
307                 gameobj->SetPhysicsController(physicscontroller,isDynamic);
308
309                 
310                 if (!gameobj->getClientInfo())
311                         std::cout << "BL_RegisterSumoObject: WARNING: Object " << gameobj->GetName() << " has no client info" << std::endl;
312                 physicscontroller->setNewClientInfo(gameobj->getClientInfo());
313                 
314
315                 gameobj->GetSGNode()->AddSGController(physicscontroller);
316
317                 gameobj->getClientInfo()->m_type = (isActor ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC);
318
319                 // store materialname in auxinfo, needed for touchsensors
320                 gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL);
321
322                 physicscontroller->SetObject(gameobj->GetSGNode());
323 }
324
325 static DT_ShapeHandle InstancePhysicsComplex(RAS_MeshObject* meshobj, RAS_DisplayArray *darray, RAS_IPolyMaterial *mat)
326 {
327         // instance a mesh from a single vertex array & material
328         const RAS_TexVert *vertex_array = &darray->m_vertex[0];
329         DT_VertexBaseHandle vertex_base = DT_NewVertexBase(vertex_array[0].getXYZ(), sizeof(RAS_TexVert));
330         
331         DT_ShapeHandle shape = DT_NewComplexShape(vertex_base);
332         
333         std::vector<DT_Index> indices;
334         for (int p = 0; p < meshobj->NumPolygons(); p++)
335         {
336                 RAS_Polygon* poly = meshobj->GetPolygon(p);
337         
338                 // only add polygons that have the collisionflag set
339                 if (poly->IsCollider())
340                 {
341                         DT_Begin();
342                           DT_VertexIndex(poly->GetVertexOffset(0));
343                           DT_VertexIndex(poly->GetVertexOffset(1));
344                           DT_VertexIndex(poly->GetVertexOffset(2));
345                         DT_End();
346                         
347                         // tesselate
348                         if (poly->VertexCount() == 4)
349                         {
350                                 DT_Begin();
351                                   DT_VertexIndex(poly->GetVertexOffset(0));
352                                   DT_VertexIndex(poly->GetVertexOffset(2));
353                                   DT_VertexIndex(poly->GetVertexOffset(3));
354                                 DT_End();
355                         }
356                 }
357         }
358
359         //DT_VertexIndices(indices.size(), &indices[0]);
360         DT_EndComplexShape();
361         
362         map_gamemesh_to_instance.insert(GEN_HashedPtr(meshobj), new KX_PhysicsInstance(vertex_base, darray, mat));
363         return shape;
364 }
365
366 static DT_ShapeHandle InstancePhysicsPolytope(RAS_MeshObject* meshobj, RAS_DisplayArray *darray, RAS_IPolyMaterial *mat)
367 {
368         // instance a mesh from a single vertex array & material
369         const RAS_TexVert *vertex_array = &darray->m_vertex[0];
370         DT_VertexBaseHandle vertex_base = DT_NewVertexBase(vertex_array[0].getXYZ(), sizeof(RAS_TexVert));
371         
372         std::vector<DT_Index> indices;
373         for (int p = 0; p < meshobj->NumPolygons(); p++)
374         {
375                 RAS_Polygon* poly = meshobj->GetPolygon(p);
376         
377                 // only add polygons that have the collisionflag set
378                 if (poly->IsCollider())
379                 {
380                         indices.push_back(poly->GetVertexOffset(0));
381                         indices.push_back(poly->GetVertexOffset(1));
382                         indices.push_back(poly->GetVertexOffset(2));
383                         
384                         if (poly->VertexCount() == 4)
385                                 indices.push_back(poly->GetVertexOffset(3));
386                 }
387         }
388
389         DT_ShapeHandle shape = DT_NewPolytope(vertex_base);
390         DT_VertexIndices(indices.size(), &indices[0]);
391         DT_EndPolytope();
392         
393         map_gamemesh_to_instance.insert(GEN_HashedPtr(meshobj), new KX_PhysicsInstance(vertex_base, darray, mat));
394         return shape;
395 }
396
397 // This will have to be a method in a class somewhere...
398 // Update SOLID with a changed physics mesh.
399 // not used... yet.
400 bool KX_ReInstanceShapeFromMesh(RAS_MeshObject* meshobj)
401 {
402         KX_PhysicsInstance *instance = *map_gamemesh_to_instance[GEN_HashedPtr(meshobj)];
403         if (instance)
404         {
405                 const RAS_TexVert *vertex_array = &instance->m_darray->m_vertex[0];
406                 DT_ChangeVertexBase(instance->m_vertexbase, vertex_array[0].getXYZ());
407                 return true;
408         }
409         return false;
410 }
411
412 static DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj, bool polytope)
413 {
414
415         DT_ShapeHandle *shapeptr = map_gamemesh_to_sumoshape[GEN_HashedPtr(meshobj)];
416         // Mesh has already been converted: reuse
417         if (shapeptr)
418         {
419                 return *shapeptr;
420         }
421         
422         // Mesh has no polygons!
423         int numpolys = meshobj->NumPolygons();
424         if (!numpolys)
425         {
426                 return NULL;
427         }
428         
429         // Count the number of collision polygons and check they all come from the same 
430         // vertex array
431         int numvalidpolys = 0;
432         RAS_DisplayArray *darray = NULL;
433         RAS_IPolyMaterial *poly_material = NULL;
434         bool reinstance = true;
435
436         for (int p=0; p<numpolys; p++)
437         {
438                 RAS_Polygon* poly = meshobj->GetPolygon(p);
439         
440                 // only add polygons that have the collisionflag set
441                 if (poly->IsCollider())
442                 {
443                         // check polygon is from the same vertex array
444                         if (poly->GetDisplayArray() != darray)
445                         {
446                                 if (darray == NULL)
447                                         darray = poly->GetDisplayArray();
448                                 else
449                                 {
450                                         reinstance = false;
451                                         darray = NULL;
452                                 }
453                         }
454                         
455                         // check poly is from the same material
456                         if (poly->GetMaterial()->GetPolyMaterial() != poly_material)
457                         {
458                                 if (poly_material)
459                                 {
460                                         reinstance = false;
461                                         poly_material = NULL;
462                                 }
463                                 else
464                                         poly_material = poly->GetMaterial()->GetPolyMaterial();
465                         }
466                         
467                         // count the number of collision polys
468                         numvalidpolys++;
469                         
470                         // We have one collision poly, and we can't reinstance, so we
471                         // might as well break here.
472                         if (!reinstance)
473                                 break;
474                 }
475         }
476         
477         // No collision polygons
478         if (numvalidpolys < 1)
479                 return NULL;
480         
481         DT_ShapeHandle shape;
482         if (reinstance)
483         {
484                 if (polytope)
485                         shape = InstancePhysicsPolytope(meshobj, darray, poly_material);
486                 else
487                         shape = InstancePhysicsComplex(meshobj, darray, poly_material);
488         }
489         else
490         {
491                 if (polytope)
492                 {
493                         std::cout << "CreateShapeFromMesh: " << meshobj->GetName() << " is not suitable for polytope." << std::endl;
494                         if (!poly_material)
495                                 std::cout << "                     Check mesh materials." << std::endl;
496                         if (darray == NULL)
497                                 std::cout << "                     Check number of vertices." << std::endl;
498                 }
499                 
500                 shape = DT_NewComplexShape(NULL);
501                         
502                 numvalidpolys = 0;
503         
504                 for (int p2=0; p2<numpolys; p2++)
505                 {
506                         RAS_Polygon* poly = meshobj->GetPolygon(p2);
507                 
508                         // only add polygons that have the collisionflag set
509                         if (poly->IsCollider())
510                         {   /* We have to tesselate here because SOLID can only raycast triangles */
511                            DT_Begin();
512                                 /* V1, V2, V3 */
513                                 DT_Vertex(poly->GetVertex(2)->getXYZ());
514                                 DT_Vertex(poly->GetVertex(1)->getXYZ());
515                                 DT_Vertex(poly->GetVertex(0)->getXYZ());
516                                 
517                                 numvalidpolys++;
518                            DT_End();
519                                 
520                                 if (poly->VertexCount() == 4)
521                                 {
522                                    DT_Begin();
523                                         /* V1, V3, V4 */
524                                         DT_Vertex(poly->GetVertex(3)->getXYZ());
525                                         DT_Vertex(poly->GetVertex(2)->getXYZ());
526                                         DT_Vertex(poly->GetVertex(0)->getXYZ());
527                                 
528                                         numvalidpolys++;
529                                    DT_End();
530                                 }
531                 
532                         }
533                 }
534                 
535                 DT_EndComplexShape();
536         }
537
538         if (numvalidpolys > 0)
539         {
540                 map_gamemesh_to_sumoshape.insert(GEN_HashedPtr(meshobj),shape);
541                 return shape;
542         }
543
544         delete shape;
545         return NULL;
546 }
547
548 void    KX_ClearSumoSharedShapes()
549 {
550         int numshapes = map_gamemesh_to_sumoshape.size();
551         int i;
552         for (i=0;i<numshapes ;i++)
553         {
554                 DT_ShapeHandle shape = *map_gamemesh_to_sumoshape.at(i);
555                 DT_DeleteShape(shape);
556         }
557         
558         map_gamemesh_to_sumoshape.clear();
559         
560         for (i=0; i < map_gamemesh_to_instance.size(); i++)
561                 delete *map_gamemesh_to_instance.at(i);
562         
563         map_gamemesh_to_instance.clear();
564 }
565
566
567
568
569
570 #endif //USE_SUMO_SOLID
571
572
573 #ifdef USE_ODE
574
575 void    KX_ConvertODEEngineObject(KX_GameObject* gameobj,
576                                                          RAS_MeshObject* meshobj,
577                                                          KX_Scene* kxscene,
578                                                         struct  PHY_ShapeProps* shapeprops,
579                                                         struct  PHY_MaterialProps*      smmaterial,
580                                                         struct  KX_ObjectProperties*    objprop)
581 {
582         
583         // not yet, future extension :)
584         bool dyna=objprop->m_dyna;
585         bool fullRigidBody= ( objprop->m_dyna && objprop->m_angular_rigidbody) != 0;
586         bool phantom = objprop->m_ghost;
587         class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
588
589         class ODEPhysicsEnvironment* odeEnv =
590                 (ODEPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
591
592         dxSpace* space = odeEnv->GetOdeSpace();
593         dxWorld* world = odeEnv->GetOdeWorld();
594
595         bool isSphere = false;
596
597         switch (objprop->m_boundclass)
598         {
599         case KX_BOUNDBOX:
600                 {
601
602                                 KX_OdePhysicsController* physicscontroller = 
603                                         new KX_OdePhysicsController(
604                                         dyna,
605                                         fullRigidBody,
606                                         phantom,
607                                         motionstate,
608                                         space,
609                                         world,
610                                         shapeprops->m_mass,
611                                         smmaterial->m_friction,
612                                         smmaterial->m_restitution,
613                                         isSphere,
614                                         objprop->m_boundobject.box.m_center,
615                                         objprop->m_boundobject.box.m_extends,
616                                         objprop->m_boundobject.c.m_radius
617                                         );
618
619                                 gameobj->SetPhysicsController(physicscontroller);
620                                 physicscontroller->setNewClientInfo(gameobj->getClientInfo());                                          
621                                 gameobj->GetSGNode()->AddSGController(physicscontroller);
622
623                                 bool isActor = objprop->m_isactor;
624                                 STR_String materialname;
625                                 if (meshobj)
626                                         materialname = meshobj->GetMaterialName(0);
627
628                                 const char* matname = materialname.ReadPtr();
629
630
631                                 physicscontroller->SetObject(gameobj->GetSGNode());
632
633                                 break;
634                         }
635         default:
636                 {
637                 }
638         };
639
640 }
641
642
643 #endif // USE_ODE
644
645
646 #ifdef USE_BULLET
647
648 #include "CcdPhysicsEnvironment.h"
649 #include "CcdPhysicsController.h"
650 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
651
652 #include "KX_BulletPhysicsController.h"
653 #include "btBulletDynamicsCommon.h"
654
655                                                         #ifdef WIN32
656 #if _MSC_VER >= 1310
657 //only use SIMD Hull code under Win32
658 //#define TEST_HULL 1
659 #ifdef TEST_HULL
660 #define USE_HULL 1
661 //#define TEST_SIMD_HULL 1
662
663 #include "NarrowPhaseCollision/Hull.h"
664 #endif //#ifdef TEST_HULL
665
666 #endif //_MSC_VER 
667 #endif //WIN32
668
669
670                                                         
671         class KX_SoftBodyDeformer : public RAS_Deformer
672         {
673                 class RAS_MeshObject*                   m_pMeshObject;
674                 class BL_DeformableGameObject*  m_gameobj;
675
676         public:
677                 KX_SoftBodyDeformer(RAS_MeshObject*     pMeshObject,BL_DeformableGameObject*    gameobj)
678                         :m_pMeshObject(pMeshObject),
679                         m_gameobj(gameobj)
680                 {
681                         //printf("KX_SoftBodyDeformer\n");
682                 };
683
684                 virtual ~KX_SoftBodyDeformer()
685                 {
686                         //printf("~KX_SoftBodyDeformer\n");
687                 };
688                 virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map)
689                 {
690                         void **h_obj = (*map)[m_gameobj];
691
692                         if (h_obj) {
693                                 m_gameobj = (BL_DeformableGameObject*)(*h_obj);
694                                 m_pMeshObject = m_gameobj->GetMesh(0);
695                         } else {
696                                 m_gameobj = NULL;
697                                 m_pMeshObject = NULL;
698                         }
699                 }
700                 virtual bool Apply(class RAS_IPolyMaterial *polymat)
701                 {
702                         KX_BulletPhysicsController* ctrl = (KX_BulletPhysicsController*) m_gameobj->GetPhysicsController();
703                         if (!ctrl)
704                                 return false;
705
706                         btSoftBody* softBody= ctrl->GetSoftBody();
707                         if (!softBody)
708                                 return false;
709
710                         //printf("apply\n");
711                         RAS_MeshSlot::iterator it;
712                         RAS_MeshMaterial *mmat;
713                         RAS_MeshSlot *slot;
714                         size_t i;
715
716                         // update the vertex in m_transverts
717                         Update();
718
719
720
721                         // The vertex cache can only be updated for this deformer:
722                         // Duplicated objects with more than one ploymaterial (=multiple mesh slot per object)
723                         // share the same mesh (=the same cache). As the rendering is done per polymaterial
724                         // cycling through the objects, the entire mesh cache cannot be updated in one shot.
725                         mmat = m_pMeshObject->GetMeshMaterial(polymat);
726                         if(!mmat->m_slots[(void*)m_gameobj])
727                                 return true;
728
729                         slot = *mmat->m_slots[(void*)m_gameobj];
730
731                         // for each array
732                         for(slot->begin(it); !slot->end(it); slot->next(it)) 
733                         {
734                                 btSoftBody::tNodeArray&   nodes(softBody->m_nodes);
735
736                                 int index = 0;
737                                 for(i=it.startvertex; i<it.endvertex; i++,index++) {
738                                         RAS_TexVert& v = it.vertex[i];
739                                         btAssert(v.getSoftBodyIndex() >= 0);
740
741                                         MT_Point3 pt (
742                                                 nodes[v.getSoftBodyIndex()].m_x.getX(),
743                                                 nodes[v.getSoftBodyIndex()].m_x.getY(),
744                                                 nodes[v.getSoftBodyIndex()].m_x.getZ());
745                                         v.SetXYZ(pt);
746
747                                         MT_Vector3 normal (
748                                                 nodes[v.getSoftBodyIndex()].m_n.getX(),
749                                                 nodes[v.getSoftBodyIndex()].m_n.getY(),
750                                                 nodes[v.getSoftBodyIndex()].m_n.getZ());
751                                         v.SetNormal(normal);
752
753                                 }
754                         }
755                         return true;
756                 }
757                 virtual bool Update(void)
758                 {
759                         //printf("update\n");
760                         m_bDynamic = true;
761                         return true;//??
762                 }
763                 virtual bool UpdateBuckets(void)
764                 {
765                         // this is to update the mesh slots outside the rasterizer, 
766                         // no need to do it for this deformer, it's done in any case in Apply()
767                         return false;
768                 }
769
770                 virtual RAS_Deformer *GetReplica()
771                 {
772                         KX_SoftBodyDeformer* deformer = new KX_SoftBodyDeformer(*this);
773                         deformer->ProcessReplica();
774                         return deformer;
775                 }
776                 virtual void ProcessReplica()
777                 {
778                         // we have two pointers to deal with but we cannot do it now, will be done in Relink
779                         m_bDynamic = false;
780                 }
781                 virtual bool SkipVertexTransform()
782                 {
783                         return true;
784                 }
785
786         protected:
787                 //class RAS_MeshObject  *m_pMesh;
788         };
789
790
791 // forward declarations
792
793 void    KX_ConvertBulletObject( class   KX_GameObject* gameobj,
794         class   RAS_MeshObject* meshobj,
795         class   KX_Scene* kxscene,
796         struct  PHY_ShapeProps* shapeprops,
797         struct  PHY_MaterialProps*      smmaterial,
798         struct  KX_ObjectProperties*    objprop)
799 {
800
801         CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
802         assert(env);
803         
804
805         bool isbulletdyna = false;
806         CcdConstructionInfo ci;
807         class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
808         class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo();
809
810         
811
812         if (!objprop->m_dyna)
813         {
814                 ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
815         }
816         if (objprop->m_ghost)
817         {
818                 ci.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
819         }
820
821         ci.m_MotionState = motionstate;
822         ci.m_gravity = btVector3(0,0,0);
823         ci.m_localInertiaTensor =btVector3(0,0,0);
824         ci.m_mass = objprop->m_dyna ? shapeprops->m_mass : 0.f;
825         ci.m_clamp_vel_min = shapeprops->m_clamp_vel_min;
826         ci.m_clamp_vel_max = shapeprops->m_clamp_vel_max;
827         ci.m_margin = objprop->m_margin;
828         shapeInfo->m_radius = objprop->m_radius;
829         isbulletdyna = objprop->m_dyna;
830         
831         ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f);
832         
833         btCollisionShape* bm = 0;
834
835         switch (objprop->m_boundclass)
836         {
837         case KX_BOUNDSPHERE:
838                 {
839                         //float radius = objprop->m_radius;
840                         //btVector3 inertiaHalfExtents (
841                         //      radius,
842                         //      radius,
843                         //      radius);
844                         
845                         //blender doesn't support multisphere, but for testing:
846
847                         //bm = new MultiSphereShape(inertiaHalfExtents,,&trans.getOrigin(),&radius,1);
848                         shapeInfo->m_shapeType = PHY_SHAPE_SPHERE;
849                         bm = shapeInfo->CreateBulletShape();
850                         break;
851                 };
852         case KX_BOUNDBOX:
853                 {
854                         shapeInfo->m_halfExtend.setValue(
855                                 objprop->m_boundobject.box.m_extends[0],
856                                 objprop->m_boundobject.box.m_extends[1],
857                                 objprop->m_boundobject.box.m_extends[2]);
858
859                         shapeInfo->m_halfExtend /= 2.0;
860                         shapeInfo->m_halfExtend = shapeInfo->m_halfExtend.absolute();
861                         shapeInfo->m_shapeType = PHY_SHAPE_BOX;
862                         bm = shapeInfo->CreateBulletShape();
863                         break;
864                 };
865         case KX_BOUNDCYLINDER:
866                 {
867                         shapeInfo->m_halfExtend.setValue(
868                                 objprop->m_boundobject.c.m_radius,
869                                 objprop->m_boundobject.c.m_radius,
870                                 objprop->m_boundobject.c.m_height * 0.5f
871                         );
872                         shapeInfo->m_shapeType = PHY_SHAPE_CYLINDER;
873                         bm = shapeInfo->CreateBulletShape();
874                         break;
875                 }
876
877         case KX_BOUNDCONE:
878                 {
879                         shapeInfo->m_radius = objprop->m_boundobject.c.m_radius;
880                         shapeInfo->m_height = objprop->m_boundobject.c.m_height;
881                         shapeInfo->m_shapeType = PHY_SHAPE_CONE;
882                         bm = shapeInfo->CreateBulletShape();
883                         break;
884                 }
885         case KX_BOUNDPOLYTOPE:
886                 {
887                         shapeInfo->SetMesh(meshobj, true,false);
888                         bm = shapeInfo->CreateBulletShape();
889                         break;
890                 }
891         case KX_BOUNDMESH:
892                 {
893                         
894                         if (!ci.m_mass ||objprop->m_softbody)
895                         {                               
896                                 // mesh shapes can be shared, check first if we already have a shape on that mesh
897                                 class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, false);
898                                 if (sharedShapeInfo != NULL) 
899                                 {
900                                         delete shapeInfo;
901                                         shapeInfo = sharedShapeInfo;
902                                         shapeInfo->AddRef();
903                                 } else
904                                 {
905                                         shapeInfo->SetMesh(meshobj, false,false);
906                                 }
907
908                                 // Soft bodies require welding. Only avoid remove doubles for non-soft bodies!
909                                 if (objprop->m_softbody)
910                                 {
911                                         shapeInfo->setVertexWeldingThreshold1(objprop->m_soft_welding); //todo: expose this to the UI
912                                 }
913
914                                 bm = shapeInfo->CreateBulletShape();
915                                 //no moving concave meshes, so don't bother calculating inertia
916                                 //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
917                         } else
918                         {
919                                 shapeInfo->SetMesh(meshobj, false,true);
920                                 bm = shapeInfo->CreateBulletShape();
921                         }
922
923                         break;
924                 }
925         }
926
927
928 //      ci.m_localInertiaTensor.setValue(0.1f,0.1f,0.1f);
929
930         if (!bm)
931         {
932                 delete motionstate;
933                 delete shapeInfo;
934                 return;
935         }
936
937         bm->setMargin(ci.m_margin);
938
939
940                 if (objprop->m_isCompoundChild)
941                 {
942                         //find parent, compound shape and add to it
943                         //take relative transform into account!
944                         KX_BulletPhysicsController* parentCtrl = (KX_BulletPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController();
945                         assert(parentCtrl);
946                         CcdShapeConstructionInfo* parentShapeInfo = parentCtrl->GetShapeInfo();
947                         btRigidBody* rigidbody = parentCtrl->GetRigidBody();
948                         btCollisionShape* colShape = rigidbody->getCollisionShape();
949                         assert(colShape->isCompound());
950                         btCompoundShape* compoundShape = (btCompoundShape*)colShape;
951
952                         // compute the local transform from parent, this may include a parent inverse node
953                         SG_Node* gameNode = gameobj->GetSGNode();
954                         SG_Node* parentInverseNode = gameNode->GetSGParent();
955                         if (parentInverseNode && parentInverseNode->GetSGClientObject() != NULL)
956                                 // this is not a parent inverse node, cancel it
957                                 parentInverseNode = NULL;
958                         // now combine the parent inverse node and the game node
959                         MT_Point3 childPos = gameNode->GetLocalPosition();
960                         MT_Matrix3x3 childRot = gameNode->GetLocalOrientation();
961                         MT_Vector3 childScale = gameNode->GetLocalScale();
962                         if (parentInverseNode)
963                         {
964                                 const MT_Point3& parentInversePos = parentInverseNode->GetLocalPosition();
965                                 const MT_Matrix3x3& parentInverseRot = parentInverseNode->GetLocalOrientation();
966                                 const MT_Vector3& parentInverseScale = parentInverseNode->GetLocalScale();
967                                 childRot =  parentInverseRot * childRot;
968                                 childScale = parentInverseScale * childScale;
969                                 childPos = parentInversePos+parentInverseScale*(parentInverseRot*childPos);
970                         }
971
972                         shapeInfo->m_childScale.setValue(childScale.x(),childScale.y(),childScale.z());
973                         bm->setLocalScaling(shapeInfo->m_childScale);
974                         
975                         shapeInfo->m_childTrans.setOrigin(btVector3(childPos.x(),childPos.y(),childPos.z()));
976                         float rotval[12];
977                         childRot.getValue(rotval);
978                         btMatrix3x3 newRot;
979                         newRot.setValue(rotval[0],rotval[1],rotval[2],rotval[4],rotval[5],rotval[6],rotval[8],rotval[9],rotval[10]);
980                         newRot = newRot.transpose();
981
982                         shapeInfo->m_childTrans.setBasis(newRot);
983                         parentShapeInfo->AddShape(shapeInfo);   
984                         
985                         compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
986                         //do some recalc?
987                         //recalc inertia for rigidbody
988                         if (!rigidbody->isStaticOrKinematicObject())
989                         {
990                                 btVector3 localInertia;
991                                 float mass = 1.f/rigidbody->getInvMass();
992                                 compoundShape->calculateLocalInertia(mass,localInertia);
993                                 rigidbody->setMassProps(mass,localInertia);
994                         }
995                         return;
996                 }
997
998                 if (objprop->m_hasCompoundChildren)
999                 {
1000                         // create a compound shape info
1001                         CcdShapeConstructionInfo *compoundShapeInfo = new CcdShapeConstructionInfo();
1002                         compoundShapeInfo->m_shapeType = PHY_SHAPE_COMPOUND;
1003                         compoundShapeInfo->AddShape(shapeInfo);
1004                         // create the compound shape manually as we already have the child shape
1005                         btCompoundShape* compoundShape = new btCompoundShape();
1006                         compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
1007                         // now replace the shape
1008                         bm = compoundShape;
1009                         shapeInfo = compoundShapeInfo;
1010                 }
1011
1012
1013
1014
1015
1016
1017 #ifdef TEST_SIMD_HULL
1018         if (bm->IsPolyhedral())
1019         {
1020                 PolyhedralConvexShape* polyhedron = static_cast<PolyhedralConvexShape*>(bm);
1021                 if (!polyhedron->m_optionalHull)
1022                 {
1023                         //first convert vertices in 'Point3' format
1024                         int numPoints = polyhedron->GetNumVertices();
1025                         Point3* points = new Point3[numPoints+1];
1026                         //first 4 points should not be co-planar, so add central point to satisfy MakeHull
1027                         points[0] = Point3(0.f,0.f,0.f);
1028                         
1029                         btVector3 vertex;
1030                         for (int p=0;p<numPoints;p++)
1031                         {
1032                                 polyhedron->GetVertex(p,vertex);
1033                                 points[p+1] = Point3(vertex.getX(),vertex.getY(),vertex.getZ());
1034                         }
1035
1036                         Hull* hull = Hull::MakeHull(numPoints+1,points);
1037                         polyhedron->m_optionalHull = hull;
1038                 }
1039
1040         }
1041 #endif //TEST_SIMD_HULL
1042
1043
1044         ci.m_collisionShape = bm;
1045         ci.m_shapeInfo = shapeInfo;
1046         ci.m_friction = smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice
1047         ci.m_restitution = smmaterial->m_restitution;
1048         ci.m_physicsEnv = env;
1049         // drag / damping is inverted
1050         ci.m_linearDamping = 1.f - shapeprops->m_lin_drag;
1051         ci.m_angularDamping = 1.f - shapeprops->m_ang_drag;
1052         //need a bit of damping, else system doesn't behave well
1053         ci.m_inertiaFactor = shapeprops->m_inertia/0.4f;//defaults to 0.4, don't want to change behaviour
1054         
1055         ci.m_do_anisotropic = shapeprops->m_do_anisotropic;
1056         ci.m_anisotropicFriction.setValue(shapeprops->m_friction_scaling[0],shapeprops->m_friction_scaling[1],shapeprops->m_friction_scaling[2]);
1057
1058
1059 //////////
1060         //do Fh, do Rot Fh
1061         ci.m_do_fh = shapeprops->m_do_fh;
1062         ci.m_do_rot_fh = shapeprops->m_do_rot_fh ;
1063         ci.m_fh_damping = smmaterial->m_fh_damping;
1064         ci.m_fh_distance = smmaterial->m_fh_distance;
1065         ci.m_fh_normal = smmaterial->m_fh_normal;
1066         ci.m_fh_spring = smmaterial->m_fh_spring;
1067         ci.m_radius = objprop->m_radius;
1068         
1069         
1070         ///////////////////
1071         ci.m_gamesoftFlag = objprop->m_gamesoftFlag;
1072         ci.m_soft_linStiff = objprop->m_soft_linStiff;
1073         ci.m_soft_angStiff = objprop->m_soft_angStiff;          /* angular stiffness 0..1 */
1074         ci.m_soft_volume= objprop->m_soft_volume;                       /* volume preservation 0..1 */
1075
1076         ci.m_soft_viterations= objprop->m_soft_viterations;             /* Velocities solver iterations */
1077         ci.m_soft_piterations= objprop->m_soft_piterations;             /* Positions solver iterations */
1078         ci.m_soft_diterations= objprop->m_soft_diterations;             /* Drift solver iterations */
1079         ci.m_soft_citerations= objprop->m_soft_citerations;             /* Cluster solver iterations */
1080
1081         ci.m_soft_kSRHR_CL= objprop->m_soft_kSRHR_CL;           /* Soft vs rigid hardness [0,1] (cluster only) */
1082         ci.m_soft_kSKHR_CL= objprop->m_soft_kSKHR_CL;           /* Soft vs kinetic hardness [0,1] (cluster only) */
1083         ci.m_soft_kSSHR_CL= objprop->m_soft_kSSHR_CL;           /* Soft vs soft hardness [0,1] (cluster only) */
1084         ci.m_soft_kSR_SPLT_CL= objprop->m_soft_kSR_SPLT_CL;     /* Soft vs rigid impulse split [0,1] (cluster only) */
1085
1086         ci.m_soft_kSK_SPLT_CL= objprop->m_soft_kSK_SPLT_CL;     /* Soft vs rigid impulse split [0,1] (cluster only) */
1087         ci.m_soft_kSS_SPLT_CL= objprop->m_soft_kSS_SPLT_CL;     /* Soft vs rigid impulse split [0,1] (cluster only) */
1088         ci.m_soft_kVCF= objprop->m_soft_kVCF;                   /* Velocities correction factor (Baumgarte) */
1089         ci.m_soft_kDP= objprop->m_soft_kDP;                     /* Damping coefficient [0,1] */
1090
1091         ci.m_soft_kDG= objprop->m_soft_kDG;                     /* Drag coefficient [0,+inf] */
1092         ci.m_soft_kLF= objprop->m_soft_kLF;                     /* Lift coefficient [0,+inf] */
1093         ci.m_soft_kPR= objprop->m_soft_kPR;                     /* Pressure coefficient [-inf,+inf] */
1094         ci.m_soft_kVC= objprop->m_soft_kVC;                     /* Volume conversation coefficient [0,+inf] */
1095
1096         ci.m_soft_kDF= objprop->m_soft_kDF;                     /* Dynamic friction coefficient [0,1] */
1097         ci.m_soft_kMT= objprop->m_soft_kMT;                     /* Pose matching coefficient [0,1] */
1098         ci.m_soft_kCHR= objprop->m_soft_kCHR;                   /* Rigid contacts hardness [0,1] */
1099         ci.m_soft_kKHR= objprop->m_soft_kKHR;                   /* Kinetic contacts hardness [0,1] */
1100
1101         ci.m_soft_kSHR= objprop->m_soft_kSHR;                   /* Soft contacts hardness [0,1] */
1102         ci.m_soft_kAHR= objprop->m_soft_kAHR;                   /* Anchors hardness [0,1] */
1103         ci.m_soft_collisionflags= objprop->m_soft_collisionflags;       /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */
1104         ci.m_soft_numclusteriterations= objprop->m_soft_numclusteriterations;   /* number of iterations to refine collision clusters*/
1105
1106         ////////////////////
1107
1108         ci.m_collisionFilterGroup = (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : short(CcdConstructionInfo::StaticFilter);
1109         ci.m_collisionFilterMask = (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
1110         ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody;
1111         ci.m_bSoft = objprop->m_softbody;
1112         MT_Vector3 scaling = gameobj->NodeGetWorldScaling();
1113         ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]);
1114         KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,objprop->m_hasCompoundChildren);
1115         // shapeInfo is reference counted, decrement now as we don't use it anymore
1116         if (shapeInfo)
1117                 shapeInfo->Release();
1118
1119         if (objprop->m_in_active_layer)
1120         {
1121                 env->addCcdPhysicsController( physicscontroller);
1122         }
1123
1124         
1125
1126         gameobj->SetPhysicsController(physicscontroller,isbulletdyna);
1127         physicscontroller->setNewClientInfo(gameobj->getClientInfo());          
1128         {
1129                 btRigidBody* rbody = physicscontroller->GetRigidBody();
1130
1131                 if (rbody)
1132                 {
1133                         if (objprop->m_angular_rigidbody)
1134                         {
1135                                 btVector3 linearFactor(
1136                                         objprop->m_lockXaxis? 0 : 1,
1137                                         objprop->m_lockYaxis? 0 : 1,
1138                                         objprop->m_lockZaxis? 0 : 1);
1139                                 btVector3 angularFactor(
1140                                         objprop->m_lockXRotaxis? 0 : 1,
1141                                         objprop->m_lockYRotaxis? 0 : 1,
1142                                         objprop->m_lockZRotaxis? 0 : 1);
1143                                 rbody->setLinearFactor(linearFactor);
1144                                 rbody->setAngularFactor(angularFactor);
1145                         }
1146
1147                         if (rbody && objprop->m_disableSleeping)
1148                         {
1149                                 rbody->setActivationState(DISABLE_DEACTIVATION);
1150                         }
1151                 }
1152         }
1153
1154         CcdPhysicsController* parentCtrl = objprop->m_dynamic_parent ? (KX_BulletPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController() : 0;
1155         physicscontroller->setParentCtrl(parentCtrl);
1156
1157         
1158         //Now done directly in ci.m_collisionFlags so that it propagates to replica
1159         //if (objprop->m_ghost)
1160         //{
1161         //      rbody->setCollisionFlags(rbody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
1162         //}
1163         
1164         if (objprop->m_dyna && !objprop->m_angular_rigidbody)
1165         {
1166                 /*
1167                 //setting the inertia could achieve similar results to constraint the up
1168                 //but it is prone to instability, so use special 'Angular' constraint
1169                 btVector3 inertia = physicscontroller->GetRigidBody()->getInvInertiaDiagLocal();
1170                 inertia.setX(0.f);
1171                 inertia.setZ(0.f);
1172
1173                 physicscontroller->GetRigidBody()->setInvInertiaDiagLocal(inertia);
1174                 physicscontroller->GetRigidBody()->updateInertiaTensor();
1175                 */
1176
1177                 //env->createConstraint(physicscontroller,0,PHY_ANGULAR_CONSTRAINT,0,0,0,0,0,1);
1178         
1179                 //Now done directly in ci.m_bRigid so that it propagates to replica
1180                 //physicscontroller->GetRigidBody()->setAngularFactor(0.f);
1181                 ;
1182         }
1183
1184         bool isActor = objprop->m_isactor;
1185         gameobj->getClientInfo()->m_type = (isActor ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC);
1186         // store materialname in auxinfo, needed for touchsensors
1187         if (meshobj)
1188         {
1189                 const STR_String& matname=meshobj->GetMaterialName(0);
1190                 gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL);
1191         } else
1192         {
1193                 gameobj->getClientInfo()->m_auxilary_info = 0;
1194         }
1195
1196
1197         gameobj->GetSGNode()->AddSGController(physicscontroller);
1198
1199         STR_String materialname;
1200         if (meshobj)
1201                 materialname = meshobj->GetMaterialName(0);
1202
1203         physicscontroller->SetObject(gameobj->GetSGNode());
1204
1205
1206         ///test for soft bodies
1207         if (objprop->m_softbody && physicscontroller)
1208         {
1209                 btSoftBody* softBody = physicscontroller->GetSoftBody();
1210                 if (softBody && gameobj->GetMesh(0))//only the first mesh, if any
1211                 {
1212                         //should be a mesh then, so add a soft body deformer
1213                         KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer( gameobj->GetMesh(0),(BL_DeformableGameObject*)gameobj);
1214                         gameobj->SetDeformer(softbodyDeformer);
1215                 }
1216         }
1217
1218 }
1219
1220
1221 void    KX_ClearBulletSharedShapes()
1222 {
1223 }
1224
1225 #endif
1226