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