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