diff options
Diffstat (limited to 'source/gameengine/Ketsji/KX_BulletPhysicsController.cpp')
-rw-r--r-- | source/gameengine/Ketsji/KX_BulletPhysicsController.cpp | 577 |
1 files changed, 0 insertions, 577 deletions
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp deleted file mode 100644 index e990974a646..00000000000 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ /dev/null @@ -1,577 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file gameengine/Ketsji/KX_BulletPhysicsController.cpp - * \ingroup ketsji - */ - -//under visual studio the #define in KX_ConvertPhysicsObject.h is quicker for recompilation -#include "KX_ConvertPhysicsObject.h" - -#ifdef WITH_BULLET - -#include "KX_BulletPhysicsController.h" - -#include "btBulletDynamicsCommon.h" -#include "SG_Spatial.h" - -#include "KX_GameObject.h" -#include "KX_MotionState.h" -#include "KX_ClientObjectInfo.h" - -#include "PHY_IPhysicsEnvironment.h" -#include "CcdPhysicsEnvironment.h" -#include "BulletSoftBody/btSoftBody.h" - - -KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool sensor, bool character, bool compound) -: KX_IPhysicsController(dyna,sensor,character,compound,(PHY_IPhysicsController*)this), -CcdPhysicsController(ci), -m_savedCollisionFlags(0), -m_savedCollisionFilterGroup(0), -m_savedCollisionFilterMask(0), -m_savedMass(0.0), -m_savedDyna(false), -m_suspended(false), -m_bulletChildShape(NULL) -{ -} - -KX_BulletPhysicsController::~KX_BulletPhysicsController () -{ - // The game object has a direct link to - if (m_pObject) - { - // If we cheat in SetObject, we must also cheat here otherwise the - // object will still things it has a physical controller - // Note that it requires that m_pObject is reset in case the object is deleted - // before the controller (usual case, see KX_Scene::RemoveNodeDestructObjec) - // The non usual case is when the object is not deleted because its reference is hanging - // in a AddObject actuator but the node is deleted. This case is covered here. - KX_GameObject* gameobj = (KX_GameObject*) m_pObject->GetSGClientObject(); - gameobj->SetPhysicsController(NULL,false); - } -} - -void KX_BulletPhysicsController::resolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) -{ - CcdPhysicsController::resolveCombinedVelocities(linvelX,linvelY,linvelZ,angVelX,angVelY,angVelZ); - -} - - - /////////////////////////////////// - // KX_IPhysicsController interface - //////////////////////////////////// - -void KX_BulletPhysicsController::applyImpulse(const MT_Point3& attach, const MT_Vector3& impulse) -{ - CcdPhysicsController::applyImpulse(attach[0],attach[1],attach[2],impulse[0],impulse[1],impulse[2]); - -} - -float KX_BulletPhysicsController::GetLinVelocityMin() -{ - return (float)CcdPhysicsController::GetLinVelocityMin(); -} -void KX_BulletPhysicsController::SetLinVelocityMin(float val) -{ - CcdPhysicsController::SetLinVelocityMin(val); -} - -void KX_BulletPhysicsController::Jump() -{ - CcdPhysicsController::Jump(); -} - -float KX_BulletPhysicsController::GetLinVelocityMax() -{ - return (float)CcdPhysicsController::GetLinVelocityMax(); -} -void KX_BulletPhysicsController::SetLinVelocityMax(float val) -{ - CcdPhysicsController::SetLinVelocityMax(val); -} - -void KX_BulletPhysicsController::SetObject (SG_IObject* object) -{ - SG_Controller::SetObject(object); - - // cheating here... - //should not be necessary, is it for duplicates ? - - KX_GameObject* gameobj = (KX_GameObject*) object->GetSGClientObject(); - gameobj->SetPhysicsController(this,gameobj->IsDynamic()); - CcdPhysicsController::setNewClientInfo(gameobj->getClientInfo()); - - if (m_bSensor) - { - // use a different callback function for sensor object, - // bullet will not synchronize, we must do it explicitly - SG_Callbacks& callbacks = gameobj->GetSGNode()->GetCallBackFunctions(); - callbacks.m_updatefunc = KX_GameObject::SynchronizeTransformFunc; - } -} - -MT_Scalar KX_BulletPhysicsController::GetRadius() -{ - return MT_Scalar(CcdPhysicsController::GetRadius()); -} - -void KX_BulletPhysicsController::setMargin (float collisionMargin) -{ - CcdPhysicsController::SetMargin(collisionMargin); -} -void KX_BulletPhysicsController::RelativeTranslate(const MT_Vector3& dloc,bool local) -{ - CcdPhysicsController::RelativeTranslate(dloc[0],dloc[1],dloc[2],local); - -} - -void KX_BulletPhysicsController::SetWalkDirection(const MT_Vector3& dloc,bool local) -{ - CcdPhysicsController::SetWalkDirection(dloc[0],dloc[1],dloc[2],local); -} - -void KX_BulletPhysicsController::RelativeRotate(const MT_Matrix3x3& drot,bool local) -{ - float rotval[9]; - drot.getValue3x3(rotval); - CcdPhysicsController::RelativeRotate(rotval,local); -} - -void KX_BulletPhysicsController::ApplyTorque(const MT_Vector3& torque,bool local) -{ - CcdPhysicsController::ApplyTorque(torque.x(),torque.y(),torque.z(),local); -} -void KX_BulletPhysicsController::ApplyForce(const MT_Vector3& force,bool local) -{ - CcdPhysicsController::ApplyForce(force.x(),force.y(),force.z(),local); -} -MT_Vector3 KX_BulletPhysicsController::GetLinearVelocity() -{ - float angVel[3]; - //CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]); - CcdPhysicsController::GetLinearVelocity(angVel[0],angVel[1],angVel[2]);//rcruiz - return MT_Vector3(angVel[0],angVel[1],angVel[2]); -} -MT_Vector3 KX_BulletPhysicsController::GetAngularVelocity() -{ - float angVel[3]; - //CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]); - CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]);//rcruiz - return MT_Vector3(angVel[0],angVel[1],angVel[2]); -} -MT_Vector3 KX_BulletPhysicsController::GetVelocity(const MT_Point3& pos) -{ - float linVel[3]; - CcdPhysicsController::GetVelocity(pos[0], pos[1], pos[2], linVel[0],linVel[1],linVel[2]); - return MT_Vector3(linVel[0],linVel[1],linVel[2]); -} - -MT_Vector3 KX_BulletPhysicsController::GetWalkDirection() -{ - float dir[3]; - CcdPhysicsController::GetWalkDirection(dir[0], dir[1], dir[2]); - return MT_Vector3(dir[0], dir[1], dir[2]); -} - -void KX_BulletPhysicsController::SetAngularVelocity(const MT_Vector3& ang_vel,bool local) -{ - CcdPhysicsController::SetAngularVelocity(ang_vel.x(),ang_vel.y(),ang_vel.z(),local); - -} -void KX_BulletPhysicsController::SetLinearVelocity(const MT_Vector3& lin_vel,bool local) -{ - CcdPhysicsController::SetLinearVelocity(lin_vel.x(),lin_vel.y(),lin_vel.z(),local); -} -void KX_BulletPhysicsController::getOrientation(MT_Quaternion& orn) -{ - float myorn[4]; - CcdPhysicsController::getOrientation(myorn[0],myorn[1],myorn[2],myorn[3]); - orn = MT_Quaternion(myorn[0],myorn[1],myorn[2],myorn[3]); -} -void KX_BulletPhysicsController::setOrientation(const MT_Matrix3x3& orn) -{ - 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]); - CcdPhysicsController::setWorldOrientation(btmat); -} -void KX_BulletPhysicsController::setPosition(const MT_Point3& pos) -{ - CcdPhysicsController::setPosition(pos.x(),pos.y(),pos.z()); -} -void KX_BulletPhysicsController::setScaling(const MT_Vector3& scaling) -{ - CcdPhysicsController::setScaling(scaling.x(),scaling.y(),scaling.z()); -} -void KX_BulletPhysicsController::SetTransform() -{ - btVector3 pos; - btVector3 scale; - float ori[12]; - m_MotionState->getWorldPosition(pos.m_floats[0],pos.m_floats[1],pos.m_floats[2]); - m_MotionState->getWorldScaling(scale.m_floats[0],scale.m_floats[1],scale.m_floats[2]); - m_MotionState->getWorldOrientation(ori); - btMatrix3x3 rot(ori[0], ori[4], ori[8], - ori[1], ori[5], ori[9], - ori[2], ori[6], ori[10]); - CcdPhysicsController::forceWorldTransform(rot, pos); -} - -MT_Scalar KX_BulletPhysicsController::GetMass() -{ - if (GetSoftBody()) - return GetSoftBody()->getTotalMass(); - - MT_Scalar invmass = 0.f; - if (GetRigidBody()) - invmass = GetRigidBody()->getInvMass(); - if (invmass) - return 1.f/invmass; - return 0.f; - -} - -MT_Vector3 KX_BulletPhysicsController::GetLocalInertia() -{ - MT_Vector3 inertia(0.f, 0.f, 0.f); - btVector3 inv_inertia; - if (GetRigidBody()) { - inv_inertia = GetRigidBody()->getInvInertiaDiagLocal(); - if (!btFuzzyZero(inv_inertia.getX()) && - !btFuzzyZero(inv_inertia.getY()) && - !btFuzzyZero(inv_inertia.getZ())) - inertia = MT_Vector3(1.f/inv_inertia.getX(), 1.f/inv_inertia.getY(), 1.f/inv_inertia.getZ()); - } - return inertia; -} - -MT_Vector3 KX_BulletPhysicsController::getReactionForce() -{ - assert(0); - return MT_Vector3(0.f,0.f,0.f); -} -void KX_BulletPhysicsController::setRigidBody(bool rigid) -{ - CcdPhysicsController::setRigidBody(rigid); -} - -/* This function dynamically adds the collision shape of another controller to - * the current controller shape provided it is a compound shape. - * The idea is that dynamic parenting on a compound object will dynamically extend the shape - */ -void KX_BulletPhysicsController::AddCompoundChild(KX_IPhysicsController* child) -{ - if (child == NULL || !IsCompound()) - return; - // other controller must be a bullet controller too - // verify that body and shape exist and match - KX_BulletPhysicsController* childCtrl = dynamic_cast<KX_BulletPhysicsController*>(child); - btRigidBody* rootBody = GetRigidBody(); - btRigidBody* childBody = childCtrl->GetRigidBody(); - if (!rootBody || !childBody) - return; - const btCollisionShape* rootShape = rootBody->getCollisionShape(); - const btCollisionShape* childShape = childBody->getCollisionShape(); - if (!rootShape || - !childShape || - rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE || - childShape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) - return; - btCompoundShape* compoundShape = (btCompoundShape*)rootShape; - // compute relative transformation between parent and child - btTransform rootTrans; - btTransform childTrans; - rootBody->getMotionState()->getWorldTransform(rootTrans); - childBody->getMotionState()->getWorldTransform(childTrans); - btVector3 rootScale = rootShape->getLocalScaling(); - rootScale[0] = 1.0/rootScale[0]; - rootScale[1] = 1.0/rootScale[1]; - rootScale[2] = 1.0/rootScale[2]; - // relative scale = child_scale/parent_scale - btVector3 relativeScale = childShape->getLocalScaling()*rootScale; - btMatrix3x3 rootRotInverse = rootTrans.getBasis().transpose(); - // relative pos = parent_rot^-1 * ((parent_pos-child_pos)/parent_scale) - btVector3 relativePos = rootRotInverse*((childTrans.getOrigin()-rootTrans.getOrigin())*rootScale); - // relative rot = parent_rot^-1 * child_rot - btMatrix3x3 relativeRot = rootRotInverse*childTrans.getBasis(); - // create a proxy shape info to store the transformation - CcdShapeConstructionInfo* proxyShapeInfo = new CcdShapeConstructionInfo(); - // store the transformation to this object shapeinfo - proxyShapeInfo->m_childTrans.setOrigin(relativePos); - proxyShapeInfo->m_childTrans.setBasis(relativeRot); - proxyShapeInfo->m_childScale.setValue(relativeScale[0], relativeScale[1], relativeScale[2]); - // we will need this to make sure that we remove the right proxy later when unparenting - proxyShapeInfo->m_userData = childCtrl; - proxyShapeInfo->SetProxy(childCtrl->GetShapeInfo()->AddRef()); - // add to parent compound shapeinfo (increments ref count) - GetShapeInfo()->AddShape(proxyShapeInfo); - // create new bullet collision shape from the object shapeinfo and set scaling - btCollisionShape* newChildShape = proxyShapeInfo->CreateBulletShape(childCtrl->GetMargin(), childCtrl->getConstructionInfo().m_bGimpact, true); - newChildShape->setLocalScaling(relativeScale); - // add bullet collision shape to parent compound collision shape - compoundShape->addChildShape(proxyShapeInfo->m_childTrans,newChildShape); - // proxyShapeInfo is not needed anymore, release it - proxyShapeInfo->Release(); - // remember we created this shape - childCtrl->m_bulletChildShape = newChildShape; - // recompute inertia of parent - if (!rootBody->isStaticOrKinematicObject()) - { - btVector3 localInertia; - float mass = 1.f/rootBody->getInvMass(); - compoundShape->calculateLocalInertia(mass,localInertia); - rootBody->setMassProps(mass,localInertia); - } - // must update the broadphase cache, - GetPhysicsEnvironment()->refreshCcdPhysicsController(this); - // remove the children - GetPhysicsEnvironment()->disableCcdPhysicsController(childCtrl); -} - -/* Reverse function of the above, it will remove a shape from a compound shape - * provided that the former was added to the later using AddCompoundChild() - */ -void KX_BulletPhysicsController::RemoveCompoundChild(KX_IPhysicsController* child) -{ - if (child == NULL || !IsCompound()) - return; - // other controller must be a bullet controller too - // verify that body and shape exist and match - KX_BulletPhysicsController* childCtrl = dynamic_cast<KX_BulletPhysicsController*>(child); - btRigidBody* rootBody = GetRigidBody(); - btRigidBody* childBody = childCtrl->GetRigidBody(); - if (!rootBody || !childBody) - return; - const btCollisionShape* rootShape = rootBody->getCollisionShape(); - if (!rootShape || - rootShape->getShapeType() != COMPOUND_SHAPE_PROXYTYPE) - return; - btCompoundShape* compoundShape = (btCompoundShape*)rootShape; - // retrieve the shapeInfo - CcdShapeConstructionInfo* childShapeInfo = childCtrl->GetShapeInfo(); - CcdShapeConstructionInfo* rootShapeInfo = GetShapeInfo(); - // and verify that the child is part of the parent - int i = rootShapeInfo->FindChildShape(childShapeInfo, childCtrl); - if (i < 0) - return; - rootShapeInfo->RemoveChildShape(i); - if (childCtrl->m_bulletChildShape) - { - int numChildren = compoundShape->getNumChildShapes(); - for (i=0; i<numChildren; i++) - { - if (compoundShape->getChildShape(i) == childCtrl->m_bulletChildShape) - { - compoundShape->removeChildShapeByIndex(i); - compoundShape->recalculateLocalAabb(); - break; - } - } - delete childCtrl->m_bulletChildShape; - childCtrl->m_bulletChildShape = NULL; - } - // recompute inertia of parent - if (!rootBody->isStaticOrKinematicObject()) - { - btVector3 localInertia; - float mass = 1.f/rootBody->getInvMass(); - compoundShape->calculateLocalInertia(mass,localInertia); - rootBody->setMassProps(mass,localInertia); - } - // must update the broadphase cache, - GetPhysicsEnvironment()->refreshCcdPhysicsController(this); - // reactivate the children - GetPhysicsEnvironment()->enableCcdPhysicsController(childCtrl); -} - -void KX_BulletPhysicsController::SetMass(MT_Scalar newmass) -{ - btRigidBody *body = GetRigidBody(); - if (body && !m_suspended && newmass>MT_EPSILON && GetMass()>MT_EPSILON) - { - btVector3 grav = body->getGravity(); - btVector3 accel = grav / GetMass(); - - btBroadphaseProxy* handle = body->getBroadphaseHandle(); - GetPhysicsEnvironment()->updateCcdPhysicsController(this, - newmass, - body->getCollisionFlags(), - handle->m_collisionFilterGroup, - handle->m_collisionFilterMask); - body->setGravity(accel); - } -} - -void KX_BulletPhysicsController::SuspendDynamics(bool ghost) -{ - btRigidBody *body = GetRigidBody(); - if (body && !m_suspended && !IsSensor()) - { - btBroadphaseProxy* handle = body->getBroadphaseHandle(); - m_savedCollisionFlags = body->getCollisionFlags(); - m_savedMass = GetMass(); - m_savedDyna = m_bDyna; - m_savedCollisionFilterGroup = handle->m_collisionFilterGroup; - m_savedCollisionFilterMask = handle->m_collisionFilterMask; - m_suspended = true; - GetPhysicsEnvironment()->updateCcdPhysicsController(this, - 0.0, - btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)), - btBroadphaseProxy::StaticFilter, - btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); - m_bDyna = false; - } -} - -void KX_BulletPhysicsController::RestoreDynamics() -{ - btRigidBody *body = GetRigidBody(); - if (body && m_suspended) - { - // before make sure any position change that was done in this logic frame are accounted for - SetTransform(); - GetPhysicsEnvironment()->updateCcdPhysicsController(this, - m_savedMass, - m_savedCollisionFlags, - m_savedCollisionFilterGroup, - m_savedCollisionFilterMask); - body->activate(); - m_bDyna = m_savedDyna; - m_suspended = false; - } -} - -SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode) -{ - PHY_IMotionState* motionstate = new KX_MotionState(destnode); - - KX_BulletPhysicsController* physicsreplica = new KX_BulletPhysicsController(*this); - - //parentcontroller is here be able to avoid collisions between parent/child - - PHY_IPhysicsController* parentctrl = NULL; - KX_BulletPhysicsController* parentKxCtrl = NULL; - CcdPhysicsController* ccdParent = NULL; - - - if (destnode != destnode->GetRootSGParent()) - { - KX_GameObject* clientgameobj = (KX_GameObject*) destnode->GetRootSGParent()->GetSGClientObject(); - if (clientgameobj) - { - parentctrl = (KX_BulletPhysicsController*)clientgameobj->GetPhysicsController(); - } else - { - // it could be a false node, try the children - NodeList::const_iterator childit; - for ( - childit = destnode->GetSGChildren().begin(); - childit!= destnode->GetSGChildren().end(); - ++childit - ) { - KX_GameObject *clientgameobj_child = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject()); - if (clientgameobj_child) - { - parentKxCtrl = (KX_BulletPhysicsController*)clientgameobj_child->GetPhysicsController(); - parentctrl = parentKxCtrl; - ccdParent = parentKxCtrl; - } - } - } - } - - physicsreplica->setParentCtrl(ccdParent); - physicsreplica->PostProcessReplica(motionstate,parentctrl); - physicsreplica->m_userdata = (PHY_IPhysicsController*)physicsreplica; - physicsreplica->m_bulletChildShape = NULL; - return physicsreplica; - -} - - - -void KX_BulletPhysicsController::SetSumoTransform(bool nondynaonly) -{ - - if (!m_bDyna && !m_bSensor && !m_bCharacter) - { - btCollisionObject* object = GetRigidBody(); - object->setActivationState(ACTIVE_TAG); - object->setCollisionFlags(object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - } else - { - if (!nondynaonly) - { - /* - btTransform worldTrans; - if (GetRigidBody()) - { - GetRigidBody()->getMotionState()->getWorldTransform(worldTrans); - GetRigidBody()->setCenterOfMassTransform(worldTrans); - } - */ - /* - scaling? - if (m_bDyna) - { - m_sumoObj->setScaling(MT_Vector3(1,1,1)); - } else - { - MT_Vector3 scale; - GetWorldScaling(scale); - m_sumoObj->setScaling(scale); - } - */ - - } - } -} - -// todo: remove next line ! -void KX_BulletPhysicsController::SetSimulatedTime(double time) -{ -} - -// call from scene graph to update -bool KX_BulletPhysicsController::Update(double time) -{ - return false; - - // todo: check this code - //if (GetMass()) - //{ - // return false;//true; -// } -// return false; -} - - -const char* KX_BulletPhysicsController::getName() -{ - if (m_pObject) - { - KX_GameObject* gameobj = (KX_GameObject*) m_pObject->GetSGClientObject(); - return gameobj->GetName(); - } - return 0; -} - -#endif // WITH_BULLET |