BGE bug #17731 fixed: No sleeping Button disables dynamics of an object if it's paren...
[blender.git] / source / gameengine / Ketsji / KX_BulletPhysicsController.cpp
1 //under visual studio the #define in KX_ConvertPhysicsObject.h is quicker for recompilation
2 #include "KX_ConvertPhysicsObject.h"
3
4 #ifdef USE_BULLET
5
6 #include "KX_BulletPhysicsController.h"
7
8 #include "btBulletDynamicsCommon.h"
9 #include "SG_Spatial.h"
10
11 #include "KX_GameObject.h"
12 #include "KX_MotionState.h"
13 #include "KX_ClientObjectInfo.h"
14
15 #include "PHY_IPhysicsEnvironment.h"
16 #include "CcdPhysicsEnvironment.h"
17 #include "BulletSoftBody/btSoftBody.h"
18
19
20 KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna)
21 : KX_IPhysicsController(dyna,(PHY_IPhysicsController*)this),
22 CcdPhysicsController(ci),
23 m_savedCollisionFlags(0)
24 {
25
26 }
27         
28 KX_BulletPhysicsController::~KX_BulletPhysicsController ()
29 {
30         // The game object has a direct link to 
31         if (m_pObject)
32         {
33                 // If we cheat in SetObject, we must also cheat here otherwise the 
34                 // object will still things it has a physical controller
35                 // Note that it requires that m_pObject is reset in case the object is deleted
36                 // before the controller (usual case, see KX_Scene::RemoveNodeDestructObjec)
37                 // The non usual case is when the object is not deleted because its reference is hanging
38                 // in a AddObject actuator but the node is deleted. This case is covered here.
39                 KX_GameObject* gameobj = (KX_GameObject*)       m_pObject->GetSGClientObject();
40                 gameobj->SetPhysicsController(NULL,false);
41         }
42 }
43
44 void    KX_BulletPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ)
45 {
46         CcdPhysicsController::resolveCombinedVelocities(linvelX,linvelY,linvelZ,angVelX,angVelY,angVelZ);
47
48 }
49
50
51         ///////////////////////////////////
52         //      KX_IPhysicsController interface
53         ////////////////////////////////////
54
55 void    KX_BulletPhysicsController::applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse)
56 {
57                 CcdPhysicsController::applyImpulse(attach[0],attach[1],attach[2],impulse[0],impulse[1],impulse[2]);
58
59 }
60
61 void    KX_BulletPhysicsController::SetObject (SG_IObject* object)
62 {
63         SG_Controller::SetObject(object);
64
65         // cheating here...
66         //should not be necessary, is it for duplicates ?
67
68         KX_GameObject* gameobj = (KX_GameObject*)       object->GetSGClientObject();
69         gameobj->SetPhysicsController(this,gameobj->IsDynamic());
70         CcdPhysicsController::setNewClientInfo(gameobj->getClientInfo());
71
72
73 }
74
75
76 void    KX_BulletPhysicsController::setMargin (float collisionMargin)
77 {
78         CcdPhysicsController::SetMargin(collisionMargin);
79 }
80 void    KX_BulletPhysicsController::RelativeTranslate(const MT_Vector3& dloc,bool local)
81 {
82         CcdPhysicsController::RelativeTranslate(dloc[0],dloc[1],dloc[2],local);
83
84 }
85
86 void    KX_BulletPhysicsController::RelativeRotate(const MT_Matrix3x3& drot,bool local)
87 {
88         float   rotval[12];
89         drot.getValue(rotval);
90         CcdPhysicsController::RelativeRotate(rotval,local);
91 }
92
93 void    KX_BulletPhysicsController::ApplyTorque(const MT_Vector3& torque,bool local)
94 {
95                 CcdPhysicsController::ApplyTorque(torque.x(),torque.y(),torque.z(),local);
96 }
97 void    KX_BulletPhysicsController::ApplyForce(const MT_Vector3& force,bool local)
98 {
99         CcdPhysicsController::ApplyForce(force.x(),force.y(),force.z(),local);
100 }
101 MT_Vector3 KX_BulletPhysicsController::GetLinearVelocity()
102 {
103         float angVel[3];
104         //CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]);
105         CcdPhysicsController::GetLinearVelocity(angVel[0],angVel[1],angVel[2]);//rcruiz
106         return MT_Vector3(angVel[0],angVel[1],angVel[2]);
107 }
108 MT_Vector3 KX_BulletPhysicsController::GetAngularVelocity()
109 {
110         float angVel[3];
111         //CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]);
112         CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]);//rcruiz
113         return MT_Vector3(angVel[0],angVel[1],angVel[2]);
114 }
115 MT_Vector3 KX_BulletPhysicsController::GetVelocity(const MT_Point3& pos)
116 {
117         float linVel[3];
118         CcdPhysicsController::GetVelocity(pos[0], pos[1], pos[2], linVel[0],linVel[1],linVel[2]);
119         return MT_Vector3(linVel[0],linVel[1],linVel[2]);
120 }
121
122 void    KX_BulletPhysicsController::SetAngularVelocity(const MT_Vector3& ang_vel,bool local)
123 {
124         CcdPhysicsController::SetAngularVelocity(ang_vel.x(),ang_vel.y(),ang_vel.z(),local);
125
126 }
127 void    KX_BulletPhysicsController::SetLinearVelocity(const MT_Vector3& lin_vel,bool local)
128 {
129         CcdPhysicsController::SetLinearVelocity(lin_vel.x(),lin_vel.y(),lin_vel.z(),local);
130 }
131 void    KX_BulletPhysicsController::getOrientation(MT_Quaternion& orn)
132 {
133         float myorn[4];
134         CcdPhysicsController::getOrientation(myorn[0],myorn[1],myorn[2],myorn[3]);
135         orn = MT_Quaternion(myorn[0],myorn[1],myorn[2],myorn[3]);
136 }
137 void KX_BulletPhysicsController::setOrientation(const MT_Matrix3x3& orn)
138 {
139         btMatrix3x3 btmat(orn[0][0], orn[0][1], orn[0][2], orn[1][0], orn[1][1], orn[1][2], orn[2][0], orn[2][1], orn[2][2]);
140         CcdPhysicsController::setWorldOrientation(btmat);
141 }
142 void KX_BulletPhysicsController::setPosition(const MT_Point3& pos)
143 {
144         CcdPhysicsController::setPosition(pos.x(),pos.y(),pos.z());
145 }
146 void KX_BulletPhysicsController::setScaling(const MT_Vector3& scaling)
147 {
148         CcdPhysicsController::setScaling(scaling.x(),scaling.y(),scaling.z());
149 }
150 MT_Scalar       KX_BulletPhysicsController::GetMass()
151 {
152         if (GetSoftBody())
153                 return GetSoftBody()->getTotalMass();
154         
155         MT_Scalar invmass = 0.f;
156         if (GetRigidBody())
157                 invmass = GetRigidBody()->getInvMass();
158         if (invmass)
159                 return 1.f/invmass;
160         return 0.f;
161
162 }
163
164 MT_Scalar KX_BulletPhysicsController::GetRadius()
165 {
166         return MT_Scalar(CcdPhysicsController::GetRadius());
167 }
168
169 MT_Vector3      KX_BulletPhysicsController::getReactionForce()
170 {
171         assert(0);
172         return MT_Vector3(0.f,0.f,0.f);
173 }
174 void    KX_BulletPhysicsController::setRigidBody(bool rigid)
175 {
176 }
177
178 void    KX_BulletPhysicsController::SuspendDynamics(bool ghost)
179 {
180         btRigidBody *body = GetRigidBody();
181         if (body && body->getActivationState() != DISABLE_SIMULATION)
182         {
183                 btBroadphaseProxy* handle = body->getBroadphaseHandle();
184                 m_savedCollisionFlags = body->getCollisionFlags();
185                 m_savedMass = GetMass();
186                 m_savedCollisionFilterGroup = handle->m_collisionFilterGroup;
187                 m_savedCollisionFilterMask = handle->m_collisionFilterMask;
188                 m_savedActivationState = body->getActivationState();
189                 body->forceActivationState(DISABLE_SIMULATION);
190                 GetPhysicsEnvironment()->updateCcdPhysicsController(this, 
191                         0.0,
192                         btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)),
193                         btBroadphaseProxy::StaticFilter, 
194                         btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
195         }
196 }
197
198 void    KX_BulletPhysicsController::RestoreDynamics()
199 {
200         btRigidBody *body = GetRigidBody();
201         if (body && body->getActivationState() == DISABLE_SIMULATION)
202         {
203                 GetPhysicsEnvironment()->updateCcdPhysicsController(this, 
204                         m_savedMass,
205                         m_savedCollisionFlags,
206                         m_savedCollisionFilterGroup,
207                         m_savedCollisionFilterMask);
208                 GetRigidBody()->forceActivationState(m_savedActivationState);
209         }
210 }
211
212 SG_Controller*  KX_BulletPhysicsController::GetReplica(class SG_Node* destnode)
213 {
214         PHY_IMotionState* motionstate = new KX_MotionState(destnode);
215
216         KX_BulletPhysicsController* physicsreplica = new KX_BulletPhysicsController(*this);
217
218         //parentcontroller is here be able to avoid collisions between parent/child
219
220         PHY_IPhysicsController* parentctrl = NULL;
221         KX_BulletPhysicsController* parentKxCtrl = NULL;
222         CcdPhysicsController* ccdParent = NULL;
223
224         
225         if (destnode != destnode->GetRootSGParent())
226         {
227                 KX_GameObject* clientgameobj = (KX_GameObject*) destnode->GetRootSGParent()->GetSGClientObject();
228                 if (clientgameobj)
229                 {
230                         parentctrl = (KX_BulletPhysicsController*)clientgameobj->GetPhysicsController();
231                 } else
232                 {
233                         // it could be a false node, try the children
234                         NodeList::const_iterator childit;
235                         for (
236                                 childit = destnode->GetSGChildren().begin();
237                         childit!= destnode->GetSGChildren().end();
238                         ++childit
239                                 ) {
240                                 KX_GameObject *clientgameobj = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject());
241                                 if (clientgameobj)
242                                 {
243                                         parentKxCtrl = (KX_BulletPhysicsController*)clientgameobj->GetPhysicsController();
244                                         parentctrl = parentKxCtrl;
245                                         ccdParent = parentKxCtrl;
246                                 }
247                         }
248                 }
249         }
250
251         physicsreplica->setParentCtrl(ccdParent);
252         physicsreplica->PostProcessReplica(motionstate,parentctrl);
253         physicsreplica->m_userdata = (PHY_IPhysicsController*)physicsreplica;
254         return physicsreplica;
255         
256 }
257
258
259
260 void    KX_BulletPhysicsController::SetSumoTransform(bool nondynaonly)
261 {
262         if (GetRigidBody())
263                 GetRigidBody()->activate(true);
264
265         if (!m_bDyna)
266         {
267                 GetCollisionObject()->setCollisionFlags(GetRigidBody()->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
268         } else
269         {
270                 if (!nondynaonly)
271                 {
272                         btTransform worldTrans;
273                         if (GetRigidBody())
274                         {
275                                 GetRigidBody()->getMotionState()->getWorldTransform(worldTrans);
276                                 GetRigidBody()->setCenterOfMassTransform(worldTrans);
277                         }
278                         
279                         /*
280                         scaling?
281                         if (m_bDyna)
282                         {
283                                 m_sumoObj->setScaling(MT_Vector3(1,1,1));
284                         } else
285                         {
286                                 MT_Vector3 scale;
287                                 GetWorldScaling(scale);
288                                 m_sumoObj->setScaling(scale);
289                         }
290                         */
291
292                 }
293         }
294 }
295
296 // todo: remove next line !
297 void    KX_BulletPhysicsController::SetSimulatedTime(double time)
298 {
299 }
300         
301 // call from scene graph to update
302 bool KX_BulletPhysicsController::Update(double time)
303 {
304         return false;
305
306         // todo: check this code
307         //if (GetMass())
308         //{
309         //      return false;//true;
310 //      }
311 //      return false;
312 }
313
314 #endif //#ifdef USE_BULLET