![]() |
Blender V2.61 - r43446
|
00001 00004 //under visual studio the #define in KX_ConvertPhysicsObject.h is quicker for recompilation 00005 #include "KX_ConvertPhysicsObject.h" 00006 00007 #ifdef USE_BULLET 00008 00009 #include "KX_BulletPhysicsController.h" 00010 00011 #include "btBulletDynamicsCommon.h" 00012 #include "SG_Spatial.h" 00013 00014 #include "KX_GameObject.h" 00015 #include "KX_MotionState.h" 00016 #include "KX_ClientObjectInfo.h" 00017 00018 #include "PHY_IPhysicsEnvironment.h" 00019 #include "CcdPhysicsEnvironment.h" 00020 #include "BulletSoftBody/btSoftBody.h" 00021 00022 00023 KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool sensor, bool compound) 00024 : KX_IPhysicsController(dyna,sensor,compound,(PHY_IPhysicsController*)this), 00025 CcdPhysicsController(ci), 00026 m_savedCollisionFlags(0), 00027 m_savedCollisionFilterGroup(0), 00028 m_savedCollisionFilterMask(0), 00029 m_savedMass(0.0), 00030 m_savedDyna(false), 00031 m_suspended(false), 00032 m_bulletChildShape(NULL) 00033 { 00034 } 00035 00036 KX_BulletPhysicsController::~KX_BulletPhysicsController () 00037 { 00038 // The game object has a direct link to 00039 if (m_pObject) 00040 { 00041 // If we cheat in SetObject, we must also cheat here otherwise the 00042 // object will still things it has a physical controller 00043 // Note that it requires that m_pObject is reset in case the object is deleted 00044 // before the controller (usual case, see KX_Scene::RemoveNodeDestructObjec) 00045 // The non usual case is when the object is not deleted because its reference is hanging 00046 // in a AddObject actuator but the node is deleted. This case is covered here. 00047 KX_GameObject* gameobj = (KX_GameObject*) m_pObject->GetSGClientObject(); 00048 gameobj->SetPhysicsController(NULL,false); 00049 } 00050 } 00051 00052 void KX_BulletPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) 00053 { 00054 CcdPhysicsController::resolveCombinedVelocities(linvelX,linvelY,linvelZ,angVelX,angVelY,angVelZ); 00055 00056 } 00057 00058 00060 // KX_IPhysicsController interface 00062 00063 void KX_BulletPhysicsController::applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse) 00064 { 00065 CcdPhysicsController::applyImpulse(attach[0],attach[1],attach[2],impulse[0],impulse[1],impulse[2]); 00066 00067 } 00068 00069 float KX_BulletPhysicsController::GetLinVelocityMin() 00070 { 00071 return (float)CcdPhysicsController::GetLinVelocityMin(); 00072 } 00073 void KX_BulletPhysicsController::SetLinVelocityMin(float val) 00074 { 00075 CcdPhysicsController::SetLinVelocityMin(val); 00076 } 00077 00078 float KX_BulletPhysicsController::GetLinVelocityMax() 00079 { 00080 return (float)CcdPhysicsController::GetLinVelocityMax(); 00081 } 00082 void KX_BulletPhysicsController::SetLinVelocityMax(float val) 00083 { 00084 CcdPhysicsController::SetLinVelocityMax(val); 00085 } 00086 00087 void KX_BulletPhysicsController::SetObject (SG_IObject* object) 00088 { 00089 SG_Controller::SetObject(object); 00090 00091 // cheating here... 00092 //should not be necessary, is it for duplicates ? 00093 00094 KX_GameObject* gameobj = (KX_GameObject*) object->GetSGClientObject(); 00095 gameobj->SetPhysicsController(this,gameobj->IsDynamic()); 00096 CcdPhysicsController::setNewClientInfo(gameobj->getClientInfo()); 00097 00098 if (m_bSensor) 00099 { 00100 // use a different callback function for sensor object, 00101 // bullet will not synchronize, we must do it explicitly 00102 SG_Callbacks& callbacks = gameobj->GetSGNode()->GetCallBackFunctions(); 00103 callbacks.m_updatefunc = KX_GameObject::SynchronizeTransformFunc; 00104 } 00105 } 00106 00107 MT_Scalar KX_BulletPhysicsController::GetRadius() 00108 { 00109 return MT_Scalar(CcdPhysicsController::GetRadius()); 00110 } 00111 00112 void KX_BulletPhysicsController::setMargin (float collisionMargin) 00113 { 00114 CcdPhysicsController::SetMargin(collisionMargin); 00115 } 00116 void KX_BulletPhysicsController::RelativeTranslate(const MT_Vector3& dloc,bool local) 00117 { 00118 CcdPhysicsController::RelativeTranslate(dloc[0],dloc[1],dloc[2],local); 00119 00120 } 00121 00122 void KX_BulletPhysicsController::RelativeRotate(const MT_Matrix3x3& drot,bool local) 00123 { 00124 float rotval[12]; 00125 drot.getValue(rotval); 00126 CcdPhysicsController::RelativeRotate(rotval,local); 00127 } 00128 00129 void KX_BulletPhysicsController::ApplyTorque(const MT_Vector3& torque,bool local) 00130 { 00131 CcdPhysicsController::ApplyTorque(torque.x(),torque.y(),torque.z(),local); 00132 } 00133 void KX_BulletPhysicsController::ApplyForce(const MT_Vector3& force,bool local) 00134 { 00135 CcdPhysicsController::ApplyForce(force.x(),force.y(),force.z(),local); 00136 } 00137 MT_Vector3 KX_BulletPhysicsController::GetLinearVelocity() 00138 { 00139 float angVel[3]; 00140 //CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]); 00141 CcdPhysicsController::GetLinearVelocity(angVel[0],angVel[1],angVel[2]);//rcruiz 00142 return MT_Vector3(angVel[0],angVel[1],angVel[2]); 00143 } 00144 MT_Vector3 KX_BulletPhysicsController::GetAngularVelocity() 00145 { 00146 float angVel[3]; 00147 //CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]); 00148 CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]);//rcruiz 00149 return MT_Vector3(angVel[0],angVel[1],angVel[2]); 00150 } 00151 MT_Vector3 KX_BulletPhysicsController::GetVelocity(const MT_Point3& pos) 00152 { 00153 float linVel[3]; 00154 CcdPhysicsController::GetVelocity(pos[0], pos[1], pos[2], linVel[0],linVel[1],linVel[2]); 00155 return MT_Vector3(linVel[0],linVel[1],linVel[2]); 00156 } 00157 00158 void KX_BulletPhysicsController::SetAngularVelocity(const MT_Vector3& ang_vel,bool local) 00159 { 00160 CcdPhysicsController::SetAngularVelocity(ang_vel.x(),ang_vel.y(),ang_vel.z(),local); 00161 00162 } 00163 void KX_BulletPhysicsController::SetLinearVelocity(const MT_Vector3& lin_vel,bool local) 00164 { 00165 CcdPhysicsController::SetLinearVelocity(lin_vel.x(),lin_vel.y(),lin_vel.z(),local); 00166 } 00167 void KX_BulletPhysicsController::getOrientation(MT_Quaternion& orn) 00168 { 00169 float myorn[4]; 00170 CcdPhysicsController::getOrientation(myorn[0],myorn[1],myorn[2],myorn[3]); 00171 orn = MT_Quaternion(myorn[0],myorn[1],myorn[2],myorn[3]); 00172 } 00173 void KX_BulletPhysicsController::setOrientation(const MT_Matrix3x3& orn) 00174 { 00175 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]); 00176 CcdPhysicsController::setWorldOrientation(btmat); 00177 } 00178 void KX_BulletPhysicsController::setPosition(const MT_Point3& pos) 00179 { 00180 CcdPhysicsController::setPosition(pos.x(),pos.y(),pos.z()); 00181 } 00182 void KX_BulletPhysicsController::setScaling(const MT_Vector3& scaling) 00183 { 00184 CcdPhysicsController::setScaling(scaling.x(),scaling.y(),scaling.z()); 00185 } 00186 void KX_BulletPhysicsController::SetTransform() 00187 { 00188 btVector3 pos; 00189 btVector3 scale; 00190 float ori[12]; 00191 m_MotionState->getWorldPosition(pos.m_floats[0],pos.m_floats[1],pos.m_floats[2]); 00192 m_MotionState->getWorldScaling(scale.m_floats[0],scale.m_floats[1],scale.m_floats[2]); 00193 m_MotionState->getWorldOrientation(ori); 00194 btMatrix3x3 rot(ori[0], ori[4], ori[8], 00195 ori[1], ori[5], ori[9], 00196 ori[2], ori[6], ori[10]); 00197 CcdPhysicsController::forceWorldTransform(rot, pos); 00198 } 00199 00200 MT_Scalar KX_BulletPhysicsController::GetMass() 00201 { 00202 if (GetSoftBody()) 00203 return GetSoftBody()->getTotalMass(); 00204 00205 MT_Scalar invmass = 0.f; 00206 if (GetRigidBody()) 00207 invmass = GetRigidBody()->getInvMass(); 00208 if (invmass) 00209 return 1.f/invmass; 00210 return 0.f; 00211 00212 } 00213 00214 MT_Vector3 KX_BulletPhysicsController::GetLocalInertia() 00215 { 00216 MT_Vector3 inertia(0.f, 0.f, 0.f); 00217 btVector3 inv_inertia; 00218 if (GetRigidBody()) { 00219 inv_inertia = GetRigidBody()->getInvInertiaDiagLocal(); 00220 if (!btFuzzyZero(inv_inertia.getX()) && 00221 !btFuzzyZero(inv_inertia.getY()) && 00222 !btFuzzyZero(inv_inertia.getZ())) 00223 inertia = MT_Vector3(1.f/inv_inertia.getX(), 1.f/inv_inertia.getY(), 1.f/inv_inertia.getZ()); 00224 } 00225 return inertia; 00226 } 00227 00228 MT_Vector3 KX_BulletPhysicsController::getReactionForce() 00229 { 00230 assert(0); 00231 return MT_Vector3(0.f,0.f,0.f); 00232 } 00233 void KX_BulletPhysicsController::setRigidBody(bool rigid) 00234 { 00235 } 00236 00237 /* This function dynamically adds the collision shape of another controller to 00238 the current controller shape provided it is a compound shape. 00239 The idea is that dynamic parenting on a compound object will dynamically extend the shape 00240 */ 00241 void KX_BulletPhysicsController::AddCompoundChild(KX_IPhysicsController* child) 00242 { 00243 if (child == NULL || !IsCompound()) 00244 return; 00245 // other controller must be a bullet controller too 00246 // verify that body and shape exist and match 00247 KX_BulletPhysicsController* childCtrl = dynamic_cast<KX_BulletPhysicsController*>(child); 00248 btRigidBody* rootBody = GetRigidBody(); 00249 btRigidBody* childBody = childCtrl->GetRigidBody(); 00250 if (!rootBody || !childBody) 00251 return; 00252 const btCollisionShape* rootShape = rootBody->getCollisionShape(); 00253 const btCollisionShape* childShape = childBody->getCollisionShape(); 00254 if (!rootShape || 00255 !childShape || 00256 rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE || 00257 childShape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) 00258 return; 00259 btCompoundShape* compoundShape = (btCompoundShape*)rootShape; 00260 // compute relative transformation between parent and child 00261 btTransform rootTrans; 00262 btTransform childTrans; 00263 rootBody->getMotionState()->getWorldTransform(rootTrans); 00264 childBody->getMotionState()->getWorldTransform(childTrans); 00265 btVector3 rootScale = rootShape->getLocalScaling(); 00266 rootScale[0] = 1.0/rootScale[0]; 00267 rootScale[1] = 1.0/rootScale[1]; 00268 rootScale[2] = 1.0/rootScale[2]; 00269 // relative scale = child_scale/parent_scale 00270 btVector3 relativeScale = childShape->getLocalScaling()*rootScale; 00271 btMatrix3x3 rootRotInverse = rootTrans.getBasis().transpose(); 00272 // relative pos = parent_rot^-1 * ((parent_pos-child_pos)/parent_scale) 00273 btVector3 relativePos = rootRotInverse*((childTrans.getOrigin()-rootTrans.getOrigin())*rootScale); 00274 // relative rot = parent_rot^-1 * child_rot 00275 btMatrix3x3 relativeRot = rootRotInverse*childTrans.getBasis(); 00276 // create a proxy shape info to store the transformation 00277 CcdShapeConstructionInfo* proxyShapeInfo = new CcdShapeConstructionInfo(); 00278 // store the transformation to this object shapeinfo 00279 proxyShapeInfo->m_childTrans.setOrigin(relativePos); 00280 proxyShapeInfo->m_childTrans.setBasis(relativeRot); 00281 proxyShapeInfo->m_childScale.setValue(relativeScale[0], relativeScale[1], relativeScale[2]); 00282 // we will need this to make sure that we remove the right proxy later when unparenting 00283 proxyShapeInfo->m_userData = childCtrl; 00284 proxyShapeInfo->SetProxy(childCtrl->GetShapeInfo()->AddRef()); 00285 // add to parent compound shapeinfo (increments ref count) 00286 GetShapeInfo()->AddShape(proxyShapeInfo); 00287 // create new bullet collision shape from the object shapeinfo and set scaling 00288 btCollisionShape* newChildShape = proxyShapeInfo->CreateBulletShape(childCtrl->GetMargin(), childCtrl->getConstructionInfo().m_bGimpact, true); 00289 newChildShape->setLocalScaling(relativeScale); 00290 // add bullet collision shape to parent compound collision shape 00291 compoundShape->addChildShape(proxyShapeInfo->m_childTrans,newChildShape); 00292 // proxyShapeInfo is not needed anymore, release it 00293 proxyShapeInfo->Release(); 00294 // remember we created this shape 00295 childCtrl->m_bulletChildShape = newChildShape; 00296 // recompute inertia of parent 00297 if (!rootBody->isStaticOrKinematicObject()) 00298 { 00299 btVector3 localInertia; 00300 float mass = 1.f/rootBody->getInvMass(); 00301 compoundShape->calculateLocalInertia(mass,localInertia); 00302 rootBody->setMassProps(mass,localInertia); 00303 } 00304 // must update the broadphase cache, 00305 GetPhysicsEnvironment()->refreshCcdPhysicsController(this); 00306 // remove the children 00307 GetPhysicsEnvironment()->disableCcdPhysicsController(childCtrl); 00308 } 00309 00310 /* Reverse function of the above, it will remove a shape from a compound shape 00311 provided that the former was added to the later using AddCompoundChild() 00312 */ 00313 void KX_BulletPhysicsController::RemoveCompoundChild(KX_IPhysicsController* child) 00314 { 00315 if (child == NULL || !IsCompound()) 00316 return; 00317 // other controller must be a bullet controller too 00318 // verify that body and shape exist and match 00319 KX_BulletPhysicsController* childCtrl = dynamic_cast<KX_BulletPhysicsController*>(child); 00320 btRigidBody* rootBody = GetRigidBody(); 00321 btRigidBody* childBody = childCtrl->GetRigidBody(); 00322 if (!rootBody || !childBody) 00323 return; 00324 const btCollisionShape* rootShape = rootBody->getCollisionShape(); 00325 if (!rootShape || 00326 rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE) 00327 return; 00328 btCompoundShape* compoundShape = (btCompoundShape*)rootShape; 00329 // retrieve the shapeInfo 00330 CcdShapeConstructionInfo* childShapeInfo = childCtrl->GetShapeInfo(); 00331 CcdShapeConstructionInfo* rootShapeInfo = GetShapeInfo(); 00332 // and verify that the child is part of the parent 00333 int i = rootShapeInfo->FindChildShape(childShapeInfo, childCtrl); 00334 if (i < 0) 00335 return; 00336 rootShapeInfo->RemoveChildShape(i); 00337 if (childCtrl->m_bulletChildShape) 00338 { 00339 int numChildren = compoundShape->getNumChildShapes(); 00340 for (i=0; i<numChildren; i++) 00341 { 00342 if (compoundShape->getChildShape(i) == childCtrl->m_bulletChildShape) 00343 { 00344 compoundShape->removeChildShapeByIndex(i); 00345 compoundShape->recalculateLocalAabb(); 00346 break; 00347 } 00348 } 00349 delete childCtrl->m_bulletChildShape; 00350 childCtrl->m_bulletChildShape = NULL; 00351 } 00352 // recompute inertia of parent 00353 if (!rootBody->isStaticOrKinematicObject()) 00354 { 00355 btVector3 localInertia; 00356 float mass = 1.f/rootBody->getInvMass(); 00357 compoundShape->calculateLocalInertia(mass,localInertia); 00358 rootBody->setMassProps(mass,localInertia); 00359 } 00360 // must update the broadphase cache, 00361 GetPhysicsEnvironment()->refreshCcdPhysicsController(this); 00362 // reactivate the children 00363 GetPhysicsEnvironment()->enableCcdPhysicsController(childCtrl); 00364 } 00365 00366 void KX_BulletPhysicsController::SetMass(MT_Scalar newmass) 00367 { 00368 btRigidBody *body = GetRigidBody(); 00369 if (body && !m_suspended && newmass>MT_EPSILON && GetMass()>MT_EPSILON) 00370 { 00371 btVector3 grav = body->getGravity(); 00372 btVector3 accel = grav / GetMass(); 00373 00374 btBroadphaseProxy* handle = body->getBroadphaseHandle(); 00375 GetPhysicsEnvironment()->updateCcdPhysicsController(this, 00376 newmass, 00377 body->getCollisionFlags(), 00378 handle->m_collisionFilterGroup, 00379 handle->m_collisionFilterMask); 00380 body->setGravity(accel); 00381 } 00382 } 00383 00384 void KX_BulletPhysicsController::SuspendDynamics(bool ghost) 00385 { 00386 btRigidBody *body = GetRigidBody(); 00387 if (body && !m_suspended && !IsSensor()) 00388 { 00389 btBroadphaseProxy* handle = body->getBroadphaseHandle(); 00390 m_savedCollisionFlags = body->getCollisionFlags(); 00391 m_savedMass = GetMass(); 00392 m_savedDyna = m_bDyna; 00393 m_savedCollisionFilterGroup = handle->m_collisionFilterGroup; 00394 m_savedCollisionFilterMask = handle->m_collisionFilterMask; 00395 m_suspended = true; 00396 GetPhysicsEnvironment()->updateCcdPhysicsController(this, 00397 0.0, 00398 btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)), 00399 btBroadphaseProxy::StaticFilter, 00400 btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); 00401 m_bDyna = false; 00402 } 00403 } 00404 00405 void KX_BulletPhysicsController::RestoreDynamics() 00406 { 00407 btRigidBody *body = GetRigidBody(); 00408 if (body && m_suspended) 00409 { 00410 // before make sure any position change that was done in this logic frame are accounted for 00411 SetTransform(); 00412 GetPhysicsEnvironment()->updateCcdPhysicsController(this, 00413 m_savedMass, 00414 m_savedCollisionFlags, 00415 m_savedCollisionFilterGroup, 00416 m_savedCollisionFilterMask); 00417 body->activate(); 00418 m_bDyna = m_savedDyna; 00419 m_suspended = false; 00420 } 00421 } 00422 00423 SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode) 00424 { 00425 PHY_IMotionState* motionstate = new KX_MotionState(destnode); 00426 00427 KX_BulletPhysicsController* physicsreplica = new KX_BulletPhysicsController(*this); 00428 00429 //parentcontroller is here be able to avoid collisions between parent/child 00430 00431 PHY_IPhysicsController* parentctrl = NULL; 00432 KX_BulletPhysicsController* parentKxCtrl = NULL; 00433 CcdPhysicsController* ccdParent = NULL; 00434 00435 00436 if (destnode != destnode->GetRootSGParent()) 00437 { 00438 KX_GameObject* clientgameobj = (KX_GameObject*) destnode->GetRootSGParent()->GetSGClientObject(); 00439 if (clientgameobj) 00440 { 00441 parentctrl = (KX_BulletPhysicsController*)clientgameobj->GetPhysicsController(); 00442 } else 00443 { 00444 // it could be a false node, try the children 00445 NodeList::const_iterator childit; 00446 for ( 00447 childit = destnode->GetSGChildren().begin(); 00448 childit!= destnode->GetSGChildren().end(); 00449 ++childit 00450 ) { 00451 KX_GameObject *clientgameobj_child = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject()); 00452 if (clientgameobj_child) 00453 { 00454 parentKxCtrl = (KX_BulletPhysicsController*)clientgameobj_child->GetPhysicsController(); 00455 parentctrl = parentKxCtrl; 00456 ccdParent = parentKxCtrl; 00457 } 00458 } 00459 } 00460 } 00461 00462 physicsreplica->setParentCtrl(ccdParent); 00463 physicsreplica->PostProcessReplica(motionstate,parentctrl); 00464 physicsreplica->m_userdata = (PHY_IPhysicsController*)physicsreplica; 00465 physicsreplica->m_bulletChildShape = NULL; 00466 return physicsreplica; 00467 00468 } 00469 00470 00471 00472 void KX_BulletPhysicsController::SetSumoTransform(bool nondynaonly) 00473 { 00474 00475 if (!m_bDyna && !m_bSensor) 00476 { 00477 btCollisionObject* object = GetRigidBody(); 00478 object->setActivationState(ACTIVE_TAG); 00479 object->setCollisionFlags(object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); 00480 } else 00481 { 00482 if (!nondynaonly) 00483 { 00484 /* 00485 btTransform worldTrans; 00486 if (GetRigidBody()) 00487 { 00488 GetRigidBody()->getMotionState()->getWorldTransform(worldTrans); 00489 GetRigidBody()->setCenterOfMassTransform(worldTrans); 00490 } 00491 */ 00492 /* 00493 scaling? 00494 if (m_bDyna) 00495 { 00496 m_sumoObj->setScaling(MT_Vector3(1,1,1)); 00497 } else 00498 { 00499 MT_Vector3 scale; 00500 GetWorldScaling(scale); 00501 m_sumoObj->setScaling(scale); 00502 } 00503 */ 00504 00505 } 00506 } 00507 } 00508 00509 // todo: remove next line ! 00510 void KX_BulletPhysicsController::SetSimulatedTime(double time) 00511 { 00512 } 00513 00514 // call from scene graph to update 00515 bool KX_BulletPhysicsController::Update(double time) 00516 { 00517 return false; 00518 00519 // todo: check this code 00520 //if (GetMass()) 00521 //{ 00522 // return false;//true; 00523 // } 00524 // return false; 00525 } 00526 00527 00528 const char* KX_BulletPhysicsController::getName() 00529 { 00530 if (m_pObject) 00531 { 00532 KX_GameObject* gameobj = (KX_GameObject*) m_pObject->GetSGClientObject(); 00533 return gameobj->GetName(); 00534 } 00535 return 0; 00536 } 00537 00538 #endif // USE_BULLET