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