svn merge -r 16351:16368 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / source / gameengine / Physics / Bullet / CcdPhysicsController.cpp
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose, 
8 including commercial applications, and to alter it and redistribute it freely, 
9 subject to the following restrictions:
10
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16 #include "CcdPhysicsController.h"
17 #include "btBulletDynamicsCommon.h"
18
19 #include "PHY_IMotionState.h"
20 #include "CcdPhysicsEnvironment.h"
21 #include "RAS_MeshObject.h"
22
23
24 class BP_Proxy;
25
26 ///todo: fill all the empty CcdPhysicsController methods, hook them up to the btRigidBody class
27
28 //'temporarily' global variables
29 //float gDeactivationTime = 2.f;
30 //bool  gDisableDeactivation = false;
31 extern float gDeactivationTime;
32 extern bool gDisableDeactivation;
33
34
35 float gLinearSleepingTreshold = 0.8f;
36 float gAngularSleepingTreshold = 1.0f;
37
38
39 btVector3 startVel(0,0,0);//-10000);
40
41 CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
42 :m_cci(ci)
43 {
44         m_collisionDelay = 0;
45         m_newClientInfo = 0;
46         m_registerCount = 0;
47                 
48         // copy pointers locally to allow smart release
49         m_MotionState = ci.m_MotionState;
50         m_collisionShape = ci.m_collisionShape;
51         // apply scaling before creating rigid body
52         m_collisionShape->setLocalScaling(m_cci.m_scaling);
53         if (m_cci.m_mass)
54                 m_collisionShape->calculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor);
55         // shape info is shared, increment ref count
56         m_shapeInfo = ci.m_shapeInfo;
57         if (m_shapeInfo)
58                 m_shapeInfo->AddRef();
59         
60         m_bulletMotionState = 0;
61         
62         
63         CreateRigidbody();
64         
65
66         
67         #ifdef WIN32
68         if (m_body->getInvMass())
69                 m_body->setLinearVelocity(startVel);
70         #endif
71
72 }
73
74 btTransform     CcdPhysicsController::GetTransformFromMotionState(PHY_IMotionState* motionState)
75 {
76         btTransform trans;
77         float tmp[3];
78         motionState->getWorldPosition(tmp[0],tmp[1],tmp[2]);
79         trans.setOrigin(btVector3(tmp[0],tmp[1],tmp[2]));
80
81         btQuaternion orn;
82         motionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]);
83         trans.setRotation(orn);
84         return trans;
85
86 }
87
88 class   BlenderBulletMotionState : public btMotionState
89 {
90         PHY_IMotionState*       m_blenderMotionState;
91
92 public:
93
94         BlenderBulletMotionState(PHY_IMotionState* bms)
95                 :m_blenderMotionState(bms)
96         {
97
98         }
99
100         virtual void    getWorldTransform(btTransform& worldTrans ) const
101         {
102                 float pos[3];
103                 float quatOrn[4];
104
105                 m_blenderMotionState->getWorldPosition(pos[0],pos[1],pos[2]);
106                 m_blenderMotionState->getWorldOrientation(quatOrn[0],quatOrn[1],quatOrn[2],quatOrn[3]);
107                 worldTrans.setOrigin(btVector3(pos[0],pos[1],pos[2]));
108                 worldTrans.setBasis(btMatrix3x3(btQuaternion(quatOrn[0],quatOrn[1],quatOrn[2],quatOrn[3])));
109         }
110
111         virtual void    setWorldTransform(const btTransform& worldTrans)
112         {
113                 m_blenderMotionState->setWorldPosition(worldTrans.getOrigin().getX(),worldTrans.getOrigin().getY(),worldTrans.getOrigin().getZ());
114                 btQuaternion rotQuat = worldTrans.getRotation();
115                 m_blenderMotionState->setWorldOrientation(rotQuat[0],rotQuat[1],rotQuat[2],rotQuat[3]);
116                 m_blenderMotionState->calculateWorldTransformations();
117         }
118
119 };
120
121
122 void CcdPhysicsController::CreateRigidbody()
123 {
124
125         btTransform trans = GetTransformFromMotionState(m_MotionState);
126
127         m_bulletMotionState = new BlenderBulletMotionState(m_MotionState);
128
129         btRigidBody::btRigidBodyConstructionInfo rbci(m_cci.m_mass,m_bulletMotionState,m_collisionShape,m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
130         rbci.m_linearDamping = m_cci.m_linearDamping;
131         rbci.m_angularDamping = m_cci.m_angularDamping;
132         rbci.m_friction = m_cci.m_friction;
133         rbci.m_restitution = m_cci.m_restitution;
134         
135         m_body = new btRigidBody(rbci);
136         
137         //
138         // init the rigidbody properly
139         //
140         
141         //setMassProps this also sets collisionFlags
142         //convert collision flags!
143         //special case: a near/radar sensor controller should not be defined static or it will
144         //generate loads of static-static collision messages on the console
145         if ((m_cci.m_collisionFilterGroup & CcdConstructionInfo::SensorFilter) != 0)
146         {
147                 // reset the flags that have been set so far
148                 m_body->setCollisionFlags(0);
149         }
150         m_body->setCollisionFlags(m_body->getCollisionFlags() | m_cci.m_collisionFlags);
151         m_body->setGravity( m_cci.m_gravity);
152         m_body->setDamping(m_cci.m_linearDamping, m_cci.m_angularDamping);
153
154         if (!m_cci.m_bRigid)
155         {
156                 m_body->setAngularFactor(0.f);
157         }
158 }
159
160 static void DeleteBulletShape(btCollisionShape* shape)
161 {
162         if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
163         {
164                 // shapes based on meshes use an interface that contains the vertices.
165                 btTriangleMeshShape* meshShape = static_cast<btTriangleMeshShape*>(shape);
166                 btStridingMeshInterface* meshInterface = meshShape->getMeshInterface();
167                 if (meshInterface)
168                         delete meshInterface;
169         }
170         delete shape;
171 }
172
173 CcdPhysicsController::~CcdPhysicsController()
174 {
175         //will be reference counted, due to sharing
176         if (m_cci.m_physicsEnv)
177                 m_cci.m_physicsEnv->removeCcdPhysicsController(this);
178
179         if (m_MotionState)
180                 delete m_MotionState;
181         if (m_bulletMotionState)
182                 delete m_bulletMotionState;
183         delete m_body;
184
185         if (m_collisionShape)
186         {
187                 // collision shape is always unique to the controller, can delete it here
188                 if (m_collisionShape->isCompound())
189                 {
190                         // bullet does not delete the child shape, must do it here
191                         btCompoundShape* compoundShape = (btCompoundShape*)m_collisionShape;
192                         int numChild = compoundShape->getNumChildShapes();
193                         for (int i=numChild-1 ; i >= 0; i--)
194                         {
195                                 btCollisionShape* childShape = compoundShape->getChildShape(i);
196                                 DeleteBulletShape(childShape);
197                         }
198                 }
199                 DeleteBulletShape(m_collisionShape);
200         }
201         if (m_shapeInfo)
202         {
203                 m_shapeInfo->Release();
204         }
205 }
206
207
208                 /**
209                         SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding')
210                 */
211 bool            CcdPhysicsController::SynchronizeMotionStates(float time)
212 {
213         //sync non-static to motionstate, and static from motionstate (todo: add kinematic etc.)
214
215         if (!m_body->isStaticObject())
216         {
217                 const btVector3& worldPos = m_body->getCenterOfMassPosition();
218                 m_MotionState->setWorldPosition(worldPos[0],worldPos[1],worldPos[2]);
219                 
220                 const btQuaternion& worldquat = m_body->getOrientation();
221                 m_MotionState->setWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]);
222
223                 m_MotionState->calculateWorldTransformations();
224
225                 float scale[3];
226                 m_MotionState->getWorldScaling(scale[0],scale[1],scale[2]);
227                 btVector3 scaling(scale[0],scale[1],scale[2]);
228                 GetCollisionShape()->setLocalScaling(scaling);
229         } else
230         {
231                 btVector3 worldPos;
232                 btQuaternion worldquat;
233
234 /*              m_MotionState->getWorldPosition(worldPos[0],worldPos[1],worldPos[2]);
235                 m_MotionState->getWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]);
236                 btTransform oldTrans = m_body->getCenterOfMassTransform();
237                 btTransform newTrans(worldquat,worldPos);
238                                 
239                 m_body->setCenterOfMassTransform(newTrans);
240                 //need to keep track of previous position for friction effects...
241                 
242                 m_MotionState->calculateWorldTransformations();
243 */
244                 float scale[3];
245                 m_MotionState->getWorldScaling(scale[0],scale[1],scale[2]);
246                 btVector3 scaling(scale[0],scale[1],scale[2]);
247                 GetCollisionShape()->setLocalScaling(scaling);
248         }
249         return true;
250
251 }
252
253                 /**
254                         WriteMotionStateToDynamics synchronizes dynas, kinematic and deformable entities (and do 'late binding')
255                 */
256                 
257 void            CcdPhysicsController::WriteMotionStateToDynamics(bool nondynaonly)
258 {
259
260 }
261 void            CcdPhysicsController::WriteDynamicsToMotionState()
262 {
263 }
264                 // controller replication
265 void            CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl)
266 {
267         m_MotionState = motionstate;
268         m_registerCount = 0;
269         m_collisionShape = NULL;
270
271         // always create a new shape to avoid scaling bug
272         if (m_shapeInfo)
273         {
274                 m_shapeInfo->AddRef();
275                 m_collisionShape = m_shapeInfo->CreateBulletShape();
276
277                 if (m_collisionShape)
278                 {
279                         // new shape has no scaling, apply initial scaling
280                         m_collisionShape->setLocalScaling(m_cci.m_scaling);
281                         if (m_cci.m_mass)
282                                 m_collisionShape->calculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor);
283                 }
284         }
285
286         m_body = 0;
287         CreateRigidbody();
288
289         if (m_body)
290         {
291                 if (m_cci.m_mass)
292                 {
293                         m_body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
294                 } 
295         }                       
296         m_cci.m_physicsEnv->addCcdPhysicsController(this);
297
298
299 /*      SM_Object* dynaparent=0;
300         SumoPhysicsController* sumoparentctrl = (SumoPhysicsController* )parentctrl;
301         
302         if (sumoparentctrl)
303         {
304                 dynaparent = sumoparentctrl->GetSumoObject();
305         }
306         
307         SM_Object* orgsumoobject = m_sumoObj;
308         
309         
310         m_sumoObj       =       new SM_Object(
311                 orgsumoobject->getShapeHandle(), 
312                 orgsumoobject->getMaterialProps(),                      
313                 orgsumoobject->getShapeProps(),
314                 dynaparent);
315         
316         m_sumoObj->setRigidBody(orgsumoobject->isRigidBody());
317         
318         m_sumoObj->setMargin(orgsumoobject->getMargin());
319         m_sumoObj->setPosition(orgsumoobject->getPosition());
320         m_sumoObj->setOrientation(orgsumoobject->getOrientation());
321         //if it is a dyna, register for a callback
322         m_sumoObj->registerCallback(*this);
323         
324         m_sumoScene->add(* (m_sumoObj));
325         */
326
327
328
329 }
330
331                 // kinematic methods
332 void            CcdPhysicsController::RelativeTranslate(float dlocX,float dlocY,float dlocZ,bool local)
333 {
334         if (m_body)
335         {
336                 m_body->activate(true);
337                 if (m_body->isStaticObject())
338                 {
339                         m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
340                 }
341
342
343                 btVector3 dloc(dlocX,dlocY,dlocZ);
344                 btTransform xform = m_body->getCenterOfMassTransform();
345
346                 if (local)
347                 {
348                         dloc = xform.getBasis()*dloc;
349                 }
350
351                 xform.setOrigin(xform.getOrigin() + dloc);
352                 m_body->setCenterOfMassTransform(xform);
353         }
354
355 }
356
357 void            CcdPhysicsController::RelativeRotate(const float rotval[9],bool local)
358 {
359         if (m_body)
360         {
361                 m_body->activate(true);
362                 if (m_body->isStaticObject())
363                 {
364                         m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
365                 }
366
367                 btMatrix3x3 drotmat(    rotval[0],rotval[4],rotval[8],
368                                                                 rotval[1],rotval[5],rotval[9],
369                                                                 rotval[2],rotval[6],rotval[10]);
370
371
372                 btMatrix3x3 currentOrn;
373                 GetWorldOrientation(currentOrn);
374
375                 btTransform xform = m_body->getCenterOfMassTransform();
376
377                 xform.setBasis(xform.getBasis()*(local ? 
378                 drotmat : (currentOrn.inverse() * drotmat * currentOrn)));
379
380                 m_body->setCenterOfMassTransform(xform);
381         }
382
383 }
384
385 void CcdPhysicsController::GetWorldOrientation(btMatrix3x3& mat)
386 {
387         float orn[4];
388         m_MotionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]);
389         btQuaternion quat(orn[0],orn[1],orn[2],orn[3]);
390         mat.setRotation(quat);
391 }
392
393 void            CcdPhysicsController::getOrientation(float &quatImag0,float &quatImag1,float &quatImag2,float &quatReal)
394 {
395         btQuaternion q = m_body->getCenterOfMassTransform().getRotation();
396         quatImag0 = q[0];
397         quatImag1 = q[1];
398         quatImag2 = q[2];
399         quatReal = q[3];
400 }
401 void            CcdPhysicsController::setOrientation(float quatImag0,float quatImag1,float quatImag2,float quatReal)
402 {
403         if (m_body)
404         {
405                 m_body->activate(true);
406                 if (m_body->isStaticObject())
407                 {
408                         m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
409                 }
410                 // not required
411                 //m_MotionState->setWorldOrientation(quatImag0,quatImag1,quatImag2,quatReal);
412                 btTransform xform  = m_body->getCenterOfMassTransform();
413                 xform.setRotation(btQuaternion(quatImag0,quatImag1,quatImag2,quatReal));
414                 m_body->setCenterOfMassTransform(xform);
415                 // not required
416                 //m_bulletMotionState->setWorldTransform(xform);
417         }
418
419 }
420
421 void CcdPhysicsController::setWorldOrientation(const btMatrix3x3& orn)
422 {
423         if (m_body)
424         {
425                 m_body->activate(true);
426                 if (m_body->isStaticObject())
427                 {
428                         m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
429                 }
430                 // not required
431                 //m_MotionState->setWorldOrientation(quatImag0,quatImag1,quatImag2,quatReal);
432                 btTransform xform  = m_body->getCenterOfMassTransform();
433                 xform.setBasis(orn);
434                 m_body->setCenterOfMassTransform(xform);
435                 // not required
436                 //m_bulletMotionState->setWorldTransform(xform);
437         }
438
439 }
440
441 void            CcdPhysicsController::setPosition(float posX,float posY,float posZ)
442 {
443         if (m_body)
444         {
445                 m_body->activate(true);
446                 if (m_body->isStaticObject())
447                 {
448                         m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
449                 }
450                 // not required, this function is only used to update the physic controller
451                 //m_MotionState->setWorldPosition(posX,posY,posZ);
452                 btTransform xform  = m_body->getCenterOfMassTransform();
453                 xform.setOrigin(btVector3(posX,posY,posZ));
454                 m_body->setCenterOfMassTransform(xform);
455                 // not required
456                 //m_bulletMotionState->setWorldTransform(xform);
457         }
458
459
460 }
461 void            CcdPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ)
462 {
463 }
464
465 void            CcdPhysicsController::getPosition(PHY__Vector3& pos) const
466 {
467         const btTransform& xform = m_body->getCenterOfMassTransform();
468         pos[0] = xform.getOrigin().x();
469         pos[1] = xform.getOrigin().y();
470         pos[2] = xform.getOrigin().z();
471 }
472
473 void            CcdPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ)
474 {
475         if (!btFuzzyZero(m_cci.m_scaling.x()-scaleX) ||
476                 !btFuzzyZero(m_cci.m_scaling.y()-scaleY) ||
477                 !btFuzzyZero(m_cci.m_scaling.z()-scaleZ))
478         {
479                 m_cci.m_scaling = btVector3(scaleX,scaleY,scaleZ);
480
481                 if (m_body && m_body->getCollisionShape())
482                 {
483                         m_body->getCollisionShape()->setLocalScaling(m_cci.m_scaling);
484                         
485                         //printf("no inertia recalc for fixed objects with mass=0\n");
486                         if (m_cci.m_mass)
487                         {
488                                 m_body->getCollisionShape()->calculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor);
489                                 m_body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
490                         } 
491                         
492                 }
493         }
494 }
495                 
496                 // physics methods
497 void            CcdPhysicsController::ApplyTorque(float torqueX,float torqueY,float torqueZ,bool local)
498 {
499         btVector3 torque(torqueX,torqueY,torqueZ);
500         btTransform xform = m_body->getCenterOfMassTransform();
501         if (m_body && torque.length2() > (SIMD_EPSILON*SIMD_EPSILON))
502         {
503                 m_body->activate();
504                 if (m_body->isStaticObject())
505                 {
506                         m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
507                 }
508                 if (local)
509                 {
510                         torque  = xform.getBasis()*torque;
511                 }
512                 m_body->applyTorque(torque);
513         }
514 }
515
516 void            CcdPhysicsController::ApplyForce(float forceX,float forceY,float forceZ,bool local)
517 {
518         btVector3 force(forceX,forceY,forceZ);
519         
520         if (m_body && force.length2() > (SIMD_EPSILON*SIMD_EPSILON))
521         {
522                 m_body->activate();
523                 if (m_body->isStaticObject())
524                 {
525                         m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
526                 }
527                 {
528                         btTransform xform = m_body->getCenterOfMassTransform();
529                         if (local)
530                         {       
531                                 force   = xform.getBasis()*force;
532                         }
533                 }
534                 m_body->applyCentralForce(force);
535         }
536 }
537 void            CcdPhysicsController::SetAngularVelocity(float ang_velX,float ang_velY,float ang_velZ,bool local)
538 {
539         btVector3 angvel(ang_velX,ang_velY,ang_velZ);
540         if (m_body && angvel.length2() > (SIMD_EPSILON*SIMD_EPSILON))
541         {
542                 m_body->activate(true);
543                 if (m_body->isStaticObject())
544                 {
545                         m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
546                 }
547                 {
548                         btTransform xform = m_body->getCenterOfMassTransform();
549                         if (local)
550                         {
551                                 angvel  = xform.getBasis()*angvel;
552                         }
553                 }
554                 m_body->setAngularVelocity(angvel);
555         }
556
557 }
558 void            CcdPhysicsController::SetLinearVelocity(float lin_velX,float lin_velY,float lin_velZ,bool local)
559 {
560
561         btVector3 linVel(lin_velX,lin_velY,lin_velZ);
562         if (m_body && linVel.length2() > (SIMD_EPSILON*SIMD_EPSILON))
563         {
564                 m_body->activate(true);
565                 if (m_body->isStaticObject())
566                 {
567                         m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
568                 }
569
570                 {
571                         btTransform xform = m_body->getCenterOfMassTransform();
572                         if (local)
573                         {
574                                 linVel  = xform.getBasis()*linVel;
575                         }
576                 }
577                 m_body->setLinearVelocity(linVel);
578         }
579 }
580 void            CcdPhysicsController::applyImpulse(float attachX,float attachY,float attachZ, float impulseX,float impulseY,float impulseZ)
581 {
582         btVector3 impulse(impulseX,impulseY,impulseZ);
583
584         if (m_body && impulse.length2() > (SIMD_EPSILON*SIMD_EPSILON))
585         {
586                 m_body->activate();
587                 if (m_body->isStaticObject())
588                 {
589                         m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
590                 }
591                 
592                 btVector3 pos(attachX,attachY,attachZ);
593
594                 m_body->applyImpulse(impulse,pos);
595         }
596
597 }
598 void            CcdPhysicsController::SetActive(bool active)
599 {
600 }
601                 // reading out information from physics
602 void            CcdPhysicsController::GetLinearVelocity(float& linvX,float& linvY,float& linvZ)
603 {
604         const btVector3& linvel = this->m_body->getLinearVelocity();
605         linvX = linvel.x();
606         linvY = linvel.y();
607         linvZ = linvel.z();
608
609 }
610
611 void            CcdPhysicsController::GetAngularVelocity(float& angVelX,float& angVelY,float& angVelZ)
612 {
613         const btVector3& angvel= m_body->getAngularVelocity();
614         angVelX = angvel.x();
615         angVelY = angvel.y();
616         angVelZ = angvel.z();
617 }
618
619 void            CcdPhysicsController::GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ)
620 {
621         btVector3 pos(posX,posY,posZ);
622         btVector3 rel_pos = pos-m_body->getCenterOfMassPosition();
623         btVector3 linvel = m_body->getVelocityInLocalPoint(rel_pos);
624         linvX = linvel.x();
625         linvY = linvel.y();
626         linvZ = linvel.z();
627 }
628 void            CcdPhysicsController::getReactionForce(float& forceX,float& forceY,float& forceZ)
629 {
630 }
631
632                 // dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted 
633 void            CcdPhysicsController::setRigidBody(bool rigid)
634 {
635         if (!rigid)
636         {
637                 //fake it for now
638                 btVector3 inertia = m_body->getInvInertiaDiagLocal();
639                 inertia[1] = 0.f;
640                 m_body->setInvInertiaDiagLocal(inertia);
641                 m_body->updateInertiaTensor();
642         }
643 }
644
645                 // clientinfo for raycasts for example
646 void*           CcdPhysicsController::getNewClientInfo()
647 {
648         return m_newClientInfo;
649 }
650 void            CcdPhysicsController::setNewClientInfo(void* clientinfo)
651 {
652         m_newClientInfo = clientinfo;
653 }
654
655
656 void    CcdPhysicsController::UpdateDeactivation(float timeStep)
657 {
658         m_body->updateDeactivation( timeStep);
659 }
660
661 bool CcdPhysicsController::wantsSleeping()
662 {
663
664         return m_body->wantsSleeping();
665 }
666
667 PHY_IPhysicsController* CcdPhysicsController::GetReplica()
668 {
669         // This is used only to replicate Near and Radar sensor controllers
670         // The replication of object physics controller is done in KX_BulletPhysicsController::GetReplica()
671         CcdConstructionInfo cinfo = m_cci;
672         if (m_shapeInfo)
673         {
674                 // This situation does not normally happen
675                 cinfo.m_collisionShape = m_shapeInfo->CreateBulletShape();
676         } 
677         else if (m_collisionShape)
678         {
679                 switch (m_collisionShape->getShapeType())
680                 {
681                 case SPHERE_SHAPE_PROXYTYPE:
682                         {
683                                 btSphereShape* orgShape = (btSphereShape*)m_collisionShape;
684                                 cinfo.m_collisionShape = new btSphereShape(*orgShape);
685                                 break;
686                         }
687
688                 case CONE_SHAPE_PROXYTYPE:
689                         {
690                                 btConeShape* orgShape = (btConeShape*)m_collisionShape;
691                                 cinfo.m_collisionShape = new btConeShape(*orgShape);
692                                 break;
693                         }
694
695                 default:
696                         {
697                                 return 0;
698                         }
699                 }
700         }
701
702         cinfo.m_MotionState = new DefaultMotionState();
703         cinfo.m_shapeInfo = m_shapeInfo;
704
705         CcdPhysicsController* replica = new CcdPhysicsController(cinfo);
706         return replica;
707 }
708
709 ///////////////////////////////////////////////////////////
710 ///A small utility class, DefaultMotionState
711 ///
712 ///////////////////////////////////////////////////////////
713
714 DefaultMotionState::DefaultMotionState()
715 {
716         m_worldTransform.setIdentity();
717         m_localScaling.setValue(1.f,1.f,1.f);
718 }
719
720
721 DefaultMotionState::~DefaultMotionState()
722 {
723
724 }
725
726 void    DefaultMotionState::getWorldPosition(float& posX,float& posY,float& posZ)
727 {
728         posX = m_worldTransform.getOrigin().x();
729         posY = m_worldTransform.getOrigin().y();
730         posZ = m_worldTransform.getOrigin().z();
731 }
732
733 void    DefaultMotionState::getWorldScaling(float& scaleX,float& scaleY,float& scaleZ)
734 {
735         scaleX = m_localScaling.getX();
736         scaleY = m_localScaling.getY();
737         scaleZ = m_localScaling.getZ();
738 }
739
740 void    DefaultMotionState::getWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal)
741 {
742         quatIma0 = m_worldTransform.getRotation().x();
743         quatIma1 = m_worldTransform.getRotation().y();
744         quatIma2 = m_worldTransform.getRotation().z();
745         quatReal = m_worldTransform.getRotation()[3];
746 }
747                 
748 void    DefaultMotionState::setWorldPosition(float posX,float posY,float posZ)
749 {
750         btPoint3 pos(posX,posY,posZ);
751         m_worldTransform.setOrigin( pos );
752 }
753
754 void    DefaultMotionState::setWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal)
755 {
756         btQuaternion orn(quatIma0,quatIma1,quatIma2,quatReal);
757         m_worldTransform.setRotation( orn );
758 }
759                 
760 void    DefaultMotionState::calculateWorldTransformations()
761 {
762
763 }
764
765 // Shape constructor
766 bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope)
767 {
768         // assume no shape information
769         m_shapeType = PHY_SHAPE_NONE;
770         m_vertexArray.clear();
771         m_polygonIndexArray.clear();
772         m_meshObject = NULL;
773
774         if (!meshobj)
775                 return false;
776
777         // Mesh has no polygons!
778         int numpolys = meshobj->NumPolygons();
779         if (!numpolys)
780         {
781                 return false;
782         }
783
784         // check that we have at least one colliding polygon
785         int numvalidpolys = 0;
786
787         for (int p=0; p<numpolys; p++)
788         {
789                 RAS_Polygon* poly = meshobj->GetPolygon(p);
790
791                 // only add polygons that have the collisionflag set
792                 if (poly->IsCollider())
793                 {
794                         numvalidpolys++;
795                         break;
796                 }
797         }
798
799         // No collision polygons
800         if (numvalidpolys < 1)
801                 return false;
802
803         m_shapeType = (polytope) ? PHY_SHAPE_POLYTOPE : PHY_SHAPE_MESH;
804
805         numvalidpolys = 0;
806
807         for (int p2=0; p2<numpolys; p2++)
808         {
809                 RAS_Polygon* poly = meshobj->GetPolygon(p2);
810
811                 // only add polygons that have the collisionflag set
812                 if (poly->IsCollider())
813                 {   
814                         //Bullet can raycast any shape, so
815                         if (polytope)
816                         {
817                                 for (int i=0;i<poly->VertexCount();i++)
818                                 {
819                                         const float* vtx = poly->GetVertex(i)->getXYZ();
820                                         btPoint3 point(vtx[0],vtx[1],vtx[2]);
821                                         m_vertexArray.push_back(point);
822                                         numvalidpolys++;
823                                 }
824                         } else
825                         {
826                                 {
827                                         const float* vtx = poly->GetVertex(2)->getXYZ();
828                                         btPoint3 vertex0(vtx[0],vtx[1],vtx[2]);
829
830                                         vtx = poly->GetVertex(1)->getXYZ();
831                                         btPoint3 vertex1(vtx[0],vtx[1],vtx[2]);
832
833                                         vtx = poly->GetVertex(0)->getXYZ();
834                                         btPoint3 vertex2(vtx[0],vtx[1],vtx[2]);
835
836                                         m_vertexArray.push_back(vertex0);
837                                         m_vertexArray.push_back(vertex1);
838                                         m_vertexArray.push_back(vertex2);
839                                         m_polygonIndexArray.push_back(p2);
840                                         numvalidpolys++;
841                                 }
842                                 if (poly->VertexCount() == 4)
843                                 {
844                                         const float* vtx = poly->GetVertex(3)->getXYZ();
845                                         btPoint3 vertex0(vtx[0],vtx[1],vtx[2]);
846
847                                         vtx = poly->GetVertex(2)->getXYZ();
848                                         btPoint3 vertex1(vtx[0],vtx[1],vtx[2]);
849
850                                         vtx = poly->GetVertex(0)->getXYZ();
851                                         btPoint3 vertex2(vtx[0],vtx[1],vtx[2]);
852
853                                         m_vertexArray.push_back(vertex0);
854                                         m_vertexArray.push_back(vertex1);
855                                         m_vertexArray.push_back(vertex2);
856                                         m_polygonIndexArray.push_back(p2);
857                                         numvalidpolys++;
858                                 }
859                         }               
860                 }
861         }
862
863         if (!numvalidpolys)
864         {
865                 // should not happen
866                 m_shapeType = PHY_SHAPE_NONE;
867                 return false;
868         }
869         m_meshObject = meshobj;
870         return true;
871 }
872
873 btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape()
874 {
875         btCollisionShape* collisionShape = 0;
876         btTriangleMeshShape* concaveShape = 0;
877         btTriangleMesh* collisionMeshData = 0;
878         btCompoundShape* compoundShape = 0;
879         CcdShapeConstructionInfo* nextShapeInfo;
880
881         switch (m_shapeType) 
882         {
883         case PHY_SHAPE_NONE:
884                 break;
885
886         case PHY_SHAPE_BOX:
887                 collisionShape = new btBoxShape(m_halfExtend);
888                 break;
889
890         case PHY_SHAPE_SPHERE:
891                 collisionShape = new btSphereShape(m_radius);
892                 break;
893
894         case PHY_SHAPE_CYLINDER:
895                 collisionShape = new btCylinderShapeZ(m_halfExtend);
896                 break;
897
898         case PHY_SHAPE_CONE:
899                 collisionShape = new btConeShapeZ(m_radius, m_height);
900                 break;
901
902         case PHY_SHAPE_POLYTOPE:
903                 collisionShape = new btConvexHullShape(&m_vertexArray.begin()->getX(), m_vertexArray.size());
904                 break;
905
906         case PHY_SHAPE_MESH:
907                 collisionMeshData = new btTriangleMesh();
908                 // m_vertexArray is necessarily a multiple of 3
909                 for (std::vector<btPoint3>::iterator it=m_vertexArray.begin(); it != m_vertexArray.end(); )
910                 {
911             collisionMeshData->addTriangle(*it++,*it++,*it++);
912                 }
913                 concaveShape = new btBvhTriangleMeshShape( collisionMeshData, true );
914                 concaveShape->recalcLocalAabb();
915                 collisionShape = concaveShape;
916                 break;
917
918         case PHY_SHAPE_COMPOUND:
919                 if (m_nextShape)
920                 {
921                         compoundShape = new btCompoundShape();
922                         for (nextShapeInfo=m_nextShape; nextShapeInfo; nextShapeInfo = nextShapeInfo->m_nextShape)
923                         {
924                                 collisionShape = nextShapeInfo->CreateBulletShape();
925                                 if (collisionShape)
926                                 {
927                                         compoundShape->addChildShape(nextShapeInfo->m_childTrans, collisionShape);
928                                 }
929                         }
930                         collisionShape = compoundShape;
931                 }
932         }
933         return collisionShape;
934 }
935
936 void CcdShapeConstructionInfo::AddShape(CcdShapeConstructionInfo* shapeInfo)
937 {
938         CcdShapeConstructionInfo* nextShape = this;
939         while (nextShape->m_nextShape != NULL)
940                 nextShape = nextShape->m_nextShape;
941         nextShape->m_nextShape = shapeInfo;
942 }
943
944 CcdShapeConstructionInfo::~CcdShapeConstructionInfo()
945 {
946         CcdShapeConstructionInfo* childShape = m_nextShape;
947
948         while (childShape)
949         {
950                 CcdShapeConstructionInfo* nextShape = childShape->m_nextShape;
951                 childShape->m_nextShape = NULL;
952                 childShape->Release();
953                 childShape = nextShape;
954         }
955         
956         m_vertexArray.clear();
957 }
958
959