4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
30 #pragma warning (disable : 4786)
33 #include "MT_assert.h"
35 // defines USE_ODE to choose physics engine
36 #include "KX_ConvertPhysicsObject.h"
37 #include "KX_GameObject.h"
38 #include "RAS_MeshObject.h"
40 #include "SYS_System.h"
42 #include "PHY_Pro.h" //todo cleanup
43 #include "KX_ClientObjectInfo.h"
46 #include "GEN_HashedPtr.h"
48 #include "KX_PhysicsEngineEnums.h"
51 #include "KX_MotionState.h" // bridge between motionstate and scenegraph node
55 #include "KX_OdePhysicsController.h"
56 #include "OdePhysicsEnvironment.h"
60 // USE_SUMO_SOLID is defined in headerfile KX_ConvertPhysicsObject.h
64 #include "SumoPhysicsEnvironment.h"
65 #include "KX_SumoPhysicsController.h"
68 // sumo physics specific
69 #include "SM_Object.h"
70 #include "SM_FhObject.h"
72 #include "SM_ClientObjectInfo.h"
74 #include "KX_SumoPhysicsController.h"
76 struct KX_PhysicsInstance
78 DT_VertexBaseHandle m_vertexbase;
79 RAS_DisplayArray* m_darray;
80 RAS_IPolyMaterial* m_material;
82 KX_PhysicsInstance(DT_VertexBaseHandle vertex_base, RAS_DisplayArray *darray, RAS_IPolyMaterial* mat)
83 : m_vertexbase(vertex_base),
91 DT_DeleteVertexBase(m_vertexbase);
95 static GEN_Map<GEN_HashedPtr,DT_ShapeHandle> map_gamemesh_to_sumoshape;
96 static GEN_Map<GEN_HashedPtr, KX_PhysicsInstance*> map_gamemesh_to_instance;
98 // forward declarations
99 static void BL_RegisterSumoObject(KX_GameObject* gameobj,class SM_Scene* sumoScene,class SM_Object* sumoObj,const STR_String& matname,bool isDynamic,bool isActor);
100 static DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj, bool polytope);
102 void KX_ConvertSumoObject( KX_GameObject* gameobj,
103 RAS_MeshObject* meshobj,
105 PHY_ShapeProps* kxshapeprops,
106 PHY_MaterialProps* kxmaterial,
107 struct KX_ObjectProperties* objprop)
111 SM_ShapeProps* smprop = new SM_ShapeProps;
113 smprop->m_ang_drag = kxshapeprops->m_ang_drag;
114 smprop->m_do_anisotropic = kxshapeprops->m_do_anisotropic;
115 smprop->m_do_fh = kxshapeprops->m_do_fh;
116 smprop->m_do_rot_fh = kxshapeprops->m_do_rot_fh ;
117 smprop->m_friction_scaling[0] = kxshapeprops->m_friction_scaling[0];
118 smprop->m_friction_scaling[1] = kxshapeprops->m_friction_scaling[1];
119 smprop->m_friction_scaling[2] = kxshapeprops->m_friction_scaling[2];
120 smprop->m_inertia = MT_Vector3(1., 1., 1.) * kxshapeprops->m_inertia;
121 smprop->m_lin_drag = kxshapeprops->m_lin_drag;
122 smprop->m_mass = kxshapeprops->m_mass;
123 smprop->m_radius = objprop->m_radius;
126 SM_MaterialProps* smmaterial = new SM_MaterialProps;
128 smmaterial->m_fh_damping = kxmaterial->m_fh_damping;
129 smmaterial->m_fh_distance = kxmaterial->m_fh_distance;
130 smmaterial->m_fh_normal = kxmaterial->m_fh_normal;
131 smmaterial->m_fh_spring = kxmaterial->m_fh_spring;
132 smmaterial->m_friction = kxmaterial->m_friction;
133 smmaterial->m_restitution = kxmaterial->m_restitution;
135 SumoPhysicsEnvironment* sumoEnv =
136 (SumoPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
138 SM_Scene* sceneptr = sumoEnv->GetSumoScene();
140 SM_Object* sumoObj=NULL;
142 if (objprop->m_dyna && objprop->m_isactor)
144 DT_ShapeHandle shape = NULL;
145 bool polytope = false;
146 switch (objprop->m_boundclass)
149 shape = DT_NewBox(objprop->m_boundobject.box.m_extends[0],
150 objprop->m_boundobject.box.m_extends[1],
151 objprop->m_boundobject.box.m_extends[2]);
152 smprop->m_inertia.scale(objprop->m_boundobject.box.m_extends[0]*objprop->m_boundobject.box.m_extends[0],
153 objprop->m_boundobject.box.m_extends[1]*objprop->m_boundobject.box.m_extends[1],
154 objprop->m_boundobject.box.m_extends[2]*objprop->m_boundobject.box.m_extends[2]);
155 smprop->m_inertia *= smprop->m_mass/MT_Vector3(objprop->m_boundobject.box.m_extends).length();
157 case KX_BOUNDCYLINDER:
158 shape = DT_NewCylinder(smprop->m_radius, objprop->m_boundobject.c.m_height);
159 smprop->m_inertia.scale(smprop->m_mass*smprop->m_radius*smprop->m_radius,
160 smprop->m_mass*smprop->m_radius*smprop->m_radius,
161 smprop->m_mass*objprop->m_boundobject.c.m_height*objprop->m_boundobject.c.m_height);
164 shape = DT_NewCone(objprop->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);
169 /* Dynamic mesh objects. WARNING! slow. */
170 case KX_BOUNDPOLYTOPE:
174 if (meshobj && meshobj->NumPolygons() > 0)
176 if ((shape = CreateShapeFromMesh(meshobj, polytope)))
178 // TODO: calculate proper inertia
179 smprop->m_inertia *= smprop->m_mass*smprop->m_radius*smprop->m_radius;
183 /* If CreateShapeFromMesh fails, fall through and use sphere */
186 shape = DT_NewSphere(objprop->m_radius);
187 smprop->m_inertia *= smprop->m_mass*smprop->m_radius*smprop->m_radius;
192 sumoObj = new SM_Object(shape, !objprop->m_ghost?smmaterial:NULL,smprop,NULL);
194 sumoObj->setRigidBody(objprop->m_angular_rigidbody?true:false);
196 BL_RegisterSumoObject(gameobj,sceneptr,sumoObj,"",true, true);
200 // non physics object
203 int numpolys = meshobj->NumPolygons();
206 DT_ShapeHandle complexshape=0;
207 bool polytope = false;
209 switch (objprop->m_boundclass)
212 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 complexshape = DT_NewSphere(objprop->m_boundobject.c.m_radius);
217 case KX_BOUNDCYLINDER:
218 complexshape = DT_NewCylinder(objprop->m_boundobject.c.m_radius, objprop->m_boundobject.c.m_height);
221 complexshape = DT_NewCone(objprop->m_boundobject.c.m_radius, objprop->m_boundobject.c.m_height);
223 case KX_BOUNDPOLYTOPE:
230 complexshape = CreateShapeFromMesh(meshobj, polytope);
231 //std::cout << "Convert Physics Mesh: " << meshobj->GetName() << std::endl;
232 /* if (!complexshape)
234 // Something has to be done here - if the object has no polygons, it will not be able to have
235 // sensors attached to it.
236 DT_Vector3 pt = {0., 0., 0.};
237 complexshape = DT_NewSphere(1.0);
238 objprop->m_ghost = evilObject = true;
246 SM_Object *dynamicParent = NULL;
248 if (objprop->m_dynamic_parent)
250 // problem is how to find the dynamic parent
252 KX_SumoPhysicsController* sumoctrl =
253 (KX_SumoPhysicsController*)
254 objprop->m_dynamic_parent->GetPhysicsController();
258 dynamicParent = sumoctrl->GetSumoObject();
261 MT_assert(dynamicParent);
265 sumoObj = new SM_Object(complexshape,!objprop->m_ghost?smmaterial:NULL,NULL, dynamicParent);
266 const STR_String& matname=meshobj->GetMaterialName(0);
269 BL_RegisterSumoObject(gameobj,sceneptr,
279 // physics object get updated here !
282 // lazy evaluation because we might not support scaling !gameobj->UpdateTransform();
284 if (objprop->m_in_active_layer && sumoObj)
286 sceneptr->add(*sumoObj);
293 static void BL_RegisterSumoObject(
294 KX_GameObject* gameobj,
295 class SM_Scene* sumoScene,
296 class SM_Object* sumoObj,
297 const STR_String& matname,
301 PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
303 // need easy access, not via 'node' etc.
304 KX_SumoPhysicsController* physicscontroller = new KX_SumoPhysicsController(sumoScene,sumoObj,motionstate,isDynamic);
305 gameobj->SetPhysicsController(physicscontroller,isDynamic);
308 if (!gameobj->getClientInfo())
309 std::cout << "BL_RegisterSumoObject: WARNING: Object " << gameobj->GetName() << " has no client info" << std::endl;
310 physicscontroller->setNewClientInfo(gameobj->getClientInfo());
313 gameobj->GetSGNode()->AddSGController(physicscontroller);
315 gameobj->getClientInfo()->m_type = (isActor ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC);
317 // store materialname in auxinfo, needed for touchsensors
318 gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL);
320 physicscontroller->SetObject(gameobj->GetSGNode());
323 static DT_ShapeHandle InstancePhysicsComplex(RAS_MeshObject* meshobj, RAS_DisplayArray *darray, RAS_IPolyMaterial *mat)
325 // instance a mesh from a single vertex array & material
326 const RAS_TexVert *vertex_array = &darray->m_vertex[0];
327 DT_VertexBaseHandle vertex_base = DT_NewVertexBase(vertex_array[0].getXYZ(), sizeof(RAS_TexVert));
329 DT_ShapeHandle shape = DT_NewComplexShape(vertex_base);
331 std::vector<DT_Index> indices;
332 for (int p = 0; p < meshobj->NumPolygons(); p++)
334 RAS_Polygon* poly = meshobj->GetPolygon(p);
336 // only add polygons that have the collisionflag set
337 if (poly->IsCollider())
340 DT_VertexIndex(poly->GetVertexOffset(0));
341 DT_VertexIndex(poly->GetVertexOffset(1));
342 DT_VertexIndex(poly->GetVertexOffset(2));
346 if (poly->VertexCount() == 4)
349 DT_VertexIndex(poly->GetVertexOffset(0));
350 DT_VertexIndex(poly->GetVertexOffset(2));
351 DT_VertexIndex(poly->GetVertexOffset(3));
357 //DT_VertexIndices(indices.size(), &indices[0]);
358 DT_EndComplexShape();
360 map_gamemesh_to_instance.insert(GEN_HashedPtr(meshobj), new KX_PhysicsInstance(vertex_base, darray, mat));
364 static DT_ShapeHandle InstancePhysicsPolytope(RAS_MeshObject* meshobj, RAS_DisplayArray *darray, RAS_IPolyMaterial *mat)
366 // instance a mesh from a single vertex array & material
367 const RAS_TexVert *vertex_array = &darray->m_vertex[0];
368 DT_VertexBaseHandle vertex_base = DT_NewVertexBase(vertex_array[0].getXYZ(), sizeof(RAS_TexVert));
370 std::vector<DT_Index> indices;
371 for (int p = 0; p < meshobj->NumPolygons(); p++)
373 RAS_Polygon* poly = meshobj->GetPolygon(p);
375 // only add polygons that have the collisionflag set
376 if (poly->IsCollider())
378 indices.push_back(poly->GetVertexOffset(0));
379 indices.push_back(poly->GetVertexOffset(1));
380 indices.push_back(poly->GetVertexOffset(2));
382 if (poly->VertexCount() == 4)
383 indices.push_back(poly->GetVertexOffset(3));
387 DT_ShapeHandle shape = DT_NewPolytope(vertex_base);
388 DT_VertexIndices(indices.size(), &indices[0]);
391 map_gamemesh_to_instance.insert(GEN_HashedPtr(meshobj), new KX_PhysicsInstance(vertex_base, darray, mat));
395 // This will have to be a method in a class somewhere...
396 // Update SOLID with a changed physics mesh.
398 bool KX_ReInstanceShapeFromMesh(RAS_MeshObject* meshobj)
400 KX_PhysicsInstance *instance = *map_gamemesh_to_instance[GEN_HashedPtr(meshobj)];
403 const RAS_TexVert *vertex_array = &instance->m_darray->m_vertex[0];
404 DT_ChangeVertexBase(instance->m_vertexbase, vertex_array[0].getXYZ());
410 static DT_ShapeHandle CreateShapeFromMesh(RAS_MeshObject* meshobj, bool polytope)
413 DT_ShapeHandle *shapeptr = map_gamemesh_to_sumoshape[GEN_HashedPtr(meshobj)];
414 // Mesh has already been converted: reuse
420 // Mesh has no polygons!
421 int numpolys = meshobj->NumPolygons();
427 // Count the number of collision polygons and check they all come from the same
429 int numvalidpolys = 0;
430 RAS_DisplayArray *darray = NULL;
431 RAS_IPolyMaterial *poly_material = NULL;
432 bool reinstance = true;
434 for (int p=0; p<numpolys; p++)
436 RAS_Polygon* poly = meshobj->GetPolygon(p);
438 // only add polygons that have the collisionflag set
439 if (poly->IsCollider())
441 // check polygon is from the same vertex array
442 if (poly->GetDisplayArray() != darray)
445 darray = poly->GetDisplayArray();
453 // check poly is from the same material
454 if (poly->GetMaterial()->GetPolyMaterial() != poly_material)
459 poly_material = NULL;
462 poly_material = poly->GetMaterial()->GetPolyMaterial();
465 // count the number of collision polys
468 // We have one collision poly, and we can't reinstance, so we
469 // might as well break here.
475 // No collision polygons
476 if (numvalidpolys < 1)
479 DT_ShapeHandle shape;
483 shape = InstancePhysicsPolytope(meshobj, darray, poly_material);
485 shape = InstancePhysicsComplex(meshobj, darray, poly_material);
491 std::cout << "CreateShapeFromMesh: " << meshobj->GetName() << " is not suitable for polytope." << std::endl;
493 std::cout << " Check mesh materials." << std::endl;
495 std::cout << " Check number of vertices." << std::endl;
498 shape = DT_NewComplexShape(NULL);
502 for (int p2=0; p2<numpolys; p2++)
504 RAS_Polygon* poly = meshobj->GetPolygon(p2);
506 // only add polygons that have the collisionflag set
507 if (poly->IsCollider())
508 { /* We have to tesselate here because SOLID can only raycast triangles */
511 DT_Vertex(poly->GetVertex(2)->getXYZ());
512 DT_Vertex(poly->GetVertex(1)->getXYZ());
513 DT_Vertex(poly->GetVertex(0)->getXYZ());
518 if (poly->VertexCount() == 4)
522 DT_Vertex(poly->GetVertex(3)->getXYZ());
523 DT_Vertex(poly->GetVertex(2)->getXYZ());
524 DT_Vertex(poly->GetVertex(0)->getXYZ());
533 DT_EndComplexShape();
536 if (numvalidpolys > 0)
538 map_gamemesh_to_sumoshape.insert(GEN_HashedPtr(meshobj),shape);
546 void KX_ClearSumoSharedShapes()
548 int numshapes = map_gamemesh_to_sumoshape.size();
550 for (i=0;i<numshapes ;i++)
552 DT_ShapeHandle shape = *map_gamemesh_to_sumoshape.at(i);
553 DT_DeleteShape(shape);
556 map_gamemesh_to_sumoshape.clear();
558 for (i=0; i < map_gamemesh_to_instance.size(); i++)
559 delete *map_gamemesh_to_instance.at(i);
561 map_gamemesh_to_instance.clear();
568 #endif //USE_SUMO_SOLID
573 void KX_ConvertODEEngineObject(KX_GameObject* gameobj,
574 RAS_MeshObject* meshobj,
576 struct PHY_ShapeProps* shapeprops,
577 struct PHY_MaterialProps* smmaterial,
578 struct KX_ObjectProperties* objprop)
581 // not yet, future extension :)
582 bool dyna=objprop->m_dyna;
583 bool fullRigidBody= ( objprop->m_dyna && objprop->m_angular_rigidbody) != 0;
584 bool phantom = objprop->m_ghost;
585 class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
587 class ODEPhysicsEnvironment* odeEnv =
588 (ODEPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
590 dxSpace* space = odeEnv->GetOdeSpace();
591 dxWorld* world = odeEnv->GetOdeWorld();
593 bool isSphere = false;
595 switch (objprop->m_boundclass)
600 KX_OdePhysicsController* physicscontroller =
601 new KX_OdePhysicsController(
609 smmaterial->m_friction,
610 smmaterial->m_restitution,
612 objprop->m_boundobject.box.m_center,
613 objprop->m_boundobject.box.m_extends,
614 objprop->m_boundobject.c.m_radius
617 gameobj->SetPhysicsController(physicscontroller);
618 physicscontroller->setNewClientInfo(gameobj->getClientInfo());
619 gameobj->GetSGNode()->AddSGController(physicscontroller);
621 bool isActor = objprop->m_isactor;
622 STR_String materialname;
624 materialname = meshobj->GetMaterialName(0);
626 const char* matname = materialname.ReadPtr();
629 physicscontroller->SetObject(gameobj->GetSGNode());
646 #include "CcdPhysicsEnvironment.h"
647 #include "CcdPhysicsController.h"
648 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
650 #include "KX_BulletPhysicsController.h"
651 #include "btBulletDynamicsCommon.h"
655 //only use SIMD Hull code under Win32
656 //#define TEST_HULL 1
659 //#define TEST_SIMD_HULL 1
661 #include "NarrowPhaseCollision/Hull.h"
662 #endif //#ifdef TEST_HULL
668 // forward declarations
670 void KX_ConvertBulletObject( class KX_GameObject* gameobj,
671 class RAS_MeshObject* meshobj,
672 class KX_Scene* kxscene,
673 struct PHY_ShapeProps* shapeprops,
674 struct PHY_MaterialProps* smmaterial,
675 struct KX_ObjectProperties* objprop)
678 CcdPhysicsEnvironment* env = (CcdPhysicsEnvironment*)kxscene->GetPhysicsEnvironment();
682 bool isbulletdyna = false;
683 CcdConstructionInfo ci;
684 class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
685 class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo();
689 if (!objprop->m_dyna)
691 ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
693 if (objprop->m_ghost)
695 ci.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
698 ci.m_MotionState = motionstate;
699 ci.m_gravity = btVector3(0,0,0);
700 ci.m_localInertiaTensor =btVector3(0,0,0);
701 ci.m_mass = objprop->m_dyna ? shapeprops->m_mass : 0.f;
702 ci.m_margin = objprop->m_margin;
703 shapeInfo->m_radius = objprop->m_radius;
704 isbulletdyna = objprop->m_dyna;
706 ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f);
708 btCollisionShape* bm = 0;
710 switch (objprop->m_boundclass)
714 //float radius = objprop->m_radius;
715 //btVector3 inertiaHalfExtents (
720 //blender doesn't support multisphere, but for testing:
722 //bm = new MultiSphereShape(inertiaHalfExtents,,&trans.getOrigin(),&radius,1);
723 shapeInfo->m_shapeType = PHY_SHAPE_SPHERE;
724 bm = shapeInfo->CreateBulletShape();
729 shapeInfo->m_halfExtend.setValue(
730 objprop->m_boundobject.box.m_extends[0],
731 objprop->m_boundobject.box.m_extends[1],
732 objprop->m_boundobject.box.m_extends[2]);
734 shapeInfo->m_halfExtend /= 2.0;
735 shapeInfo->m_halfExtend = shapeInfo->m_halfExtend.absolute();
736 shapeInfo->m_shapeType = PHY_SHAPE_BOX;
737 bm = shapeInfo->CreateBulletShape();
740 case KX_BOUNDCYLINDER:
742 shapeInfo->m_halfExtend.setValue(
743 objprop->m_boundobject.c.m_radius,
744 objprop->m_boundobject.c.m_radius,
745 objprop->m_boundobject.c.m_height * 0.5f
747 shapeInfo->m_shapeType = PHY_SHAPE_CYLINDER;
748 bm = shapeInfo->CreateBulletShape();
754 shapeInfo->m_radius = objprop->m_boundobject.c.m_radius;
755 shapeInfo->m_height = objprop->m_boundobject.c.m_height;
756 shapeInfo->m_shapeType = PHY_SHAPE_CONE;
757 bm = shapeInfo->CreateBulletShape();
760 case KX_BOUNDPOLYTOPE:
762 shapeInfo->SetMesh(meshobj, true);
763 bm = shapeInfo->CreateBulletShape();
770 shapeInfo->SetMesh(meshobj, false);
771 bm = shapeInfo->CreateBulletShape();
772 //no moving concave meshes, so don't bother calculating inertia
773 //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor);
781 // ci.m_localInertiaTensor.setValue(0.1f,0.1f,0.1f);
790 bm->setMargin(ci.m_margin);
793 if (objprop->m_isCompoundChild)
795 //find parent, compound shape and add to it
796 //take relative transform into account!
797 KX_BulletPhysicsController* parentCtrl = (KX_BulletPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController();
799 CcdShapeConstructionInfo* parentShapeInfo = parentCtrl->GetShapeInfo();
800 btRigidBody* rigidbody = parentCtrl->GetRigidBody();
801 btCollisionShape* colShape = rigidbody->getCollisionShape();
802 assert(colShape->isCompound());
803 btCompoundShape* compoundShape = (btCompoundShape*)colShape;
805 // compute the local transform from parent, this may include a parent inverse node
806 SG_Node* gameNode = gameobj->GetSGNode();
807 SG_Node* parentInverseNode = gameNode->GetSGParent();
808 if (parentInverseNode && parentInverseNode->GetSGClientObject() != NULL)
809 // this is not a parent inverse node, cancel it
810 parentInverseNode = NULL;
811 // now combine the parent inverse node and the game node
812 MT_Point3 childPos = gameNode->GetLocalPosition();
813 MT_Matrix3x3 childRot = gameNode->GetLocalOrientation();
814 MT_Vector3 childScale = gameNode->GetLocalScale();
815 if (parentInverseNode)
817 const MT_Point3& parentInversePos = parentInverseNode->GetLocalPosition();
818 const MT_Matrix3x3& parentInverseRot = parentInverseNode->GetLocalOrientation();
819 const MT_Vector3& parentInverseScale = parentInverseNode->GetLocalScale();
820 childRot = parentInverseRot * childRot;
821 childScale = parentInverseScale * childScale;
822 childPos = parentInversePos+parentInverseScale*(parentInverseRot*childPos);
825 shapeInfo->m_childScale.setValue(childScale.x(),childScale.y(),childScale.z());
826 bm->setLocalScaling(shapeInfo->m_childScale);
828 shapeInfo->m_childTrans.setOrigin(btVector3(childPos.x(),childPos.y(),childPos.z()));
830 childRot.getValue(rotval);
832 newRot.setValue(rotval[0],rotval[1],rotval[2],rotval[4],rotval[5],rotval[6],rotval[8],rotval[9],rotval[10]);
833 newRot = newRot.transpose();
835 shapeInfo->m_childTrans.setBasis(newRot);
836 parentShapeInfo->AddShape(shapeInfo);
838 compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
840 //recalc inertia for rigidbody
841 if (!rigidbody->isStaticOrKinematicObject())
843 btVector3 localInertia;
844 float mass = 1.f/rigidbody->getInvMass();
845 compoundShape->calculateLocalInertia(mass,localInertia);
846 rigidbody->setMassProps(mass,localInertia);
851 if (objprop->m_hasCompoundChildren)
853 // create a compound shape info
854 CcdShapeConstructionInfo *compoundShapeInfo = new CcdShapeConstructionInfo();
855 compoundShapeInfo->m_shapeType = PHY_SHAPE_COMPOUND;
856 compoundShapeInfo->AddShape(shapeInfo);
857 // create the compound shape manually as we already have the child shape
858 btCompoundShape* compoundShape = new btCompoundShape();
859 compoundShape->addChildShape(shapeInfo->m_childTrans,bm);
860 // now replace the shape
862 shapeInfo = compoundShapeInfo;
870 #ifdef TEST_SIMD_HULL
871 if (bm->IsPolyhedral())
873 PolyhedralConvexShape* polyhedron = static_cast<PolyhedralConvexShape*>(bm);
874 if (!polyhedron->m_optionalHull)
876 //first convert vertices in 'Point3' format
877 int numPoints = polyhedron->GetNumVertices();
878 Point3* points = new Point3[numPoints+1];
879 //first 4 points should not be co-planar, so add central point to satisfy MakeHull
880 points[0] = Point3(0.f,0.f,0.f);
883 for (int p=0;p<numPoints;p++)
885 polyhedron->GetVertex(p,vertex);
886 points[p+1] = Point3(vertex.getX(),vertex.getY(),vertex.getZ());
889 Hull* hull = Hull::MakeHull(numPoints+1,points);
890 polyhedron->m_optionalHull = hull;
894 #endif //TEST_SIMD_HULL
897 ci.m_collisionShape = bm;
898 ci.m_shapeInfo = shapeInfo;
899 ci.m_friction = smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice
900 ci.m_restitution = smmaterial->m_restitution;
901 ci.m_physicsEnv = env;
902 // drag / damping is inverted
903 ci.m_linearDamping = 1.f - shapeprops->m_lin_drag;
904 ci.m_angularDamping = 1.f - shapeprops->m_ang_drag;
905 //need a bit of damping, else system doesn't behave well
906 ci.m_inertiaFactor = shapeprops->m_inertia/0.4f;//defaults to 0.4, don't want to change behaviour
907 ci.m_collisionFilterGroup = (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : short(CcdConstructionInfo::StaticFilter);
908 ci.m_collisionFilterMask = (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter);
909 ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody;
910 MT_Vector3 scaling = gameobj->NodeGetWorldScaling();
911 ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]);
912 KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna);
913 // shapeInfo is reference counted, decrement now as we don't use it anymore
915 shapeInfo->Release();
917 if (objprop->m_in_active_layer)
919 env->addCcdPhysicsController( physicscontroller);
924 gameobj->SetPhysicsController(physicscontroller,isbulletdyna);
925 physicscontroller->setNewClientInfo(gameobj->getClientInfo());
926 btRigidBody* rbody = physicscontroller->GetRigidBody();
928 if (objprop->m_disableSleeping)
929 rbody->setActivationState(DISABLE_DEACTIVATION);
931 //Now done directly in ci.m_collisionFlags so that it propagates to replica
932 //if (objprop->m_ghost)
934 // rbody->setCollisionFlags(rbody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
937 if (objprop->m_dyna && !objprop->m_angular_rigidbody)
940 //setting the inertia could achieve similar results to constraint the up
941 //but it is prone to instability, so use special 'Angular' constraint
942 btVector3 inertia = physicscontroller->GetRigidBody()->getInvInertiaDiagLocal();
946 physicscontroller->GetRigidBody()->setInvInertiaDiagLocal(inertia);
947 physicscontroller->GetRigidBody()->updateInertiaTensor();
950 //env->createConstraint(physicscontroller,0,PHY_ANGULAR_CONSTRAINT,0,0,0,0,0,1);
952 //Now done directly in ci.m_bRigid so that it propagates to replica
953 //physicscontroller->GetRigidBody()->setAngularFactor(0.f);
957 bool isActor = objprop->m_isactor;
958 gameobj->getClientInfo()->m_type = (isActor ? KX_ClientObjectInfo::ACTOR : KX_ClientObjectInfo::STATIC);
959 // store materialname in auxinfo, needed for touchsensors
962 const STR_String& matname=meshobj->GetMaterialName(0);
963 gameobj->getClientInfo()->m_auxilary_info = (matname.Length() ? (void*)(matname.ReadPtr()+2) : NULL);
966 gameobj->getClientInfo()->m_auxilary_info = 0;
970 gameobj->GetSGNode()->AddSGController(physicscontroller);
972 STR_String materialname;
974 materialname = meshobj->GetMaterialName(0);
976 physicscontroller->SetObject(gameobj->GetSGNode());
981 void KX_ClearBulletSharedShapes()