diff options
Diffstat (limited to 'source/gameengine/Physics')
19 files changed, 0 insertions, 9089 deletions
diff --git a/source/gameengine/Physics/Bullet/CMakeLists.txt b/source/gameengine/Physics/Bullet/CMakeLists.txt deleted file mode 100644 index 8b00f1b47fa..00000000000 --- a/source/gameengine/Physics/Bullet/CMakeLists.txt +++ /dev/null @@ -1,73 +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. -# -# The Original Code is Copyright (C) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Jacques Beaurain. -# -# ***** END GPL LICENSE BLOCK ***** - -# since this includes bullet we get errors from the headers too -remove_strict_flags() - -set(INC - . - ../common - ../../Converter - ../../Expressions - ../../GameLogic - ../../Ketsji - ../../Rasterizer - ../../SceneGraph - ../../../blender/blenkernel - ../../../blender/blenlib - ../../../blender/gpu - ../../../blender/makesdna - ../../../../intern/container - ../../../../intern/guardedalloc - ../../../../intern/glew-mx - ../../../../intern/string -) - -set(INC_SYS - ../../../../intern/moto/include - ${GLEW_INCLUDE_PATH} - ${PYTHON_INCLUDE_DIRS} -) - -set(SRC - CcdPhysicsEnvironment.cpp - CcdPhysicsController.cpp - CcdGraphicController.cpp - - CcdGraphicController.h - CcdPhysicsController.h - CcdPhysicsEnvironment.h -) - -if(WITH_BULLET) - list(APPEND INC_SYS - ${BULLET_INCLUDE_DIRS} - ) - add_definitions(-DWITH_BULLET) -endif() - -add_definitions(${GL_DEFINITIONS}) - -blender_add_lib(ge_phys_bullet "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.cpp b/source/gameengine/Physics/Bullet/CcdGraphicController.cpp deleted file mode 100644 index 470a5431843..00000000000 --- a/source/gameengine/Physics/Bullet/CcdGraphicController.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/** \file gameengine/Physics/Bullet/CcdGraphicController.cpp - * \ingroup physbullet - */ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, -subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - -#include "CcdPhysicsEnvironment.h" -#include "CcdGraphicController.h" -#include "btBulletDynamicsCommon.h" -#include "MT_Point3.h" - - -CcdGraphicController::CcdGraphicController (CcdPhysicsEnvironment* phyEnv, PHY_IMotionState* motionState) : - m_localAabbMin(0.f, 0.f, 0.f), - m_localAabbMax(0.f, 0.f, 0.f), - m_motionState(motionState), - m_phyEnv(phyEnv), - m_handle(NULL), - m_newClientInfo(NULL) -{ -} - -CcdGraphicController::~CcdGraphicController() -{ - if (m_phyEnv) - m_phyEnv->RemoveCcdGraphicController(this); - - if (m_motionState) - delete m_motionState; -} - -void CcdGraphicController::SetLocalAabb(const btVector3& aabbMin,const btVector3& aabbMax) -{ - m_localAabbMin = aabbMin; - m_localAabbMax = aabbMax; - SetGraphicTransform(); -} - -void CcdGraphicController::SetLocalAabb(const MT_Point3& aabbMin,const MT_Point3& aabbMax) -{ - m_localAabbMin.setValue(aabbMin[0],aabbMin[1],aabbMin[2]); - m_localAabbMax.setValue(aabbMax[0],aabbMax[1],aabbMax[2]); - SetGraphicTransform(); -} - -void CcdGraphicController::SetLocalAabb(const MT_Vector3& aabbMin,const MT_Vector3& aabbMax) -{ - m_localAabbMin.setValue(aabbMin[0],aabbMin[1],aabbMin[2]); - m_localAabbMax.setValue(aabbMax[0],aabbMax[1],aabbMax[2]); - SetGraphicTransform(); -} - -void CcdGraphicController::SetLocalAabb(const float* aabbMin,const float* aabbMax) -{ - m_localAabbMin.setValue(aabbMin[0],aabbMin[1],aabbMin[2]); - m_localAabbMax.setValue(aabbMax[0],aabbMax[1],aabbMax[2]); - SetGraphicTransform(); -} - -void CcdGraphicController::GetAabb(btVector3& aabbMin, btVector3& aabbMax) -{ - 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]); - - btVector3 localAabbMin = m_localAabbMin; - btVector3 localAabbMax = m_localAabbMax; - btVector3 tmpAabbMin = m_localAabbMin * scale; - btVector3 tmpAabbMax = m_localAabbMax * scale; - - localAabbMin[0] = (scale.getX() >= 0.0f) ? tmpAabbMin[0] : tmpAabbMax[0]; - localAabbMin[1] = (scale.getY() >= 0.0f) ? tmpAabbMin[1] : tmpAabbMax[1]; - localAabbMin[2] = (scale.getZ() >= 0.0f) ? tmpAabbMin[2] : tmpAabbMax[2]; - localAabbMax[0] = (scale.getX() <= 0.0f) ? tmpAabbMin[0] : tmpAabbMax[0]; - localAabbMax[1] = (scale.getY() <= 0.0f) ? tmpAabbMin[1] : tmpAabbMax[1]; - localAabbMax[2] = (scale.getZ() <= 0.0f) ? tmpAabbMin[2] : tmpAabbMax[2]; - - btVector3 localHalfExtents = btScalar(0.5f)*(localAabbMax-localAabbMin); - btVector3 localCenter = btScalar(0.5f)*(localAabbMax+localAabbMin); - - btMatrix3x3 abs_b = rot.absolute(); - btVector3 center = rot*localCenter + pos; - btVector3 extent = abs_b*localHalfExtents; - aabbMin = center - extent; - aabbMax = center + extent; -} - -bool CcdGraphicController::SetGraphicTransform() -{ - if (!m_handle) - return false; - btVector3 aabbMin; - btVector3 aabbMax; - GetAabb(aabbMin, aabbMax); - // update Aabb in broadphase - m_phyEnv->GetCullingTree()->setAabb(m_handle,aabbMin,aabbMax,NULL); - return true; -} - -PHY_IGraphicController* CcdGraphicController::GetReplica(class PHY_IMotionState* motionState) -{ - CcdGraphicController* replica = new CcdGraphicController(*this); - replica->m_motionState = motionState; - replica->m_newClientInfo = NULL; - replica->m_handle = NULL; - // don't add the graphic controller now: work around a bug in Bullet with rescaling, - // (the scale of the controller is not yet defined). - //m_phyEnv->addCcdGraphicController(replica); - return replica; -} - -void CcdGraphicController::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* env) -{ - CcdPhysicsEnvironment* phyEnv = static_cast<CcdPhysicsEnvironment*>(env); - /* Updates the m_phyEnv's m_cullingTree & m_cullingCache */ - if (GetBroadphaseHandle()) { - /* insert into the new physics scene */ - Activate(false); - m_phyEnv= phyEnv; - Activate(true); - } - else { - m_phyEnv= phyEnv; - } -} - -void CcdGraphicController::Activate(bool active) -{ - if (active) - m_phyEnv->AddCcdGraphicController(this); - else - m_phyEnv->RemoveCcdGraphicController(this); - -} diff --git a/source/gameengine/Physics/Bullet/CcdGraphicController.h b/source/gameengine/Physics/Bullet/CcdGraphicController.h deleted file mode 100644 index e76ad86301e..00000000000 --- a/source/gameengine/Physics/Bullet/CcdGraphicController.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, -subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - -/** \file CcdGraphicController.h - * \ingroup physbullet - */ - - -#ifndef __CCDGRAPHICCONTROLLER_H__ -#define __CCDGRAPHICCONTROLLER_H__ - -#include "PHY_IGraphicController.h" - -#include "btBulletDynamicsCommon.h" -#include "LinearMath/btTransform.h" - -#include "PHY_IMotionState.h" -#include "MT_Point3.h" - -class CcdPhysicsEnvironment; -class btCollisionObject; - -///CcdGraphicController is a graphic object that supports view frustrum culling and occlusion -class CcdGraphicController : public PHY_IGraphicController -{ -public: - CcdGraphicController(CcdPhysicsEnvironment* phyEnv, PHY_IMotionState* motionState); - - virtual ~CcdGraphicController(); - - void SetLocalAabb(const btVector3& aabbMin,const btVector3& aabbMax); - void SetLocalAabb(const MT_Point3& aabbMin,const MT_Point3& aabbMax); - virtual void SetLocalAabb(const MT_Vector3& aabbMin,const MT_Vector3& aabbMax); - virtual void SetLocalAabb(const float aabbMin[3],const float aabbMax[3]); - - PHY_IMotionState* GetMotionState() { return m_motionState; } - void GetAabb(btVector3& aabbMin, btVector3& aabbMax); - - virtual void SetBroadphaseHandle(btBroadphaseProxy* handle) { m_handle = handle; } - virtual btBroadphaseProxy* GetBroadphaseHandle() { return m_handle; } - - virtual void SetPhysicsEnvironment(class PHY_IPhysicsEnvironment* env); - - //////////////////////////////////// - // PHY_IGraphicController interface - //////////////////////////////////// - - /** - * Updates the Aabb based on the motion state - */ - virtual bool SetGraphicTransform(); - /** - * Add/remove to environment - */ - virtual void Activate(bool active); - - // client info for culling - virtual void* GetNewClientInfo() { return m_newClientInfo; } - virtual void SetNewClientInfo(void* clientinfo) { m_newClientInfo = clientinfo; } - virtual PHY_IGraphicController* GetReplica(class PHY_IMotionState* motionstate); - -private: - // unscaled aabb corner - btVector3 m_localAabbMin; - btVector3 m_localAabbMax; - - PHY_IMotionState* m_motionState; - CcdPhysicsEnvironment* m_phyEnv; - btBroadphaseProxy* m_handle; - void* m_newClientInfo; - - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:CcdGraphicController") -#endif -}; - -#endif /* BULLET2_PHYSICSCONTROLLER_H */ diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp deleted file mode 100644 index b3cee944880..00000000000 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ /dev/null @@ -1,2668 +0,0 @@ -/** \file gameengine/Physics/Bullet/CcdPhysicsController.cpp - * \ingroup physbullet - */ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, -subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - -#ifndef WIN32 -#include <stdint.h> -#endif - -#include "CcdPhysicsController.h" -#include "btBulletDynamicsCommon.h" -#include "BulletCollision/CollisionDispatch/btGhostObject.h" -#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" -#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" - -#include "PHY_IMotionState.h" -#include "CcdPhysicsEnvironment.h" -#include "RAS_MeshObject.h" -#include "RAS_Polygon.h" -#include "RAS_Deformer.h" -#include "KX_GameObject.h" - -#include "BulletSoftBody/btSoftBody.h" -#include "BulletSoftBody/btSoftBodyInternals.h" -#include "BulletSoftBody/btSoftBodyHelpers.h" -#include "LinearMath/btConvexHull.h" -#include "BulletCollision/Gimpact/btGImpactShape.h" - -#include "BulletSoftBody/btSoftRigidDynamicsWorld.h" - -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" - -extern "C"{ - #include "BLI_utildefines.h" - #include "BKE_cdderivedmesh.h" -} - - -class BP_Proxy; - -///todo: fill all the empty CcdPhysicsController methods, hook them up to the btRigidBody class - -//'temporarily' global variables -//float gDeactivationTime = 2.f; -//bool gDisableDeactivation = false; -extern float gDeactivationTime; -extern bool gDisableDeactivation; - - -float gLinearSleepingTreshold; -float gAngularSleepingTreshold; - -BlenderBulletCharacterController::BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight) - : btKinematicCharacterController(ghost,shape,stepHeight,2), - m_motionState(motionState), - m_jumps(0), - m_maxJumps(1) -{ -} - -void BlenderBulletCharacterController::updateAction(btCollisionWorld *collisionWorld, btScalar dt) -{ - if (onGround()) - m_jumps = 0; - - btKinematicCharacterController::updateAction(collisionWorld,dt); - m_motionState->setWorldTransform(getGhostObject()->getWorldTransform()); -} - -unsigned char BlenderBulletCharacterController::getMaxJumps() const -{ - return m_maxJumps; -} - -void BlenderBulletCharacterController::setMaxJumps(unsigned char maxJumps) -{ - m_maxJumps = maxJumps; -} - -unsigned char BlenderBulletCharacterController::getJumpCount() const -{ - return m_jumps; -} - -bool BlenderBulletCharacterController::canJump() const -{ - return (onGround() && m_maxJumps > 0) || m_jumps < m_maxJumps; -} - -void BlenderBulletCharacterController::jump() -{ - if (!canJump()) - return; - - m_verticalVelocity = m_jumpSpeed; - m_wasJumping = true; - m_jumps++; -} - -const btVector3& BlenderBulletCharacterController::getWalkDirection() -{ - return m_walkDirection; -} - -bool CleanPairCallback::processOverlap(btBroadphasePair &pair) -{ - if ((pair.m_pProxy0 == m_cleanProxy) || (pair.m_pProxy1 == m_cleanProxy)) { - m_pairCache->cleanOverlappingPair(pair, m_dispatcher); - CcdPhysicsController *ctrl0 = (CcdPhysicsController*)(((btCollisionObject*)pair.m_pProxy0->m_clientObject)->getUserPointer()); - CcdPhysicsController *ctrl1 = (CcdPhysicsController*)(((btCollisionObject*)pair.m_pProxy1->m_clientObject)->getUserPointer()); - ctrl0->GetCollisionObject()->activate(false); - ctrl1->GetCollisionObject()->activate(false); - } - return false; -} - -CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci) -:m_cci(ci) -{ - m_prototypeTransformInitialized = false; - m_softbodyMappingDone = false; - m_collisionDelay = 0; - m_newClientInfo = 0; - m_registerCount = 0; - m_softBodyTransformInitialized = false; - m_parentCtrl = 0; - // copy pointers locally to allow smart release - m_MotionState = ci.m_MotionState; - m_collisionShape = ci.m_collisionShape; - // apply scaling before creating rigid body - m_collisionShape->setLocalScaling(m_cci.m_scaling); - if (m_cci.m_mass) - m_collisionShape->calculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor); - // shape info is shared, increment ref count - m_shapeInfo = ci.m_shapeInfo; - if (m_shapeInfo) - m_shapeInfo->AddRef(); - - m_bulletChildShape = NULL; - - m_bulletMotionState = 0; - m_characterController = 0; - m_savedCollisionFlags = 0; - m_savedCollisionFilterGroup = 0; - m_savedCollisionFilterMask = 0; - m_savedMass = 0.0f; - m_savedDyna = false; - m_suspended = false; - - CreateRigidbody(); -} - -void CcdPhysicsController::addCcdConstraintRef(btTypedConstraint* c) -{ - int index = m_ccdConstraintRefs.findLinearSearch(c); - if (index == m_ccdConstraintRefs.size()) - m_ccdConstraintRefs.push_back(c); -} - -void CcdPhysicsController::removeCcdConstraintRef(btTypedConstraint* c) -{ - m_ccdConstraintRefs.remove(c); -} - -btTypedConstraint* CcdPhysicsController::getCcdConstraintRef(int index) -{ - return m_ccdConstraintRefs[index]; -} - -int CcdPhysicsController::getNumCcdConstraintRefs() const -{ - return m_ccdConstraintRefs.size(); -} - -btTransform& CcdPhysicsController::GetTransformFromMotionState(PHY_IMotionState* motionState) -{ - static btTransform trans; - btVector3 tmp; - motionState->GetWorldPosition(tmp.m_floats[0], tmp.m_floats[1], tmp.m_floats[2]); - trans.setOrigin(tmp); - - float ori[12]; - motionState->GetWorldOrientation(ori); - trans.getBasis().setFromOpenGLSubMatrix(ori); - //btQuaternion orn; - //motionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]); - //trans.setRotation(orn); - return trans; - -} - -class BlenderBulletMotionState : public btMotionState -{ - PHY_IMotionState* m_blenderMotionState; - -public: - - BlenderBulletMotionState(PHY_IMotionState* bms) - :m_blenderMotionState(bms) - { - - } - - void getWorldTransform(btTransform& worldTrans ) const - { - btVector3 pos; - float ori[12]; - - m_blenderMotionState->GetWorldPosition(pos.m_floats[0],pos.m_floats[1],pos.m_floats[2]); - m_blenderMotionState->GetWorldOrientation(ori); - worldTrans.setOrigin(pos); - worldTrans.getBasis().setFromOpenGLSubMatrix(ori); - } - - void setWorldTransform(const btTransform& worldTrans) - { - m_blenderMotionState->SetWorldPosition(worldTrans.getOrigin().getX(),worldTrans.getOrigin().getY(),worldTrans.getOrigin().getZ()); - btQuaternion rotQuat = worldTrans.getRotation(); - m_blenderMotionState->SetWorldOrientation(rotQuat[0],rotQuat[1],rotQuat[2],rotQuat[3]); - m_blenderMotionState->CalculateWorldTransformations(); - } - -}; - -btRigidBody* CcdPhysicsController::GetRigidBody() -{ - return btRigidBody::upcast(m_object); -} -const btRigidBody* CcdPhysicsController::GetRigidBody() const -{ - return btRigidBody::upcast(m_object); -} - -btCollisionObject* CcdPhysicsController::GetCollisionObject() -{ - return m_object; -} -btSoftBody* CcdPhysicsController::GetSoftBody() -{ - return btSoftBody::upcast(m_object); -} -btKinematicCharacterController* CcdPhysicsController::GetCharacterController() -{ - return m_characterController; -} - -#include "BulletSoftBody/btSoftBodyHelpers.h" - - -bool CcdPhysicsController::CreateSoftbody() -{ - int shapeType = m_cci.m_collisionShape ? m_cci.m_collisionShape->getShapeType() : 0; - - //disable soft body until first sneak preview is ready - if (!m_cci.m_bSoft || !m_cci.m_collisionShape || - ((shapeType != CONVEX_HULL_SHAPE_PROXYTYPE)&& - (shapeType != TRIANGLE_MESH_SHAPE_PROXYTYPE) && - (shapeType != SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE))) - { - return false; - } - - btRigidBody::btRigidBodyConstructionInfo rbci(m_cci.m_mass,m_bulletMotionState,m_collisionShape,m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor); - rbci.m_linearDamping = m_cci.m_linearDamping; - rbci.m_angularDamping = m_cci.m_angularDamping; - rbci.m_friction = m_cci.m_friction; - rbci.m_restitution = m_cci.m_restitution; - - btVector3 p(0.0f,0.0f,0.0f);// = getOrigin(); - //btSoftBody* psb=btSoftBodyHelpers::CreateRope(worldInfo, btVector3(-10,0,i*0.25),btVector3(10,0,i*0.25), 16,1+2); - btSoftBody* psb = 0; - btSoftBodyWorldInfo& worldInfo = m_cci.m_physicsEnv->GetDynamicsWorld()->getWorldInfo(); - - if (m_cci.m_collisionShape->getShapeType() == CONVEX_HULL_SHAPE_PROXYTYPE) { - btConvexHullShape* convexHull = (btConvexHullShape* )m_cci.m_collisionShape; - { - int nvertices = convexHull->getNumPoints(); - const btVector3* vertices = convexHull->getPoints(); - - HullDesc hdsc(QF_TRIANGLES,nvertices,vertices); - HullResult hres; - HullLibrary hlib; /*??*/ - hdsc.mMaxVertices=nvertices; - hlib.CreateConvexHull(hdsc,hres); - - psb = new btSoftBody(&worldInfo, (int)hres.mNumOutputVertices, - &hres.m_OutputVertices[0], 0); - for (int i = 0; i < (int)hres.mNumFaces; ++i) { - const unsigned int idx[3] = {hres.m_Indices[i * 3 + 0], - hres.m_Indices[i * 3 + 1], - hres.m_Indices[i * 3 + 2]}; - if (idx[0] < idx[1]) psb->appendLink(idx[0], idx[1]); - if (idx[1] < idx[2]) psb->appendLink(idx[1], idx[2]); - if (idx[2] < idx[0]) psb->appendLink(idx[2], idx[0]); - psb->appendFace(idx[0], idx[1], idx[2]); - } - hlib.ReleaseResult(hres); - } - } - else { - int numtris = 0; - if (m_cci.m_collisionShape->getShapeType() ==SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) - { - btScaledBvhTriangleMeshShape* scaledtrimeshshape = (btScaledBvhTriangleMeshShape*) m_cci.m_collisionShape; - btBvhTriangleMeshShape* trimeshshape = scaledtrimeshshape->getChildShape(); - - ///only deal with meshes that have 1 sub part/component, for now - if (trimeshshape->getMeshInterface()->getNumSubParts()==1) - { - unsigned char* vertexBase; - btScalar* scaledVertexBase; - btVector3 localScaling; - PHY_ScalarType vertexType; - int numverts; - int vertexstride; - unsigned char* indexbase; - int indexstride; - PHY_ScalarType indexType; - trimeshshape->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numverts,vertexType,vertexstride,&indexbase,indexstride,numtris,indexType); - localScaling = scaledtrimeshshape->getLocalScaling(); - scaledVertexBase = new btScalar[numverts*3]; - for (int i=0; i<numverts*3; i+=3) - { - scaledVertexBase[i] = ((const btScalar*)vertexBase)[i] * localScaling.getX(); - scaledVertexBase[i+1] = ((const btScalar*)vertexBase)[i+1] * localScaling.getY(); - scaledVertexBase[i+2] = ((const btScalar*)vertexBase)[i+2] * localScaling.getZ(); - } - psb = btSoftBodyHelpers::CreateFromTriMesh(worldInfo,scaledVertexBase,(const int*)indexbase,numtris,false); - delete [] scaledVertexBase; - } - } else - { - btTriangleMeshShape* trimeshshape = (btTriangleMeshShape*) m_cci.m_collisionShape; - ///only deal with meshes that have 1 sub part/component, for now - if (trimeshshape->getMeshInterface()->getNumSubParts()==1) - { - unsigned char* vertexBase; - PHY_ScalarType vertexType; - int numverts; - int vertexstride; - unsigned char* indexbase; - int indexstride; - PHY_ScalarType indexType; - trimeshshape->getMeshInterface()->getLockedVertexIndexBase(&vertexBase,numverts,vertexType,vertexstride,&indexbase,indexstride,numtris,indexType); - - psb = btSoftBodyHelpers::CreateFromTriMesh(worldInfo,(const btScalar*)vertexBase,(const int*)indexbase,numtris,false); - } - } - // store face tag so that we can find our original face when doing ray casting - btSoftBody::Face* ft; - int i; - for (i=0, ft=&psb->m_faces[0]; i<numtris; ++i, ++ft) - { - // Hack!! use m_tag to store the face number, normally it is a pointer - // add 1 to make sure it is never 0 - ft->m_tag = (void*)((uintptr_t)(i+1)); - } - } - if (m_cci.m_margin > 0.f) - { - psb->getCollisionShape()->setMargin(m_cci.m_margin); - psb->updateBounds(); - } - m_object = psb; - - //btSoftBody::Material* pm=psb->appendMaterial(); - btSoftBody::Material* pm=psb->m_materials[0]; - pm->m_kLST = m_cci.m_soft_linStiff; - pm->m_kAST = m_cci.m_soft_angStiff; - pm->m_kVST = m_cci.m_soft_volume; - psb->m_cfg.collisions = 0; - - if (m_cci.m_soft_collisionflags & CCD_BSB_COL_CL_RS) - { - psb->m_cfg.collisions += btSoftBody::fCollision::CL_RS; - } else - { - psb->m_cfg.collisions += btSoftBody::fCollision::SDF_RS; - } - if (m_cci.m_soft_collisionflags & CCD_BSB_COL_CL_SS) - { - psb->m_cfg.collisions += btSoftBody::fCollision::CL_SS; - } else - { - psb->m_cfg.collisions += btSoftBody::fCollision::VF_SS; - } - - - psb->m_cfg.kSRHR_CL = m_cci.m_soft_kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */ - psb->m_cfg.kSKHR_CL = m_cci.m_soft_kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */ - psb->m_cfg.kSSHR_CL = m_cci.m_soft_kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */ - psb->m_cfg.kSR_SPLT_CL = m_cci.m_soft_kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ - - psb->m_cfg.kSK_SPLT_CL = m_cci.m_soft_kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ - psb->m_cfg.kSS_SPLT_CL = m_cci.m_soft_kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ - psb->m_cfg.kVCF = m_cci.m_soft_kVCF; /* Velocities correction factor (Baumgarte) */ - psb->m_cfg.kDP = m_cci.m_soft_kDP; /* Damping coefficient [0,1] */ - - psb->m_cfg.kDG = m_cci.m_soft_kDG; /* Drag coefficient [0,+inf] */ - psb->m_cfg.kLF = m_cci.m_soft_kLF; /* Lift coefficient [0,+inf] */ - psb->m_cfg.kPR = m_cci.m_soft_kPR; /* Pressure coefficient [-inf,+inf] */ - psb->m_cfg.kVC = m_cci.m_soft_kVC; /* Volume conversation coefficient [0,+inf] */ - - psb->m_cfg.kDF = m_cci.m_soft_kDF; /* Dynamic friction coefficient [0,1] */ - psb->m_cfg.kMT = m_cci.m_soft_kMT; /* Pose matching coefficient [0,1] */ - psb->m_cfg.kCHR = m_cci.m_soft_kCHR; /* Rigid contacts hardness [0,1] */ - psb->m_cfg.kKHR = m_cci.m_soft_kKHR; /* Kinetic contacts hardness [0,1] */ - - psb->m_cfg.kSHR = m_cci.m_soft_kSHR; /* Soft contacts hardness [0,1] */ - psb->m_cfg.kAHR = m_cci.m_soft_kAHR; /* Anchors hardness [0,1] */ - - if (m_cci.m_gamesoftFlag & CCD_BSB_BENDING_CONSTRAINTS)//OB_SB_GOAL) - { - psb->generateBendingConstraints(2,pm); - } - - psb->m_cfg.piterations = m_cci.m_soft_piterations; - psb->m_cfg.viterations = m_cci.m_soft_viterations; - psb->m_cfg.diterations = m_cci.m_soft_diterations; - psb->m_cfg.citerations = m_cci.m_soft_citerations; - - if (m_cci.m_gamesoftFlag & CCD_BSB_SHAPE_MATCHING)//OB_SB_GOAL) - { - psb->setPose(false,true);// - } else - { - psb->setPose(true,false); - } - - psb->randomizeConstraints(); - - if (m_cci.m_soft_collisionflags & (CCD_BSB_COL_CL_RS+CCD_BSB_COL_CL_SS)) - { - psb->generateClusters(m_cci.m_soft_numclusteriterations); - } - - psb->setTotalMass(m_cci.m_mass); - - psb->setCollisionFlags(0); - - ///create a mapping between graphics mesh vertices and soft body vertices - { - RAS_MeshObject* rasMesh= GetShapeInfo()->GetMesh(); - - if (rasMesh && !m_softbodyMappingDone) - { - //printf("apply\n"); - RAS_MeshSlot::iterator it; - RAS_MeshMaterial *mmat; - RAS_MeshSlot *slot; - size_t i; - - //for each material - for (int m=0;m<rasMesh->NumMaterials();m++) - { - mmat = rasMesh->GetMeshMaterial(m); - - slot = mmat->m_baseslot; - for (slot->begin(it); !slot->end(it); slot->next(it)) - { - int index = 0; - for (i=it.startvertex; i<it.endvertex; i++,index++) - { - RAS_TexVert* vertex = &it.vertex[i]; - //search closest index, and store it in vertex - vertex->setSoftBodyIndex(0); - btScalar maxDistSqr = 1e30; - btSoftBody::tNodeArray& nodes(psb->m_nodes); - btVector3 xyz = btVector3(vertex->getXYZ()[0],vertex->getXYZ()[1],vertex->getXYZ()[2]); - for (int n=0;n<nodes.size();n++) - { - btScalar distSqr = (nodes[n].m_x - xyz).length2(); - if (distSqr<maxDistSqr) - { - maxDistSqr = distSqr; - - vertex->setSoftBodyIndex(n); - } - } - } - } - } - } - } - m_softbodyMappingDone = true; - - btTransform startTrans; - rbci.m_motionState->getWorldTransform(startTrans); - - m_MotionState->SetWorldPosition(startTrans.getOrigin().getX(),startTrans.getOrigin().getY(),startTrans.getOrigin().getZ()); - m_MotionState->SetWorldOrientation(0,0,0,1); - - if (!m_prototypeTransformInitialized) - { - m_prototypeTransformInitialized = true; - m_softBodyTransformInitialized = true; - psb->transform(startTrans); - } - m_object->setCollisionFlags(m_object->getCollisionFlags() | m_cci.m_collisionFlags); - if (m_cci.m_do_anisotropic) - m_object->setAnisotropicFriction(m_cci.m_anisotropicFriction); - return true; -} - -bool CcdPhysicsController::CreateCharacterController() -{ - if (!m_cci.m_bCharacter) - return false; - - m_object = new btPairCachingGhostObject(); - m_object->setCollisionShape(m_collisionShape); - m_object->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); - - btTransform trans; - m_bulletMotionState->getWorldTransform(trans); - m_object->setWorldTransform(trans); - - m_characterController = new BlenderBulletCharacterController(m_bulletMotionState,(btPairCachingGhostObject*)m_object,(btConvexShape*)m_collisionShape,m_cci.m_stepHeight); - - m_characterController->setJumpSpeed(m_cci.m_jumpSpeed); - m_characterController->setFallSpeed(m_cci.m_fallSpeed); - m_characterController->setMaxJumps(m_cci.m_maxJumps); - - return true; -} - -void CcdPhysicsController::CreateRigidbody() -{ - - //btTransform trans = GetTransformFromMotionState(m_MotionState); - m_bulletMotionState = new BlenderBulletMotionState(m_MotionState); - - ///either create a btCollisionObject, btRigidBody or btSoftBody - if (CreateSoftbody() || CreateCharacterController()) - // soft body created, done - return; - - //create a rgid collision object - btRigidBody::btRigidBodyConstructionInfo rbci(m_cci.m_mass,m_bulletMotionState,m_collisionShape,m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor); - rbci.m_linearDamping = m_cci.m_linearDamping; - rbci.m_angularDamping = m_cci.m_angularDamping; - rbci.m_friction = m_cci.m_friction; - rbci.m_restitution = m_cci.m_restitution; - m_object = new btRigidBody(rbci); - - // - // init the rigidbody properly - // - - //setMassProps this also sets collisionFlags - //convert collision flags! - //special case: a near/radar sensor controller should not be defined static or it will - //generate loads of static-static collision messages on the console - if (m_cci.m_bSensor) - { - // reset the flags that have been set so far - GetCollisionObject()->setCollisionFlags(0); - // sensor must never go to sleep: they need to detect continously - GetCollisionObject()->setActivationState(DISABLE_DEACTIVATION); - } - GetCollisionObject()->setCollisionFlags(m_object->getCollisionFlags() | m_cci.m_collisionFlags); - btRigidBody* body = GetRigidBody(); - - if (body) - { - body->setGravity( m_cci.m_gravity); - body->setDamping(m_cci.m_linearDamping, m_cci.m_angularDamping); - - if (!m_cci.m_bRigid) - { - body->setAngularFactor(0.f); - } - // use bullet's default contact processing theshold, blender's old default of 1 is too small here. - // if there's really a need to change this, it should be exposed in the ui first. -// body->setContactProcessingThreshold(m_cci.m_contactProcessingThreshold); - body->setSleepingThresholds(gLinearSleepingTreshold, gAngularSleepingTreshold); - - } - if (m_object && m_cci.m_do_anisotropic) - { - m_object->setAnisotropicFriction(m_cci.m_anisotropicFriction); - } - -} - -static void DeleteBulletShape(btCollisionShape* shape, bool free) -{ - if (shape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) { - /* If we use Bullet scaled shape (btScaledBvhTriangleMeshShape) we have to - * free the child of the unscaled shape (btTriangleMeshShape) here. - */ - btTriangleMeshShape *meshShape = ((btScaledBvhTriangleMeshShape *)shape)->getChildShape(); - if (meshShape) - delete meshShape; - } - if (free) { - delete shape; - } -} - -bool CcdPhysicsController::DeleteControllerShape( ) -{ - if (m_collisionShape) - { - // collision shape is always unique to the controller, can delete it here - if (m_collisionShape->isCompound()) - { - // bullet does not delete the child shape, must do it here - btCompoundShape* compoundShape = (btCompoundShape*)m_collisionShape; - int numChild = compoundShape->getNumChildShapes(); - for (int i=numChild-1 ; i >= 0; i--) - { - btCollisionShape* childShape = compoundShape->getChildShape(i); - DeleteBulletShape(childShape, true); - } - } - DeleteBulletShape(m_collisionShape, true); - - return true; - } - - return false; -} - -bool CcdPhysicsController::ReplaceControllerShape(btCollisionShape *newShape) -{ - if (m_collisionShape) - DeleteControllerShape(); - - // If newShape is NULL it means to create a new Bullet shape. - if (!newShape) - newShape = m_shapeInfo->CreateBulletShape(m_cci.m_margin, m_cci.m_bGimpact, !m_cci.m_bSoft); - - m_object->setCollisionShape(newShape); - m_collisionShape = newShape; - m_cci.m_collisionShape = newShape; - - btSoftBody *softBody = GetSoftBody(); - if (softBody) { - btSoftRigidDynamicsWorld *world = GetPhysicsEnvironment()->GetDynamicsWorld(); - // remove the old softBody - world->removeSoftBody(softBody); - - // soft body must be recreated - delete m_object; - m_object = NULL; - // force complete reinitialization - m_softbodyMappingDone = false; - m_prototypeTransformInitialized = false; - m_softBodyTransformInitialized = false; - - CreateSoftbody(); - assert(m_object); - - btSoftBody *newSoftBody = GetSoftBody(); - // set the user - newSoftBody->setUserPointer(this); - // add the new softbody - world->addSoftBody(newSoftBody); - } - - return true; -} - -CcdPhysicsController::~CcdPhysicsController() -{ - //will be reference counted, due to sharing - if (m_cci.m_physicsEnv) - m_cci.m_physicsEnv->RemoveCcdPhysicsController(this); - - if (m_MotionState) - delete m_MotionState; - if (m_bulletMotionState) - delete m_bulletMotionState; - if (m_characterController) - delete m_characterController; - delete m_object; - - DeleteControllerShape(); - - if (m_shapeInfo) - { - m_shapeInfo->Release(); - } -} - -void CcdPhysicsController::SimulationTick(float timestep) -{ - btRigidBody *body = GetRigidBody(); - if (!body || body->isStaticObject()) - return; - - // Clamp linear velocity - if (m_cci.m_clamp_vel_max > 0.0f || m_cci.m_clamp_vel_min > 0.0f) { - const btVector3 &linvel = body->getLinearVelocity(); - btScalar len = linvel.length(); - - if (m_cci.m_clamp_vel_max > 0.0f && len > m_cci.m_clamp_vel_max) - body->setLinearVelocity(linvel * (m_cci.m_clamp_vel_max / len)); - else if (m_cci.m_clamp_vel_min > 0.0f && !btFuzzyZero(len) && len < m_cci.m_clamp_vel_min) - body->setLinearVelocity(linvel * (m_cci.m_clamp_vel_min / len)); - } - - // Clamp angular velocity - if (m_cci.m_clamp_angvel_max > 0.0f || m_cci.m_clamp_angvel_min > 0.0f) { - const btVector3 &angvel = body->getAngularVelocity(); - btScalar len = angvel.length(); - - if (m_cci.m_clamp_angvel_max > 0.0f && len > m_cci.m_clamp_angvel_max) - body->setAngularVelocity(angvel * (m_cci.m_clamp_angvel_max / len)); - else if (m_cci.m_clamp_angvel_min > 0.0f && !btFuzzyZero(len) && len < m_cci.m_clamp_angvel_min) - body->setAngularVelocity(angvel * (m_cci.m_clamp_angvel_min / len)); - } -} - - -/** - * SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding') - */ -bool CcdPhysicsController::SynchronizeMotionStates(float time) -{ - //sync non-static to motionstate, and static from motionstate (todo: add kinematic etc.) - - btSoftBody* sb = GetSoftBody(); - if (sb) - { - if (sb->m_pose.m_bframe) - { - btVector3 worldPos = sb->m_pose.m_com; - btQuaternion worldquat; - btMatrix3x3 trs = sb->m_pose.m_rot*sb->m_pose.m_scl; - trs.getRotation(worldquat); - m_MotionState->SetWorldPosition(worldPos[0],worldPos[1],worldPos[2]); - m_MotionState->SetWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]); - } - else - { - btVector3 aabbMin,aabbMax; - sb->getAabb(aabbMin,aabbMax); - btVector3 worldPos = (aabbMax+aabbMin)*0.5f; - m_MotionState->SetWorldPosition(worldPos[0],worldPos[1],worldPos[2]); - } - m_MotionState->CalculateWorldTransformations(); - return true; - } - - btRigidBody* body = GetRigidBody(); - - if (body && !body->isStaticObject()) - { - const btTransform& xform = body->getCenterOfMassTransform(); - const btMatrix3x3& worldOri = xform.getBasis(); - const btVector3& worldPos = xform.getOrigin(); - float ori[12]; - worldOri.getOpenGLSubMatrix(ori); - m_MotionState->SetWorldOrientation(ori); - m_MotionState->SetWorldPosition(worldPos[0],worldPos[1],worldPos[2]); - m_MotionState->CalculateWorldTransformations(); - - float scale[3]; - m_MotionState->GetWorldScaling(scale[0],scale[1],scale[2]); - btVector3 scaling(scale[0],scale[1],scale[2]); - GetCollisionShape()->setLocalScaling(scaling); - } else - { - btVector3 worldPos; - btQuaternion worldquat; - -/* m_MotionState->getWorldPosition(worldPos[0],worldPos[1],worldPos[2]); - m_MotionState->getWorldOrientation(worldquat[0],worldquat[1],worldquat[2],worldquat[3]); - btTransform oldTrans = m_body->getCenterOfMassTransform(); - btTransform newTrans(worldquat,worldPos); - - SetCenterOfMassTransform(newTrans); - //need to keep track of previous position for friction effects... - - m_MotionState->calculateWorldTransformations(); -*/ - float scale[3]; - m_MotionState->GetWorldScaling(scale[0],scale[1],scale[2]); - btVector3 scaling(scale[0],scale[1],scale[2]); - GetCollisionShape()->setLocalScaling(scaling); - } - return true; - -} - - /** - * WriteMotionStateToDynamics synchronizes dynas, kinematic and deformable entities (and do 'late binding') - */ - -void CcdPhysicsController::WriteMotionStateToDynamics(bool nondynaonly) -{ - btTransform& xform = CcdPhysicsController::GetTransformFromMotionState(m_MotionState); - SetCenterOfMassTransform(xform); -} - -void CcdPhysicsController::WriteDynamicsToMotionState() -{ -} - // controller replication -void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl) -{ - SetParentCtrl((CcdPhysicsController*)parentctrl); - m_softBodyTransformInitialized=false; - m_MotionState = motionstate; - m_registerCount = 0; - m_collisionShape = NULL; - - // Clear all old constraints. - m_ccdConstraintRefs.clear(); - - // always create a new shape to avoid scaling bug - if (m_shapeInfo) - { - m_shapeInfo->AddRef(); - m_collisionShape = m_shapeInfo->CreateBulletShape(m_cci.m_margin, m_cci.m_bGimpact, !m_cci.m_bSoft); - - if (m_collisionShape) - { - // new shape has no scaling, apply initial scaling - //m_collisionShape->setMargin(m_cci.m_margin); - m_collisionShape->setLocalScaling(m_cci.m_scaling); - - if (m_cci.m_mass) - m_collisionShape->calculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor); - } - } - - // load some characterists that are not - btRigidBody* oldbody = GetRigidBody(); - m_object = 0; - CreateRigidbody(); - btRigidBody* body = GetRigidBody(); - if (body) - { - if (m_cci.m_mass) - { - body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor); - } - - if (oldbody) - { - body->setLinearFactor(oldbody->getLinearFactor()); - body->setAngularFactor(oldbody->getAngularFactor()); - if (oldbody->getActivationState() == DISABLE_DEACTIVATION) - body->setActivationState(DISABLE_DEACTIVATION); - } - } - // sensor object are added when needed - if (!m_cci.m_bSensor) - m_cci.m_physicsEnv->AddCcdPhysicsController(this); - - -} - -void CcdPhysicsController::SetPhysicsEnvironment(class PHY_IPhysicsEnvironment *env) -{ - // can safely assume CCD environment - CcdPhysicsEnvironment *physicsEnv = static_cast<CcdPhysicsEnvironment*>(env); - - if (m_cci.m_physicsEnv != physicsEnv) - { - // since the environment is changing, we must also move the controler to the - // new environment. Note that we don't handle sensor explicitly: this - // function can be called on sensor but only when they are not registered - if (m_cci.m_physicsEnv->RemoveCcdPhysicsController(this)) - { - physicsEnv->AddCcdPhysicsController(this); - - // Set the object to be active so it can at least by evaluated once. - // This fixes issues with static objects not having their physics meshes - // in the right spot when lib loading. - this->GetCollisionObject()->setActivationState(ACTIVE_TAG); - } - m_cci.m_physicsEnv = physicsEnv; - } -} - -void CcdPhysicsController::SetCenterOfMassTransform(btTransform& xform) -{ - btRigidBody* body = GetRigidBody(); - if (body) - { - body->setCenterOfMassTransform(xform); - } else - { - //either collision object or soft body? - if (GetSoftBody()) - { - - } else - { - - if (m_object->isStaticOrKinematicObject()) - { - m_object->setInterpolationWorldTransform(m_object->getWorldTransform()); - } else - { - m_object->setInterpolationWorldTransform(xform); - } - m_object->setWorldTransform(xform); - } - } -} - - // kinematic methods -void CcdPhysicsController::RelativeTranslate(const MT_Vector3& dlocin,bool local) -{ - if (m_object) - { - m_object->activate(true); - if (m_object->isStaticObject()) - { - if (!m_cci.m_bSensor) - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - // kinematic object should not set the transform, it disturbs the velocity interpolation - return; - } - - btVector3 dloc(dlocin.x(), dlocin.y(), dlocin.z()); - btTransform xform = m_object->getWorldTransform(); - - if (local) - dloc = xform.getBasis()*dloc; - - xform.setOrigin(xform.getOrigin() + dloc); - SetCenterOfMassTransform(xform); - } - -} - -void CcdPhysicsController::RelativeRotate(const MT_Matrix3x3& rotval,bool local) -{ - if (m_object) - { - m_object->activate(true); - if (m_object->isStaticObject()) - { - if (!m_cci.m_bSensor) - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - // kinematic object should not set the transform, it disturbs the velocity interpolation - return; - } - - btMatrix3x3 drotmat(rotval[0].x(), rotval[0].y(), rotval[0].z(), - rotval[1].x(), rotval[1].y(), rotval[1].z(), - rotval[2].x(), rotval[2].y(), rotval[2].z()); - - - btMatrix3x3 currentOrn; - GetWorldOrientation(currentOrn); - - btTransform xform = m_object->getWorldTransform(); - - xform.setBasis(xform.getBasis()*(local ? - drotmat : (currentOrn.inverse() * drotmat * currentOrn))); - - SetCenterOfMassTransform(xform); - } -} - - -void CcdPhysicsController::GetWorldOrientation(btMatrix3x3& mat) -{ - float ori[12]; - m_MotionState->GetWorldOrientation(ori); - mat.setFromOpenGLSubMatrix(ori); -} - -MT_Matrix3x3 CcdPhysicsController::GetOrientation() -{ - btMatrix3x3 orn = m_object->getWorldTransform().getBasis(); - return MT_Matrix3x3(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]); -} - -void CcdPhysicsController::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]); - SetWorldOrientation(btmat); -} - -void CcdPhysicsController::SetWorldOrientation(const btMatrix3x3& orn) -{ - if (m_object) - { - m_object->activate(true); - if (m_object->isStaticObject() && !m_cci.m_bSensor) - { - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - } - // not required - //m_MotionState->setWorldOrientation(quatImag0,quatImag1,quatImag2,quatReal); - btTransform xform = m_object->getWorldTransform(); - xform.setBasis(orn); - SetCenterOfMassTransform(xform); - // not required - //m_bulletMotionState->setWorldTransform(xform); - //only once! - if (!m_softBodyTransformInitialized && GetSoftBody()) - { - m_softbodyStartTrans.setBasis(orn); - xform.setOrigin(m_softbodyStartTrans.getOrigin()); - GetSoftBody()->transform(xform); - m_softBodyTransformInitialized = true; - } - - } - -} - -void CcdPhysicsController::SetPosition(const MT_Vector3& pos) -{ - if (m_object) - { - m_object->activate(true); - if (m_object->isStaticObject()) - { - if (!m_cci.m_bSensor) - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - // kinematic object should not set the transform, it disturbs the velocity interpolation - return; - } - // not required, this function is only used to update the physic controller - //m_MotionState->setWorldPosition(posX,posY,posZ); - btTransform xform = m_object->getWorldTransform(); - xform.setOrigin(btVector3(pos.x(), pos.y(), pos.z())); - SetCenterOfMassTransform(xform); - if (!m_softBodyTransformInitialized) - m_softbodyStartTrans.setOrigin(xform.getOrigin()); - // not required - //m_bulletMotionState->setWorldTransform(xform); - } -} - -void CcdPhysicsController::ForceWorldTransform(const btMatrix3x3& mat, const btVector3& pos) -{ - if (m_object) - { - btTransform& xform = m_object->getWorldTransform(); - xform.setBasis(mat); - xform.setOrigin(pos); - } -} - - -void CcdPhysicsController::ResolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) -{ -} - -void CcdPhysicsController::RefreshCollisions() -{ - // the object is in an inactive layer so it's useless to update it and can cause problems - if (!GetPhysicsEnvironment()->IsActiveCcdPhysicsController(this)) - return; - - btSoftRigidDynamicsWorld *dw = GetPhysicsEnvironment()->GetDynamicsWorld(); - btBroadphaseProxy *proxy = m_object->getBroadphaseHandle(); - btDispatcher *dispatcher = dw->getDispatcher(); - btOverlappingPairCache *pairCache = dw->getPairCache(); - - CleanPairCallback cleanPairs(proxy, pairCache, dispatcher); - pairCache->processAllOverlappingPairs(&cleanPairs, dispatcher); - - // Forcibly recreate the physics object - btBroadphaseProxy* handle = m_object->getBroadphaseHandle(); - GetPhysicsEnvironment()->UpdateCcdPhysicsController(this, GetMass(), m_object->getCollisionFlags(), handle->m_collisionFilterGroup, handle->m_collisionFilterMask); -} - -void CcdPhysicsController::SuspendDynamics(bool ghost) -{ - btRigidBody *body = GetRigidBody(); - if (body && !m_suspended && !GetConstructionInfo().m_bSensor && GetPhysicsEnvironment()->IsActiveCcdPhysicsController(this)) - { - btBroadphaseProxy* handle = body->getBroadphaseHandle(); - - m_savedCollisionFlags = body->getCollisionFlags(); - m_savedMass = GetMass(); - m_savedDyna = m_cci.m_bDyna; - m_savedCollisionFilterGroup = handle->m_collisionFilterGroup; - m_savedCollisionFilterMask = handle->m_collisionFilterMask; - m_suspended = true; - GetPhysicsEnvironment()->UpdateCcdPhysicsController(this, - 0.0f, - btCollisionObject::CF_STATIC_OBJECT|((ghost)?btCollisionObject::CF_NO_CONTACT_RESPONSE:(m_savedCollisionFlags&btCollisionObject::CF_NO_CONTACT_RESPONSE)), - btBroadphaseProxy::StaticFilter, - btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); - m_cci.m_bDyna = false; - } -} - -void CcdPhysicsController::RestoreDynamics() -{ - btRigidBody *body = GetRigidBody(); - if (body && m_suspended && GetPhysicsEnvironment()->IsActiveCcdPhysicsController(this)) - { - // 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_cci.m_bDyna = m_savedDyna; - m_suspended = false; - } -} - -void CcdPhysicsController::GetPosition(MT_Vector3& pos) const -{ - const btTransform& xform = m_object->getWorldTransform(); - pos[0] = xform.getOrigin().x(); - pos[1] = xform.getOrigin().y(); - pos[2] = xform.getOrigin().z(); -} - -void CcdPhysicsController::SetScaling(const MT_Vector3& scale) -{ - if (!btFuzzyZero(m_cci.m_scaling.x()-scale.x()) || - !btFuzzyZero(m_cci.m_scaling.y()-scale.y()) || - !btFuzzyZero(m_cci.m_scaling.z()-scale.z())) - { - m_cci.m_scaling = btVector3(scale.x(),scale.y(),scale.z()); - - if (m_object && m_object->getCollisionShape()) - { - m_object->activate(true); // without this, sleeping objects scale wont be applied in bullet if python changes the scale - Campbell. - m_object->getCollisionShape()->setLocalScaling(m_cci.m_scaling); - - //printf("no inertia recalc for fixed objects with mass=0\n"); - btRigidBody* body = GetRigidBody(); - if (body && m_cci.m_mass) - { - body->getCollisionShape()->calculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor); - body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor); - } - - } - } -} - -void CcdPhysicsController::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]); - ForceWorldTransform(rot, pos); - - if (!IsDynamic() && !GetConstructionInfo().m_bSensor && !GetCharacterController()) - { - btCollisionObject* object = GetRigidBody(); - object->setActivationState(ACTIVE_TAG); - object->setCollisionFlags(object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - } -} - -MT_Scalar CcdPhysicsController::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; - -} - -void CcdPhysicsController::SetMass(MT_Scalar newmass) -{ - btRigidBody *body = GetRigidBody(); - if (body && !m_suspended && newmass>MT_EPSILON && GetMass()>MT_EPSILON) - { - btBroadphaseProxy* handle = body->getBroadphaseHandle(); - GetPhysicsEnvironment()->UpdateCcdPhysicsController(this, - newmass, - body->getCollisionFlags(), - handle->m_collisionFilterGroup, - handle->m_collisionFilterMask); - } -} - - // physics methods -void CcdPhysicsController::ApplyTorque(const MT_Vector3& torquein,bool local) -{ - btVector3 torque(torquein.x(),torquein.y(),torquein.z()); - btTransform xform = m_object->getWorldTransform(); - - - if (m_object && torque.length2() > (SIMD_EPSILON*SIMD_EPSILON)) - { - btRigidBody* body = GetRigidBody(); - m_object->activate(); - if (m_object->isStaticObject()) - { - if (!m_cci.m_bSensor) - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - return; - } - if (local) - { - torque = xform.getBasis()*torque; - } - if (body) - { - if (m_cci.m_bRigid) - { - body->applyTorque(torque); - } - else - { - //workaround for incompatibility between 'DYNAMIC' game object, and angular factor - //a DYNAMIC object has some inconsistency: it has no angular effect due to collisions, but still has torque - const btVector3 angFac = body->getAngularFactor(); - btVector3 tmpFac(1,1,1); - body->setAngularFactor(tmpFac); - body->applyTorque(torque); - body->setAngularFactor(angFac); - } - } - } -} - -void CcdPhysicsController::ApplyForce(const MT_Vector3& forcein,bool local) -{ - btVector3 force(forcein.x(),forcein.y(),forcein.z()); - - - if (m_object && force.length2() > (SIMD_EPSILON*SIMD_EPSILON)) - { - m_object->activate(); - if (m_object->isStaticObject()) - { - if (!m_cci.m_bSensor) - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - return; - } - btTransform xform = m_object->getWorldTransform(); - - if (local) - { - force = xform.getBasis()*force; - } - btRigidBody* body = GetRigidBody(); - if (body) - body->applyCentralForce(force); - btSoftBody* soft = GetSoftBody(); - if (soft) - { - // the force is applied on each node, must reduce it in the same extend - if (soft->m_nodes.size() > 0) - force /= soft->m_nodes.size(); - soft->addForce(force); - } - } -} -void CcdPhysicsController::SetAngularVelocity(const MT_Vector3& ang_vel,bool local) -{ - btVector3 angvel(ang_vel.x(),ang_vel.y(),ang_vel.z()); - - /* Refuse tiny tiny velocities, as they might cause instabilities. */ - float vel_squared = angvel.length2(); - if (vel_squared > 0 && vel_squared <= (SIMD_EPSILON*SIMD_EPSILON)) - angvel = btVector3(0, 0, 0); - - if (m_object) - { - m_object->activate(true); - if (m_object->isStaticObject()) - { - if (!m_cci.m_bSensor) - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - return; - } - btTransform xform = m_object->getWorldTransform(); - if (local) - { - angvel = xform.getBasis()*angvel; - } - btRigidBody* body = GetRigidBody(); - if (body) - body->setAngularVelocity(angvel); - } - -} -void CcdPhysicsController::SetLinearVelocity(const MT_Vector3& lin_vel,bool local) -{ - btVector3 linVel(lin_vel.x(),lin_vel.y(),lin_vel.z()); - - /* Refuse tiny tiny velocities, as they might cause instabilities. */ - float vel_squared = linVel.length2(); - if (vel_squared > 0 && vel_squared <= (SIMD_EPSILON*SIMD_EPSILON)) - linVel = btVector3(0, 0, 0); - - if (m_object) - { - m_object->activate(true); - if (m_object->isStaticObject()) - { - if (!m_cci.m_bSensor) - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - return; - } - - btSoftBody* soft = GetSoftBody(); - if (soft) - { - if (local) - { - linVel = m_softbodyStartTrans.getBasis()*linVel; - } - soft->setVelocity(linVel); - } else - { - btTransform xform = m_object->getWorldTransform(); - if (local) - { - linVel = xform.getBasis()*linVel; - } - btRigidBody* body = GetRigidBody(); - if (body) - body->setLinearVelocity(linVel); - } - } -} -void CcdPhysicsController::ApplyImpulse(const MT_Point3& attach, const MT_Vector3& impulsein, bool local) -{ - btVector3 pos; - btVector3 impulse(impulsein.x(), impulsein.y(), impulsein.z()); - - if (m_object && impulse.length2() > (SIMD_EPSILON*SIMD_EPSILON)) - { - m_object->activate(); - if (m_object->isStaticObject()) - { - if (!m_cci.m_bSensor) - m_object->setCollisionFlags(m_object->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); - return; - } - - btTransform xform = m_object->getWorldTransform(); - - if (local) - { - pos = btVector3(attach.x(), attach.y(), attach.z()); - impulse = xform.getBasis() * impulse; - } - else { - /* If the point of impulse application is not equal to the object position - * then an angular momentum is generated in the object*/ - pos = btVector3(attach.x()-xform.getOrigin().x(), attach.y()-xform.getOrigin().y(), attach.z()-xform.getOrigin().z()); - } - - btRigidBody* body = GetRigidBody(); - if (body) - body->applyImpulse(impulse,pos); - - } - -} - -void CcdPhysicsController::Jump() -{ - if (m_object && m_characterController) - m_characterController->jump(); -} - -void CcdPhysicsController::SetActive(bool active) -{ -} - -float CcdPhysicsController::GetLinearDamping() const -{ - const btRigidBody* body = GetRigidBody(); - if (body) - return body->getLinearDamping(); - return 0; -} - -float CcdPhysicsController::GetAngularDamping() const -{ - const btRigidBody* body = GetRigidBody(); - if (body) - return body->getAngularDamping(); - return 0; -} - -void CcdPhysicsController::SetLinearDamping(float damping) -{ - SetDamping(damping, GetAngularDamping()); -} - -void CcdPhysicsController::SetAngularDamping(float damping) -{ - SetDamping(GetLinearDamping(), damping); -} - -void CcdPhysicsController::SetDamping(float linear, float angular) -{ - btRigidBody* body = GetRigidBody(); - if (!body) return; - - body->setDamping(linear, angular); -} - - - // reading out information from physics -MT_Vector3 CcdPhysicsController::GetLinearVelocity() -{ - btRigidBody* body = GetRigidBody(); - if (body) - { - const btVector3& linvel = body->getLinearVelocity(); - return MT_Vector3(linvel.x(), linvel.y(), linvel.z()); - } - - return MT_Vector3(0.f, 0.f, 0.f); -} - -MT_Vector3 CcdPhysicsController::GetAngularVelocity() -{ - btRigidBody* body = GetRigidBody(); - if (body) - { - const btVector3& angvel= body->getAngularVelocity(); - return MT_Vector3(angvel.x(), angvel.y(), angvel.z()); - } - - return MT_Vector3(0.f, 0.f, 0.f); -} - -MT_Vector3 CcdPhysicsController::GetVelocity(const MT_Point3 &posin) -{ - btVector3 pos(posin.x(), posin.y(), posin.z()); - btRigidBody* body = GetRigidBody(); - if (body) - { - btVector3 linvel = body->getVelocityInLocalPoint(pos); - return MT_Vector3(linvel.x(), linvel.y(), linvel.z()); - } - - return MT_Vector3(0.f, 0.f, 0.f); -} - -MT_Vector3 CcdPhysicsController::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; -} - - // dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted -void CcdPhysicsController::SetRigidBody(bool rigid) -{ - btRigidBody* body = GetRigidBody(); - if (body) - { - m_cci.m_bRigid = rigid; - if (!rigid) { - body->setAngularFactor(0.f); - body->setAngularVelocity(btVector3(0.f, 0.f, 0.f)); - } - else - body->setAngularFactor(m_cci.m_angularFactor); - } -} - - // clientinfo for raycasts for example -void* CcdPhysicsController::GetNewClientInfo() -{ - return m_newClientInfo; -} -void CcdPhysicsController::SetNewClientInfo(void* clientinfo) -{ - m_newClientInfo = clientinfo; - - if (m_cci.m_bSensor) - { - // use a different callback function for sensor object, - // bullet will not synchronize, we must do it explicitly - SG_Callbacks& callbacks = KX_GameObject::GetClientObject((KX_ClientObjectInfo*)clientinfo)->GetSGNode()->GetCallBackFunctions(); - callbacks.m_updatefunc = KX_GameObject::SynchronizeTransformFunc; - } -} - - -void CcdPhysicsController::UpdateDeactivation(float timeStep) -{ - btRigidBody* body = GetRigidBody(); - if (body) - { - body->updateDeactivation( timeStep); - } -} - -bool CcdPhysicsController::WantsSleeping() -{ - btRigidBody* body = GetRigidBody(); - if (body) - { - return body->wantsSleeping(); - } - //check it out - return true; -} -/* 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 CcdPhysicsController::AddCompoundChild(PHY_IPhysicsController* child) -{ - if (child == NULL || !IsCompound()) - return; - // other controller must be a bullet controller too - // verify that body and shape exist and match - CcdPhysicsController* childCtrl = dynamic_cast<CcdPhysicsController*>(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) - 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.0f/rootScale[0]; - rootScale[1] = 1.0f/rootScale[1]; - rootScale[2] = 1.0f/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()->RemoveCcdPhysicsController(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 CcdPhysicsController::RemoveCompoundChild(PHY_IPhysicsController* child) -{ - if (child == NULL || !IsCompound()) - return; - // other controller must be a bullet controller too - // verify that body and shape exist and match - CcdPhysicsController* childCtrl = dynamic_cast<CcdPhysicsController*>(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()->AddCcdPhysicsController(childCtrl); -} - -PHY_IPhysicsController* CcdPhysicsController::GetReplica() -{ - CcdPhysicsController* replica = new CcdPhysicsController(*this); - return replica; -} - -// Keeping this separate for now, maybe we can combine it with GetReplica()... -PHY_IPhysicsController* CcdPhysicsController::GetReplicaForSensors() -{ - // This is used only to replicate Near and Radar sensor controllers - // The replication of object physics controller is done in KX_BulletPhysicsController::GetReplica() - CcdConstructionInfo cinfo = m_cci; - if (m_shapeInfo) - { - // This situation does not normally happen - cinfo.m_collisionShape = m_shapeInfo->CreateBulletShape(m_cci.m_margin, m_cci.m_bGimpact, !m_cci.m_bSoft); - } - else if (m_collisionShape) - { - switch (m_collisionShape->getShapeType()) - { - case SPHERE_SHAPE_PROXYTYPE: - { - btSphereShape* orgShape = (btSphereShape*)m_collisionShape; - cinfo.m_collisionShape = new btSphereShape(*orgShape); - break; - } - - case CONE_SHAPE_PROXYTYPE: - { - btConeShape* orgShape = (btConeShape*)m_collisionShape; - cinfo.m_collisionShape = new btConeShape(*orgShape); - break; - } - - default: - { - return 0; - } - } - } - - cinfo.m_MotionState = new DefaultMotionState(); - cinfo.m_shapeInfo = m_shapeInfo; - - CcdPhysicsController* replica = new CcdPhysicsController(cinfo); - return replica; -} - -/* Refresh the physics object from either an object or a mesh. - * from_gameobj and from_meshobj can be NULL - * - * when setting the mesh, the following vars get priority - * 1) from_meshobj - creates the phys mesh from RAS_MeshObject - * 2) from_gameobj - creates the phys mesh from the DerivedMesh where possible, else the RAS_MeshObject - * 3) this - update the phys mesh from DerivedMesh or RAS_MeshObject - * - * Most of the logic behind this is in m_shapeInfo->UpdateMesh(...) - */ -bool CcdPhysicsController::ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_MeshObject *from_meshobj) -{ - if (m_shapeInfo->m_shapeType != PHY_SHAPE_MESH) - return false; - - if (!from_gameobj && !from_meshobj) - from_gameobj = KX_GameObject::GetClientObject((KX_ClientObjectInfo*)GetNewClientInfo()); - - /* updates the arrays used for making the new bullet mesh */ - m_shapeInfo->UpdateMesh(from_gameobj, from_meshobj); - - /* create the new bullet mesh */ - GetPhysicsEnvironment()->UpdateCcdPhysicsControllerShape(m_shapeInfo); - - return true; -} - -void CcdPhysicsController::ReplicateConstraints(KX_GameObject *replica, std::vector<KX_GameObject*> constobj) -{ - if (replica->GetConstraints().size() == 0 || !replica->GetPhysicsController()) - return; - - PHY_IPhysicsEnvironment *physEnv = GetPhysicsEnvironment(); - - vector<bRigidBodyJointConstraint*> constraints = replica->GetConstraints(); - vector<bRigidBodyJointConstraint*>::iterator consit; - - /* Object could have some constraints, iterate over all of theme to ensure that every constraint is recreated. */ - for (consit = constraints.begin(); consit != constraints.end(); ++consit) { - /* Try to find the constraint targets in the list of group objects. */ - bRigidBodyJointConstraint *dat = (*consit); - vector<KX_GameObject*>::iterator memit; - for (memit = constobj.begin(); memit != constobj.end(); ++memit) { - KX_GameObject *member = (*memit); - /* If the group member is the actual target for the constraint. */ - if (dat->tar->id.name + 2 == member->GetName() && member->GetPhysicsController()) - physEnv->SetupObjectConstraints(replica, member, dat); - } - } - -} - -/////////////////////////////////////////////////////////// -///A small utility class, DefaultMotionState -/// -/////////////////////////////////////////////////////////// - -DefaultMotionState::DefaultMotionState() -{ - m_worldTransform.setIdentity(); - m_localScaling.setValue(1.f,1.f,1.f); -} - - -DefaultMotionState::~DefaultMotionState() -{ - -} - -void DefaultMotionState::GetWorldPosition(float& posX,float& posY,float& posZ) -{ - posX = m_worldTransform.getOrigin().x(); - posY = m_worldTransform.getOrigin().y(); - posZ = m_worldTransform.getOrigin().z(); -} - -void DefaultMotionState::GetWorldScaling(float& scaleX,float& scaleY,float& scaleZ) -{ - scaleX = m_localScaling.getX(); - scaleY = m_localScaling.getY(); - scaleZ = m_localScaling.getZ(); -} - -void DefaultMotionState::GetWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal) -{ - btQuaternion quat = m_worldTransform.getRotation(); - quatIma0 = quat.x(); - quatIma1 = quat.y(); - quatIma2 = quat.z(); - quatReal = quat[3]; -} - -void DefaultMotionState::GetWorldOrientation(float* ori) -{ - m_worldTransform.getBasis().getOpenGLSubMatrix(ori); -} - -void DefaultMotionState::SetWorldOrientation(const float* ori) -{ - m_worldTransform.getBasis().setFromOpenGLSubMatrix(ori); -} -void DefaultMotionState::SetWorldPosition(float posX,float posY,float posZ) -{ - btVector3 pos(posX,posY,posZ); - m_worldTransform.setOrigin( pos ); -} - -void DefaultMotionState::SetWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal) -{ - btQuaternion orn(quatIma0,quatIma1,quatIma2,quatReal); - m_worldTransform.setRotation( orn ); -} - -void DefaultMotionState::CalculateWorldTransformations() -{ - -} - -// Shape constructor -std::map<RAS_MeshObject*, CcdShapeConstructionInfo*> CcdShapeConstructionInfo::m_meshShapeMap; - -CcdShapeConstructionInfo* CcdShapeConstructionInfo::FindMesh(RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope) -{ - if (polytope || dm) - // not yet supported - return NULL; - - std::map<RAS_MeshObject*,CcdShapeConstructionInfo*>::const_iterator mit = m_meshShapeMap.find(mesh); - if (mit != m_meshShapeMap.end()) - return mit->second; - return NULL; -} - -bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject *meshobj, DerivedMesh *dm, bool polytope) -{ - int numpolys, numverts; - - // assume no shape information - // no support for dynamic change of shape yet - assert(IsUnused()); - m_shapeType = PHY_SHAPE_NONE; - m_meshObject = NULL; - bool free_dm = false; - - // No mesh object or mesh has no polys - if (!meshobj || !meshobj->HasColliderPolygon()) { - m_vertexArray.clear(); - m_polygonIndexArray.clear(); - m_triFaceArray.clear(); - m_triFaceUVcoArray.clear(); - return false; - } - - if (!dm) { - free_dm = true; - dm = CDDM_from_mesh(meshobj->GetMesh()); - } - - // Some meshes with modifiers returns 0 polys, call DM_ensure_tessface avoid this. - DM_ensure_tessface(dm); - - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getTessFaceArray(dm); - numpolys = dm->getNumTessFaces(dm); - numverts = dm->getNumVerts(dm); - MTFace *tface = (MTFace *)dm->getTessFaceDataArray(dm, CD_MTFACE); - - /* double lookup */ - const int *index_mf_to_mpoly = (const int *)dm->getTessFaceDataArray(dm, CD_ORIGINDEX); - const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX); - if (!index_mf_to_mpoly) { - index_mp_to_orig = NULL; - } - - m_shapeType = (polytope) ? PHY_SHAPE_POLYTOPE : PHY_SHAPE_MESH; - - /* Convert blender geometry into bullet mesh, need these vars for mapping */ - std::vector<bool> vert_tag_array(numverts, false); - unsigned int tot_bt_verts = 0; - - if (polytope) { - // Tag verts we're using - for (int p2 = 0; p2 < numpolys; p2++) { - MFace *mf = &mface[p2]; - const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2; - RAS_Polygon *poly = (origi != ORIGINDEX_NONE) ? meshobj->GetPolygon(origi) : NULL; - - // only add polygons that have the collision flag set - if (poly && poly->IsCollider()) { - if (!vert_tag_array[mf->v1]) { - vert_tag_array[mf->v1] = true; - tot_bt_verts++; - } - if (!vert_tag_array[mf->v2]) { - vert_tag_array[mf->v2] = true; - tot_bt_verts++; - } - if (!vert_tag_array[mf->v3]) { - vert_tag_array[mf->v3] = true; - tot_bt_verts++; - } - if (mf->v4 && !vert_tag_array[mf->v4]) { - vert_tag_array[mf->v4] = true; - tot_bt_verts++; - } - } - } - - /* Can happen with ngons */ - if (!tot_bt_verts) { - goto cleanup_empty_mesh; - } - - m_vertexArray.resize(tot_bt_verts * 3); - - btScalar *bt = &m_vertexArray[0]; - - for (int p2 = 0; p2 < numpolys; p2++) { - MFace *mf = &mface[p2]; - const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2; - RAS_Polygon *poly = (origi != ORIGINDEX_NONE) ? meshobj->GetPolygon(origi) : NULL; - - // only add polygons that have the collisionflag set - if (poly->IsCollider()) { - if (vert_tag_array[mf->v1]) { - const float *vtx = mvert[mf->v1].co; - vert_tag_array[mf->v1] = false; - *bt++ = vtx[0]; - *bt++ = vtx[1]; - *bt++ = vtx[2]; - } - if (vert_tag_array[mf->v2]) { - const float *vtx = mvert[mf->v2].co; - vert_tag_array[mf->v2] = false; - *bt++ = vtx[0]; - *bt++ = vtx[1]; - *bt++ = vtx[2]; - } - if (vert_tag_array[mf->v3]) { - const float *vtx = mvert[mf->v3].co; - vert_tag_array[mf->v3] = false; - *bt++ = vtx[0]; - *bt++ = vtx[1]; - *bt++ = vtx[2]; - } - if (mf->v4 && vert_tag_array[mf->v4]) { - const float *vtx = mvert[mf->v4].co; - vert_tag_array[mf->v4] = false; - *bt++ = vtx[0]; - *bt++ = vtx[1]; - *bt++ = vtx[2]; - } - } - } - } - else { - unsigned int tot_bt_tris = 0; - std::vector<int> vert_remap_array(numverts, 0); - - // Tag verts we're using - for (int p2 = 0; p2 < numpolys; p2++) { - MFace *mf = &mface[p2]; - const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2; - RAS_Polygon *poly = (origi != ORIGINDEX_NONE) ? meshobj->GetPolygon(origi) : NULL; - - // only add polygons that have the collision flag set - if (poly && poly->IsCollider()) { - if (!vert_tag_array[mf->v1]) { - vert_tag_array[mf->v1] = true; - vert_remap_array[mf->v1] = tot_bt_verts; - tot_bt_verts++; - } - if (!vert_tag_array[mf->v2]) { - vert_tag_array[mf->v2] = true; - vert_remap_array[mf->v2] = tot_bt_verts; - tot_bt_verts++; - } - if (!vert_tag_array[mf->v3]) { - vert_tag_array[mf->v3] = true; - vert_remap_array[mf->v3] = tot_bt_verts; - tot_bt_verts++; - } - if (mf->v4 && !vert_tag_array[mf->v4]) { - vert_tag_array[mf->v4] = true; - vert_remap_array[mf->v4] = tot_bt_verts; - tot_bt_verts++; - } - tot_bt_tris += (mf->v4 ? 2 : 1); /* a quad or a tri */ - } - } - - /* Can happen with ngons */ - if (!tot_bt_verts) { - goto cleanup_empty_mesh; - } - - m_vertexArray.resize(tot_bt_verts * 3); - m_polygonIndexArray.resize(tot_bt_tris); - m_triFaceArray.resize(tot_bt_tris * 3); - btScalar *bt = &m_vertexArray[0]; - int *poly_index_pt = &m_polygonIndexArray[0]; - int *tri_pt = &m_triFaceArray[0]; - - UVco *uv_pt = NULL; - if (tface) { - m_triFaceUVcoArray.resize(tot_bt_tris * 3); - uv_pt = &m_triFaceUVcoArray[0]; - } - else - m_triFaceUVcoArray.clear(); - - for (int p2 = 0; p2 < numpolys; p2++) { - MFace *mf = &mface[p2]; - MTFace *tf = (tface) ? &tface[p2] : NULL; - const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2; - RAS_Polygon *poly = (origi != ORIGINDEX_NONE) ? meshobj->GetPolygon(origi) : NULL; - - // only add polygons that have the collisionflag set - if (poly && poly->IsCollider()) { - MVert *v1 = &mvert[mf->v1]; - MVert *v2 = &mvert[mf->v2]; - MVert *v3 = &mvert[mf->v3]; - - // the face indices - tri_pt[0] = vert_remap_array[mf->v1]; - tri_pt[1] = vert_remap_array[mf->v2]; - tri_pt[2] = vert_remap_array[mf->v3]; - tri_pt = tri_pt + 3; - if (tf) { - uv_pt[0].uv[0] = tf->uv[0][0]; - uv_pt[0].uv[1] = tf->uv[0][1]; - uv_pt[1].uv[0] = tf->uv[1][0]; - uv_pt[1].uv[1] = tf->uv[1][1]; - uv_pt[2].uv[0] = tf->uv[2][0]; - uv_pt[2].uv[1] = tf->uv[2][1]; - uv_pt += 3; - } - - // m_polygonIndexArray - *poly_index_pt = origi; - poly_index_pt++; - - // the vertex location - if (vert_tag_array[mf->v1]) { /* *** v1 *** */ - vert_tag_array[mf->v1] = false; - *bt++ = v1->co[0]; - *bt++ = v1->co[1]; - *bt++ = v1->co[2]; - } - if (vert_tag_array[mf->v2]) { /* *** v2 *** */ - vert_tag_array[mf->v2] = false; - *bt++ = v2->co[0]; - *bt++ = v2->co[1]; - *bt++ = v2->co[2]; - } - if (vert_tag_array[mf->v3]) { /* *** v3 *** */ - vert_tag_array[mf->v3] = false; - *bt++ = v3->co[0]; - *bt++ = v3->co[1]; - *bt++ = v3->co[2]; - } - - if (mf->v4) - { - MVert *v4 = &mvert[mf->v4]; - - tri_pt[0] = vert_remap_array[mf->v1]; - tri_pt[1] = vert_remap_array[mf->v3]; - tri_pt[2] = vert_remap_array[mf->v4]; - tri_pt = tri_pt + 3; - if (tf) - { - uv_pt[0].uv[0] = tf->uv[0][0]; - uv_pt[0].uv[1] = tf->uv[0][1]; - uv_pt[1].uv[0] = tf->uv[2][0]; - uv_pt[1].uv[1] = tf->uv[2][1]; - uv_pt[2].uv[0] = tf->uv[3][0]; - uv_pt[2].uv[1] = tf->uv[3][1]; - uv_pt += 3; - } - - // m_polygonIndexArray - *poly_index_pt = origi; - poly_index_pt++; - - // the vertex location - if (vert_tag_array[mf->v4]) { /* *** v4 *** */ - vert_tag_array[mf->v4] = false; - *bt++ = v4->co[0]; - *bt++ = v4->co[1]; - *bt++ = v4->co[2]; - } - } - } - } - - - /* If this ever gets confusing, print out an OBJ file for debugging */ -#if 0 - printf("# vert count %d\n", m_vertexArray.size()); - for (i = 0; i < m_vertexArray.size(); i += 1) { - printf("v %.6f %.6f %.6f\n", m_vertexArray[i].x(), m_vertexArray[i].y(), m_vertexArray[i].z()); - } - - printf("# face count %d\n", m_triFaceArray.size()); - for (i = 0; i < m_triFaceArray.size(); i += 3) { - printf("f %d %d %d\n", m_triFaceArray[i] + 1, m_triFaceArray[i + 1] + 1, m_triFaceArray[i + 2] + 1); - } -#endif - - } - -#if 0 - if (validpolys == false) - { - // should not happen - m_shapeType = PHY_SHAPE_NONE; - return false; - } -#endif - - m_meshObject = meshobj; - if (free_dm) { - dm->release(dm); - dm = NULL; - } - - // sharing only on static mesh at present, if you change that, you must also change in FindMesh - if (!polytope && !dm) { - // triangle shape can be shared, store the mesh object in the map - m_meshShapeMap.insert(std::pair<RAS_MeshObject *, CcdShapeConstructionInfo *>(meshobj, this)); - } - return true; - - -cleanup_empty_mesh: - m_shapeType = PHY_SHAPE_NONE; - m_meshObject = NULL; - m_vertexArray.clear(); - m_polygonIndexArray.clear(); - m_triFaceArray.clear(); - m_triFaceUVcoArray.clear(); - if (free_dm) { - dm->release(dm); - } - return false; -} - -#include <cstdio> - -/* Updates the arrays used by CreateBulletShape(), - * take care that recalcLocalAabb() runs after CreateBulletShape is called. - * */ -bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject *gameobj, class RAS_MeshObject *meshobj) -{ - int numpolys; - int numverts; - - unsigned int tot_bt_tris = 0; - unsigned int tot_bt_verts = 0; - - int i, j; - int v_orig; - - /* Use for looping over verts in a face as a try or 2 tris */ - const int quad_verts[7] = {0, 1, 2, 0, 2, 3, -1}; - const int tri_verts[4] = {0, 1, 2, -1}; - const int *fv_pt; - - if (!gameobj && !meshobj) - return false; - - if (m_shapeType != PHY_SHAPE_MESH) - return false; - - RAS_Deformer *deformer = gameobj ? gameobj->GetDeformer() : NULL; - DerivedMesh *dm = NULL; - - if (deformer) - dm = deformer->GetPhysicsMesh(); - - /* get the mesh from the object if not defined */ - if (!meshobj) { - /* modifier mesh */ - if (dm) - meshobj = deformer->GetRasMesh(); - - /* game object first mesh */ - if (!meshobj) { - if (gameobj->GetMeshCount() > 0) { - meshobj = gameobj->GetMesh(0); - } - } - } - - if (dm && deformer->GetRasMesh() == meshobj) { - /* - * Derived Mesh Update - * - * */ - - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getTessFaceArray(dm); - numpolys = dm->getNumTessFaces(dm); - numverts = dm->getNumVerts(dm); - - /* double lookup */ - const int *index_mf_to_mpoly = (const int *)dm->getTessFaceDataArray(dm, CD_ORIGINDEX); - const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX); - if (!index_mf_to_mpoly) { - index_mp_to_orig = NULL; - } - - MFace *mf; - MVert *mv; - - if (CustomData_has_layer(&dm->faceData, CD_MTFACE)) { - MTFace *tface = (MTFace *)dm->getTessFaceDataArray(dm, CD_MTFACE); - MTFace *tf; - - std::vector<bool> vert_tag_array(numverts, false); - std::vector<int> vert_remap_array(numverts, 0); - - for (mf = mface, tf = tface, i = 0; i < numpolys; mf++, tf++, i++) { - // 2.8x TODO: use GEMAT_NOPHYSICS. - // if (tf->mode & TF_DYNAMIC) - { - int flen; - - if (mf->v4) { - tot_bt_tris += 2; - flen = 4; - } - else { - tot_bt_tris++; - flen = 3; - } - - for (j = 0; j < flen; j++) { - v_orig = (*(&mf->v1 + j)); - - if (!vert_tag_array[v_orig]) { - vert_tag_array[v_orig] = true; - vert_remap_array[v_orig] = tot_bt_verts; - tot_bt_verts++; - } - } - } - } - - m_vertexArray.resize(tot_bt_verts * 3); - btScalar *bt = &m_vertexArray[0]; - - m_triFaceArray.resize(tot_bt_tris * 3); - int *tri_pt = &m_triFaceArray[0]; - - m_triFaceUVcoArray.resize(tot_bt_tris * 3); - UVco *uv_pt = &m_triFaceUVcoArray[0]; - - m_polygonIndexArray.resize(tot_bt_tris); - int *poly_index_pt = &m_polygonIndexArray[0]; - - for (mf = mface, tf = tface, i = 0; i < numpolys; mf++, tf++, i++) { - // 2.8x TODO: use GEMAT_NOPHYSICS. - // if (tf->mode & TF_DYNAMIC) - { - int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i; - - if (mf->v4) { - fv_pt = quad_verts; - *poly_index_pt++ = origi; - *poly_index_pt++ = origi; - } - else { - fv_pt = tri_verts; - *poly_index_pt++ = origi; - } - - for (; *fv_pt > -1; fv_pt++) { - v_orig = (*(&mf->v1 + (*fv_pt))); - - if (vert_tag_array[v_orig]) - { - mv = mvert + v_orig; - *bt++ = mv->co[0]; - *bt++ = mv->co[1]; - *bt++ = mv->co[2]; - - vert_tag_array[v_orig] = false; - } - *tri_pt++ = vert_remap_array[v_orig]; - uv_pt->uv[0] = tf->uv[*fv_pt][0]; - uv_pt->uv[1] = tf->uv[*fv_pt][1]; - uv_pt++; - } - } - } - } - else { - /* no need for a vertex mapping. simple/fast */ - - tot_bt_verts = numverts; - - for (mf = mface, i = 0; i < numpolys; mf++, i++) { - tot_bt_tris += (mf->v4 ? 2 : 1); - } - - m_vertexArray.resize(tot_bt_verts * 3); - btScalar *bt = &m_vertexArray[0]; - - m_triFaceArray.resize(tot_bt_tris * 3); - int *tri_pt = &m_triFaceArray[0]; - - m_polygonIndexArray.resize(tot_bt_tris); - int *poly_index_pt = &m_polygonIndexArray[0]; - - m_triFaceUVcoArray.clear(); - - for (mv = mvert, i = 0; i < numverts; mv++, i++) { - *bt++ = mv->co[0]; *bt++ = mv->co[1]; *bt++ = mv->co[2]; - } - - for (mf = mface, i = 0; i < numpolys; mf++, i++) { - int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i; - - if (mf->v4) { - fv_pt = quad_verts; - *poly_index_pt++ = origi; - *poly_index_pt++ = origi; - } - else { - fv_pt = tri_verts; - *poly_index_pt++ = origi; - } - - for (; *fv_pt > -1; fv_pt++) - *tri_pt++ = (*(&mf->v1 + (*fv_pt))); - } - } - } - else { /* - * RAS Mesh Update - * - * */ - /* Note!, gameobj can be NULL here */ - - /* transverts are only used for deformed RAS_Meshes, the RAS_TexVert data - * is too hard to get at, see below for details */ - float(*transverts)[3] = NULL; - int transverts_tot = 0; /* with deformed meshes - should always be greater than the max orginal index, or we get crashes */ - - if (deformer) { - /* map locations from the deformed array - * - * Could call deformer->Update(); but rely on redraw updating. - * */ - transverts = deformer->GetTransVerts(&transverts_tot); - } - - // Tag verts we're using - numpolys = meshobj->NumPolygons(); - numverts = meshobj->m_sharedvertex_map.size(); - const float *xyz; - - - std::vector<bool> vert_tag_array(numverts, false); - std::vector<int> vert_remap_array(numverts, 0); - - for (int p = 0; p < numpolys; p++) { - RAS_Polygon *poly = meshobj->GetPolygon(p); - if (poly->IsCollider()) { - for (i = 0; i < poly->VertexCount(); i++) { - v_orig = poly->GetVertex(i)->getOrigIndex(); - if (!vert_tag_array[v_orig]) { - vert_tag_array[v_orig] = true; - vert_remap_array[v_orig] = tot_bt_verts; - tot_bt_verts++; - } - } - tot_bt_tris += (poly->VertexCount() == 4 ? 2 : 1); - } - } - - // This case happens when none of the polys are colliders - if (tot_bt_tris == 0 || tot_bt_verts == 0) - return false; - - m_vertexArray.resize(tot_bt_verts * 3); - btScalar *bt = &m_vertexArray[0]; - - m_triFaceArray.resize(tot_bt_tris * 3); - int *tri_pt = &m_triFaceArray[0]; - - /* cant be used for anything useful in this case, since we don't rely on the original mesh - * will just be an array like pythons range(tot_bt_tris) */ - m_polygonIndexArray.resize(tot_bt_tris); - - - int p = 0; - int t = 0; - while (t < tot_bt_tris) { - RAS_Polygon *poly = meshobj->GetPolygon(p); - - if (poly->IsCollider()) { - /* quad or tri loop */ - fv_pt = (poly->VertexCount() == 3 ? tri_verts : quad_verts); - - for (; *fv_pt > -1; fv_pt++) { - v_orig = poly->GetVertex(*fv_pt)->getOrigIndex(); - if (vert_tag_array[v_orig]) { - if (transverts) { - /* deformed mesh, using RAS_TexVert locations would be too troublesome - * because they are use the gameob as a hash in the material slot */ - *bt++ = transverts[v_orig][0]; - *bt++ = transverts[v_orig][1]; - *bt++ = transverts[v_orig][2]; - } - else { - /* static mesh python may have modified */ - xyz = meshobj->GetVertexLocation(v_orig); - *bt++ = xyz[0]; - *bt++ = xyz[1]; - *bt++ = xyz[2]; - } - vert_tag_array[v_orig] = false; - } - *tri_pt++ = vert_remap_array[v_orig]; - } - } - // first triangle - m_polygonIndexArray[t] = p; - - // if the poly is a quad we transform it in two triangles - if (poly->VertexCount() == 4) { - t++; - // second triangle - m_polygonIndexArray[t] = p; - } - t++; - p++; - } - } - -#if 0 - /* needs #include <cstdio> */ - printf("# vert count %d\n", m_vertexArray.size()); - for (int i = 0; i < m_vertexArray.size(); i += 3) { - printf("v %.6f %.6f %.6f\n", m_vertexArray[i], m_vertexArray[i + 1], m_vertexArray[i + 2]); - } - - printf("# face count %d\n", m_triFaceArray.size()); - for (int i = 0; i < m_triFaceArray.size(); i += 3) { - printf("f %d %d %d\n", m_triFaceArray[i] + 1, m_triFaceArray[i + 1] + 1, m_triFaceArray[i + 2] + 1); - } -#endif - - /* force recreation of the m_triangleIndexVertexArray. - * If this has multiple users we cant delete */ - if (m_triangleIndexVertexArray) { - m_forceReInstance = true; - } - - // Make sure to also replace the mesh in the shape map! Otherwise we leave dangling references when we free. - // Note, this whole business could cause issues with shared meshes. If we update one mesh, do we replace - // them all? - std::map<RAS_MeshObject *, CcdShapeConstructionInfo *>::iterator mit = m_meshShapeMap.find(m_meshObject); - if (mit != m_meshShapeMap.end()) { - m_meshShapeMap.erase(mit); - m_meshShapeMap[meshobj] = this; - } - - m_meshObject = meshobj; - - if (dm) { - dm->needsFree = 1; - dm->release(dm); - } - return true; -} - -bool CcdShapeConstructionInfo::SetProxy(CcdShapeConstructionInfo* shapeInfo) -{ - if (shapeInfo == NULL) - return false; - // no support for dynamic change - assert(IsUnused()); - m_shapeType = PHY_SHAPE_PROXY; - m_shapeProxy = shapeInfo; - return true; -} - -btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape(btScalar margin, bool useGimpact, bool useBvh) -{ - btCollisionShape* collisionShape = 0; - btCompoundShape* compoundShape = 0; - - if (m_shapeType == PHY_SHAPE_PROXY && m_shapeProxy != NULL) - return m_shapeProxy->CreateBulletShape(margin, useGimpact, useBvh); - - switch (m_shapeType) - { - default: - break; - - case PHY_SHAPE_BOX: - collisionShape = new btBoxShape(m_halfExtend); - collisionShape->setMargin(margin); - break; - - case PHY_SHAPE_SPHERE: - collisionShape = new btSphereShape(m_radius); - collisionShape->setMargin(margin); - break; - - case PHY_SHAPE_CYLINDER: - collisionShape = new btCylinderShapeZ(m_halfExtend); - collisionShape->setMargin(margin); - break; - - case PHY_SHAPE_CONE: - collisionShape = new btConeShapeZ(m_radius, m_height); - collisionShape->setMargin(margin); - break; - - case PHY_SHAPE_POLYTOPE: - collisionShape = new btConvexHullShape(&m_vertexArray[0], m_vertexArray.size()/3, 3*sizeof(btScalar)); - collisionShape->setMargin(margin); - break; - - case PHY_SHAPE_CAPSULE: - collisionShape = new btCapsuleShapeZ(m_radius, m_height); - collisionShape->setMargin(margin); - break; - - case PHY_SHAPE_MESH: - // Let's use the latest btScaledBvhTriangleMeshShape: it allows true sharing of - // triangle mesh information between duplicates => drastic performance increase when - // duplicating complex mesh objects. - // BUT it causes a small performance decrease when sharing is not required: - // 9 multiplications/additions and one function call for each triangle that passes the mid phase filtering - // One possible optimization is to use directly the btBvhTriangleMeshShape when the scale is 1,1,1 - // and btScaledBvhTriangleMeshShape otherwise. - if (useGimpact) { - if (!m_triangleIndexVertexArray || m_forceReInstance) { - if (m_triangleIndexVertexArray) - delete m_triangleIndexVertexArray; - - m_triangleIndexVertexArray = new btTriangleIndexVertexArray( - m_polygonIndexArray.size(), - m_triFaceArray.data(), - 3 * sizeof(int), - m_vertexArray.size() / 3, - &m_vertexArray[0], - 3 * sizeof(btScalar)); - m_forceReInstance = false; - } - - btGImpactMeshShape *gimpactShape = new btGImpactMeshShape(m_triangleIndexVertexArray); - gimpactShape->setMargin(margin); - gimpactShape->updateBound(); - collisionShape = gimpactShape; - } - else { - if (!m_triangleIndexVertexArray || m_forceReInstance) { - ///enable welding, only for the objects that need it (such as soft bodies) - if (0.0f != m_weldingThreshold1) { - btTriangleMesh *collisionMeshData = new btTriangleMesh(true, false); - collisionMeshData->m_weldingThreshold = m_weldingThreshold1; - bool removeDuplicateVertices = true; - // m_vertexArray not in multiple of 3 anymore, use m_triFaceArray - for (unsigned int i = 0; i < m_triFaceArray.size(); i += 3) { - btScalar *bt = &m_vertexArray[3 * m_triFaceArray[i]]; - btVector3 v1(bt[0], bt[1], bt[2]); - bt = &m_vertexArray[3 * m_triFaceArray[i + 1]]; - btVector3 v2(bt[0], bt[1], bt[2]); - bt = &m_vertexArray[3 * m_triFaceArray[i + 2]]; - btVector3 v3(bt[0], bt[1], bt[2]); - collisionMeshData->addTriangle(v1, v2, v3, removeDuplicateVertices); - } - m_triangleIndexVertexArray = collisionMeshData; - } - else { - m_triangleIndexVertexArray = new btTriangleIndexVertexArray( - m_polygonIndexArray.size(), - m_triFaceArray.data(), - 3 * sizeof(int), - m_vertexArray.size() / 3, - &m_vertexArray[0], - 3 * sizeof(btScalar)); - } - - m_forceReInstance = false; - } - - btBvhTriangleMeshShape *unscaledShape = new btBvhTriangleMeshShape(m_triangleIndexVertexArray, true, useBvh); - unscaledShape->setMargin(margin); - collisionShape = new btScaledBvhTriangleMeshShape(unscaledShape, btVector3(1.0f, 1.0f, 1.0f)); - collisionShape->setMargin(margin); - } - break; - - case PHY_SHAPE_COMPOUND: - if (m_shapeArray.size() > 0) - { - compoundShape = new btCompoundShape(); - for (std::vector<CcdShapeConstructionInfo*>::iterator sit = m_shapeArray.begin(); - sit != m_shapeArray.end(); - sit++) - { - collisionShape = (*sit)->CreateBulletShape(margin, useGimpact, useBvh); - if (collisionShape) - { - collisionShape->setLocalScaling((*sit)->m_childScale); - compoundShape->addChildShape((*sit)->m_childTrans, collisionShape); - } - } - collisionShape = compoundShape; - } - break; - } - return collisionShape; -} - -void CcdShapeConstructionInfo::AddShape(CcdShapeConstructionInfo* shapeInfo) -{ - m_shapeArray.push_back(shapeInfo); - shapeInfo->AddRef(); -} - -CcdShapeConstructionInfo::~CcdShapeConstructionInfo() -{ - for (std::vector<CcdShapeConstructionInfo*>::iterator sit = m_shapeArray.begin(); - sit != m_shapeArray.end(); - sit++) - { - (*sit)->Release(); - } - m_shapeArray.clear(); - - if (m_triangleIndexVertexArray) - delete m_triangleIndexVertexArray; - m_vertexArray.clear(); - if (m_shapeType == PHY_SHAPE_MESH && m_meshObject != NULL) - { - std::map<RAS_MeshObject*,CcdShapeConstructionInfo*>::iterator mit = m_meshShapeMap.find(m_meshObject); - if (mit != m_meshShapeMap.end() && mit->second == this) - { - m_meshShapeMap.erase(mit); - } - } - if (m_shapeType == PHY_SHAPE_PROXY && m_shapeProxy != NULL) - { - m_shapeProxy->Release(); - } -} - diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h deleted file mode 100644 index 831e7346df7..00000000000 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h +++ /dev/null @@ -1,832 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, -subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - -/** \file CcdPhysicsController.h - * \ingroup physbullet - */ - - -#ifndef __CCDPHYSICSCONTROLLER_H__ -#define __CCDPHYSICSCONTROLLER_H__ - -#include <vector> -#include <map> - -#include "PHY_IPhysicsController.h" - -/// PHY_IPhysicsController is the abstract simplified Interface to a physical object. -/// It contains the IMotionState and IDeformableMesh Interfaces. -#include "btBulletDynamicsCommon.h" -#include "BulletDynamics/Character/btKinematicCharacterController.h" -#include "LinearMath/btTransform.h" - -#include "PHY_IMotionState.h" -#include "PHY_ICharacter.h" - -extern float gDeactivationTime; -extern float gLinearSleepingTreshold; -extern float gAngularSleepingTreshold; -extern bool gDisableDeactivation; -class CcdPhysicsEnvironment; -class btMotionState; -class RAS_MeshObject; -struct DerivedMesh; -class btCollisionShape; - - -#define CCD_BSB_SHAPE_MATCHING 2 -#define CCD_BSB_BENDING_CONSTRAINTS 8 -#define CCD_BSB_AERO_VPOINT 16 /* aero model, Vertex normals are oriented toward velocity*/ -#define CCD_BSB_AERO_VTWOSIDE 32 /* aero model, Vertex normals are flipped to match velocity */ - -/* BulletSoftBody.collisionflags */ -#define CCD_BSB_COL_SDF_RS 2 /* SDF based rigid vs soft */ -#define CCD_BSB_COL_CL_RS 4 /* Cluster based rigid vs soft */ -#define CCD_BSB_COL_CL_SS 8 /* Cluster based soft vs soft */ -#define CCD_BSB_COL_VF_SS 16 /* Vertex/Face based soft vs soft */ - - -// Shape contructor -// It contains all the information needed to create a simple bullet shape at runtime -class CcdShapeConstructionInfo -{ -public: - struct UVco - { - float uv[2]; - }; - - static CcdShapeConstructionInfo* FindMesh(class RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope); - - CcdShapeConstructionInfo() : - m_shapeType(PHY_SHAPE_NONE), - m_radius(1.0f), - m_height(1.0f), - m_halfExtend(0.f,0.f,0.f), - m_childScale(1.0f,1.0f,1.0f), - m_userData(NULL), - m_refCount(1), - m_meshObject(NULL), - m_triangleIndexVertexArray(NULL), - m_forceReInstance(false), - m_weldingThreshold1(0.f), - m_shapeProxy(NULL) - { - m_childTrans.setIdentity(); - } - - ~CcdShapeConstructionInfo(); - - CcdShapeConstructionInfo* AddRef() - { - m_refCount++; - return this; - } - - int Release() - { - if (--m_refCount > 0) - return m_refCount; - delete this; - return 0; - } - - bool IsUnused(void) - { - return (m_meshObject==NULL && m_shapeArray.size() == 0 && m_shapeProxy == NULL); - } - - void AddShape(CcdShapeConstructionInfo* shapeInfo); - - btStridingMeshInterface *GetMeshInterface() - { - return m_triangleIndexVertexArray; - } - - CcdShapeConstructionInfo* GetChildShape(int i) - { - if (i < 0 || i >= (int)m_shapeArray.size()) - return NULL; - - return m_shapeArray.at(i); - } - int FindChildShape(CcdShapeConstructionInfo* shapeInfo, void* userData) - { - if (shapeInfo == NULL) - return -1; - for (int i=0; i<(int)m_shapeArray.size(); i++) - { - CcdShapeConstructionInfo* childInfo = m_shapeArray.at(i); - if ((userData == NULL || userData == childInfo->m_userData) && - (childInfo == shapeInfo || - (childInfo->m_shapeType == PHY_SHAPE_PROXY && - childInfo->m_shapeProxy == shapeInfo))) - return i; - } - return -1; - } - - bool RemoveChildShape(int i) - { - if (i < 0 || i >= (int)m_shapeArray.size()) - return false; - m_shapeArray.at(i)->Release(); - if (i < (int)m_shapeArray.size()-1) - m_shapeArray[i] = m_shapeArray.back(); - m_shapeArray.pop_back(); - return true; - } - - bool SetMesh(class RAS_MeshObject* mesh, struct DerivedMesh* dm, bool polytope); - RAS_MeshObject* GetMesh(void) - { - return m_meshObject; - } - - bool UpdateMesh(class KX_GameObject* gameobj, class RAS_MeshObject* mesh); - - - bool SetProxy(CcdShapeConstructionInfo* shapeInfo); - CcdShapeConstructionInfo* GetProxy(void) - { - return m_shapeProxy; - } - - btCollisionShape* CreateBulletShape(btScalar margin, bool useGimpact=false, bool useBvh=true); - - // member variables - PHY_ShapeType m_shapeType; - btScalar m_radius; - btScalar m_height; - btVector3 m_halfExtend; - btTransform m_childTrans; - btVector3 m_childScale; - void* m_userData; - btAlignedObjectArray<btScalar> m_vertexArray; // Contains both vertex array for polytope shape and - // triangle array for concave mesh shape. Each vertex is 3 consecutive values - // In this case a triangle is made of 3 consecutive points - std::vector<int> m_polygonIndexArray; // Contains the array of polygon index in the - // original mesh that correspond to shape triangles. - // only set for concave mesh shape. - - std::vector<int> m_triFaceArray; // Contains an array of triplets of face indices - // quads turn into 2 tris - - std::vector<UVco> m_triFaceUVcoArray; // Contains an array of pair of UV coordinate for each vertex of faces - // quads turn into 2 tris - - void setVertexWeldingThreshold1(float threshold) - { - m_weldingThreshold1 = threshold*threshold; - } -protected: - static std::map<RAS_MeshObject*, CcdShapeConstructionInfo*> m_meshShapeMap; - int m_refCount; // this class is shared between replicas - // keep track of users so that we can release it - RAS_MeshObject* m_meshObject; // Keep a pointer to the original mesh - // The list of vertexes and indexes for the triangle mesh, shared between Bullet shape. - btTriangleIndexVertexArray *m_triangleIndexVertexArray; - std::vector<CcdShapeConstructionInfo*> m_shapeArray; // for compound shapes - bool m_forceReInstance; //use gimpact for concave dynamic/moving collision detection - float m_weldingThreshold1; //welding closeby vertices together can improve softbody stability etc. - CcdShapeConstructionInfo* m_shapeProxy; // only used for PHY_SHAPE_PROXY, pointer to actual shape info - - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:CcdShapeConstructionInfo") -#endif -}; - -struct CcdConstructionInfo -{ - - ///CollisionFilterGroups provides some optional usage of basic collision filtering - ///this is done during broadphase, so very early in the pipeline - ///more advanced collision filtering should be done in btCollisionDispatcher::NeedsCollision - enum CollisionFilterGroups - { - DefaultFilter = 1, - StaticFilter = 2, - KinematicFilter = 4, - DebrisFilter = 8, - SensorFilter = 16, - CharacterFilter = 32, - AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorFilter | CharacterFilter, - }; - - - CcdConstructionInfo() - :m_localInertiaTensor(1.f, 1.f, 1.f), - m_gravity(0,0,0), - m_scaling(1.f,1.f,1.f), - m_linearFactor(0.f, 0.f, 0.f), - m_angularFactor(0.f, 0.f, 0.f), - m_mass(0.f), - m_clamp_vel_min(-1.f), - m_clamp_vel_max(-1.f), - m_clamp_angvel_min(0.0f), - m_clamp_angvel_max(0.0f), - m_restitution(0.1f), - m_friction(0.5f), - m_linearDamping(0.1f), - m_angularDamping(0.1f), - m_margin(0.06f), - m_gamesoftFlag(0), - m_soft_linStiff(1.f), - m_soft_angStiff(1.f), - m_soft_volume(1.f), - m_soft_viterations(0), - m_soft_piterations(1), - m_soft_diterations(0), - m_soft_citerations(4), - m_soft_kSRHR_CL(0.1f), - m_soft_kSKHR_CL(1.f), - m_soft_kSSHR_CL(0.5f), - m_soft_kSR_SPLT_CL(0.5f), - m_soft_kSK_SPLT_CL(0.5f), - m_soft_kSS_SPLT_CL(0.5f), - m_soft_kVCF(1.f), - m_soft_kDP(0.f), - m_soft_kDG(0.f), - m_soft_kLF(0.f), - m_soft_kPR(0.f), - m_soft_kVC(0.f), - m_soft_kDF(0.2f), - m_soft_kMT(0), - m_soft_kCHR(1.0f), - m_soft_kKHR(0.1f), - m_soft_kSHR(1.0f), - m_soft_kAHR(0.7f), - m_collisionFlags(0), - m_bDyna(false), - m_bRigid(false), - m_bSoft(false), - m_bSensor(false), - m_bCharacter(false), - m_bGimpact(false), - m_collisionFilterGroup(DefaultFilter), - m_collisionFilterMask(AllFilter), - m_collisionShape(0), - m_MotionState(0), - m_shapeInfo(0), - m_physicsEnv(0), - m_inertiaFactor(1.f), - m_do_anisotropic(false), - m_anisotropicFriction(1.f,1.f,1.f), - m_do_fh(false), - m_do_rot_fh(false), - m_fh_spring(0.f), - m_fh_damping(0.f), - m_fh_distance(1.f), - m_fh_normal(false) - // m_contactProcessingThreshold(1e10f) - { - - } - - btVector3 m_localInertiaTensor; - btVector3 m_gravity; - btVector3 m_scaling; - btVector3 m_linearFactor; - btVector3 m_angularFactor; - btScalar m_mass; - btScalar m_clamp_vel_min; - btScalar m_clamp_vel_max; - btScalar m_clamp_angvel_min; // Minimum angular velocity, in radians/sec. - btScalar m_clamp_angvel_max; // Maximum angular velocity, in radians/sec. - btScalar m_restitution; - btScalar m_friction; - btScalar m_linearDamping; - btScalar m_angularDamping; - btScalar m_margin; - - //////////////////// - float m_stepHeight; - float m_jumpSpeed; - float m_fallSpeed; - unsigned char m_maxJumps; - - int m_gamesoftFlag; - float m_soft_linStiff; /* linear stiffness 0..1 */ - float m_soft_angStiff; /* angular stiffness 0..1 */ - float m_soft_volume; /* volume preservation 0..1 */ - - int m_soft_viterations; /* Velocities solver iterations */ - int m_soft_piterations; /* Positions solver iterations */ - int m_soft_diterations; /* Drift solver iterations */ - int m_soft_citerations; /* Cluster solver iterations */ - - float m_soft_kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */ - float m_soft_kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */ - float m_soft_kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */ - float m_soft_kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ - - float m_soft_kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ - float m_soft_kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ - float m_soft_kVCF; /* Velocities correction factor (Baumgarte) */ - float m_soft_kDP; /* Damping coefficient [0,1] */ - - float m_soft_kDG; /* Drag coefficient [0,+inf] */ - float m_soft_kLF; /* Lift coefficient [0,+inf] */ - float m_soft_kPR; /* Pressure coefficient [-inf,+inf] */ - float m_soft_kVC; /* Volume conversation coefficient [0,+inf] */ - - float m_soft_kDF; /* Dynamic friction coefficient [0,1] */ - float m_soft_kMT; /* Pose matching coefficient [0,1] */ - float m_soft_kCHR; /* Rigid contacts hardness [0,1] */ - float m_soft_kKHR; /* Kinetic contacts hardness [0,1] */ - - float m_soft_kSHR; /* Soft contacts hardness [0,1] */ - float m_soft_kAHR; /* Anchors hardness [0,1] */ - int m_soft_collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */ - int m_soft_numclusteriterations; /* number of iterations to refine collision clusters*/ -/////////////////// - - - - int m_collisionFlags; - bool m_bDyna; - bool m_bRigid; - bool m_bSoft; - bool m_bSensor; - bool m_bCharacter; - bool m_bGimpact; // use Gimpact for mesh body - - ///optional use of collision group/mask: - ///only collision with object goups that match the collision mask. - ///this is very basic early out. advanced collision filtering should be - ///done in the btCollisionDispatcher::NeedsCollision and NeedsResponse - ///both values default to 1 - short int m_collisionFilterGroup; - short int m_collisionFilterMask; - - ///these pointers are used as argument passing for the CcdPhysicsController constructor - ///and not anymore after that - class btCollisionShape* m_collisionShape; - class PHY_IMotionState* m_MotionState; - class CcdShapeConstructionInfo* m_shapeInfo; - - CcdPhysicsEnvironment* m_physicsEnv; //needed for self-replication - float m_inertiaFactor;//tweak the inertia (hooked up to Blender 'formfactor' - bool m_do_anisotropic; - btVector3 m_anisotropicFriction; - - bool m_do_fh; ///< Should the object have a linear Fh spring? - bool m_do_rot_fh; ///< Should the object have an angular Fh spring? - btScalar m_fh_spring; ///< Spring constant (both linear and angular) - btScalar m_fh_damping; ///< Damping factor (linear and angular) in range [0, 1] - btScalar m_fh_distance; ///< The range above the surface where Fh is active. - bool m_fh_normal; ///< Should the object slide off slopes? - float m_radius;//for fh backwards compatibility - - ///m_contactProcessingThreshold allows to process contact points with positive distance - ///normally only contacts with negative distance (penetration) are solved - ///however, rigid body stacking is more stable when positive contacts are still passed into the constraint solver - ///this might sometimes lead to collisions with 'internal edges' such as a sliding character controller - ///so disable/set m_contactProcessingThreshold to zero for sliding characters etc. - // float m_contactProcessingThreshold;///< Process contacts with positive distance in range [0..INF] -}; - -class btRigidBody; -class btCollisionObject; -class btSoftBody; -class btPairCachingGhostObject; - -class BlenderBulletCharacterController : public btKinematicCharacterController, public PHY_ICharacter -{ -private: - btMotionState* m_motionState; - unsigned char m_jumps; - unsigned char m_maxJumps; - -public: - BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight); - - virtual void updateAction(btCollisionWorld *collisionWorld, btScalar dt); - - unsigned char getMaxJumps() const; - - void setMaxJumps(unsigned char maxJumps); - - unsigned char getJumpCount() const; - - virtual bool canJump() const; - - virtual void jump(); - - const btVector3& getWalkDirection(); - - // PHY_ICharacter interface - virtual void Jump() { jump(); } - virtual bool OnGround() { return onGround(); } - virtual float GetGravity() { return getGravity(); } - virtual void SetGravity(float gravity) { setGravity(gravity); } - virtual unsigned char GetMaxJumps() { return getMaxJumps(); } - virtual void SetMaxJumps(unsigned char maxJumps) { setMaxJumps(maxJumps); } - virtual unsigned char GetJumpCount() { return getJumpCount(); } - virtual void SetWalkDirection(const MT_Vector3& dir) - { - btVector3 vec = btVector3(dir[0], dir[1], dir[2]); - setWalkDirection(vec); - } - virtual MT_Vector3 GetWalkDirection() - { - btVector3 vec = getWalkDirection(); - return MT_Vector3(vec[0], vec[1], vec[2]); - } - -#ifdef WITH_CXX_GUARDEDALLOC - using PHY_ICharacter::operator new; - using PHY_ICharacter::operator delete; -#endif -}; - -class CleanPairCallback : public btOverlapCallback -{ - btBroadphaseProxy *m_cleanProxy; - btOverlappingPairCache *m_pairCache; - btDispatcher *m_dispatcher; - -public: - CleanPairCallback(btBroadphaseProxy *cleanProxy, btOverlappingPairCache *pairCache, btDispatcher *dispatcher) - :m_cleanProxy(cleanProxy), - m_pairCache(pairCache), - m_dispatcher(dispatcher) - { - } - - virtual bool processOverlap(btBroadphasePair &pair); -}; - -///CcdPhysicsController is a physics object that supports continuous collision detection and time of impact based physics resolution. -class CcdPhysicsController : public PHY_IPhysicsController -{ -protected: - btCollisionObject* m_object; - BlenderBulletCharacterController* m_characterController; - - - class PHY_IMotionState* m_MotionState; - btMotionState* m_bulletMotionState; - class btCollisionShape* m_collisionShape; - class CcdShapeConstructionInfo* m_shapeInfo; - btCollisionShape* m_bulletChildShape; - - btAlignedObjectArray<btTypedConstraint*> m_ccdConstraintRefs; // keep track of typed constraints referencing this rigid body - friend class CcdPhysicsEnvironment; // needed when updating the controller - - //some book keeping for replication - bool m_softbodyMappingDone; - bool m_softBodyTransformInitialized; - bool m_prototypeTransformInitialized; - btTransform m_softbodyStartTrans; - - - void* m_newClientInfo; - int m_registerCount; // needed when multiple sensors use the same controller - CcdConstructionInfo m_cci;//needed for replication - - CcdPhysicsController* m_parentCtrl; - - int m_savedCollisionFlags; - short m_savedCollisionFilterGroup; - short m_savedCollisionFilterMask; - MT_Scalar m_savedMass; - bool m_savedDyna; - bool m_suspended; - - - void GetWorldOrientation(btMatrix3x3& mat); - - void CreateRigidbody(); - bool CreateSoftbody(); - bool CreateCharacterController(); - - bool Register() { - return (m_registerCount++ == 0) ? true : false; - } - bool Unregister() { - return (--m_registerCount == 0) ? true : false; - } - - bool Registered() const - { - return (m_registerCount != 0); - } - - void addCcdConstraintRef(btTypedConstraint* c); - void removeCcdConstraintRef(btTypedConstraint* c); - btTypedConstraint* getCcdConstraintRef(int index); - int getNumCcdConstraintRefs() const; - - void SetWorldOrientation(const btMatrix3x3& mat); - void ForceWorldTransform(const btMatrix3x3& mat, const btVector3& pos); - - public: - - int m_collisionDelay; - - - CcdPhysicsController (const CcdConstructionInfo& ci); - - /** - * Delete the current Bullet shape used in the rigid body. - */ - bool DeleteControllerShape(); - - /** - * Delete the old Bullet shape and set the new Bullet shape : newShape - * \param newShape The new Bullet shape to set, if is NULL we create a new Bullet shape - */ - bool ReplaceControllerShape(btCollisionShape *newShape); - - virtual ~CcdPhysicsController(); - - CcdConstructionInfo& GetConstructionInfo() - { - return m_cci; - } - const CcdConstructionInfo& GetConstructionInfo() const - { - return m_cci; - } - - - btRigidBody* GetRigidBody(); - const btRigidBody* GetRigidBody() const; - btCollisionObject* GetCollisionObject(); - btSoftBody* GetSoftBody(); - btKinematicCharacterController* GetCharacterController(); - - CcdShapeConstructionInfo* GetShapeInfo() { return m_shapeInfo; } - - btCollisionShape* GetCollisionShape() { - return m_object->getCollisionShape(); - } - //////////////////////////////////// - // PHY_IPhysicsController interface - //////////////////////////////////// - - - /** - * SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding') - */ - virtual bool SynchronizeMotionStates(float time); - - /** - * Called for every physics simulation step. Use this method for - * things like limiting linear and angular velocity. - */ - void SimulationTick(float timestep); - - /** - * WriteMotionStateToDynamics ynchronizes dynas, kinematic and deformable entities (and do 'late binding') - */ - - virtual void WriteMotionStateToDynamics(bool nondynaonly); - virtual void WriteDynamicsToMotionState(); - - // controller replication - virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl); - virtual void SetPhysicsEnvironment(class PHY_IPhysicsEnvironment *env); - - // kinematic methods - virtual void RelativeTranslate(const MT_Vector3& dloc,bool local); - virtual void RelativeRotate(const MT_Matrix3x3&rotval, bool local); - virtual MT_Matrix3x3 GetOrientation(); - virtual void SetOrientation(const MT_Matrix3x3& orn); - virtual void SetPosition(const MT_Vector3& pos); - virtual void GetPosition(MT_Vector3& pos) const; - virtual void SetScaling(const MT_Vector3& scale); - virtual void SetTransform(); - - virtual MT_Scalar GetMass(); - virtual void SetMass(MT_Scalar newmass); - - // physics methods - virtual void ApplyImpulse(const MT_Point3& attach, const MT_Vector3& impulsein, bool local); - virtual void ApplyTorque(const MT_Vector3& torque,bool local); - virtual void ApplyForce(const MT_Vector3& force,bool local); - virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local); - virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local); - virtual void Jump(); - virtual void SetActive(bool active); - - virtual float GetLinearDamping() const; - virtual float GetAngularDamping() const; - virtual void SetLinearDamping(float damping); - virtual void SetAngularDamping(float damping); - virtual void SetDamping(float linear, float angular); - - // reading out information from physics - virtual MT_Vector3 GetLinearVelocity(); - virtual MT_Vector3 GetAngularVelocity(); - virtual MT_Vector3 GetVelocity(const MT_Point3& posin); - virtual MT_Vector3 GetLocalInertia(); - - // dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted - virtual void SetRigidBody(bool rigid); - - - virtual void ResolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ); - virtual void RefreshCollisions(); - virtual void SuspendDynamics(bool ghost); - virtual void RestoreDynamics(); - - // Shape control - virtual void AddCompoundChild(PHY_IPhysicsController* child); - virtual void RemoveCompoundChild(PHY_IPhysicsController* child); - - // clientinfo for raycasts for example - virtual void* GetNewClientInfo(); - virtual void SetNewClientInfo(void* clientinfo); - virtual PHY_IPhysicsController* GetReplica(); - virtual PHY_IPhysicsController* GetReplicaForSensors(); - - ///There should be no 'SetCollisionFilterGroup' method, as changing this during run-time is will result in errors - short int GetCollisionFilterGroup() const - { - return m_cci.m_collisionFilterGroup; - } - ///There should be no 'SetCollisionFilterGroup' method, as changing this during run-time is will result in errors - short int GetCollisionFilterMask() const - { - return m_cci.m_collisionFilterMask; - } - - virtual void CalcXform() {} - virtual void SetMargin(float margin) - { - if (m_collisionShape) { - m_collisionShape->setMargin(margin); - // if the shape use a unscaled shape we have also to set the correct margin in it - if (m_collisionShape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) - ((btScaledBvhTriangleMeshShape *)m_collisionShape)->getChildShape()->setMargin(margin); - } - } - virtual float GetMargin() const - { - return (m_collisionShape) ? m_collisionShape->getMargin() : 0.f; - } - virtual float GetRadius() const - { - // this is not the actual shape radius, it's only used for Fh support - return m_cci.m_radius; - } - virtual void SetRadius(float margin) - { - if (m_collisionShape && m_collisionShape->getShapeType() == SPHERE_SHAPE_PROXYTYPE) - { - btSphereShape* sphereShape = static_cast<btSphereShape*>(m_collisionShape); - sphereShape->setUnscaledRadius(margin); - } - m_cci.m_radius = margin; - } - - // velocity clamping - virtual void SetLinVelocityMin(float val) - { - m_cci.m_clamp_vel_min= val; - } - virtual float GetLinVelocityMin() const - { - return m_cci.m_clamp_vel_min; - } - virtual void SetLinVelocityMax(float val) - { - m_cci.m_clamp_vel_max= val; - } - virtual float GetLinVelocityMax() const - { - return m_cci.m_clamp_vel_max; - } - - virtual void SetAngularVelocityMin(float val) - { - m_cci.m_clamp_angvel_min = val; - } - virtual float GetAngularVelocityMin() const - { - return m_cci.m_clamp_angvel_min; - } - virtual void SetAngularVelocityMax(float val) - { - m_cci.m_clamp_angvel_max = val; - } - virtual float GetAngularVelocityMax() const - { - return m_cci.m_clamp_angvel_max; - } - - bool WantsSleeping(); - - void UpdateDeactivation(float timeStep); - - void SetCenterOfMassTransform(btTransform& xform); - - static btTransform& GetTransformFromMotionState(PHY_IMotionState* motionState); - - void setAabb(const btVector3& aabbMin,const btVector3& aabbMax); - - - class PHY_IMotionState* GetMotionState() - { - return m_MotionState; - } - - const class PHY_IMotionState* GetMotionState() const - { - return m_MotionState; - } - - class CcdPhysicsEnvironment* GetPhysicsEnvironment() - { - return m_cci.m_physicsEnv; - } - - void SetParentCtrl(CcdPhysicsController* parentCtrl) - { - m_parentCtrl = parentCtrl; - } - - CcdPhysicsController* GetParentCtrl() - { - return m_parentCtrl; - } - - const CcdPhysicsController* GetParentCtrl() const - { - return m_parentCtrl; - } - - virtual bool IsDynamic() - { - return GetConstructionInfo().m_bDyna; - } - - virtual bool IsSuspended() const - { - return m_suspended; - } - - virtual bool IsCompound() - { - return GetConstructionInfo().m_shapeInfo->m_shapeType == PHY_SHAPE_COMPOUND; - } - - virtual bool ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj); - - /* Method to replicate rigid body joint contraints for group instances. */ - virtual void ReplicateConstraints(KX_GameObject *gameobj, std::vector<KX_GameObject*> constobj); - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:CcdPhysicsController") -#endif -}; - - - - -///DefaultMotionState implements standard motionstate, using btTransform -class DefaultMotionState : public PHY_IMotionState - -{ - public: - DefaultMotionState(); - - virtual ~DefaultMotionState(); - - virtual void GetWorldPosition(float& posX,float& posY,float& posZ); - virtual void GetWorldScaling(float& scaleX,float& scaleY,float& scaleZ); - virtual void GetWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal); - - virtual void SetWorldPosition(float posX,float posY,float posZ); - virtual void SetWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal); - virtual void GetWorldOrientation(float* ori); - virtual void SetWorldOrientation(const float* ori); - - virtual void CalculateWorldTransformations(); - - btTransform m_worldTransform; - btVector3 m_localScaling; - - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:DefaultMotionState") -#endif -}; - - -#endif /* __CCDPHYSICSCONTROLLER_H__ */ diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp deleted file mode 100644 index 78d2d88cc65..00000000000 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ /dev/null @@ -1,3795 +0,0 @@ -/** \file gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp - * \ingroup physbullet - */ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, -subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - - - - -#include "CcdPhysicsEnvironment.h" -#include "CcdPhysicsController.h" -#include "CcdGraphicController.h" - -#include <algorithm> -#include "btBulletDynamicsCommon.h" -#include "LinearMath/btIDebugDraw.h" -#include "BulletCollision/CollisionDispatch/btGhostObject.h" -#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" -#include "BulletSoftBody/btSoftRigidDynamicsWorld.h" -#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" -#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h" -#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" - -//profiling/timings -#include "LinearMath/btQuickprof.h" - - -#include "PHY_IMotionState.h" -#include "PHY_ICharacter.h" -#include "PHY_Pro.h" -#include "KX_GameObject.h" -#include "KX_PythonInit.h" // for KX_RasterizerDrawDebugLine -#include "KX_BlenderSceneConverter.h" -#include "RAS_MeshObject.h" -#include "RAS_Polygon.h" -#include "RAS_TexVert.h" - -#include "DNA_scene_types.h" -#include "DNA_world_types.h" -#include "DNA_object_force_types.h" - -extern "C" { - #include "BLI_utildefines.h" - #include "BKE_object.h" -} - -#define CCD_CONSTRAINT_DISABLE_LINKED_COLLISION 0x80 - -#ifdef NEW_BULLET_VEHICLE_SUPPORT -#include "BulletDynamics/Vehicle/btRaycastVehicle.h" -#include "BulletDynamics/Vehicle/btVehicleRaycaster.h" -#include "BulletDynamics/Vehicle/btWheelInfo.h" -#include "PHY_IVehicle.h" -static btRaycastVehicle::btVehicleTuning gTuning; - -#endif //NEW_BULLET_VEHICLE_SUPPORT -#include "LinearMath/btAabbUtil2.h" -#include "MT_Matrix4x4.h" -#include "MT_Vector3.h" -#include "MT_MinMax.h" - -#ifdef WIN32 -void DrawRasterizerLine(const float* from,const float* to,int color); -#endif - - -#include "BulletDynamics/ConstraintSolver/btContactConstraint.h" - - -#include <stdio.h> -#include <string.h> // for memset - -// This was copied from the old KX_ConvertPhysicsObjects -#ifdef WIN32 -#ifdef _MSC_VER -//only use SIMD Hull code under Win32 -//#define TEST_HULL 1 -#ifdef TEST_HULL -#define USE_HULL 1 -//#define TEST_SIMD_HULL 1 - -#include "NarrowPhaseCollision/Hull.h" -#endif //#ifdef TEST_HULL - -#endif //_MSC_VER -#endif //WIN32 - -#ifdef NEW_BULLET_VEHICLE_SUPPORT -class WrapperVehicle : public PHY_IVehicle -{ - - btRaycastVehicle* m_vehicle; - PHY_IPhysicsController* m_chassis; - -public: - - WrapperVehicle(btRaycastVehicle* vehicle,PHY_IPhysicsController* chassis) - :m_vehicle(vehicle), - m_chassis(chassis) - { - } - - ~WrapperVehicle() - { - delete m_vehicle; - } - - btRaycastVehicle* GetVehicle() - { - return m_vehicle; - } - - PHY_IPhysicsController* GetChassis() - { - return m_chassis; - } - - virtual void AddWheel( - PHY_IMotionState* motionState, - MT_Vector3 connectionPoint, - MT_Vector3 downDirection, - MT_Vector3 axleDirection, - float suspensionRestLength, - float wheelRadius, - bool hasSteering - ) - { - btVector3 connectionPointCS0(connectionPoint[0],connectionPoint[1],connectionPoint[2]); - btVector3 wheelDirectionCS0(downDirection[0],downDirection[1],downDirection[2]); - btVector3 wheelAxle(axleDirection[0],axleDirection[1],axleDirection[2]); - - - btWheelInfo& info = m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxle, - suspensionRestLength,wheelRadius,gTuning,hasSteering); - info.m_clientInfo = motionState; - - } - - void SyncWheels() - { - int numWheels = GetNumWheels(); - int i; - for (i=0;i<numWheels;i++) - { - btWheelInfo& info = m_vehicle->getWheelInfo(i); - PHY_IMotionState* motionState = (PHY_IMotionState*)info.m_clientInfo; - // m_vehicle->updateWheelTransformsWS(info,false); - m_vehicle->updateWheelTransform(i,false); - btTransform trans = m_vehicle->getWheelInfo(i).m_worldTransform; - btQuaternion orn = trans.getRotation(); - const btVector3& pos = trans.getOrigin(); - motionState->SetWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]); - motionState->SetWorldPosition(pos.x(),pos.y(),pos.z()); - - } - } - - virtual int GetNumWheels() const - { - return m_vehicle->getNumWheels(); - } - - virtual void GetWheelPosition(int wheelIndex,float& posX,float& posY,float& posZ) const - { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { - btVector3 origin = m_vehicle->getWheelTransformWS(wheelIndex).getOrigin(); - - posX = origin.x(); - posY = origin.y(); - posZ = origin.z(); - } - } - - virtual void GetWheelOrientationQuaternion(int wheelIndex,float& quatX,float& quatY,float& quatZ,float& quatW) const - { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { - btQuaternion quat = m_vehicle->getWheelTransformWS(wheelIndex).getRotation(); - - quatX = quat.x(); - quatY = quat.y(); - quatZ = quat.z(); - quatW = quat.w(); - } - } - - virtual float GetWheelRotation(int wheelIndex) const - { - float rotation = 0.f; - - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { - btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); - rotation = info.m_rotation; - } - - return rotation; - } - - - - virtual int GetUserConstraintId() const - { - return m_vehicle->getUserConstraintId(); - } - - virtual int GetUserConstraintType() const - { - return m_vehicle->getUserConstraintType(); - } - - virtual void SetSteeringValue(float steering,int wheelIndex) - { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) { - m_vehicle->setSteeringValue(steering,wheelIndex); - } - } - - virtual void ApplyEngineForce(float force,int wheelIndex) - { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) { - m_vehicle->applyEngineForce(force,wheelIndex); - } - } - - virtual void ApplyBraking(float braking,int wheelIndex) - { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { - btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); - info.m_brake = braking; - } - } - - virtual void SetWheelFriction(float friction,int wheelIndex) - { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { - btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); - info.m_frictionSlip = friction; - } - - } - - virtual void SetSuspensionStiffness(float suspensionStiffness,int wheelIndex) - { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { - btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); - info.m_suspensionStiffness = suspensionStiffness; - - } - } - - virtual void SetSuspensionDamping(float suspensionDamping,int wheelIndex) - { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { - btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); - info.m_wheelsDampingRelaxation = suspensionDamping; - } - } - - virtual void SetSuspensionCompression(float suspensionCompression,int wheelIndex) - { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { - btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); - info.m_wheelsDampingCompression = suspensionCompression; - } - } - - - - virtual void SetRollInfluence(float rollInfluence,int wheelIndex) - { - if ((wheelIndex>=0) && (wheelIndex< m_vehicle->getNumWheels())) - { - btWheelInfo& info = m_vehicle->getWheelInfo(wheelIndex); - info.m_rollInfluence = rollInfluence; - } - } - - virtual void SetCoordinateSystem(int rightIndex,int upIndex,int forwardIndex) - { - m_vehicle->setCoordinateSystem(rightIndex,upIndex,forwardIndex); - } - - - -}; - -class BlenderVehicleRaycaster: public btDefaultVehicleRaycaster -{ - btDynamicsWorld* m_dynamicsWorld; -public: - BlenderVehicleRaycaster(btDynamicsWorld* world) - :btDefaultVehicleRaycaster(world), m_dynamicsWorld(world) - { - } - - virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result) - { - // RayResultCallback& resultCallback; - - btCollisionWorld::ClosestRayResultCallback rayCallback(from,to); - - // We override btDefaultVehicleRaycaster so we can set this flag, otherwise our - // vehicles go crazy (http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=9662) - rayCallback.m_flags |= btTriangleRaycastCallback::kF_UseSubSimplexConvexCastRaytest; - - m_dynamicsWorld->rayTest(from, to, rayCallback); - - if (rayCallback.hasHit()) - { - - const btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); - if (body && body->hasContactResponse()) - { - result.m_hitPointInWorld = rayCallback.m_hitPointWorld; - result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld; - result.m_hitNormalInWorld.normalize(); - result.m_distFraction = rayCallback.m_closestHitFraction; - return (void*)body; - } - } - return 0; - } -}; -#endif //NEW_BULLET_VEHICLE_SUPPORT - -class CcdOverlapFilterCallBack : public btOverlapFilterCallback -{ -private: - class CcdPhysicsEnvironment* m_physEnv; -public: - CcdOverlapFilterCallBack(CcdPhysicsEnvironment* env) : - m_physEnv(env) - { - } - virtual ~CcdOverlapFilterCallBack() - { - } - // return true when pairs need collision - virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const; -}; - - -void CcdPhysicsEnvironment::SetDebugDrawer(btIDebugDraw* debugDrawer) -{ - if (debugDrawer && m_dynamicsWorld) - m_dynamicsWorld->setDebugDrawer(debugDrawer); - m_debugDrawer = debugDrawer; -} - -#if 0 -static void DrawAabb(btIDebugDraw* debugDrawer,const btVector3& from,const btVector3& to,const btVector3& color) -{ - btVector3 halfExtents = (to-from)* 0.5f; - btVector3 center = (to+from) *0.5f; - int i,j; - - btVector3 edgecoord(1.f,1.f,1.f),pa,pb; - for (i=0;i<4;i++) - { - for (j=0;j<3;j++) - { - pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], - edgecoord[2]*halfExtents[2]); - pa+=center; - - int othercoord = j%3; - edgecoord[othercoord]*=-1.f; - pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], - edgecoord[2]*halfExtents[2]); - pb+=center; - - debugDrawer->drawLine(pa,pb,color); - } - edgecoord = btVector3(-1.f,-1.f,-1.f); - if (i<3) - edgecoord[i]*=-1.f; - } -} -#endif - - - - - -CcdPhysicsEnvironment::CcdPhysicsEnvironment(bool useDbvtCulling,btDispatcher* dispatcher,btOverlappingPairCache* pairCache) -:m_cullingCache(NULL), -m_cullingTree(NULL), -m_numIterations(10), -m_numTimeSubSteps(1), -m_ccdMode(0), -m_solverType(-1), -m_profileTimings(0), -m_enableSatCollisionDetection(false), -m_deactivationTime(2.0f), -m_linearDeactivationThreshold(0.8f), -m_angularDeactivationThreshold(1.0f), -m_contactBreakingThreshold(0.02f), -m_solver(NULL), -m_ownPairCache(NULL), -m_filterCallback(NULL), -m_ghostPairCallback(NULL), -m_ownDispatcher(NULL), -m_scalingPropagated(false) -{ - - for (int i=0;i<PHY_NUM_RESPONSE;i++) - { - m_triggerCallbacks[i] = 0; - } - -// m_collisionConfiguration = new btDefaultCollisionConfiguration(); - m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); - //m_collisionConfiguration->setConvexConvexMultipointIterations(); - - if (!dispatcher) - { - btCollisionDispatcher* disp = new btCollisionDispatcher(m_collisionConfiguration); - dispatcher = disp; - btGImpactCollisionAlgorithm::registerAlgorithm(disp); - m_ownDispatcher = dispatcher; - } - - //m_broadphase = new btAxisSweep3(btVector3(-1000,-1000,-1000),btVector3(1000,1000,1000)); - //m_broadphase = new btSimpleBroadphase(); - m_broadphase = new btDbvtBroadphase(); - // avoid any collision in the culling tree - if (useDbvtCulling) { - m_cullingCache = new btNullPairCache(); - m_cullingTree = new btDbvtBroadphase(m_cullingCache); - } - - m_filterCallback = new CcdOverlapFilterCallBack(this); - m_ghostPairCallback = new btGhostPairCallback(); - m_broadphase->getOverlappingPairCache()->setOverlapFilterCallback(m_filterCallback); - m_broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(m_ghostPairCallback); - - SetSolverType(1);//issues with quickstep and memory allocations -// m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration); - m_dynamicsWorld = new btSoftRigidDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration); - m_dynamicsWorld->setInternalTickCallback(&CcdPhysicsEnvironment::StaticSimulationSubtickCallback, this); - //m_dynamicsWorld->getSolverInfo().m_linearSlop = 0.01f; - //m_dynamicsWorld->getSolverInfo().m_solverMode= SOLVER_USE_WARMSTARTING + SOLVER_USE_2_FRICTION_DIRECTIONS + SOLVER_RANDMIZE_ORDER + SOLVER_USE_FRICTION_WARMSTARTING; - - m_debugDrawer = 0; - SetGravity(0.f,0.f,-9.81f); -} - -void CcdPhysicsEnvironment::AddCcdPhysicsController(CcdPhysicsController* ctrl) -{ - // the controller is already added we do nothing - if (!m_controllers.insert(ctrl).second) { - return; - } - - btRigidBody* body = ctrl->GetRigidBody(); - btCollisionObject* obj = ctrl->GetCollisionObject(); - - //this m_userPointer is just used for triggers, see CallbackTriggers - obj->setUserPointer(ctrl); - if (body) { - body->setGravity(m_gravity); - body->setSleepingThresholds(m_linearDeactivationThreshold, m_angularDeactivationThreshold); - } - - if (body) - { - //use explicit group/filter for finer control over collision in bullet => near/radar sensor - m_dynamicsWorld->addRigidBody(body, ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask()); - } else - { - if (ctrl->GetSoftBody()) - { - btSoftBody* softBody = ctrl->GetSoftBody(); - m_dynamicsWorld->addSoftBody(softBody); - } else - { - if (obj->getCollisionShape()) - { - m_dynamicsWorld->addCollisionObject(obj, ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask()); - } - if (ctrl->GetCharacterController()) - { - m_dynamicsWorld->addAction(ctrl->GetCharacterController()); - } - } - } - if (obj->isStaticOrKinematicObject()) - { - obj->setActivationState(ISLAND_SLEEPING); - } - - assert(obj->getBroadphaseHandle()); -} - -void CcdPhysicsEnvironment::RemoveConstraint(btTypedConstraint *con) -{ - btRigidBody &rbA = con->getRigidBodyA(); - btRigidBody &rbB = con->getRigidBodyB(); - rbA.activate(); - rbB.activate(); - m_dynamicsWorld->removeConstraint(con); - - if (rbA.getUserPointer()) { - ((CcdPhysicsController *)rbA.getUserPointer())->removeCcdConstraintRef(con); - } - - if (rbB.getUserPointer()) { - ((CcdPhysicsController *)rbB.getUserPointer())->removeCcdConstraintRef(con); - } - - /* Since we remove the constraint in the onwer and the target, we can delete it, - * KX_ConstraintWrapper keep the constraint id not the pointer, so no problems. */ - delete con; -} - -bool CcdPhysicsEnvironment::RemoveCcdPhysicsController(CcdPhysicsController* ctrl) -{ - // if the physics controller is already removed we do nothing - if (!m_controllers.erase(ctrl)) { - return false; - } - - //also remove constraint - btRigidBody* body = ctrl->GetRigidBody(); - if (body) - { - btBroadphaseProxy *proxy = ctrl->GetCollisionObject()->getBroadphaseHandle(); - btDispatcher *dispatcher = m_dynamicsWorld->getDispatcher(); - btOverlappingPairCache *pairCache = m_dynamicsWorld->getPairCache(); - - CleanPairCallback cleanPairs(proxy, pairCache, dispatcher); - pairCache->processAllOverlappingPairs(&cleanPairs, dispatcher); - - for (int i = ctrl->getNumCcdConstraintRefs() - 1; i >= 0; i--) - { - btTypedConstraint* con = ctrl->getCcdConstraintRef(i); - RemoveConstraint(con); - } - m_dynamicsWorld->removeRigidBody(ctrl->GetRigidBody()); - - // Handle potential vehicle constraints - int numVehicles = m_wrapperVehicles.size(); - int vehicle_constraint = 0; - for (int i=0;i<numVehicles;i++) - { - WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i]; - if (wrapperVehicle->GetChassis() == ctrl) - vehicle_constraint = wrapperVehicle->GetVehicle()->getUserConstraintId(); - } - - if (vehicle_constraint > 0) - RemoveConstraintById(vehicle_constraint); - } else - { - //if a softbody - if (ctrl->GetSoftBody()) - { - m_dynamicsWorld->removeSoftBody(ctrl->GetSoftBody()); - } else - { - m_dynamicsWorld->removeCollisionObject(ctrl->GetCollisionObject()); - - if (ctrl->GetCharacterController()) - { - m_dynamicsWorld->removeAction(ctrl->GetCharacterController()); - } - } - } - - return true; -} - -void CcdPhysicsEnvironment::UpdateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask) -{ - // this function is used when the collisionning group of a controller is changed - // remove and add the collistioning object - btRigidBody* body = ctrl->GetRigidBody(); - btSoftBody *softBody = ctrl->GetSoftBody(); - btCollisionObject* obj = ctrl->GetCollisionObject(); - if (obj) - { - btVector3 inertia(0.0f,0.0f,0.0f); - m_dynamicsWorld->removeCollisionObject(obj); - obj->setCollisionFlags(newCollisionFlags); - if (body) - { - if (newMass) - body->getCollisionShape()->calculateLocalInertia(newMass, inertia); - body->setMassProps(newMass, inertia); - m_dynamicsWorld->addRigidBody(body, newCollisionGroup, newCollisionMask); - } - else if (softBody) { - m_dynamicsWorld->addSoftBody(softBody); - } - else { - m_dynamicsWorld->addCollisionObject(obj, newCollisionGroup, newCollisionMask); - } - } - // to avoid nasty interaction, we must update the property of the controller as well - ctrl->m_cci.m_mass = newMass; - ctrl->m_cci.m_collisionFilterGroup = newCollisionGroup; - ctrl->m_cci.m_collisionFilterMask = newCollisionMask; - ctrl->m_cci.m_collisionFlags = newCollisionFlags; -} - -void CcdPhysicsEnvironment::RefreshCcdPhysicsController(CcdPhysicsController* ctrl) -{ - btCollisionObject* obj = ctrl->GetCollisionObject(); - if (obj) - { - btBroadphaseProxy* proxy = obj->getBroadphaseHandle(); - if (proxy) - { - m_dynamicsWorld->getPairCache()->cleanProxyFromPairs(proxy,m_dynamicsWorld->getDispatcher()); - } - } -} - -bool CcdPhysicsEnvironment::IsActiveCcdPhysicsController(CcdPhysicsController *ctrl) -{ - return (m_controllers.find(ctrl) != m_controllers.end()); -} - -void CcdPhysicsEnvironment::AddCcdGraphicController(CcdGraphicController* ctrl) -{ - if (m_cullingTree && !ctrl->GetBroadphaseHandle()) - { - btVector3 minAabb; - btVector3 maxAabb; - ctrl->GetAabb(minAabb, maxAabb); - - ctrl->SetBroadphaseHandle(m_cullingTree->createProxy( - minAabb, - maxAabb, - INVALID_SHAPE_PROXYTYPE, // this parameter is not used - ctrl, - 0, // this object does not collision with anything - 0, - NULL, // dispatcher => this parameter is not used - 0)); - - assert(ctrl->GetBroadphaseHandle()); - } -} - -void CcdPhysicsEnvironment::RemoveCcdGraphicController(CcdGraphicController* ctrl) -{ - if (m_cullingTree) - { - btBroadphaseProxy* bp = ctrl->GetBroadphaseHandle(); - if (bp) - { - m_cullingTree->destroyProxy(bp,NULL); - ctrl->SetBroadphaseHandle(0); - } - } -} - -void CcdPhysicsEnvironment::UpdateCcdPhysicsControllerShape(CcdShapeConstructionInfo *shapeInfo) -{ - for (std::set<CcdPhysicsController *>::iterator it = m_controllers.begin(); it != m_controllers.end(); ++it) { - CcdPhysicsController *ctrl = *it; - - if (ctrl->GetShapeInfo() != shapeInfo) - continue; - - ctrl->ReplaceControllerShape(NULL); - RefreshCcdPhysicsController(ctrl); - } -} - -void CcdPhysicsEnvironment::BeginFrame() -{ - -} - -void CcdPhysicsEnvironment::DebugDrawWorld() -{ - if (m_dynamicsWorld->getDebugDrawer() && m_dynamicsWorld->getDebugDrawer()->getDebugMode() >0) - m_dynamicsWorld->debugDrawWorld(); -} - -void CcdPhysicsEnvironment::StaticSimulationSubtickCallback(btDynamicsWorld *world, btScalar timeStep) -{ - // Get the pointer to the CcdPhysicsEnvironment associated with this Bullet world. - CcdPhysicsEnvironment *this_ = static_cast<CcdPhysicsEnvironment*>(world->getWorldUserInfo()); - this_->SimulationSubtickCallback(timeStep); -} - -void CcdPhysicsEnvironment::SimulationSubtickCallback(btScalar timeStep) -{ - std::set<CcdPhysicsController*>::iterator it; - - for (it = m_controllers.begin(); it != m_controllers.end(); it++) { - (*it)->SimulationTick(timeStep); - } -} - -bool CcdPhysicsEnvironment::ProceedDeltaTime(double curTime,float timeStep,float interval) -{ - std::set<CcdPhysicsController*>::iterator it; - int i; - - // Update Bullet global variables. - gDeactivationTime = m_deactivationTime; - gContactBreakingThreshold = m_contactBreakingThreshold; - - for (it=m_controllers.begin(); it!=m_controllers.end(); it++) - { - (*it)->SynchronizeMotionStates(timeStep); - } - - float subStep = timeStep / float(m_numTimeSubSteps); - i = m_dynamicsWorld->stepSimulation(interval,25,subStep);//perform always a full simulation step -//uncomment next line to see where Bullet spend its time (printf in console) -//CProfileManager::dumpAll(); - - ProcessFhSprings(curTime,i*subStep); - - for (it=m_controllers.begin(); it!=m_controllers.end(); it++) - { - (*it)->SynchronizeMotionStates(timeStep); - } - - //for (it=m_controllers.begin(); it!=m_controllers.end(); it++) - //{ - // (*it)->SynchronizeMotionStates(timeStep); - //} - - for (i=0;i<m_wrapperVehicles.size();i++) - { - WrapperVehicle* veh = m_wrapperVehicles[i]; - veh->SyncWheels(); - } - - - CallbackTriggers(); - - return true; -} - -class ClosestRayResultCallbackNotMe : public btCollisionWorld::ClosestRayResultCallback -{ - btCollisionObject* m_owner; - btCollisionObject* m_parent; - -public: - ClosestRayResultCallbackNotMe(const btVector3& rayFromWorld,const btVector3& rayToWorld,btCollisionObject* owner,btCollisionObject* parent) - :btCollisionWorld::ClosestRayResultCallback(rayFromWorld,rayToWorld), - m_owner(owner), - m_parent(parent) - { - - } - - virtual bool needsCollision(btBroadphaseProxy* proxy0) const - { - //don't collide with self - if (proxy0->m_clientObject == m_owner) - return false; - - if (proxy0->m_clientObject == m_parent) - return false; - - return btCollisionWorld::ClosestRayResultCallback::needsCollision(proxy0); - } - -}; - -void CcdPhysicsEnvironment::ProcessFhSprings(double curTime,float interval) -{ - std::set<CcdPhysicsController*>::iterator it; - // Add epsilon to the tick rate for numerical stability - int numIter = (int)(interval*(KX_KetsjiEngine::GetTicRate() + 0.001f)); - - for (it=m_controllers.begin(); it!=m_controllers.end(); it++) - { - CcdPhysicsController* ctrl = (*it); - btRigidBody* body = ctrl->GetRigidBody(); - - if (body && (ctrl->GetConstructionInfo().m_do_fh || ctrl->GetConstructionInfo().m_do_rot_fh)) - { - //printf("has Fh or RotFh\n"); - //re-implement SM_FhObject.cpp using btCollisionWorld::rayTest and info from ctrl->getConstructionInfo() - //send a ray from {0.0, 0.0, 0.0} towards {0.0, 0.0, -10.0}, in local coordinates - CcdPhysicsController* parentCtrl = ctrl->GetParentCtrl(); - btRigidBody* parentBody = parentCtrl?parentCtrl->GetRigidBody() : 0; - btRigidBody* cl_object = parentBody ? parentBody : body; - - if (body->isStaticOrKinematicObject()) - continue; - - btVector3 rayDirLocal(0,0,-10); - - //m_dynamicsWorld - //ctrl->GetRigidBody(); - btVector3 rayFromWorld = body->getCenterOfMassPosition(); - //btVector3 rayToWorld = rayFromWorld + body->getCenterOfMassTransform().getBasis() * rayDirLocal; - //ray always points down the z axis in world space... - btVector3 rayToWorld = rayFromWorld + rayDirLocal; - - ClosestRayResultCallbackNotMe resultCallback(rayFromWorld,rayToWorld,body,parentBody); - - m_dynamicsWorld->rayTest(rayFromWorld,rayToWorld,resultCallback); - if (resultCallback.hasHit()) - { - //we hit this one: resultCallback.m_collisionObject; - CcdPhysicsController* controller = static_cast<CcdPhysicsController*>(resultCallback.m_collisionObject->getUserPointer()); - - if (controller) - { - if (controller->GetConstructionInfo().m_fh_distance < SIMD_EPSILON) - continue; - - btRigidBody* hit_object = controller->GetRigidBody(); - if (!hit_object) - continue; - - CcdConstructionInfo& hitObjShapeProps = controller->GetConstructionInfo(); - - float distance = resultCallback.m_closestHitFraction*rayDirLocal.length()-ctrl->GetConstructionInfo().m_radius; - if (distance >= hitObjShapeProps.m_fh_distance) - continue; - - - - //btVector3 ray_dir = cl_object->getCenterOfMassTransform().getBasis()* rayDirLocal.normalized(); - btVector3 ray_dir = rayDirLocal.normalized(); - btVector3 normal = resultCallback.m_hitNormalWorld; - normal.normalize(); - - for (int i=0; i<numIter; i++) - { - if (ctrl->GetConstructionInfo().m_do_fh) - { - btVector3 lspot = cl_object->getCenterOfMassPosition() + - rayDirLocal * resultCallback.m_closestHitFraction; - - - - - lspot -= hit_object->getCenterOfMassPosition(); - btVector3 rel_vel = cl_object->getLinearVelocity() - hit_object->getVelocityInLocalPoint(lspot); - btScalar rel_vel_ray = ray_dir.dot(rel_vel); - btScalar spring_extent = 1.0f - distance / hitObjShapeProps.m_fh_distance; - - btScalar i_spring = spring_extent * hitObjShapeProps.m_fh_spring; - btScalar i_damp = rel_vel_ray * hitObjShapeProps.m_fh_damping; - - cl_object->setLinearVelocity(cl_object->getLinearVelocity() + (-(i_spring + i_damp) * ray_dir)); - if (hitObjShapeProps.m_fh_normal) - { - cl_object->setLinearVelocity(cl_object->getLinearVelocity()+(i_spring + i_damp) *(normal - normal.dot(ray_dir) * ray_dir)); - } - - btVector3 lateral = rel_vel - rel_vel_ray * ray_dir; - - - if (ctrl->GetConstructionInfo().m_do_anisotropic) { - //Bullet basis contains no scaling/shear etc. - const btMatrix3x3& lcs = cl_object->getCenterOfMassTransform().getBasis(); - btVector3 loc_lateral = lateral * lcs; - const btVector3& friction_scaling = cl_object->getAnisotropicFriction(); - loc_lateral *= friction_scaling; - lateral = lcs * loc_lateral; - } - - btScalar rel_vel_lateral = lateral.length(); - - if (rel_vel_lateral > SIMD_EPSILON) { - btScalar friction_factor = hit_object->getFriction();//cl_object->getFriction(); - - btScalar max_friction = friction_factor * btMax(btScalar(0.0f), i_spring); - - btScalar rel_mom_lateral = rel_vel_lateral / cl_object->getInvMass(); - - btVector3 friction = (rel_mom_lateral > max_friction) ? - -lateral * (max_friction / rel_vel_lateral) : - -lateral; - - cl_object->applyCentralImpulse(friction); - } - } - - - if (ctrl->GetConstructionInfo().m_do_rot_fh) { - btVector3 up2 = cl_object->getWorldTransform().getBasis().getColumn(2); - - btVector3 t_spring = up2.cross(normal) * hitObjShapeProps.m_fh_spring; - btVector3 ang_vel = cl_object->getAngularVelocity(); - - // only rotations that tilt relative to the normal are damped - ang_vel -= ang_vel.dot(normal) * normal; - - btVector3 t_damp = ang_vel * hitObjShapeProps.m_fh_damping; - - cl_object->setAngularVelocity(cl_object->getAngularVelocity() + (t_spring - t_damp)); - } - } - } - } - } - } -} - -int CcdPhysicsEnvironment::GetDebugMode() const -{ - if (m_debugDrawer) { - return m_debugDrawer->getDebugMode(); - } - return 0; -} - -void CcdPhysicsEnvironment::SetDebugMode(int debugMode) -{ - if (m_debugDrawer) { - m_debugDrawer->setDebugMode(debugMode); - } -} - -void CcdPhysicsEnvironment::SetNumIterations(int numIter) -{ - m_numIterations = numIter; -} -void CcdPhysicsEnvironment::SetDeactivationTime(float dTime) -{ - m_deactivationTime = dTime; -} -void CcdPhysicsEnvironment::SetDeactivationLinearTreshold(float linTresh) -{ - m_linearDeactivationThreshold = linTresh; - - // Update from all controllers. - for (std::set<CcdPhysicsController*>::iterator it = m_controllers.begin(); it != m_controllers.end(); it++) { - if ((*it)->GetRigidBody()) - (*it)->GetRigidBody()->setSleepingThresholds(m_linearDeactivationThreshold, m_angularDeactivationThreshold); - } -} -void CcdPhysicsEnvironment::SetDeactivationAngularTreshold(float angTresh) -{ - m_angularDeactivationThreshold = angTresh; - - // Update from all controllers. - for (std::set<CcdPhysicsController*>::iterator it = m_controllers.begin(); it != m_controllers.end(); it++) { - if ((*it)->GetRigidBody()) - (*it)->GetRigidBody()->setSleepingThresholds(m_linearDeactivationThreshold, m_angularDeactivationThreshold); - } -} - -void CcdPhysicsEnvironment::SetContactBreakingTreshold(float contactBreakingTreshold) -{ - m_contactBreakingThreshold = contactBreakingTreshold; -} - - -void CcdPhysicsEnvironment::SetCcdMode(int ccdMode) -{ - m_ccdMode = ccdMode; -} - - -void CcdPhysicsEnvironment::SetSolverSorConstant(float sor) -{ - m_dynamicsWorld->getSolverInfo().m_sor = sor; -} - -void CcdPhysicsEnvironment::SetSolverTau(float tau) -{ - m_dynamicsWorld->getSolverInfo().m_tau = tau; -} -void CcdPhysicsEnvironment::SetSolverDamping(float damping) -{ - m_dynamicsWorld->getSolverInfo().m_damping = damping; -} - - -void CcdPhysicsEnvironment::SetLinearAirDamping(float damping) -{ - //gLinearAirDamping = damping; -} - -void CcdPhysicsEnvironment::SetUseEpa(bool epa) -{ - //gUseEpa = epa; -} - -void CcdPhysicsEnvironment::SetSolverType(int solverType) -{ - - switch (solverType) - { - case 1: - { - if (m_solverType != solverType) - { - - m_solver = new btSequentialImpulseConstraintSolver(); - - - break; - } - } - - case 0: - default: - if (m_solverType != solverType) - { -// m_solver = new OdeConstraintSolver(); - - break; - } - - }; - - m_solverType = solverType; -} - - - -void CcdPhysicsEnvironment::GetGravity(MT_Vector3& grav) -{ - const btVector3& gravity = m_dynamicsWorld->getGravity(); - grav[0] = gravity.getX(); - grav[1] = gravity.getY(); - grav[2] = gravity.getZ(); -} - - -void CcdPhysicsEnvironment::SetGravity(float x,float y,float z) -{ - m_gravity = btVector3(x,y,z); - m_dynamicsWorld->setGravity(m_gravity); - m_dynamicsWorld->getWorldInfo().m_gravity.setValue(x,y,z); -} - - - - -static int gConstraintUid = 1; - -//Following the COLLADA physics specification for constraints -int CcdPhysicsEnvironment::CreateUniversalD6Constraint( - class PHY_IPhysicsController* ctrlRef,class PHY_IPhysicsController* ctrlOther, - btTransform& frameInA, - btTransform& frameInB, - const btVector3& linearMinLimits, - const btVector3& linearMaxLimits, - const btVector3& angularMinLimits, - const btVector3& angularMaxLimits,int flags -) -{ - - bool disableCollisionBetweenLinkedBodies = (0!=(flags & CCD_CONSTRAINT_DISABLE_LINKED_COLLISION)); - - //we could either add some logic to recognize ball-socket and hinge, or let that up to the user - //perhaps some warning or hint that hinge/ball-socket is more efficient? - - - btGeneric6DofConstraint* genericConstraint = 0; - CcdPhysicsController* ctrl0 = (CcdPhysicsController*) ctrlRef; - CcdPhysicsController* ctrl1 = (CcdPhysicsController*) ctrlOther; - - btRigidBody* rb0 = ctrl0->GetRigidBody(); - btRigidBody* rb1 = ctrl1->GetRigidBody(); - - if (rb1) - { - - - bool useReferenceFrameA = true; - genericConstraint = new btGeneric6DofSpringConstraint( - *rb0,*rb1, - frameInA,frameInB,useReferenceFrameA); - genericConstraint->setLinearLowerLimit(linearMinLimits); - genericConstraint->setLinearUpperLimit(linearMaxLimits); - genericConstraint->setAngularLowerLimit(angularMinLimits); - genericConstraint->setAngularUpperLimit(angularMaxLimits); - } else - { - // TODO: Implement single body case... - //No, we can use a fixed rigidbody in above code, rather than unnecessary duplation of code - - } - - if (genericConstraint) - { - // m_constraints.push_back(genericConstraint); - m_dynamicsWorld->addConstraint(genericConstraint,disableCollisionBetweenLinkedBodies); - - genericConstraint->setUserConstraintId(gConstraintUid++); - genericConstraint->setUserConstraintType(PHY_GENERIC_6DOF_CONSTRAINT); - //64 bit systems can't cast pointer to int. could use size_t instead. - return genericConstraint->getUserConstraintId(); - } - return 0; -} - -void CcdPhysicsEnvironment::RemoveConstraintById(int constraintId) -{ - // For soft body constraints - if (constraintId == 0) - return; - - int i; - int numConstraints = m_dynamicsWorld->getNumConstraints(); - for (i=0;i<numConstraints;i++) - { - btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i); - if (constraint->getUserConstraintId() == constraintId) - { - RemoveConstraint(constraint); - break; - } - } - - WrapperVehicle *vehicle; - if ((vehicle = (WrapperVehicle*)GetVehicleConstraint(constraintId))) - { - m_dynamicsWorld->removeVehicle(vehicle->GetVehicle()); - m_wrapperVehicles.erase(std::remove(m_wrapperVehicles.begin(), m_wrapperVehicles.end(), vehicle)); - delete vehicle; - } -} - - -struct FilterClosestRayResultCallback : public btCollisionWorld::ClosestRayResultCallback -{ - PHY_IRayCastFilterCallback& m_phyRayFilter; - const btCollisionShape* m_hitTriangleShape; - int m_hitTriangleIndex; - - - FilterClosestRayResultCallback (PHY_IRayCastFilterCallback& phyRayFilter,const btVector3& rayFrom,const btVector3& rayTo) - : btCollisionWorld::ClosestRayResultCallback(rayFrom,rayTo), - m_phyRayFilter(phyRayFilter), - m_hitTriangleShape(NULL), - m_hitTriangleIndex(0) - { - } - - virtual ~FilterClosestRayResultCallback() - { - } - - virtual bool needsCollision(btBroadphaseProxy* proxy0) const - { - if (!(proxy0->m_collisionFilterGroup & m_collisionFilterMask)) - return false; - if (!(m_collisionFilterGroup & proxy0->m_collisionFilterMask)) - return false; - btCollisionObject* object = (btCollisionObject*)proxy0->m_clientObject; - CcdPhysicsController* phyCtrl = static_cast<CcdPhysicsController*>(object->getUserPointer()); - if (phyCtrl == m_phyRayFilter.m_ignoreController) - return false; - return m_phyRayFilter.needBroadphaseRayCast(phyCtrl); - } - - virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) - { - //CcdPhysicsController* curHit = static_cast<CcdPhysicsController*>(rayResult.m_collisionObject->getUserPointer()); - // save shape information as ClosestRayResultCallback::AddSingleResult() does not do it - if (rayResult.m_localShapeInfo) - { - m_hitTriangleShape = rayResult.m_collisionObject->getCollisionShape(); - m_hitTriangleIndex = rayResult.m_localShapeInfo->m_triangleIndex; - } else - { - m_hitTriangleShape = NULL; - m_hitTriangleIndex = 0; - } - return ClosestRayResultCallback::addSingleResult(rayResult,normalInWorldSpace); - } - -}; - -static bool GetHitTriangle(btCollisionShape* shape, CcdShapeConstructionInfo* shapeInfo, int hitTriangleIndex, btVector3 triangle[]) -{ - // this code is copied from Bullet - const unsigned char *vertexbase; - int numverts; - PHY_ScalarType type; - int stride; - const unsigned char *indexbase; - int indexstride; - int numfaces; - PHY_ScalarType indicestype; - btStridingMeshInterface* meshInterface = shapeInfo->GetMeshInterface(); - - if (!meshInterface) - return false; - - meshInterface->getLockedReadOnlyVertexIndexBase( - &vertexbase, - numverts, - type, - stride, - &indexbase, - indexstride, - numfaces, - indicestype, - 0); - - unsigned int* gfxbase = (unsigned int*)(indexbase+hitTriangleIndex*indexstride); - const btVector3& meshScaling = shape->getLocalScaling(); - for (int j=2;j>=0;j--) - { - int graphicsindex = (indicestype == PHY_SHORT) ? ((unsigned short *)gfxbase)[j] : gfxbase[j]; - - btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride); - - triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); - } - meshInterface->unLockReadOnlyVertexBase(0); - return true; -} - -PHY_IPhysicsController* CcdPhysicsEnvironment::RayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ) -{ - btVector3 rayFrom(fromX,fromY,fromZ); - btVector3 rayTo(toX,toY,toZ); - - btVector3 hitPointWorld,normalWorld; - - //Either Ray Cast with or without filtering - - //btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo); - FilterClosestRayResultCallback rayCallback(filterCallback,rayFrom,rayTo); - - - PHY_RayCastResult result; - memset(&result, 0, sizeof(result)); - - // don't collision with sensor object - rayCallback.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter; - // use faster (less accurate) ray callback, works better with 0 collision margins - rayCallback.m_flags |= btTriangleRaycastCallback::kF_UseSubSimplexConvexCastRaytest; - //, ,filterCallback.m_faceNormal); - - m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback); - if (rayCallback.hasHit()) - { - CcdPhysicsController* controller = static_cast<CcdPhysicsController*>(rayCallback.m_collisionObject->getUserPointer()); - result.m_controller = controller; - result.m_hitPoint[0] = rayCallback.m_hitPointWorld.getX(); - result.m_hitPoint[1] = rayCallback.m_hitPointWorld.getY(); - result.m_hitPoint[2] = rayCallback.m_hitPointWorld.getZ(); - - if (rayCallback.m_hitTriangleShape != NULL) - { - // identify the mesh polygon - CcdShapeConstructionInfo* shapeInfo = controller->m_shapeInfo; - if (shapeInfo) - { - btCollisionShape* shape = controller->GetCollisionObject()->getCollisionShape(); - if (shape->isCompound()) - { - btCompoundShape* compoundShape = (btCompoundShape*)shape; - CcdShapeConstructionInfo* compoundShapeInfo = shapeInfo; - // need to search which sub-shape has been hit - for (int i=0; i<compoundShape->getNumChildShapes(); i++) - { - shapeInfo = compoundShapeInfo->GetChildShape(i); - shape=compoundShape->getChildShape(i); - if (shape == rayCallback.m_hitTriangleShape) - break; - } - } - if (shape == rayCallback.m_hitTriangleShape && - rayCallback.m_hitTriangleIndex < shapeInfo->m_polygonIndexArray.size()) - { - // save original collision shape triangle for soft body - int hitTriangleIndex = rayCallback.m_hitTriangleIndex; - - result.m_meshObject = shapeInfo->GetMesh(); - if (shape->isSoftBody()) - { - // soft body using different face numbering because of randomization - // hopefully we have stored the original face number in m_tag - const btSoftBody* softBody = static_cast<const btSoftBody*>(rayCallback.m_collisionObject); - if (softBody->m_faces[hitTriangleIndex].m_tag != 0) - { - rayCallback.m_hitTriangleIndex = (int)((uintptr_t)(softBody->m_faces[hitTriangleIndex].m_tag)-1); - } - } - // retrieve the original mesh polygon (in case of quad->tri conversion) - result.m_polygon = shapeInfo->m_polygonIndexArray.at(rayCallback.m_hitTriangleIndex); - // hit triangle in world coordinate, for face normal and UV coordinate - btVector3 triangle[3]; - bool triangleOK = false; - if (filterCallback.m_faceUV && (3*rayCallback.m_hitTriangleIndex) < shapeInfo->m_triFaceUVcoArray.size()) - { - // interpolate the UV coordinate of the hit point - CcdShapeConstructionInfo::UVco* uvCo = &shapeInfo->m_triFaceUVcoArray[3*rayCallback.m_hitTriangleIndex]; - // 1. get the 3 coordinate of the triangle in world space - btVector3 v1, v2, v3; - if (shape->isSoftBody()) - { - // soft body give points directly in world coordinate - const btSoftBody* softBody = static_cast<const btSoftBody*>(rayCallback.m_collisionObject); - v1 = softBody->m_faces[hitTriangleIndex].m_n[0]->m_x; - v2 = softBody->m_faces[hitTriangleIndex].m_n[1]->m_x; - v3 = softBody->m_faces[hitTriangleIndex].m_n[2]->m_x; - } else - { - // for rigid body we must apply the world transform - triangleOK = GetHitTriangle(shape, shapeInfo, hitTriangleIndex, triangle); - if (!triangleOK) - // if we cannot get the triangle, no use to continue - goto SKIP_UV_NORMAL; - v1 = rayCallback.m_collisionObject->getWorldTransform()(triangle[0]); - v2 = rayCallback.m_collisionObject->getWorldTransform()(triangle[1]); - v3 = rayCallback.m_collisionObject->getWorldTransform()(triangle[2]); - } - // 2. compute barycentric coordinate of the hit point - btVector3 v = v2-v1; - btVector3 w = v3-v1; - btVector3 u = v.cross(w); - btScalar A = u.length(); - - v = v2-rayCallback.m_hitPointWorld; - w = v3-rayCallback.m_hitPointWorld; - u = v.cross(w); - btScalar A1 = u.length(); - - v = rayCallback.m_hitPointWorld-v1; - w = v3-v1; - u = v.cross(w); - btScalar A2 = u.length(); - - btVector3 baryCo; - baryCo.setX(A1/A); - baryCo.setY(A2/A); - baryCo.setZ(1.0f-baryCo.getX()-baryCo.getY()); - // 3. compute UV coordinate - result.m_hitUV[0] = baryCo.getX()*uvCo[0].uv[0] + baryCo.getY()*uvCo[1].uv[0] + baryCo.getZ()*uvCo[2].uv[0]; - result.m_hitUV[1] = baryCo.getX()*uvCo[0].uv[1] + baryCo.getY()*uvCo[1].uv[1] + baryCo.getZ()*uvCo[2].uv[1]; - result.m_hitUVOK = 1; - } - - // Bullet returns the normal from "outside". - // If the user requests the real normal, compute it now - if (filterCallback.m_faceNormal) - { - if (shape->isSoftBody()) - { - // we can get the real normal directly from the body - const btSoftBody* softBody = static_cast<const btSoftBody*>(rayCallback.m_collisionObject); - rayCallback.m_hitNormalWorld = softBody->m_faces[hitTriangleIndex].m_normal; - } else - { - if (!triangleOK) - triangleOK = GetHitTriangle(shape, shapeInfo, hitTriangleIndex, triangle); - if (triangleOK) - { - btVector3 triangleNormal; - triangleNormal = (triangle[1]-triangle[0]).cross(triangle[2]-triangle[0]); - rayCallback.m_hitNormalWorld = rayCallback.m_collisionObject->getWorldTransform().getBasis()*triangleNormal; - } - } - } - SKIP_UV_NORMAL: - ; - } - } - } - if (rayCallback.m_hitNormalWorld.length2() > (SIMD_EPSILON*SIMD_EPSILON)) - { - rayCallback.m_hitNormalWorld.normalize(); - } else - { - rayCallback.m_hitNormalWorld.setValue(1,0,0); - } - result.m_hitNormal[0] = rayCallback.m_hitNormalWorld.getX(); - result.m_hitNormal[1] = rayCallback.m_hitNormalWorld.getY(); - result.m_hitNormal[2] = rayCallback.m_hitNormalWorld.getZ(); - filterCallback.reportHit(&result); - } - - - return result.m_controller; -} - -// Handles occlusion culling. -// The implementation is based on the CDTestFramework -struct OcclusionBuffer -{ - struct WriteOCL - { - static inline bool Process(btScalar &q, btScalar v) - { - if (q < v) { - q = v; - } - return false; - } - static inline void Occlusion(bool &flag) - { - flag = true; - } - }; - - struct QueryOCL - { - static inline bool Process(btScalar &q, btScalar v) - { - return (q <= v); - } - static inline void Occlusion(bool &flag) - { - } - }; - - btScalar *m_buffer; - size_t m_bufferSize; - bool m_initialized; - bool m_occlusion; - int m_sizes[2]; - btScalar m_scales[2]; - btScalar m_offsets[2]; - btScalar m_wtc[16]; // world to clip transform - btScalar m_mtc[16]; // model to clip transform - // constructor: size=largest dimension of the buffer. - // Buffer size depends on aspect ratio - OcclusionBuffer() - { - m_initialized = false; - m_occlusion = false; - m_buffer = NULL; - m_bufferSize = 0; - } - // multiplication of column major matrices: m = m1 * m2 - template<typename T1, typename T2> - void CMmat4mul(btScalar *m, const T1 *m1, const T2 *m2) - { - m[0] = btScalar(m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3]); - m[1] = btScalar(m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3]); - m[2] = btScalar(m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3]); - m[3] = btScalar(m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3]); - - m[4] = btScalar(m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7]); - m[5] = btScalar(m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7]); - m[6] = btScalar(m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7]); - m[7] = btScalar(m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7]); - - m[8] = btScalar(m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11]); - m[9] = btScalar(m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11]); - m[10] = btScalar(m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11]); - m[11] = btScalar(m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11]); - - m[12] = btScalar(m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15]); - m[13] = btScalar(m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15]); - m[14] = btScalar(m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15]); - m[15] = btScalar(m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15]); - } - - void setup(int size, const int *view, float modelview[16], float projection[16]) - { - m_initialized = false; - m_occlusion = false; - // compute the size of the buffer - int maxsize = (view[2] > view[3]) ? view[2] : view[3]; - assert(maxsize > 0); - double ratio = 1.0 / (2 * maxsize); - // ensure even number - m_sizes[0] = 2 * ((int)(size * view[2] * ratio + 0.5)); - m_sizes[1] = 2 * ((int)(size * view[3] * ratio + 0.5)); - m_scales[0] = btScalar(m_sizes[0] / 2); - m_scales[1] = btScalar(m_sizes[1] / 2); - m_offsets[0] = m_scales[0] + 0.5f; - m_offsets[1] = m_scales[1] + 0.5f; - // prepare matrix - // at this time of the rendering, the modelview matrix is the - // world to camera transformation and the projection matrix is - // camera to clip transformation. combine both so that - CMmat4mul(m_wtc, projection, modelview); - } - - void initialize() - { - size_t newsize = (m_sizes[0] * m_sizes[1]) * sizeof(btScalar); - if (m_buffer) { - // see if we can reuse - if (newsize > m_bufferSize) { - free(m_buffer); - m_buffer = NULL; - m_bufferSize = 0; - } - } - if (!m_buffer) { - m_buffer = (btScalar *)calloc(1, newsize); - m_bufferSize = newsize; - } - else { - // buffer exists already, just clears it - memset(m_buffer, 0, newsize); - } - // memory allocate must succeed - assert(m_buffer != NULL); - m_initialized = true; - m_occlusion = false; - } - - void SetModelMatrix(float *fl) - { - CMmat4mul(m_mtc,m_wtc,fl); - if (!m_initialized) { - initialize(); - } - } - - // transform a segment in world coordinate to clip coordinate - void transformW(const btVector3 &x, btVector4 &t) - { - t[0] = x[0] * m_wtc[0] + x[1] * m_wtc[4] + x[2] * m_wtc[8] + m_wtc[12]; - t[1] = x[0] * m_wtc[1] + x[1] * m_wtc[5] + x[2] * m_wtc[9] + m_wtc[13]; - t[2] = x[0] * m_wtc[2] + x[1] * m_wtc[6] + x[2] * m_wtc[10] + m_wtc[14]; - t[3] = x[0] * m_wtc[3] + x[1] * m_wtc[7] + x[2] * m_wtc[11] + m_wtc[15]; - } - - void transformM(const float *x, btVector4 &t) - { - t[0] = x[0] * m_mtc[0] + x[1] * m_mtc[4] + x[2] * m_mtc[8] + m_mtc[12]; - t[1] = x[0] * m_mtc[1] + x[1] * m_mtc[5] + x[2] * m_mtc[9] + m_mtc[13]; - t[2] = x[0] * m_mtc[2] + x[1] * m_mtc[6] + x[2] * m_mtc[10] + m_mtc[14]; - t[3] = x[0] * m_mtc[3] + x[1] * m_mtc[7] + x[2] * m_mtc[11] + m_mtc[15]; - } - // convert polygon to device coordinates - static bool project(btVector4 *p, int n) - { - for (int i = 0; i < n; ++i) { - p[i][2] = 1 / p[i][3]; - p[i][0] *= p[i][2]; - p[i][1] *= p[i][2]; - } - return true; - } - // pi: closed polygon in clip coordinate, NP = number of segments - // po: same polygon with clipped segments removed - template <const int NP> - static int clip(const btVector4 *pi, btVector4 *po) - { - btScalar s[2 * NP]; - btVector4 pn[2 * NP]; - int i, j, m, n, ni; - // deal with near clipping - for (i = 0, m = 0; i < NP; ++i) { - s[i] = pi[i][2] + pi[i][3]; - if (s[i] < 0) { - m += 1 << i; - } - } - if (m == ((1 << NP) - 1)) { - return 0; - } - if (m != 0) { - for (i = NP - 1, j = 0, n = 0; j < NP; i = j++) { - const btVector4 &a = pi[i]; - const btVector4 &b = pi[j]; - const btScalar t = s[i] / (a[3] + a[2] - b[3] - b[2]); - if ((t > 0) && (t < 1)) { - pn[n][0] = a[0] + (b[0] - a[0]) * t; - pn[n][1] = a[1] + (b[1] - a[1]) * t; - pn[n][2] = a[2] + (b[2] - a[2]) * t; - pn[n][3] = a[3] + (b[3] - a[3]) * t; - ++n; - } - if (s[j] > 0) { - pn[n++] = b; - } - } - // ready to test far clipping, start from the modified polygon - pi = pn; - ni = n; - } - else { - // no clipping on the near plane, keep same vector - ni = NP; - } - // now deal with far clipping - for (i = 0, m = 0; i < ni; ++i) { - s[i] = pi[i][2] - pi[i][3]; - if (s[i] > 0) { - m += 1 << i; - } - } - if (m == ((1 << ni) - 1)) { - return 0; - } - if (m != 0) { - for (i = ni - 1, j = 0, n = 0;j < ni; i = j++) { - const btVector4 &a = pi[i]; - const btVector4 &b = pi[j]; - const btScalar t = s[i] / (a[2] - a[3] - b[2] + b[3]); - if ((t > 0) && (t < 1)) { - po[n][0] = a[0] + (b[0] - a[0]) * t; - po[n][1] = a[1] + (b[1] - a[1]) * t; - po[n][2] = a[2] + (b[2] - a[2]) * t; - po[n][3] = a[3] + (b[3] - a[3]) * t; - ++n; - } - if (s[j] < 0) { - po[n++] = b; - } - } - return n; - } - for (int i = 0; i < ni; ++i) { - po[i] = pi[i]; - } - return ni; - } - // write or check a triangle to buffer. a,b,c in device coordinates (-1,+1) - template <typename POLICY> - inline bool draw(const btVector4 &a, - const btVector4 &b, - const btVector4 &c, - const float face, - const btScalar minarea) - { - const btScalar a2 = btCross(b - a, c - a)[2]; - if ((face * a2) < 0.0f || btFabs(a2) < minarea) { - return false; - } - // further down we are normally going to write to the Zbuffer, mark it so - POLICY::Occlusion(m_occlusion); - - int x[3], y[3], ib = 1, ic = 2; - btScalar z[3]; - x[0] = (int)(a.x() * m_scales[0] + m_offsets[0]); - y[0] = (int)(a.y() * m_scales[1] + m_offsets[1]); - z[0] = a.z(); - if (a2 < 0.f) { - // negative aire is possible with double face => must - // change the order of b and c otherwise the algorithm doesn't work - ib = 2; - ic = 1; - } - x[ib] = (int)(b.x() * m_scales[0] + m_offsets[0]); - x[ic] = (int)(c.x() * m_scales[0] + m_offsets[0]); - y[ib] = (int)(b.y() * m_scales[1] + m_offsets[1]); - y[ic] = (int)(c.y() * m_scales[1] + m_offsets[1]); - z[ib] = b.z(); - z[ic] = c.z(); - const int mix = btMax(0, btMin(x[0], btMin(x[1], x[2]))); - const int mxx = btMin(m_sizes[0], 1 + btMax(x[0], btMax(x[1], x[2]))); - const int miy = btMax(0, btMin(y[0], btMin(y[1], y[2]))); - const int mxy = btMin(m_sizes[1], 1 + btMax(y[0], btMax(y[1], y[2]))); - const int width = mxx - mix; - const int height = mxy - miy; - if ((width * height) <= 1) { - // degenerated in at most one single pixel - btScalar *scan = &m_buffer[miy * m_sizes[0] + mix]; - // use for loop to detect the case where width or height == 0 - for (int iy = miy; iy < mxy; ++iy) { - for (int ix = mix; ix < mxx; ++ix) { - if (POLICY::Process(*scan, z[0])) { - return true; - } - if (POLICY::Process(*scan, z[1])) { - return true; - } - if (POLICY::Process(*scan, z[2])) { - return true; - } - } - } - } - else if (width == 1) { - // Degenerated in at least 2 vertical lines - // The algorithm below doesn't work when face has a single pixel width - // We cannot use general formulas because the plane is degenerated. - // We have to interpolate along the 3 edges that overlaps and process each pixel. - // sort the y coord to make formula simpler - int ytmp; - btScalar ztmp; - if (y[0] > y[1]) { - ytmp = y[1]; - y[1] = y[0]; - y[0] = ytmp; - ztmp = z[1]; - z[1] = z[0]; - z[0] = ztmp; - } - if (y[0] > y[2]) { - ytmp = y[2]; - y[2] = y[0]; - y[0] = ytmp; - ztmp = z[2]; - z[2] = z[0]; - z[0] = ztmp; - } - if (y[1] > y[2]) { - ytmp = y[2]; - y[2] = y[1]; - y[1] = ytmp; - ztmp = z[2]; - z[2] = z[1]; - z[1] = ztmp; - } - int dy[] = {y[0] - y[1], - y[1] - y[2], - y[2] - y[0]}; - btScalar dzy[3]; - dzy[0] = (dy[0]) ? (z[0] - z[1]) / dy[0] : btScalar(0.0f); - dzy[1] = (dy[1]) ? (z[1] - z[2]) / dy[1] : btScalar(0.0f); - dzy[2] = (dy[2]) ? (z[2] - z[0]) / dy[2] : btScalar(0.0f); - btScalar v[3] = {dzy[0] * (miy - y[0]) + z[0], - dzy[1] * (miy - y[1]) + z[1], - dzy[2] * (miy - y[2]) + z[2]}; - dy[0] = y[1] - y[0]; - dy[1] = y[0] - y[1]; - dy[2] = y[2] - y[0]; - btScalar *scan = &m_buffer[miy * m_sizes[0] + mix]; - for (int iy = miy; iy < mxy; ++iy) { - if (dy[0] >= 0 && POLICY::Process(*scan, v[0])) { - return true; - } - if (dy[1] >= 0 && POLICY::Process(*scan, v[1])) { - return true; - } - if (dy[2] >= 0 && POLICY::Process(*scan, v[2])) { - return true; - } - scan += m_sizes[0]; - v[0] += dzy[0]; - v[1] += dzy[1]; - v[2] += dzy[2]; - dy[0]--; - dy[1]++; - dy[2]--; - } - } - else if (height == 1) { - // Degenerated in at least 2 horizontal lines - // The algorithm below doesn't work when face has a single pixel width - // We cannot use general formulas because the plane is degenerated. - // We have to interpolate along the 3 edges that overlaps and process each pixel. - int xtmp; - btScalar ztmp; - if (x[0] > x[1]) { - xtmp = x[1]; - x[1] = x[0]; - x[0] = xtmp; - ztmp = z[1]; - z[1] = z[0]; - z[0] = ztmp; - } - if (x[0] > x[2]) { - xtmp = x[2]; - x[2] = x[0]; - x[0] = xtmp; - ztmp = z[2]; - z[2] = z[0]; - z[0] = ztmp; - } - if (x[1] > x[2]) { - xtmp = x[2]; - x[2] = x[1]; - x[1] = xtmp; - ztmp = z[2]; - z[2] = z[1]; - z[1] = ztmp; - } - int dx[] = {x[0] - x[1], - x[1] - x[2], - x[2] - x[0]}; - btScalar dzx[3]; - dzx[0] = (dx[0]) ? (z[0]-z[1]) / dx[0] : btScalar(0.0f); - dzx[1] = (dx[1]) ? (z[1]-z[2]) / dx[1] : btScalar(0.0f); - dzx[2] = (dx[2]) ? (z[2]-z[0]) / dx[2] : btScalar(0.0f); - btScalar v[3] = {dzx[0] * (mix - x[0]) + z[0], - dzx[1] * (mix - x[1]) + z[1], - dzx[2] * (mix - x[2]) + z[2]}; - dx[0] = x[1] - x[0]; - dx[1] = x[0] - x[1]; - dx[2] = x[2] - x[0]; - btScalar *scan = &m_buffer[miy * m_sizes[0] + mix]; - for (int ix = mix; ix < mxx; ++ix) { - if (dx[0] >= 0 && POLICY::Process(*scan, v[0])) { - return true; - } - if (dx[1] >= 0 && POLICY::Process(*scan, v[1])) { - return true; - } - if (dx[2] >= 0 && POLICY::Process(*scan, v[2])) { - return true; - } - scan++; - v[0] += dzx[0]; - v[1] += dzx[1]; - v[2] += dzx[2]; - dx[0]--; - dx[1]++; - dx[2]--; - } - } - else { - // general case - const int dx[] = {y[0] - y[1], - y[1] - y[2], - y[2] - y[0]}; - const int dy[] = {x[1] - x[0] - dx[0] * width, - x[2] - x[1] - dx[1] * width, - x[0] - x[2] - dx[2] * width}; - const int a = x[2] * y[0] + x[0] * y[1] - x[2] * y[1] - x[0] * y[2] + x[1] * y[2] - x[1] * y[0]; - const btScalar ia = 1 / (btScalar)a; - const btScalar dzx = ia * (y[2] * (z[1] - z[0]) + y[1] * (z[0] - z[2]) + y[0] * (z[2] - z[1])); - const btScalar dzy = ia * (x[2] * (z[0] - z[1]) + x[0] * (z[1] - z[2]) + x[1] * (z[2] - z[0])) - (dzx * width); - int c[] = {miy * x[1] + mix * y[0] - x[1] * y[0] - mix * y[1] + x[0] * y[1] - miy * x[0], - miy * x[2] + mix * y[1] - x[2] * y[1] - mix * y[2] + x[1] * y[2] - miy * x[1], - miy * x[0] + mix * y[2] - x[0] * y[2] - mix * y[0] + x[2] * y[0] - miy * x[2]}; - btScalar v = ia * ((z[2] * c[0]) + (z[0] * c[1]) + (z[1] * c[2])); - btScalar *scan = &m_buffer[miy * m_sizes[0]]; - - for (int iy = miy; iy < mxy; ++iy) { - for (int ix = mix; ix < mxx; ++ix) { - if ((c[0] >= 0) && (c[1] >= 0) && (c[2] >= 0)) { - if (POLICY::Process(scan[ix], v)) { - return true; - } - } - c[0] += dx[0]; c[1] += dx[1]; c[2] += dx[2]; v += dzx; - } - c[0] += dy[0]; c[1] += dy[1]; c[2] += dy[2]; v += dzy; - scan += m_sizes[0]; - } - } - return false; - } - // clip than write or check a polygon - template <const int NP, typename POLICY> - inline bool clipDraw(const btVector4 *p, - const float face, - btScalar minarea) - { - btVector4 o[NP * 2]; - int n = clip<NP>(p, o); - bool earlyexit = false; - if (n) { - project(o, n); - for (int i = 2; i < n && !earlyexit; ++i) { - earlyexit |= draw<POLICY>(o[0], o[i - 1], o[i], face, minarea); - } - } - return earlyexit; - } - // add a triangle (in model coordinate) - // face = 0.f if face is double side, - // = 1.f if face is single sided and scale is positive - // = -1.f if face is single sided and scale is negative - void appendOccluderM(const float *a, - const float *b, - const float *c, - const float face) - { - btVector4 p[3]; - transformM(a, p[0]); - transformM(b, p[1]); - transformM(c, p[2]); - clipDraw<3, WriteOCL>(p, face, btScalar(0.0f)); - } - // add a quad (in model coordinate) - void appendOccluderM(const float *a, - const float *b, - const float *c, - const float *d, - const float face) - { - btVector4 p[4]; - transformM(a, p[0]); - transformM(b, p[1]); - transformM(c, p[2]); - transformM(d, p[3]); - clipDraw<4, WriteOCL>(p, face, btScalar(0.0f)); - } - // query occluder for a box (c=center, e=extend) in world coordinate - inline bool queryOccluderW(const btVector3 &c, - const btVector3 &e) - { - if (!m_occlusion) { - // no occlusion yet, no need to check - return true; - } - btVector4 x[8]; - transformW(btVector3(c[0] - e[0], c[1] - e[1], c[2] - e[2]), x[0]); - transformW(btVector3(c[0] + e[0], c[1] - e[1], c[2] - e[2]), x[1]); - transformW(btVector3(c[0] + e[0], c[1] + e[1], c[2] - e[2]), x[2]); - transformW(btVector3(c[0] - e[0], c[1] + e[1], c[2] - e[2]), x[3]); - transformW(btVector3(c[0] - e[0], c[1] - e[1], c[2] + e[2]), x[4]); - transformW(btVector3(c[0] + e[0], c[1] - e[1], c[2] + e[2]), x[5]); - transformW(btVector3(c[0] + e[0], c[1] + e[1], c[2] + e[2]), x[6]); - transformW(btVector3(c[0] - e[0], c[1] + e[1], c[2] + e[2]), x[7]); - - for (int i = 0; i < 8; ++i) { - // the box is clipped, it's probably a large box, don't waste our time to check - if ((x[i][2] + x[i][3]) <= 0) { - return true; - } - } - static const int d[] = {1, 0, 3, 2, - 4, 5, 6, 7, - 4, 7, 3, 0, - 6, 5, 1, 2, - 7, 6, 2, 3, - 5, 4, 0, 1}; - for (unsigned int i = 0; i < (sizeof(d) / sizeof(d[0]));) { - const btVector4 p[] = {x[d[i + 0]], - x[d[i + 1]], - x[d[i + 2]], - x[d[i + 3]]}; - i += 4; - if (clipDraw<4, QueryOCL>(p, 1.0f, 0.0f)) { - return true; - } - } - return false; - } -}; - - -struct DbvtCullingCallback : btDbvt::ICollide -{ - PHY_CullingCallback m_clientCallback; - void* m_userData; - OcclusionBuffer *m_ocb; - - DbvtCullingCallback(PHY_CullingCallback clientCallback, void* userData) - { - m_clientCallback = clientCallback; - m_userData = userData; - m_ocb = NULL; - } - bool Descent(const btDbvtNode* node) - { - return(m_ocb->queryOccluderW(node->volume.Center(),node->volume.Extents())); - } - void Process(const btDbvtNode* node,btScalar depth) - { - Process(node); - } - void Process(const btDbvtNode* leaf) - { - btBroadphaseProxy* proxy=(btBroadphaseProxy*)leaf->data; - // the client object is a graphic controller - CcdGraphicController* ctrl = static_cast<CcdGraphicController*>(proxy->m_clientObject); - KX_ClientObjectInfo *info = (KX_ClientObjectInfo*)ctrl->GetNewClientInfo(); - if (m_ocb) - { - // means we are doing occlusion culling. Check if this object is an occluders - KX_GameObject* gameobj = KX_GameObject::GetClientObject(info); - if (gameobj && gameobj->GetOccluder()) - { - float *fl = gameobj->GetOpenGLMatrixPtr()->getPointer(); - // this will create the occlusion buffer if not already done - // and compute the transformation from model local space to clip space - m_ocb->SetModelMatrix(fl); - float face = (gameobj->IsNegativeScaling()) ? -1.0f : 1.0f; - // walk through the meshes and for each add to buffer - for (int i=0; i<gameobj->GetMeshCount(); i++) - { - RAS_MeshObject* meshobj = gameobj->GetMesh(i); - const float *v1, *v2, *v3, *v4; - - int polycount = meshobj->NumPolygons(); - for (int j=0; j<polycount; j++) - { - RAS_Polygon* poly = meshobj->GetPolygon(j); - switch (poly->VertexCount()) - { - case 3: - v1 = poly->GetVertex(0)->getXYZ(); - v2 = poly->GetVertex(1)->getXYZ(); - v3 = poly->GetVertex(2)->getXYZ(); - m_ocb->appendOccluderM(v1,v2,v3,((poly->IsTwoside())?0.f:face)); - break; - case 4: - v1 = poly->GetVertex(0)->getXYZ(); - v2 = poly->GetVertex(1)->getXYZ(); - v3 = poly->GetVertex(2)->getXYZ(); - v4 = poly->GetVertex(3)->getXYZ(); - m_ocb->appendOccluderM(v1,v2,v3,v4,((poly->IsTwoside())?0.f:face)); - break; - } - } - } - } - } - if (info) - (*m_clientCallback)(info, m_userData); - } -}; - -static OcclusionBuffer gOcb; -bool CcdPhysicsEnvironment::CullingTest(PHY_CullingCallback callback, void* userData, MT_Vector4 *planes, int nplanes, int occlusionRes, const int *viewport, float modelview[16], float projection[16]) -{ - if (!m_cullingTree) - return false; - DbvtCullingCallback dispatcher(callback, userData); - btVector3 planes_n[6]; - btScalar planes_o[6]; - if (nplanes > 6) - nplanes = 6; - for (int i=0; i<nplanes; i++) - { - planes_n[i].setValue(planes[i][0], planes[i][1], planes[i][2]); - planes_o[i] = planes[i][3]; - } - // if occlusionRes != 0 => occlusion culling - if (occlusionRes) - { - gOcb.setup(occlusionRes, viewport, modelview, projection); - dispatcher.m_ocb = &gOcb; - // occlusion culling, the direction of the view is taken from the first plan which MUST be the near plane - btDbvt::collideOCL(m_cullingTree->m_sets[1].m_root,planes_n,planes_o,planes_n[0],nplanes,dispatcher); - btDbvt::collideOCL(m_cullingTree->m_sets[0].m_root,planes_n,planes_o,planes_n[0],nplanes,dispatcher); - } - else { - btDbvt::collideKDOP(m_cullingTree->m_sets[1].m_root,planes_n,planes_o,nplanes,dispatcher); - btDbvt::collideKDOP(m_cullingTree->m_sets[0].m_root,planes_n,planes_o,nplanes,dispatcher); - } - return true; -} - -int CcdPhysicsEnvironment::GetNumContactPoints() -{ - return 0; -} - -void CcdPhysicsEnvironment::GetContactPoint(int i,float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ) -{ - -} - - - - -btBroadphaseInterface* CcdPhysicsEnvironment::GetBroadphase() -{ - return m_dynamicsWorld->getBroadphase(); -} - -btDispatcher* CcdPhysicsEnvironment::GetDispatcher() -{ - return m_dynamicsWorld->getDispatcher(); -} - -void CcdPhysicsEnvironment::MergeEnvironment(PHY_IPhysicsEnvironment *other_env) -{ - CcdPhysicsEnvironment *other = dynamic_cast<CcdPhysicsEnvironment*>(other_env); - if (other == NULL) { - printf("KX_Scene::MergeScene: Other scene is not using Bullet physics, not merging physics.\n"); - return; - } - - std::set<CcdPhysicsController*>::iterator it; - - while (other->m_controllers.begin() != other->m_controllers.end()) - { - it= other->m_controllers.begin(); - CcdPhysicsController* ctrl= (*it); - - other->RemoveCcdPhysicsController(ctrl); - this->AddCcdPhysicsController(ctrl); - } -} - -CcdPhysicsEnvironment::~CcdPhysicsEnvironment() -{ - -#ifdef NEW_BULLET_VEHICLE_SUPPORT - m_wrapperVehicles.clear(); -#endif //NEW_BULLET_VEHICLE_SUPPORT - - //m_broadphase->DestroyScene(); - //delete broadphase ? release reference on broadphase ? - - //first delete scene, then dispatcher, because pairs have to release manifolds on the dispatcher - //delete m_dispatcher; - delete m_dynamicsWorld; - - - if (NULL != m_ownPairCache) - delete m_ownPairCache; - - if (NULL != m_ownDispatcher) - delete m_ownDispatcher; - - if (NULL != m_solver) - delete m_solver; - - if (NULL != m_debugDrawer) - delete m_debugDrawer; - - if (NULL != m_filterCallback) - delete m_filterCallback; - - if (NULL != m_ghostPairCallback) - delete m_ghostPairCallback; - - if (NULL != m_collisionConfiguration) - delete m_collisionConfiguration; - - if (NULL != m_broadphase) - delete m_broadphase; - - if (NULL != m_cullingTree) - delete m_cullingTree; - - if (NULL != m_cullingCache) - delete m_cullingCache; - -} - - -float CcdPhysicsEnvironment::GetConstraintParam(int constraintId,int param) -{ - btTypedConstraint* typedConstraint = GetConstraintById(constraintId); - if (!typedConstraint) - return 0.0f; - - switch (typedConstraint->getUserConstraintType()) - { - case PHY_GENERIC_6DOF_CONSTRAINT: - { - - switch (param) - { - case 0: case 1: case 2: - { - //param = 0..2 are linear constraint values - btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; - genCons->calculateTransforms(); - return genCons->getRelativePivotPosition(param); - break; - } - case 3: case 4: case 5: - { - //param = 3..5 are relative constraint (Euler) angles - btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; - genCons->calculateTransforms(); - return genCons->getAngle(param-3); - break; - } - default: - { - } - } - break; - }; - default: - { - }; - }; - return 0.f; -} - -void CcdPhysicsEnvironment::SetConstraintParam(int constraintId,int param,float value0,float value1) -{ - btTypedConstraint* typedConstraint = GetConstraintById(constraintId); - if (!typedConstraint) - return; - - switch (typedConstraint->getUserConstraintType()) - { - case PHY_GENERIC_6DOF_CONSTRAINT: - { - - switch (param) - { - case 0: case 1: case 2: case 3: case 4: case 5: - { - //param = 0..5 are constraint limits, with low/high limit value - btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; - genCons->setLimit(param,value0,value1); - break; - } - case 6: case 7: case 8: - { - //param = 6,7,8 are translational motors, with value0=target velocity, value1 = max motor force - btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; - int transMotorIndex = param-6; - btTranslationalLimitMotor* transMotor = genCons->getTranslationalLimitMotor(); - transMotor->m_targetVelocity[transMotorIndex] = value0; - transMotor->m_maxMotorForce[transMotorIndex] = value1; - transMotor->m_enableMotor[transMotorIndex] = (value1>0.f); - break; - } - case 9: case 10: case 11: - { - //param = 9,10,11 are rotational motors, with value0=target velocity, value1 = max motor force - btGeneric6DofConstraint* genCons = (btGeneric6DofConstraint*)typedConstraint; - int angMotorIndex = param-9; - btRotationalLimitMotor* rotMotor = genCons->getRotationalLimitMotor(angMotorIndex); - rotMotor->m_enableMotor = (value1 > 0.f); - rotMotor->m_targetVelocity = value0; - rotMotor->m_maxMotorForce = value1; - break; - } - - case 12: case 13: case 14: case 15: case 16: case 17: - { - //param 12-17 are for motorized springs on each of the degrees of freedom - btGeneric6DofSpringConstraint* genCons = (btGeneric6DofSpringConstraint*)typedConstraint; - int springIndex = param-12; - if (value0!=0.f) - { - bool springEnabled = true; - genCons->setStiffness(springIndex,value0); - genCons->setDamping(springIndex,value1); - genCons->enableSpring(springIndex,springEnabled); - genCons->setEquilibriumPoint(springIndex); - } else - { - bool springEnabled = false; - genCons->enableSpring(springIndex,springEnabled); - } - break; - } - - default: - { - } - }; - break; - }; - case PHY_CONE_TWIST_CONSTRAINT: - { - switch (param) - { - case 3: case 4: case 5: - { - //param = 3,4,5 are constraint limits, high limit values - btConeTwistConstraint* coneTwist = (btConeTwistConstraint*)typedConstraint; - if (value1<0.0f) - coneTwist->setLimit(param,btScalar(BT_LARGE_FLOAT)); - else - coneTwist->setLimit(param,value1); - break; - } - default: - { - } - }; - break; - }; - case PHY_ANGULAR_CONSTRAINT: - case PHY_LINEHINGE_CONSTRAINT: - { - switch (param) - { - case 3: - { - //param = 3 is a constraint limit, with low/high limit value - btHingeConstraint* hingeCons = (btHingeConstraint*)typedConstraint; - hingeCons->setLimit(value0,value1); - break; - } - default: - { - } - } - break; - }; - default: - { - }; - }; -} - -btTypedConstraint* CcdPhysicsEnvironment::GetConstraintById(int constraintId) -{ - // For soft body constraints - if (constraintId == 0) - return NULL; - - int numConstraints = m_dynamicsWorld->getNumConstraints(); - int i; - for (i=0;i<numConstraints;i++) - { - btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i); - if (constraint->getUserConstraintId()==constraintId) - { - return constraint; - } - } - return 0; -} - - -void CcdPhysicsEnvironment::AddSensor(PHY_IPhysicsController* ctrl) -{ - CcdPhysicsController* ctrl1 = (CcdPhysicsController* )ctrl; - AddCcdPhysicsController(ctrl1); -} - -bool CcdPhysicsEnvironment::RemoveCollisionCallback(PHY_IPhysicsController* ctrl) -{ - CcdPhysicsController* ccdCtrl = (CcdPhysicsController*)ctrl; - return ccdCtrl->Unregister(); -} - - -void CcdPhysicsEnvironment::RemoveSensor(PHY_IPhysicsController* ctrl) -{ - RemoveCcdPhysicsController((CcdPhysicsController*)ctrl); -} - -void CcdPhysicsEnvironment::AddTouchCallback(int response_class, PHY_ResponseCallback callback, void *user) -{ - /* printf("addTouchCallback\n(response class = %i)\n",response_class); - - //map PHY_ convention into SM_ convention - switch (response_class) - { - case PHY_FH_RESPONSE: - printf("PHY_FH_RESPONSE\n"); - break; - case PHY_SENSOR_RESPONSE: - printf("PHY_SENSOR_RESPONSE\n"); - break; - case PHY_CAMERA_RESPONSE: - printf("PHY_CAMERA_RESPONSE\n"); - break; - case PHY_OBJECT_RESPONSE: - printf("PHY_OBJECT_RESPONSE\n"); - break; - case PHY_STATIC_RESPONSE: - printf("PHY_STATIC_RESPONSE\n"); - break; - default: - assert(0); - return; - } - */ - - m_triggerCallbacks[response_class] = callback; - m_triggerCallbacksUserPtrs[response_class] = user; - -} -bool CcdPhysicsEnvironment::RequestCollisionCallback(PHY_IPhysicsController* ctrl) -{ - CcdPhysicsController* ccdCtrl = static_cast<CcdPhysicsController*>(ctrl); - return ccdCtrl->Register(); -} - -void CcdPhysicsEnvironment::CallbackTriggers() -{ - bool draw_contact_points = m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints); - - if (!m_triggerCallbacks[PHY_OBJECT_RESPONSE] && !draw_contact_points) - return; - - //walk over all overlapping pairs, and if one of the involved bodies is registered for trigger callback, perform callback - btDispatcher* dispatcher = m_dynamicsWorld->getDispatcher(); - int numManifolds = dispatcher->getNumManifolds(); - for (int i=0;i<numManifolds;i++) - { - bool colliding_ctrl0 = true; - btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i); - int numContacts = manifold->getNumContacts(); - if (!numContacts) continue; - - const btRigidBody* rb0 = static_cast<const btRigidBody*>(manifold->getBody0()); - const btRigidBody* rb1 = static_cast<const btRigidBody*>(manifold->getBody1()); - if (draw_contact_points) - { - for (int j=0;j<numContacts;j++) - { - btVector3 color(1,1,0); - const btManifoldPoint& cp = manifold->getContactPoint(j); - m_debugDrawer->drawContactPoint(cp.m_positionWorldOnB, - cp.m_normalWorldOnB, - cp.getDistance(), - cp.getLifeTime(), - color); - } - } - - //m_internalOwner is set in 'addPhysicsController' - CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(rb0->getUserPointer()); - CcdPhysicsController* ctrl1 = static_cast<CcdPhysicsController*>(rb1->getUserPointer()); - bool usecallback = false; - - // Test if one of the controller is registered and use collision callback. - if (ctrl0->Registered()) - usecallback = true; - else if (ctrl1->Registered()) { - colliding_ctrl0 = false; - usecallback = true; - } - - if (usecallback) { - static PHY_CollData coll_data; - const btManifoldPoint &cp = manifold->getContactPoint(0); - - /* Make sure that "point1" is always on the object we report on, and - * "point2" on the other object. Also ensure the normal is oriented - * correctly. */ - btVector3 point1 = colliding_ctrl0 ? cp.m_positionWorldOnA : cp.m_positionWorldOnB; - btVector3 point2 = colliding_ctrl0 ? cp.m_positionWorldOnB : cp.m_positionWorldOnA; - btVector3 normal = colliding_ctrl0 ? -cp.m_normalWorldOnB : cp.m_normalWorldOnB; - - coll_data.m_point1 = MT_Vector3(point1.m_floats); - coll_data.m_point2 = MT_Vector3(point2.m_floats); - coll_data.m_normal = MT_Vector3(normal.m_floats); - - m_triggerCallbacks[PHY_OBJECT_RESPONSE](m_triggerCallbacksUserPtrs[PHY_OBJECT_RESPONSE], - ctrl0, ctrl1, &coll_data); - } - // Bullet does not refresh the manifold contact point for object without contact response - // may need to remove this when a newer Bullet version is integrated - if (!dispatcher->needsResponse(rb0, rb1)) - { - // Refresh algorithm fails sometimes when there is penetration - // (usuall the case with ghost and sensor objects) - // Let's just clear the manifold, in any case, it is recomputed on each frame. - manifold->clearManifold(); //refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform()); - } - } -} - -// This call back is called before a pair is added in the cache -// Handy to remove objects that must be ignored by sensors -bool CcdOverlapFilterCallBack::needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const -{ - btCollisionObject *colObj0, *colObj1; - CcdPhysicsController *sensorCtrl, *objCtrl; - - KX_GameObject *kxObj0 = KX_GameObject::GetClientObject( - (KX_ClientObjectInfo*) - ((CcdPhysicsController*) - (((btCollisionObject*)proxy0->m_clientObject)->getUserPointer())) - ->GetNewClientInfo()); - KX_GameObject *kxObj1 = KX_GameObject::GetClientObject( - (KX_ClientObjectInfo*) - ((CcdPhysicsController*) - (((btCollisionObject*)proxy1->m_clientObject)->getUserPointer())) - ->GetNewClientInfo()); - - // First check the filters. Note that this is called during scene - // conversion, so we can't assume the KX_GameObject instances exist. This - // may make some objects erroneously collide on the first frame, but the - // alternative is to have them erroneously miss. - bool collides; - collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; - collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); - if (kxObj0 && kxObj1) { - collides = collides && kxObj0->CheckCollision(kxObj1); - collides = collides && kxObj1->CheckCollision(kxObj0); - } - if (!collides) - return false; - - // additional check for sensor object - if (proxy0->m_collisionFilterGroup & btBroadphaseProxy::SensorTrigger) - { - // this is a sensor object, the other one can't be a sensor object because - // they exclude each other in the above test - assert(!(proxy1->m_collisionFilterGroup & btBroadphaseProxy::SensorTrigger)); - colObj0 = (btCollisionObject*)proxy0->m_clientObject; - colObj1 = (btCollisionObject*)proxy1->m_clientObject; - } - else if (proxy1->m_collisionFilterGroup & btBroadphaseProxy::SensorTrigger) - { - colObj0 = (btCollisionObject*)proxy1->m_clientObject; - colObj1 = (btCollisionObject*)proxy0->m_clientObject; - } - else - { - return true; - } - if (!colObj0 || !colObj1) - return false; - sensorCtrl = static_cast<CcdPhysicsController*>(colObj0->getUserPointer()); - objCtrl = static_cast<CcdPhysicsController*>(colObj1->getUserPointer()); - if (m_physEnv->m_triggerCallbacks[PHY_BROADPH_RESPONSE]) - { - return m_physEnv->m_triggerCallbacks[PHY_BROADPH_RESPONSE](m_physEnv->m_triggerCallbacksUserPtrs[PHY_BROADPH_RESPONSE], sensorCtrl, objCtrl, 0); - } - return true; -} - - -#ifdef NEW_BULLET_VEHICLE_SUPPORT - -//complex constraint for vehicles -PHY_IVehicle* CcdPhysicsEnvironment::GetVehicleConstraint(int constraintId) -{ - int i; - - int numVehicles = m_wrapperVehicles.size(); - for (i=0;i<numVehicles;i++) - { - WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i]; - if (wrapperVehicle->GetVehicle()->getUserConstraintId() == constraintId) - return wrapperVehicle; - } - - return 0; -} - -#endif //NEW_BULLET_VEHICLE_SUPPORT - - -PHY_ICharacter* CcdPhysicsEnvironment::GetCharacterController(KX_GameObject *ob) -{ - CcdPhysicsController* controller = (CcdPhysicsController*)ob->GetPhysicsController(); - return (controller) ? dynamic_cast<BlenderBulletCharacterController*>(controller->GetCharacterController()) : NULL; -} - - -PHY_IPhysicsController* CcdPhysicsEnvironment::CreateSphereController(float radius,const MT_Vector3& position) -{ - - CcdConstructionInfo cinfo; - memset(&cinfo, 0, sizeof(cinfo)); /* avoid uninitialized values */ - cinfo.m_collisionShape = new btSphereShape(radius); // memory leak! The shape is not deleted by Bullet and we cannot add it to the KX_Scene.m_shapes list - cinfo.m_MotionState = 0; - cinfo.m_physicsEnv = this; - // declare this object as Dyamic rather than static!! - // The reason as it is designed to detect all type of object, including static object - // It would cause static-static message to be printed on the console otherwise - cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE | btCollisionObject::CF_STATIC_OBJECT; - DefaultMotionState* motionState = new DefaultMotionState(); - cinfo.m_MotionState = motionState; - // we will add later the possibility to select the filter from option - cinfo.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter; - cinfo.m_collisionFilterGroup = CcdConstructionInfo::SensorFilter; - cinfo.m_bSensor = true; - motionState->m_worldTransform.setIdentity(); - motionState->m_worldTransform.setOrigin(btVector3(position[0],position[1],position[2])); - - CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo); - - return sphereController; -} - -int findClosestNode(btSoftBody* sb,const btVector3& worldPoint); -int findClosestNode(btSoftBody* sb,const btVector3& worldPoint) -{ - int node = -1; - - btSoftBody::tNodeArray& nodes(sb->m_nodes); - float maxDistSqr = 1e30f; - - for (int n=0;n<nodes.size();n++) - { - btScalar distSqr = (nodes[n].m_x - worldPoint).length2(); - if (distSqr<maxDistSqr) - { - maxDistSqr = distSqr; - node = n; - } - } - return node; -} - -int CcdPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl0,class PHY_IPhysicsController* ctrl1,PHY_ConstraintType type, - float pivotX,float pivotY,float pivotZ, - float axisX,float axisY,float axisZ, - float axis1X,float axis1Y,float axis1Z, - float axis2X,float axis2Y,float axis2Z,int flags - ) -{ - - bool disableCollisionBetweenLinkedBodies = (0!=(flags & CCD_CONSTRAINT_DISABLE_LINKED_COLLISION)); - - - - CcdPhysicsController* c0 = (CcdPhysicsController*)ctrl0; - CcdPhysicsController* c1 = (CcdPhysicsController*)ctrl1; - - btRigidBody* rb0 = c0 ? c0->GetRigidBody() : 0; - btRigidBody* rb1 = c1 ? c1->GetRigidBody() : 0; - - - - - bool rb0static = rb0 ? rb0->isStaticOrKinematicObject() : true; - bool rb1static = rb1 ? rb1->isStaticOrKinematicObject() : true; - - btCollisionObject* colObj0 = c0->GetCollisionObject(); - if (!colObj0) - { - return 0; - } - - btVector3 pivotInA(pivotX,pivotY,pivotZ); - - - - //it might be a soft body, let's try - btSoftBody* sb0 = c0 ? c0->GetSoftBody() : 0; - btSoftBody* sb1 = c1 ? c1->GetSoftBody() : 0; - if (sb0 && sb1) - { - //not between two soft bodies? - return 0; - } - - if (sb0) - { - //either cluster or node attach, let's find closest node first - //the soft body doesn't have a 'real' world transform, so get its initial world transform for now - btVector3 pivotPointSoftWorld = sb0->m_initialWorldTransform(pivotInA); - int node=findClosestNode(sb0,pivotPointSoftWorld); - if (node >=0) - { - bool clusterconstaint = false; -/* - switch (type) - { - case PHY_LINEHINGE_CONSTRAINT: - { - if (sb0->clusterCount() && rb1) - { - btSoftBody::LJoint::Specs ls; - ls.erp=0.5f; - ls.position=sb0->clusterCom(0); - sb0->appendLinearJoint(ls,rb1); - clusterconstaint = true; - break; - } - } - case PHY_GENERIC_6DOF_CONSTRAINT: - { - if (sb0->clusterCount() && rb1) - { - btSoftBody::AJoint::Specs as; - as.erp = 1; - as.cfm = 1; - as.axis.setValue(axisX,axisY,axisZ); - sb0->appendAngularJoint(as,rb1); - clusterconstaint = true; - break; - } - - break; - } - default: - { - - } - }; - */ - - if (!clusterconstaint) - { - if (rb1) - { - sb0->appendAnchor(node,rb1,disableCollisionBetweenLinkedBodies); - } else - { - sb0->setMass(node,0.f); - } - } - - - } - return 0;//can't remove soft body anchors yet - } - - if (sb1) - { - btVector3 pivotPointAWorld = colObj0->getWorldTransform()(pivotInA); - int node=findClosestNode(sb1,pivotPointAWorld); - if (node >=0) - { - bool clusterconstaint = false; - - /* - switch (type) - { - case PHY_LINEHINGE_CONSTRAINT: - { - if (sb1->clusterCount() && rb0) - { - btSoftBody::LJoint::Specs ls; - ls.erp=0.5f; - ls.position=sb1->clusterCom(0); - sb1->appendLinearJoint(ls,rb0); - clusterconstaint = true; - break; - } - } - case PHY_GENERIC_6DOF_CONSTRAINT: - { - if (sb1->clusterCount() && rb0) - { - btSoftBody::AJoint::Specs as; - as.erp = 1; - as.cfm = 1; - as.axis.setValue(axisX,axisY,axisZ); - sb1->appendAngularJoint(as,rb0); - clusterconstaint = true; - break; - } - - break; - } - default: - { - - - } - };*/ - - - if (!clusterconstaint) - { - if (rb0) - { - sb1->appendAnchor(node,rb0,disableCollisionBetweenLinkedBodies); - } else - { - sb1->setMass(node,0.f); - } - } - - - } - return 0;//can't remove soft body anchors yet - } - - if (rb0static && rb1static) - { - - return 0; - } - - - if (!rb0) - return 0; - - btVector3 pivotInB = rb1 ? rb1->getCenterOfMassTransform().inverse()(rb0->getCenterOfMassTransform()(pivotInA)) : - rb0->getCenterOfMassTransform() * pivotInA; - btVector3 axisInA(axisX,axisY,axisZ); - - - bool angularOnly = false; - - switch (type) - { - case PHY_POINT2POINT_CONSTRAINT: - { - // If either of the controllers is missing, we can't do anything. - if (!c0 || !c1) return 0; - - btPoint2PointConstraint* p2p = 0; - - if (rb1) - { - p2p = new btPoint2PointConstraint(*rb0, - *rb1,pivotInA,pivotInB); - } else - { - p2p = new btPoint2PointConstraint(*rb0, - pivotInA); - } - - c0->addCcdConstraintRef(p2p); - c1->addCcdConstraintRef(p2p); - m_dynamicsWorld->addConstraint(p2p,disableCollisionBetweenLinkedBodies); -// m_constraints.push_back(p2p); - - p2p->setUserConstraintId(gConstraintUid++); - p2p->setUserConstraintType(type); - //64 bit systems can't cast pointer to int. could use size_t instead. - return p2p->getUserConstraintId(); - - break; - } - - case PHY_GENERIC_6DOF_CONSTRAINT: - { - // If either of the controllers is missing, we can't do anything. - if (!c0 || !c1) return 0; - - btGeneric6DofConstraint* genericConstraint = 0; - - if (rb1) - { - btTransform frameInA; - btTransform frameInB; - - btVector3 axis1(axis1X,axis1Y,axis1Z), axis2(axis2X,axis2Y,axis2Z); - if (axis1.length() == 0.0f) - { - btPlaneSpace1( axisInA, axis1, axis2 ); - } - - frameInA.getBasis().setValue( axisInA.x(), axis1.x(), axis2.x(), - axisInA.y(), axis1.y(), axis2.y(), - axisInA.z(), axis1.z(), axis2.z() ); - frameInA.setOrigin( pivotInA ); - - btTransform inv = rb1->getCenterOfMassTransform().inverse(); - - btTransform globalFrameA = rb0->getCenterOfMassTransform() * frameInA; - - frameInB = inv * globalFrameA; - bool useReferenceFrameA = true; - - genericConstraint = new btGeneric6DofSpringConstraint( - *rb0,*rb1, - frameInA,frameInB,useReferenceFrameA); - - - } else - { - static btRigidBody s_fixedObject2( 0,0,0); - btTransform frameInA; - btTransform frameInB; - - btVector3 axis1, axis2; - btPlaneSpace1( axisInA, axis1, axis2 ); - - frameInA.getBasis().setValue( axisInA.x(), axis1.x(), axis2.x(), - axisInA.y(), axis1.y(), axis2.y(), - axisInA.z(), axis1.z(), axis2.z() ); - - frameInA.setOrigin( pivotInA ); - - ///frameInB in worldspace - frameInB = rb0->getCenterOfMassTransform() * frameInA; - - bool useReferenceFrameA = true; - genericConstraint = new btGeneric6DofSpringConstraint( - *rb0,s_fixedObject2, - frameInA,frameInB,useReferenceFrameA); - } - - if (genericConstraint) - { - //m_constraints.push_back(genericConstraint); - c0->addCcdConstraintRef(genericConstraint); - c1->addCcdConstraintRef(genericConstraint); - m_dynamicsWorld->addConstraint(genericConstraint,disableCollisionBetweenLinkedBodies); - genericConstraint->setUserConstraintId(gConstraintUid++); - genericConstraint->setUserConstraintType(type); - //64 bit systems can't cast pointer to int. could use size_t instead. - return genericConstraint->getUserConstraintId(); - } - - break; - } - case PHY_CONE_TWIST_CONSTRAINT: - { - // If either of the controllers is missing, we can't do anything. - if (!c0 || !c1) return 0; - - btConeTwistConstraint* coneTwistContraint = 0; - - - if (rb1) - { - btTransform frameInA; - btTransform frameInB; - - btVector3 axis1(axis1X,axis1Y,axis1Z), axis2(axis2X,axis2Y,axis2Z); - if (axis1.length() == 0.0f) - { - btPlaneSpace1( axisInA, axis1, axis2 ); - } - - frameInA.getBasis().setValue( axisInA.x(), axis1.x(), axis2.x(), - axisInA.y(), axis1.y(), axis2.y(), - axisInA.z(), axis1.z(), axis2.z() ); - frameInA.setOrigin( pivotInA ); - - btTransform inv = rb1->getCenterOfMassTransform().inverse(); - - btTransform globalFrameA = rb0->getCenterOfMassTransform() * frameInA; - - frameInB = inv * globalFrameA; - - coneTwistContraint = new btConeTwistConstraint( *rb0,*rb1, - frameInA,frameInB); - - - } else - { - static btRigidBody s_fixedObject2( 0,0,0); - btTransform frameInA; - btTransform frameInB; - - btVector3 axis1, axis2; - btPlaneSpace1( axisInA, axis1, axis2 ); - - frameInA.getBasis().setValue( axisInA.x(), axis1.x(), axis2.x(), - axisInA.y(), axis1.y(), axis2.y(), - axisInA.z(), axis1.z(), axis2.z() ); - - frameInA.setOrigin( pivotInA ); - - ///frameInB in worldspace - frameInB = rb0->getCenterOfMassTransform() * frameInA; - - coneTwistContraint = new btConeTwistConstraint( - *rb0,s_fixedObject2, - frameInA,frameInB); - } - - if (coneTwistContraint) - { - //m_constraints.push_back(genericConstraint); - c0->addCcdConstraintRef(coneTwistContraint); - c1->addCcdConstraintRef(coneTwistContraint); - m_dynamicsWorld->addConstraint(coneTwistContraint,disableCollisionBetweenLinkedBodies); - coneTwistContraint->setUserConstraintId(gConstraintUid++); - coneTwistContraint->setUserConstraintType(type); - //64 bit systems can't cast pointer to int. could use size_t instead. - return coneTwistContraint->getUserConstraintId(); - } - - - - break; - } - case PHY_ANGULAR_CONSTRAINT: - angularOnly = true; - - - case PHY_LINEHINGE_CONSTRAINT: - { - // If either of the controllers is missing, we can't do anything. - if (!c0 || !c1) return 0; - - btHingeConstraint* hinge = 0; - - if (rb1) - { - // We know the orientations so we should use them instead of - // having btHingeConstraint fill in the blanks any way it wants to. - btTransform frameInA; - btTransform frameInB; - - btVector3 axis1(axis1X,axis1Y,axis1Z), axis2(axis2X,axis2Y,axis2Z); - if (axis1.length() == 0.0f) - { - btPlaneSpace1( axisInA, axis1, axis2 ); - } - - // Internally btHingeConstraint's hinge-axis is z - frameInA.getBasis().setValue( axis1.x(), axis2.x(), axisInA.x(), - axis1.y(), axis2.y(), axisInA.y(), - axis1.z(), axis2.z(), axisInA.z() ); - - frameInA.setOrigin( pivotInA ); - - btTransform inv = rb1->getCenterOfMassTransform().inverse(); - - btTransform globalFrameA = rb0->getCenterOfMassTransform() * frameInA; - - frameInB = inv * globalFrameA; - - hinge = new btHingeConstraint(*rb0,*rb1,frameInA,frameInB); - - - } else - { - static btRigidBody s_fixedObject2( 0,0,0); - - btTransform frameInA; - btTransform frameInB; - - btVector3 axis1(axis1X,axis1Y,axis1Z), axis2(axis2X,axis2Y,axis2Z); - if (axis1.length() == 0.0f) - { - btPlaneSpace1( axisInA, axis1, axis2 ); - } - - // Internally btHingeConstraint's hinge-axis is z - frameInA.getBasis().setValue( axis1.x(), axis2.x(), axisInA.x(), - axis1.y(), axis2.y(), axisInA.y(), - axis1.z(), axis2.z(), axisInA.z() ); - frameInA.setOrigin( pivotInA ); - frameInB = rb0->getCenterOfMassTransform() * frameInA; - - hinge = new btHingeConstraint(*rb0, s_fixedObject2, frameInA, frameInB); - } - hinge->setAngularOnly(angularOnly); - - //m_constraints.push_back(hinge); - c0->addCcdConstraintRef(hinge); - c1->addCcdConstraintRef(hinge); - m_dynamicsWorld->addConstraint(hinge,disableCollisionBetweenLinkedBodies); - hinge->setUserConstraintId(gConstraintUid++); - hinge->setUserConstraintType(type); - //64 bit systems can't cast pointer to int. could use size_t instead. - return hinge->getUserConstraintId(); - break; - } -#ifdef NEW_BULLET_VEHICLE_SUPPORT - - case PHY_VEHICLE_CONSTRAINT: - { - btRaycastVehicle::btVehicleTuning* tuning = new btRaycastVehicle::btVehicleTuning(); - btRigidBody* chassis = rb0; - btDefaultVehicleRaycaster* raycaster = new BlenderVehicleRaycaster(m_dynamicsWorld); - btRaycastVehicle* vehicle = new btRaycastVehicle(*tuning,chassis,raycaster); - WrapperVehicle* wrapperVehicle = new WrapperVehicle(vehicle,ctrl0); - m_wrapperVehicles.push_back(wrapperVehicle); - m_dynamicsWorld->addVehicle(vehicle); - vehicle->setUserConstraintId(gConstraintUid++); - vehicle->setUserConstraintType(type); - return vehicle->getUserConstraintId(); - - break; - }; -#endif //NEW_BULLET_VEHICLE_SUPPORT - - default: - { - } - }; - - //btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB - - return 0; - -} - - - -PHY_IPhysicsController* CcdPhysicsEnvironment::CreateConeController(float coneradius,float coneheight) -{ - CcdConstructionInfo cinfo; -//don't memset cinfo: this is C++ and values should be set in the constructor! - - // we don't need a CcdShapeConstructionInfo for this shape: - // it is simple enough for the standard copy constructor (see CcdPhysicsController::GetReplica) - cinfo.m_collisionShape = new btConeShape(coneradius,coneheight); - cinfo.m_MotionState = 0; - cinfo.m_physicsEnv = this; - cinfo.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE | btCollisionObject::CF_STATIC_OBJECT; - DefaultMotionState* motionState = new DefaultMotionState(); - cinfo.m_MotionState = motionState; - - // we will add later the possibility to select the filter from option - cinfo.m_collisionFilterMask = CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter; - cinfo.m_collisionFilterGroup = CcdConstructionInfo::SensorFilter; - cinfo.m_bSensor = true; - motionState->m_worldTransform.setIdentity(); -// motionState->m_worldTransform.setOrigin(btVector3(position[0],position[1],position[2])); - - CcdPhysicsController* sphereController = new CcdPhysicsController(cinfo); - - - return sphereController; -} - -float CcdPhysicsEnvironment::getAppliedImpulse(int constraintid) -{ - // For soft body constraints - if (constraintid == 0) - return 0.0f; - - int i; - int numConstraints = m_dynamicsWorld->getNumConstraints(); - for (i=0;i<numConstraints;i++) - { - btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i); - if (constraint->getUserConstraintId() == constraintid) - { - return constraint->getAppliedImpulse(); - } - } - - return 0.f; -} - -void CcdPhysicsEnvironment::ExportFile(const char* filename) -{ - btDefaultSerializer* serializer = new btDefaultSerializer(); - - - for (int i=0;i<m_dynamicsWorld->getNumCollisionObjects();i++) - { - - btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[i]; - - CcdPhysicsController* controller = static_cast<CcdPhysicsController*>(colObj->getUserPointer()); - if (controller) - { - const char* name = KX_GameObject::GetClientObject((KX_ClientObjectInfo*)controller->GetNewClientInfo())->GetName(); - if (name) - { - serializer->registerNameForPointer(colObj,name); - } - } - } - - m_dynamicsWorld->serialize(serializer); - - FILE* file = fopen(filename,"wb"); - if (file) - { - fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file); - fclose(file); - } -} - -struct BlenderDebugDraw : public btIDebugDraw -{ - BlenderDebugDraw () : - m_debugMode(0) - { - } - - int m_debugMode; - - virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color) - { - if (m_debugMode >0) - { - MT_Vector3 kxfrom(from[0],from[1],from[2]); - MT_Vector3 kxto(to[0],to[1],to[2]); - MT_Vector3 kxcolor(color[0],color[1],color[2]); - - KX_RasterizerDrawDebugLine(kxfrom,kxto,kxcolor); - } - } - - virtual void reportErrorWarning(const char* warningString) - { - - } - - virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,float distance,int lifeTime,const btVector3& color) - { - drawLine(PointOnB, PointOnB + normalOnB, color); - drawSphere(PointOnB, 0.1f, color); - } - - virtual void setDebugMode(int debugMode) - { - m_debugMode = debugMode; - } - virtual int getDebugMode() const - { - return m_debugMode; - } - ///todo: find out if Blender can do this - virtual void draw3dText(const btVector3& location,const char* textString) - { - - } - -}; - -CcdPhysicsEnvironment *CcdPhysicsEnvironment::Create(Scene *blenderscene, bool visualizePhysics) -{ - CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment((blenderscene->gm.mode & WO_DBVT_CULLING) != 0); - ccdPhysEnv->SetDebugDrawer(new BlenderDebugDraw()); - ccdPhysEnv->SetDeactivationLinearTreshold(blenderscene->gm.lineardeactthreshold); - ccdPhysEnv->SetDeactivationAngularTreshold(blenderscene->gm.angulardeactthreshold); - ccdPhysEnv->SetDeactivationTime(blenderscene->gm.deactivationtime); - - if (visualizePhysics) - ccdPhysEnv->SetDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_DrawConstraintLimits|btIDebugDraw::DBG_DrawConstraints); - - return ccdPhysEnv; -} - -void CcdPhysicsEnvironment::ConvertObject(KX_GameObject *gameobj, RAS_MeshObject *meshobj, DerivedMesh *dm, KX_Scene *kxscene, PHY_ShapeProps *shapeprops, PHY_MaterialProps *smmaterial, PHY_IMotionState *motionstate, int activeLayerBitInfo, bool isCompoundChild, bool hasCompoundChildren) -{ - Object* blenderobject = gameobj->GetBlenderObject(); - - bool isbulletdyna = (blenderobject->gameflag & OB_DYNAMIC) != 0; - bool isbulletsensor = (blenderobject->gameflag & OB_SENSOR) != 0; - bool isbulletchar = (blenderobject->gameflag & OB_CHARACTER) != 0; - bool isbulletsoftbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0; - bool isbulletrigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0; - bool useGimpact = false; - CcdConstructionInfo ci; - class CcdShapeConstructionInfo *shapeInfo = new CcdShapeConstructionInfo(); - - // get Root Parent of blenderobject - Object *blenderparent = blenderobject->parent; - while (blenderparent && blenderparent->parent) { - blenderparent = blenderparent->parent; - } - - KX_GameObject *parent = NULL; - if (blenderparent) - { - KX_BlenderSceneConverter *converter = (KX_BlenderSceneConverter*)KX_GetActiveEngine()->GetSceneConverter(); - parent = converter->FindGameObject(blenderparent); - isbulletsoftbody = false; - } - - if (!isbulletdyna) - { - ci.m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT; - } - if ((blenderobject->gameflag & (OB_GHOST | OB_SENSOR | OB_CHARACTER)) != 0) - { - ci.m_collisionFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE; - } - - ci.m_MotionState = motionstate; - ci.m_gravity = btVector3(0,0,0); - ci.m_linearFactor = btVector3(((blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_AXIS) !=0)? 0 : 1, - ((blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_AXIS) !=0)? 0 : 1, - ((blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_AXIS) !=0)? 0 : 1); - ci.m_angularFactor = btVector3(((blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_ROT_AXIS) !=0)? 0 : 1, - ((blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_ROT_AXIS) !=0)? 0 : 1, - ((blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS) !=0)? 0 : 1); - ci.m_localInertiaTensor =btVector3(0,0,0); - ci.m_mass = isbulletdyna ? shapeprops->m_mass : 0.f; - ci.m_clamp_vel_min = shapeprops->m_clamp_vel_min; - ci.m_clamp_vel_max = shapeprops->m_clamp_vel_max; - ci.m_clamp_angvel_min = shapeprops->m_clamp_angvel_min; - ci.m_clamp_angvel_max = shapeprops->m_clamp_angvel_max; - ci.m_stepHeight = isbulletchar ? shapeprops->m_step_height : 0.f; - ci.m_jumpSpeed = isbulletchar ? shapeprops->m_jump_speed : 0.f; - ci.m_fallSpeed = isbulletchar ? shapeprops->m_fall_speed : 0.f; - ci.m_maxJumps = isbulletchar ? shapeprops->m_max_jumps : 0; - - //mmm, for now, take this for the size of the dynamicobject - // Blender uses inertia for radius of dynamic object - shapeInfo->m_radius = ci.m_radius = blenderobject->inertia; - useGimpact = ((isbulletdyna || isbulletsensor) && !isbulletsoftbody); - - if (isbulletsoftbody) - { - if (blenderobject->bsoft) - { - ci.m_margin = blenderobject->bsoft->margin; - ci.m_gamesoftFlag = blenderobject->bsoft->flag; - - ci.m_soft_linStiff = blenderobject->bsoft->linStiff; - ci.m_soft_angStiff = blenderobject->bsoft->angStiff; /* angular stiffness 0..1 */ - ci.m_soft_volume = blenderobject->bsoft->volume; /* volume preservation 0..1 */ - - ci.m_soft_viterations = blenderobject->bsoft->viterations; /* Velocities solver iterations */ - ci.m_soft_piterations = blenderobject->bsoft->piterations; /* Positions solver iterations */ - ci.m_soft_diterations = blenderobject->bsoft->diterations; /* Drift solver iterations */ - ci.m_soft_citerations = blenderobject->bsoft->citerations; /* Cluster solver iterations */ - - ci.m_soft_kSRHR_CL = blenderobject->bsoft->kSRHR_CL; /* Soft vs rigid hardness [0,1] (cluster only) */ - ci.m_soft_kSKHR_CL = blenderobject->bsoft->kSKHR_CL; /* Soft vs kinetic hardness [0,1] (cluster only) */ - ci.m_soft_kSSHR_CL = blenderobject->bsoft->kSSHR_CL; /* Soft vs soft hardness [0,1] (cluster only) */ - ci.m_soft_kSR_SPLT_CL = blenderobject->bsoft->kSR_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ - - ci.m_soft_kSK_SPLT_CL = blenderobject->bsoft->kSK_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ - ci.m_soft_kSS_SPLT_CL = blenderobject->bsoft->kSS_SPLT_CL; /* Soft vs rigid impulse split [0,1] (cluster only) */ - ci.m_soft_kVCF = blenderobject->bsoft->kVCF; /* Velocities correction factor (Baumgarte) */ - ci.m_soft_kDP = blenderobject->bsoft->kDP; /* Damping coefficient [0,1] */ - - ci.m_soft_kDG = blenderobject->bsoft->kDG; /* Drag coefficient [0,+inf] */ - ci.m_soft_kLF = blenderobject->bsoft->kLF; /* Lift coefficient [0,+inf] */ - ci.m_soft_kPR = blenderobject->bsoft->kPR; /* Pressure coefficient [-inf,+inf] */ - ci.m_soft_kVC = blenderobject->bsoft->kVC; /* Volume conversation coefficient [0,+inf] */ - - ci.m_soft_kDF = blenderobject->bsoft->kDF; /* Dynamic friction coefficient [0,1] */ - ci.m_soft_kMT = blenderobject->bsoft->kMT; /* Pose matching coefficient [0,1] */ - ci.m_soft_kCHR = blenderobject->bsoft->kCHR; /* Rigid contacts hardness [0,1] */ - ci.m_soft_kKHR = blenderobject->bsoft->kKHR; /* Kinetic contacts hardness [0,1] */ - - ci.m_soft_kSHR = blenderobject->bsoft->kSHR; /* Soft contacts hardness [0,1] */ - ci.m_soft_kAHR = blenderobject->bsoft->kAHR; /* Anchors hardness [0,1] */ - ci.m_soft_collisionflags = blenderobject->bsoft->collisionflags; /* Vertex/Face or Signed Distance Field(SDF) or Clusters, Soft versus Soft or Rigid */ - ci.m_soft_numclusteriterations = blenderobject->bsoft->numclusteriterations; /* number of iterations to refine collision clusters*/ - - } - else - { - ci.m_margin = 0.f; - ci.m_gamesoftFlag = OB_BSB_BENDING_CONSTRAINTS | OB_BSB_SHAPE_MATCHING | OB_BSB_AERO_VPOINT; - - ci.m_soft_linStiff = 0.5f; - ci.m_soft_angStiff = 1.f; /* angular stiffness 0..1 */ - ci.m_soft_volume = 1.f; /* volume preservation 0..1 */ - - ci.m_soft_viterations = 0; - ci.m_soft_piterations = 1; - ci.m_soft_diterations = 0; - ci.m_soft_citerations = 4; - - ci.m_soft_kSRHR_CL = 0.1f; - ci.m_soft_kSKHR_CL = 1.f; - ci.m_soft_kSSHR_CL = 0.5f; - ci.m_soft_kSR_SPLT_CL = 0.5f; - - ci.m_soft_kSK_SPLT_CL = 0.5f; - ci.m_soft_kSS_SPLT_CL = 0.5f; - ci.m_soft_kVCF = 1; - ci.m_soft_kDP = 0; - - ci.m_soft_kDG = 0; - ci.m_soft_kLF = 0; - ci.m_soft_kPR = 0; - ci.m_soft_kVC = 0; - - ci.m_soft_kDF = 0.2f; - ci.m_soft_kMT = 0.05f; - ci.m_soft_kCHR = 1.0f; - ci.m_soft_kKHR = 0.1f; - - ci.m_soft_kSHR = 1.f; - ci.m_soft_kAHR = 0.7f; - ci.m_soft_collisionflags = OB_BSB_COL_SDF_RS + OB_BSB_COL_VF_SS; - ci.m_soft_numclusteriterations = 16; - } - } - else - { - ci.m_margin = blenderobject->margin; - } - - ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f); - - btCollisionShape* bm = 0; - - char bounds = isbulletdyna ? OB_BOUND_SPHERE : OB_BOUND_TRIANGLE_MESH; - if (!(blenderobject->gameflag & OB_BOUNDS)) - { - if (blenderobject->gameflag & OB_SOFT_BODY) - bounds = OB_BOUND_TRIANGLE_MESH; - else if (blenderobject->gameflag & OB_CHARACTER) - bounds = OB_BOUND_SPHERE; - } - else - { - if (ELEM(blenderobject->collision_boundtype, OB_BOUND_CONVEX_HULL, OB_BOUND_TRIANGLE_MESH) - && blenderobject->type != OB_MESH) - { - // Can't use triangle mesh or convex hull on a non-mesh object, fall-back to sphere - bounds = OB_BOUND_SPHERE; - } - else - bounds = blenderobject->collision_boundtype; - } - - // Get bounds information - float bounds_center[3], bounds_extends[3]; - BoundBox *bb= BKE_object_boundbox_get(blenderobject); - if (bb==NULL) - { - bounds_center[0] = bounds_center[1] = bounds_center[2] = 0.0f; - bounds_extends[0] = bounds_extends[1] = bounds_extends[2] = 1.0f; - } - else - { - bounds_extends[0] = 0.5f * fabsf(bb->vec[0][0] - bb->vec[4][0]); - bounds_extends[1] = 0.5f * fabsf(bb->vec[0][1] - bb->vec[2][1]); - bounds_extends[2] = 0.5f * fabsf(bb->vec[0][2] - bb->vec[1][2]); - - bounds_center[0] = 0.5f * (bb->vec[0][0] + bb->vec[4][0]); - bounds_center[1] = 0.5f * (bb->vec[0][1] + bb->vec[2][1]); - bounds_center[2] = 0.5f * (bb->vec[0][2] + bb->vec[1][2]); - } - - switch (bounds) - { - case OB_BOUND_SPHERE: - { - //float radius = objprop->m_radius; - //btVector3 inertiaHalfExtents ( - // radius, - // radius, - // radius); - - //blender doesn't support multisphere, but for testing: - - //bm = new MultiSphereShape(inertiaHalfExtents,,&trans.getOrigin(),&radius,1); - shapeInfo->m_shapeType = PHY_SHAPE_SPHERE; - // XXX We calculated the radius but didn't use it? - // objprop.m_boundobject.c.m_radius = MT_max(bb.m_extends[0], MT_max(bb.m_extends[1], bb.m_extends[2])); - bm = shapeInfo->CreateBulletShape(ci.m_margin); - break; - }; - case OB_BOUND_BOX: - { - shapeInfo->m_halfExtend.setValue( - 2.f * bounds_extends[0], - 2.f * bounds_extends[1], - 2.f * bounds_extends[2]); - - shapeInfo->m_halfExtend /= 2.0f; - shapeInfo->m_halfExtend = shapeInfo->m_halfExtend.absolute(); - shapeInfo->m_shapeType = PHY_SHAPE_BOX; - bm = shapeInfo->CreateBulletShape(ci.m_margin); - break; - }; - case OB_BOUND_CYLINDER: - { - float radius = MT_max(bounds_extends[0], bounds_extends[1]); - shapeInfo->m_halfExtend.setValue( - radius, - radius, - bounds_extends[2] - ); - shapeInfo->m_shapeType = PHY_SHAPE_CYLINDER; - bm = shapeInfo->CreateBulletShape(ci.m_margin); - break; - } - - case OB_BOUND_CONE: - { - shapeInfo->m_radius = MT_max(bounds_extends[0], bounds_extends[1]); - shapeInfo->m_height = 2.f * bounds_extends[2]; - shapeInfo->m_shapeType = PHY_SHAPE_CONE; - bm = shapeInfo->CreateBulletShape(ci.m_margin); - break; - } - case OB_BOUND_CONVEX_HULL: - { - shapeInfo->SetMesh(meshobj, dm,true); - bm = shapeInfo->CreateBulletShape(ci.m_margin); - break; - } - case OB_BOUND_CAPSULE: - { - shapeInfo->m_radius = MT_max(bounds_extends[0], bounds_extends[1]); - shapeInfo->m_height = 2.f * (bounds_extends[2] - shapeInfo->m_radius); - if (shapeInfo->m_height < 0.f) - shapeInfo->m_height = 0.f; - shapeInfo->m_shapeType = PHY_SHAPE_CAPSULE; - bm = shapeInfo->CreateBulletShape(ci.m_margin); - break; - } - case OB_BOUND_TRIANGLE_MESH: - { - // mesh shapes can be shared, check first if we already have a shape on that mesh - class CcdShapeConstructionInfo *sharedShapeInfo = CcdShapeConstructionInfo::FindMesh(meshobj, dm, false); - if (sharedShapeInfo != NULL) - { - shapeInfo->Release(); - shapeInfo = sharedShapeInfo; - shapeInfo->AddRef(); - } else - { - shapeInfo->SetMesh(meshobj, dm, false); - } - - // Soft bodies can benefit from welding, don't do it on non-soft bodies - if (isbulletsoftbody) - { - // disable welding: it doesn't bring any additional stability and it breaks the relation between soft body collision shape and graphic mesh - // shapeInfo->setVertexWeldingThreshold1((blenderobject->bsoft) ? blenderobject->bsoft->welding ? 0.f); - shapeInfo->setVertexWeldingThreshold1(0.f); //todo: expose this to the UI - } - - bm = shapeInfo->CreateBulletShape(ci.m_margin, useGimpact, !isbulletsoftbody); - //should we compute inertia for dynamic shape? - //bm->calculateLocalInertia(ci.m_mass,ci.m_localInertiaTensor); - - break; - } - } - - -// ci.m_localInertiaTensor.setValue(0.1f,0.1f,0.1f); - - if (!bm) - { - delete motionstate; - shapeInfo->Release(); - return; - } - - //bm->setMargin(ci.m_margin); - - - if (isCompoundChild) - { - //find parent, compound shape and add to it - //take relative transform into account! - CcdPhysicsController* parentCtrl = (CcdPhysicsController*)parent->GetPhysicsController(); - assert(parentCtrl); - - // only makes compound shape if parent has a physics controller (i.e not an empty, etc) - if (parentCtrl) { - CcdShapeConstructionInfo* parentShapeInfo = parentCtrl->GetShapeInfo(); - btRigidBody* rigidbody = parentCtrl->GetRigidBody(); - btCollisionShape* colShape = rigidbody->getCollisionShape(); - assert(colShape->isCompound()); - btCompoundShape* compoundShape = (btCompoundShape*)colShape; - - // compute the local transform from parent, this may include several node in the chain - SG_Node* gameNode = gameobj->GetSGNode(); - SG_Node* parentNode = parent->GetSGNode(); - // relative transform - MT_Vector3 parentScale = parentNode->GetWorldScaling(); - parentScale[0] = MT_Scalar(1.0f)/parentScale[0]; - parentScale[1] = MT_Scalar(1.0f)/parentScale[1]; - parentScale[2] = MT_Scalar(1.0f)/parentScale[2]; - MT_Vector3 relativeScale = gameNode->GetWorldScaling() * parentScale; - MT_Matrix3x3 parentInvRot = parentNode->GetWorldOrientation().transposed(); - MT_Vector3 relativePos = parentInvRot*((gameNode->GetWorldPosition()-parentNode->GetWorldPosition())*parentScale); - MT_Matrix3x3 relativeRot = parentInvRot*gameNode->GetWorldOrientation(); - - shapeInfo->m_childScale.setValue(relativeScale[0],relativeScale[1],relativeScale[2]); - bm->setLocalScaling(shapeInfo->m_childScale); - shapeInfo->m_childTrans.getOrigin().setValue(relativePos[0],relativePos[1],relativePos[2]); - float rot[12]; - relativeRot.getValue(rot); - shapeInfo->m_childTrans.getBasis().setFromOpenGLSubMatrix(rot); - - parentShapeInfo->AddShape(shapeInfo); - compoundShape->addChildShape(shapeInfo->m_childTrans,bm); - //do some recalc? - //recalc inertia for rigidbody - if (!rigidbody->isStaticOrKinematicObject()) - { - btVector3 localInertia; - float mass = 1.f/rigidbody->getInvMass(); - compoundShape->calculateLocalInertia(mass,localInertia); - rigidbody->setMassProps(mass,localInertia); - } - shapeInfo->Release(); - // delete motionstate as it's not used - delete motionstate; - } - return; - } - - if (hasCompoundChildren) - { - // create a compound shape info - CcdShapeConstructionInfo *compoundShapeInfo = new CcdShapeConstructionInfo(); - compoundShapeInfo->m_shapeType = PHY_SHAPE_COMPOUND; - compoundShapeInfo->AddShape(shapeInfo); - // create the compound shape manually as we already have the child shape - btCompoundShape* compoundShape = new btCompoundShape(); - compoundShape->addChildShape(shapeInfo->m_childTrans,bm); - // now replace the shape - bm = compoundShape; - shapeInfo->Release(); - shapeInfo = compoundShapeInfo; - } - - - - - - -#ifdef TEST_SIMD_HULL - if (bm->IsPolyhedral()) - { - PolyhedralConvexShape* polyhedron = static_cast<PolyhedralConvexShape*>(bm); - if (!polyhedron->m_optionalHull) - { - //first convert vertices in 'Point3' format - int numPoints = polyhedron->GetNumVertices(); - Point3* points = new Point3[numPoints+1]; - //first 4 points should not be co-planar, so add central point to satisfy MakeHull - points[0] = Point3(0.f,0.f,0.f); - - btVector3 vertex; - for (int p=0;p<numPoints;p++) - { - polyhedron->GetVertex(p,vertex); - points[p+1] = Point3(vertex.getX(),vertex.getY(),vertex.getZ()); - } - - Hull* hull = Hull::MakeHull(numPoints+1,points); - polyhedron->m_optionalHull = hull; - } - - } -#endif //TEST_SIMD_HULL - - - ci.m_collisionShape = bm; - ci.m_shapeInfo = shapeInfo; - ci.m_friction = smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice - ci.m_restitution = smmaterial->m_restitution; - ci.m_physicsEnv = this; - // drag / damping is inverted - ci.m_linearDamping = 1.f - shapeprops->m_lin_drag; - ci.m_angularDamping = 1.f - shapeprops->m_ang_drag; - //need a bit of damping, else system doesn't behave well - ci.m_inertiaFactor = shapeprops->m_inertia/0.4f;//defaults to 0.4, don't want to change behavior - - ci.m_do_anisotropic = shapeprops->m_do_anisotropic; - ci.m_anisotropicFriction.setValue(shapeprops->m_friction_scaling[0],shapeprops->m_friction_scaling[1],shapeprops->m_friction_scaling[2]); - - -////////// - //do Fh, do Rot Fh - ci.m_do_fh = shapeprops->m_do_fh; - ci.m_do_rot_fh = shapeprops->m_do_rot_fh; - ci.m_fh_damping = smmaterial->m_fh_damping; - ci.m_fh_distance = smmaterial->m_fh_distance; - ci.m_fh_normal = smmaterial->m_fh_normal; - ci.m_fh_spring = smmaterial->m_fh_spring; - - ci.m_collisionFilterGroup = - (isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) : - (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : - (isbulletchar) ? short(CcdConstructionInfo::CharacterFilter) : - short(CcdConstructionInfo::StaticFilter); - ci.m_collisionFilterMask = - (isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) : - (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : - (isbulletchar) ? short(CcdConstructionInfo::AllFilter) : - short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter); - ci.m_bRigid = isbulletdyna && isbulletrigidbody; - ci.m_bSoft = isbulletsoftbody; - ci.m_bDyna = isbulletdyna; - ci.m_bSensor = isbulletsensor; - ci.m_bCharacter = isbulletchar; - ci.m_bGimpact = useGimpact; - MT_Vector3 scaling = gameobj->NodeGetWorldScaling(); - ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]); - CcdPhysicsController* physicscontroller = new CcdPhysicsController(ci); - // shapeInfo is reference counted, decrement now as we don't use it anymore - if (shapeInfo) - shapeInfo->Release(); - - gameobj->SetPhysicsController(physicscontroller,isbulletdyna); - - // record animation for dynamic objects - if (isbulletdyna) - gameobj->SetRecordAnimation(true); - - physicscontroller->SetNewClientInfo(gameobj->getClientInfo()); - - // don't add automatically sensor object, they are added when a collision sensor is registered - if (!isbulletsensor && (blenderobject->lay & activeLayerBitInfo) != 0) - { - this->AddCcdPhysicsController( physicscontroller); - } - - { - btRigidBody* rbody = physicscontroller->GetRigidBody(); - - if (rbody) - { - rbody->setLinearFactor(ci.m_linearFactor); - - if (isbulletrigidbody) - { - rbody->setAngularFactor(ci.m_angularFactor); - } - - if (rbody && (blenderobject->gameflag & OB_COLLISION_RESPONSE) != 0) - { - rbody->setActivationState(DISABLE_DEACTIVATION); - } - } - } - - if (parent) - physicscontroller->SuspendDynamics(false); - - CcdPhysicsController* parentCtrl = parent ? (CcdPhysicsController*)parent->GetPhysicsController() : 0; - physicscontroller->SetParentCtrl(parentCtrl); - - - //Now done directly in ci.m_collisionFlags so that it propagates to replica - //if (objprop->m_ghost) - //{ - // rbody->setCollisionFlags(rbody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); - //} - - if (isbulletdyna && !isbulletrigidbody) - { -#if 0 - //setting the inertia could achieve similar results to constraint the up - //but it is prone to instability, so use special 'Angular' constraint - btVector3 inertia = physicscontroller->GetRigidBody()->getInvInertiaDiagLocal(); - inertia.setX(0.f); - inertia.setZ(0.f); - - physicscontroller->GetRigidBody()->setInvInertiaDiagLocal(inertia); - physicscontroller->GetRigidBody()->updateInertiaTensor(); -#endif - - //this->createConstraint(physicscontroller,0,PHY_ANGULAR_CONSTRAINT,0,0,0,0,0,1); - - //Now done directly in ci.m_bRigid so that it propagates to replica - //physicscontroller->GetRigidBody()->setAngularFactor(0.f); - ; - } - - - STR_String materialname; - if (meshobj) - materialname = meshobj->GetMaterialName(0); - - -#if 0 - ///test for soft bodies - if (objprop->m_softbody && physicscontroller) - { - btSoftBody* softBody = physicscontroller->GetSoftBody(); - if (softBody && gameobj->GetMesh(0))//only the first mesh, if any - { - //should be a mesh then, so add a soft body deformer - KX_SoftBodyDeformer* softbodyDeformer = new KX_SoftBodyDeformer( gameobj->GetMesh(0),(BL_DeformableGameObject*)gameobj); - gameobj->SetDeformer(softbodyDeformer); - } - } -#endif -} - - -void CcdPhysicsEnvironment::SetupObjectConstraints(KX_GameObject *obj_src, KX_GameObject *obj_dest, - bRigidBodyJointConstraint *dat) -{ - PHY_IPhysicsController *phy_src = obj_src->GetPhysicsController(); - PHY_IPhysicsController *phy_dest = obj_dest->GetPhysicsController(); - PHY_IPhysicsEnvironment *phys_env = obj_src->GetScene()->GetPhysicsEnvironment(); - - /* We need to pass a full constraint frame, not just axis. */ - MT_Matrix3x3 localCFrame(MT_Vector3(dat->axX,dat->axY,dat->axZ)); - MT_Vector3 axis0 = localCFrame.getColumn(0); - MT_Vector3 axis1 = localCFrame.getColumn(1); - MT_Vector3 axis2 = localCFrame.getColumn(2); - MT_Vector3 scale = obj_src->NodeGetWorldScaling(); - - /* Apply not only the pivot and axis values, but also take scale into count - * this is not working well, if only one or two axis are scaled, but works ok on - * homogeneous scaling. */ - int constraintId = phys_env->CreateConstraint( - phy_src, phy_dest, (PHY_ConstraintType)dat->type, - (float)(dat->pivX * scale.x()), (float)(dat->pivY * scale.y()), (float)(dat->pivZ * scale.z()), - (float)(axis0.x() * scale.x()), (float)(axis0.y() * scale.y()), (float)(axis0.z() * scale.z()), - (float)(axis1.x() * scale.x()), (float)(axis1.y() * scale.y()), (float)(axis1.z() * scale.z()), - (float)(axis2.x() * scale.x()), (float)(axis2.y() * scale.y()), (float)(axis2.z() * scale.z()), - dat->flag); - - /* PHY_POINT2POINT_CONSTRAINT = 1, - * PHY_LINEHINGE_CONSTRAINT = 2, - * PHY_ANGULAR_CONSTRAINT = 3, - * PHY_CONE_TWIST_CONSTRAINT = 4, - * PHY_VEHICLE_CONSTRAINT = 11, - * PHY_GENERIC_6DOF_CONSTRAINT = 12 */ - - if (!constraintId) - return; - - int dof = 0; - int dof_max = 0; - int dofbit = 0; - - switch (dat->type) { - /* Set all the limits for generic 6DOF constraint. */ - case PHY_GENERIC_6DOF_CONSTRAINT: - dof_max = 6; - dofbit = 1; - break; - /* Set XYZ angular limits for cone twist constraint. */ - case PHY_CONE_TWIST_CONSTRAINT: - dof = 3; - dof_max = 6; - dofbit = 1 << 3; - break; - /* Set only X angular limits for line hinge and angular constraint. */ - case PHY_LINEHINGE_CONSTRAINT: - case PHY_ANGULAR_CONSTRAINT: - dof = 3; - dof_max = 4; - dofbit = 1 << 3; - break; - default: - break; - } - - for (; dof < dof_max; dof++) { - if (dat->flag & dofbit) { - phys_env->SetConstraintParam(constraintId, dof, dat->minLimit[dof], dat->maxLimit[dof]); - } - else { - /* minLimit > maxLimit means free (no limit) for this degree of freedom. */ - phys_env->SetConstraintParam(constraintId, dof, 1.0f, -1.0f); - } - dofbit <<= 1; - } - -} diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h deleted file mode 100644 index a64d2c8f15f..00000000000 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h +++ /dev/null @@ -1,345 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, -subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - -/** \file CcdPhysicsEnvironment.h - * \ingroup physbullet - * See also \ref bulletdoc - */ - -#ifndef __CCDPHYSICSENVIRONMENT_H__ -#define __CCDPHYSICSENVIRONMENT_H__ - -#include "PHY_IPhysicsEnvironment.h" -#include "KX_KetsjiEngine.h" - -#include <vector> -#include <set> -#include <map> -class CcdPhysicsController; -class CcdGraphicController; -#include "LinearMath/btVector3.h" -#include "LinearMath/btTransform.h" - - - - -class btTypedConstraint; -class btSimulationIslandManager; -class btCollisionDispatcher; -class btDispatcher; -//#include "btBroadphaseInterface.h" - -//switch on/off new vehicle support -#define NEW_BULLET_VEHICLE_SUPPORT 1 - -#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" - -class WrapperVehicle; -class btPersistentManifold; -class btBroadphaseInterface; -struct btDbvtBroadphase; -class btOverlappingPairCache; -class btIDebugDraw; -class btDynamicsWorld; -class PHY_IVehicle; -class CcdOverlapFilterCallBack; -class CcdShapeConstructionInfo; - -/** CcdPhysicsEnvironment is an experimental mainloop for physics simulation using optional continuous collision detection. - * Physics Environment takes care of stepping the simulation and is a container for physics entities. - * It stores rigidbodies,constraints, materials etc. - * A derived class may be able to 'construct' entities by loading and/or converting - */ -class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment -{ - friend class CcdOverlapFilterCallBack; - btVector3 m_gravity; - - // Removes the constraint and his references from the owner and the target. - void RemoveConstraint(btTypedConstraint *con); - -protected: - btIDebugDraw* m_debugDrawer; - - class btDefaultCollisionConfiguration* m_collisionConfiguration; - class btBroadphaseInterface* m_broadphase; // broadphase for dynamic world - // for culling only - btOverlappingPairCache* m_cullingCache; - struct btDbvtBroadphase* m_cullingTree; // broadphase for culling - - //solver iterations - int m_numIterations; - - //timestep subdivisions - int m_numTimeSubSteps; - - - int m_ccdMode; - int m_solverType; - int m_profileTimings; - bool m_enableSatCollisionDetection; - - float m_deactivationTime; - float m_linearDeactivationThreshold; - float m_angularDeactivationThreshold; - float m_contactBreakingThreshold; - - void ProcessFhSprings(double curTime,float timeStep); - - public: - CcdPhysicsEnvironment(bool useDbvtCulling, btDispatcher* dispatcher=0, btOverlappingPairCache* pairCache=0); - - virtual ~CcdPhysicsEnvironment(); - - ///////////////////////////////////// - //PHY_IPhysicsEnvironment interface - ///////////////////////////////////// - - /// Perform an integration step of duration 'timeStep'. - - virtual void SetDebugDrawer(btIDebugDraw* debugDrawer); - - virtual void SetNumIterations(int numIter); - virtual void SetNumTimeSubSteps(int numTimeSubSteps) - { - m_numTimeSubSteps = numTimeSubSteps; - } - virtual void SetDeactivationTime(float dTime); - virtual void SetDeactivationLinearTreshold(float linTresh); - virtual void SetDeactivationAngularTreshold(float angTresh); - virtual void SetContactBreakingTreshold(float contactBreakingTreshold); - virtual void SetCcdMode(int ccdMode); - virtual void SetSolverType(int solverType); - virtual void SetSolverSorConstant(float sor); - virtual void SetSolverTau(float tau); - virtual void SetSolverDamping(float damping); - virtual void SetLinearAirDamping(float damping); - virtual void SetUseEpa(bool epa); - - virtual int GetNumTimeSubSteps() - { - return m_numTimeSubSteps; - } - - virtual void BeginFrame(); - virtual void EndFrame() {} - /// Perform an integration step of duration 'timeStep'. - virtual bool ProceedDeltaTime(double curTime,float timeStep,float interval); - - /** - * Called by Bullet for every physical simulation (sub)tick. - * Our constructor registers this callback to Bullet, which stores a pointer to 'this' in - * the btDynamicsWorld::getWorldUserInfo() pointer. - */ - static void StaticSimulationSubtickCallback(btDynamicsWorld *world, btScalar timeStep); - void SimulationSubtickCallback(btScalar timeStep); - - virtual void DebugDrawWorld(); -// virtual bool proceedDeltaTimeOneStep(float timeStep); - - virtual void SetFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep) - { - SetNumTimeSubSteps((int)(fixedTimeStep / KX_KetsjiEngine::GetTicRate())); - } - //returns 0.f if no fixed timestep is used - - virtual float GetFixedTimeStep() { return 0.f; } - - virtual void SetDebugMode(int debugMode); - virtual int GetDebugMode()const; - - virtual void SetGravity(float x,float y,float z); - virtual void GetGravity(MT_Vector3& grav); - - - virtual int CreateConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, - float pivotX,float pivotY,float pivotZ, - float axisX,float axisY,float axisZ, - float axis1X=0,float axis1Y=0,float axis1Z=0, - float axis2X=0,float axis2Y=0,float axis2Z=0,int flag=0 - ); - - - //Following the COLLADA physics specification for constraints - virtual int CreateUniversalD6Constraint( - class PHY_IPhysicsController* ctrlRef,class PHY_IPhysicsController* ctrlOther, - btTransform& localAttachmentFrameRef, - btTransform& localAttachmentOther, - const btVector3& linearMinLimits, - const btVector3& linearMaxLimits, - const btVector3& angularMinLimits, - const btVector3& angularMaxLimits,int flags - ); - - - virtual void SetConstraintParam(int constraintId,int param,float value,float value1); - - virtual float GetConstraintParam(int constraintId,int param); - - virtual void RemoveConstraintById(int constraintid); - - virtual float getAppliedImpulse(int constraintid); - - - virtual void CallbackTriggers(); - - -#ifdef NEW_BULLET_VEHICLE_SUPPORT - //complex constraint for vehicles - virtual PHY_IVehicle* GetVehicleConstraint(int constraintId); -#else - virtual class PHY_IVehicle* GetVehicleConstraint(int constraintId) - { - return 0; - } -#endif /* NEW_BULLET_VEHICLE_SUPPORT */ - // Character physics wrapper - virtual PHY_ICharacter* GetCharacterController(class KX_GameObject* ob); - - btTypedConstraint* GetConstraintById(int constraintId); - - virtual PHY_IPhysicsController* RayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ); - virtual bool CullingTest(PHY_CullingCallback callback, void* userData, MT_Vector4* planes, int nplanes, int occlusionRes, const int *viewport, float modelview[16], float projection[16]); - - - //Methods for gamelogic collision/physics callbacks - virtual void AddSensor(PHY_IPhysicsController* ctrl); - virtual void RemoveSensor(PHY_IPhysicsController* ctrl); - virtual void AddTouchCallback(int response_class, PHY_ResponseCallback callback, void *user); - virtual bool RequestCollisionCallback(PHY_IPhysicsController* ctrl); - virtual bool RemoveCollisionCallback(PHY_IPhysicsController* ctrl); - //These two methods are used *solely* to create controllers for Near/Radar sensor! Don't use for anything else - virtual PHY_IPhysicsController* CreateSphereController(float radius,const MT_Vector3& position); - virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight); - - - virtual int GetNumContactPoints(); - - virtual void GetContactPoint(int i,float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ); - - ////////////////////// - //CcdPhysicsEnvironment interface - //////////////////////// - - void AddCcdPhysicsController(CcdPhysicsController* ctrl); - - bool RemoveCcdPhysicsController(CcdPhysicsController* ctrl); - - void UpdateCcdPhysicsController(CcdPhysicsController* ctrl, btScalar newMass, int newCollisionFlags, short int newCollisionGroup, short int newCollisionMask); - - void RefreshCcdPhysicsController(CcdPhysicsController* ctrl); - - bool IsActiveCcdPhysicsController(CcdPhysicsController *ctrl); - - void AddCcdGraphicController(CcdGraphicController* ctrl); - - void RemoveCcdGraphicController(CcdGraphicController* ctrl); - - /** - * Update all physics controllers shape which use the same shape construction info. - * Call RecreateControllerShape on controllers which use the same shape - * construction info that argument shapeInfo. - * You need to call this function when the shape construction info changed. - */ - void UpdateCcdPhysicsControllerShape(CcdShapeConstructionInfo *shapeInfo); - - btBroadphaseInterface* GetBroadphase(); - btDbvtBroadphase* GetCullingTree() { return m_cullingTree; } - - btDispatcher* GetDispatcher(); - - - bool IsSatCollisionDetectionEnabled() const - { - return m_enableSatCollisionDetection; - } - - void EnableSatCollisionDetection(bool enableSat) - { - m_enableSatCollisionDetection = enableSat; - } - - - const btPersistentManifold* GetManifold(int index) const; - - - void SyncMotionStates(float timeStep); - - class btSoftRigidDynamicsWorld* GetDynamicsWorld() - { - return m_dynamicsWorld; - } - - class btConstraintSolver* GetConstraintSolver(); - - void MergeEnvironment(PHY_IPhysicsEnvironment *other_env); - - static CcdPhysicsEnvironment *Create(struct Scene *blenderscene, bool visualizePhysics); - - virtual void ConvertObject(KX_GameObject* gameobj, - RAS_MeshObject* meshobj, - DerivedMesh* dm, - KX_Scene* kxscene, - PHY_ShapeProps* shapeprops, - PHY_MaterialProps* smmaterial, - PHY_IMotionState *motionstate, - int activeLayerBitInfo, - bool isCompoundChild, - bool hasCompoundChildren); - - /* Set the rigid body joints constraints values for converted objects and replicated group instances. */ - virtual void SetupObjectConstraints(KX_GameObject *obj_src, KX_GameObject *obj_dest, - bRigidBodyJointConstraint *dat); - - protected: - - - - std::set<CcdPhysicsController*> m_controllers; - - PHY_ResponseCallback m_triggerCallbacks[PHY_NUM_RESPONSE]; - void* m_triggerCallbacksUserPtrs[PHY_NUM_RESPONSE]; - - std::vector<WrapperVehicle*> m_wrapperVehicles; - - //use explicit btSoftRigidDynamicsWorld/btDiscreteDynamicsWorld* so that we have access to - //btDiscreteDynamicsWorld::addRigidBody(body,filter,group) - //so that we can set the body collision filter/group at the time of creation - //and not afterwards (breaks the collision system for radar/near sensor) - //Ideally we would like to have access to this function from the btDynamicsWorld interface - //class btDynamicsWorld* m_dynamicsWorld; - class btSoftRigidDynamicsWorld* m_dynamicsWorld; - - class btConstraintSolver* m_solver; - - class btOverlappingPairCache* m_ownPairCache; - - class CcdOverlapFilterCallBack* m_filterCallback; - - class btGhostPairCallback* m_ghostPairCallback; - - class btDispatcher* m_ownDispatcher; - - bool m_scalingPropagated; - - virtual void ExportFile(const char* filename); - - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:CcdPhysicsEnvironment") -#endif -}; - -#endif /* __CCDPHYSICSENVIRONMENT_H__ */ diff --git a/source/gameengine/Physics/Dummy/CMakeLists.txt b/source/gameengine/Physics/Dummy/CMakeLists.txt deleted file mode 100644 index 692331f1ce4..00000000000 --- a/source/gameengine/Physics/Dummy/CMakeLists.txt +++ /dev/null @@ -1,41 +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. -# -# The Original Code is Copyright (C) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Jacques Beaurain. -# -# ***** END GPL LICENSE BLOCK ***** - -set(INC - . - ../common -) - -set(INC_SYS - ../../../../intern/moto/include -) - -set(SRC - DummyPhysicsEnvironment.cpp - - DummyPhysicsEnvironment.h -) - -blender_add_lib(ge_phys_dummy "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp deleted file mode 100644 index 99db56bfcef..00000000000 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp +++ /dev/null @@ -1,121 +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. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp - * \ingroup physdummy - */ - - -#include <stddef.h> - -#include "DummyPhysicsEnvironment.h" -#include "PHY_IMotionState.h" - -DummyPhysicsEnvironment::DummyPhysicsEnvironment() -{ - // create physicsengine data -} - - - -DummyPhysicsEnvironment::~DummyPhysicsEnvironment() -{ - //destroy physicsengine data -} - -void DummyPhysicsEnvironment::BeginFrame() -{ - // beginning of logic frame: apply forces -} - -void DummyPhysicsEnvironment::EndFrame() -{ - // end of logic frame: clear forces -} - - - -bool DummyPhysicsEnvironment::ProceedDeltaTime(double curTime,float timeStep,float interval) -{ - //step physics simulation, typically perform - - //collision detection - //solve constraints - //integrate solution - // return true if an update was done. - return true; -} -void DummyPhysicsEnvironment::SetFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep) -{ -} - -float DummyPhysicsEnvironment::GetFixedTimeStep() -{ - return 0.f; -} - -int DummyPhysicsEnvironment::GetDebugMode() const -{ - return 0; -} - -void DummyPhysicsEnvironment::SetGravity(float x,float y,float z) -{ -} - -void DummyPhysicsEnvironment::GetGravity(class MT_Vector3& grav) -{ -} - - - - -int DummyPhysicsEnvironment::CreateConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, - float pivotX,float pivotY,float pivotZ,float axisX,float axisY,float axisZ, - float axis1X,float axis1Y,float axis1Z, - float axis2X,float axis2Y,float axis2Z,int flag - ) -{ - - int constraintid = 0; - return constraintid; - -} - -void DummyPhysicsEnvironment::RemoveConstraintById(int constraintid) -{ - if (constraintid) - { - } -} - -PHY_IPhysicsController* DummyPhysicsEnvironment::RayTest(PHY_IRayCastFilterCallback &filterCallback,float fromX,float fromY,float fromZ, float toX,float toY,float toZ) -{ - //collision detection / raytesting - return NULL; -} - diff --git a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h b/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h deleted file mode 100644 index 3e9379dd60d..00000000000 --- a/source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h +++ /dev/null @@ -1,134 +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. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file DummyPhysicsEnvironment.h - * \ingroup physdummy - */ - -#ifndef __DUMMYPHYSICSENVIRONMENT_H__ -#define __DUMMYPHYSICSENVIRONMENT_H__ - -#include "PHY_IPhysicsEnvironment.h" -#include "PHY_IMotionState.h" - -/** - * DummyPhysicsEnvironment is an empty placeholder - * Alternatives are ODE,Sumo and Dynamo PhysicsEnvironments - * Use DummyPhysicsEnvironment as a base to integrate your own physics engine - * Physics Environment takes care of stepping the simulation and is a container for physics entities (rigidbodies,constraints, materials etc.) - * - * A derived class may be able to 'construct' entities by loading and/or converting - */ -class DummyPhysicsEnvironment : public PHY_IPhysicsEnvironment -{ - -public: - DummyPhysicsEnvironment (); - virtual ~DummyPhysicsEnvironment (); - virtual void BeginFrame(); - virtual void EndFrame(); -// Perform an integration step of duration 'timeStep'. - virtual bool ProceedDeltaTime(double curTime,float timeStep,float interval); - virtual void SetFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep); - virtual float GetFixedTimeStep(); - - virtual int GetDebugMode() const; - - virtual void SetGravity(float x,float y,float z); - virtual void GetGravity(class MT_Vector3& grav); - - virtual int CreateConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, - float pivotX,float pivotY,float pivotZ, - float axisX,float axisY,float axisZ, - float axis1X=0,float axis1Y=0,float axis1Z=0, - float axis2X=0,float axis2Y=0,float axis2Z=0,int flag=0 - ); - - virtual void RemoveConstraintById(int constraintid); - - //complex constraint for vehicles - virtual PHY_IVehicle* GetVehicleConstraint(int constraintId) - { - return 0; - } - - // Character physics wrapper - virtual PHY_ICharacter* GetCharacterController(class KX_GameObject* ob) - { - return 0; - } - - virtual PHY_IPhysicsController* RayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ); - virtual bool CullingTest(PHY_CullingCallback callback, void* userData, class MT_Vector4* planes, int nplanes, int occlusionRes, const int *viewport, float modelview[16], float projection[16]) { return false; } - - - //gamelogic callbacks - virtual void AddSensor(PHY_IPhysicsController* ctrl) {} - virtual void RemoveSensor(PHY_IPhysicsController* ctrl) {} - virtual void AddTouchCallback(int response_class, PHY_ResponseCallback callback, void *user) - { - } - virtual bool RequestCollisionCallback(PHY_IPhysicsController* ctrl) { return false; } - virtual bool RemoveCollisionCallback(PHY_IPhysicsController* ctrl) { return false;} - virtual PHY_IPhysicsController* CreateSphereController(float radius,const class MT_Vector3& position) {return 0;} - virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight) { return 0;} - - virtual void SetConstraintParam(int constraintId,int param,float value,float value1) - { - } - - virtual float GetConstraintParam(int constraintId,int param) - { - return 0.f; - } - - virtual void MergeEnvironment(PHY_IPhysicsEnvironment *other_env) - { - // Dummy, nothing to do here - } - - virtual void ConvertObject(KX_GameObject* gameobj, - RAS_MeshObject* meshobj, - DerivedMesh* dm, - KX_Scene* kxscene, - PHY_ShapeProps* shapeprops, - PHY_MaterialProps* smmaterial, - PHY_IMotionState *motionstate, - int activeLayerBitInfo, - bool isCompoundChild, - bool hasCompoundChildren) - { - // All we need to do is handle the motionstate (we're supposed to own it) - delete motionstate; - } - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:DummyPhysicsEnvironment") -#endif -}; - -#endif /* __DUMMYPHYSICSENVIRONMENT_H__ */ diff --git a/source/gameengine/Physics/common/PHY_DynamicTypes.h b/source/gameengine/Physics/common/PHY_DynamicTypes.h deleted file mode 100644 index d10f48ad7a4..00000000000 --- a/source/gameengine/Physics/common/PHY_DynamicTypes.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -Bullet Continuous Collision Detection and Physics Library -Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ - -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it freely, -subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - -/** \file PHY_DynamicTypes.h - * \ingroup phys - */ - -#ifndef __PHY_DYNAMICTYPES_H__ -#define __PHY_DYNAMICTYPES_H__ - -#include "MT_Vector3.h" - -struct KX_ClientObjectInfo; - -enum -{ - PHY_FH_RESPONSE, - PHY_SENSOR_RESPONSE, /* Touch Sensors */ - PHY_CAMERA_RESPONSE, /* Visibility Culling */ - PHY_OBJECT_RESPONSE, /* Object Dynamic Geometry Response */ - PHY_STATIC_RESPONSE, /* Static Geometry Response */ - PHY_BROADPH_RESPONSE, /* broadphase Response */ - - PHY_NUM_RESPONSE -}; - -typedef struct PHY_CollData { - MT_Vector3 m_point1; /* Point in object1 in world coordinates */ - MT_Vector3 m_point2; /* Point in object2 in world coordinates */ - MT_Vector3 m_normal; /* point2 - point1 */ -} PHY_CollData; - - -typedef bool (*PHY_ResponseCallback)(void *client_data, - void *client_object1, - void *client_object2, - const PHY_CollData *coll_data); -typedef void (*PHY_CullingCallback)(KX_ClientObjectInfo* info, void* param); - - -/// PHY_PhysicsType enumerates all possible Physics Entities. -/// It is mainly used to create/add Physics Objects - -typedef enum PHY_PhysicsType { - PHY_CONVEX_RIGIDBODY=16386, - PHY_CONCAVE_RIGIDBODY=16399, - PHY_CONVEX_FIXEDBODY=16388,//'collision object' - PHY_CONCAVE_FIXEDBODY=16401, - PHY_CONVEX_KINEMATICBODY=16387,// - PHY_CONCAVE_KINEMATICBODY=16400, - PHY_CONVEX_PHANTOMBODY=16398, - PHY_CONCAVE_PHANTOMBODY=16402 -} PHY_PhysicsType; - -/// PHY_ConstraintType enumerates all supported Constraint Types -typedef enum PHY_ConstraintType { - PHY_POINT2POINT_CONSTRAINT=1, - PHY_LINEHINGE_CONSTRAINT=2, - PHY_ANGULAR_CONSTRAINT = 3,//hinge without ball socket - PHY_CONE_TWIST_CONSTRAINT = 4, - PHY_VEHICLE_CONSTRAINT=11,//complex 'constraint' that turns a rigidbody into a vehicle - PHY_GENERIC_6DOF_CONSTRAINT=12,//can leave any of the 6 degree of freedom 'free' or 'locked' - -} PHY_ConstraintType; - -typedef enum PHY_ShapeType { - PHY_SHAPE_NONE, - PHY_SHAPE_BOX, - PHY_SHAPE_SPHERE, - PHY_SHAPE_CYLINDER, - PHY_SHAPE_CONE, - PHY_SHAPE_CAPSULE, - PHY_SHAPE_MESH, - PHY_SHAPE_POLYTOPE, - PHY_SHAPE_COMPOUND, - PHY_SHAPE_PROXY -} PHY_ShapeType; - -#endif /* __PHY_DYNAMICTYPES_H__ */ diff --git a/source/gameengine/Physics/common/PHY_ICharacter.h b/source/gameengine/Physics/common/PHY_ICharacter.h deleted file mode 100644 index 1a924904b7d..00000000000 --- a/source/gameengine/Physics/common/PHY_ICharacter.h +++ /dev/null @@ -1,39 +0,0 @@ - -/** \file PHY_ICharacter.h - * \ingroup phys - */ - -#ifndef __PHY_ICHARACTER_H__ -#define __PHY_ICHARACTER_H__ - -//PHY_ICharacter provides a generic interface for "character" controllers - -#ifdef WITH_CXX_GUARDEDALLOC -#include "MEM_guardedalloc.h" -#endif - -class PHY_ICharacter -{ -public: - virtual ~PHY_ICharacter() {}; - - virtual void Jump()= 0; - virtual bool OnGround()= 0; - - virtual float GetGravity()= 0; - virtual void SetGravity(float gravity)= 0; - - virtual unsigned char GetMaxJumps() = 0; - virtual void SetMaxJumps(unsigned char maxJumps) = 0; - - virtual unsigned char GetJumpCount() = 0; - - virtual void SetWalkDirection(const class MT_Vector3& dir)=0; - virtual MT_Vector3 GetWalkDirection()=0; - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_ICharacter") -#endif -}; - -#endif //__PHY_ICHARACTER_H__ diff --git a/source/gameengine/Physics/common/PHY_IController.h b/source/gameengine/Physics/common/PHY_IController.h deleted file mode 100644 index 741fae8d2ad..00000000000 --- a/source/gameengine/Physics/common/PHY_IController.h +++ /dev/null @@ -1,63 +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. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file PHY_IController.h - * \ingroup phys - */ - -#ifndef __PHY_ICONTROLLER_H__ -#define __PHY_ICONTROLLER_H__ - -#include "PHY_DynamicTypes.h" - -class PHY_IPhysicsEnvironment; - -#ifdef WITH_CXX_GUARDEDALLOC -#include "MEM_guardedalloc.h" -#endif - -/** - * PHY_IController is the abstract simplified Interface to objects - * controlled by the physics engine. This includes the physics objects - * and the graphics object for view frustrum and occlusion culling. - */ -class PHY_IController -{ - public: - virtual ~PHY_IController() {}; - // clientinfo for raycasts for example - virtual void* GetNewClientInfo()=0; - virtual void SetNewClientInfo(void* clientinfo)=0; - virtual void SetPhysicsEnvironment(class PHY_IPhysicsEnvironment *env)=0; - - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_IController") -#endif -}; - -#endif /* __PHY_ICONTROLLER_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IGraphicController.h b/source/gameengine/Physics/common/PHY_IGraphicController.h deleted file mode 100644 index b047edd93eb..00000000000 --- a/source/gameengine/Physics/common/PHY_IGraphicController.h +++ /dev/null @@ -1,60 +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. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file PHY_IGraphicController.h - * \ingroup phys - */ - -#ifndef __PHY_IGRAPHICCONTROLLER_H__ -#define __PHY_IGRAPHICCONTROLLER_H__ - -#include "PHY_IController.h" - - -/** - * PHY_IPhysicsController is the abstract simplified Interface to a physical object. - * It contains the IMotionState and IDeformableMesh Interfaces. - */ -class PHY_IGraphicController : public PHY_IController -{ - public: - /** - * SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding') - */ - virtual bool SetGraphicTransform()=0; - virtual void Activate(bool active=true)=0; - virtual void SetLocalAabb(const class MT_Vector3& aabbMin,const class MT_Vector3& aabbMax)=0; - virtual void SetLocalAabb(const float* aabbMin,const float* aabbMax)=0; - - virtual PHY_IGraphicController* GetReplica(class PHY_IMotionState* motionstate) {return 0;} - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_IController") -#endif -}; - -#endif /* __PHY_IGRAPHICCONTROLLER_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IMotionState.h b/source/gameengine/Physics/common/PHY_IMotionState.h deleted file mode 100644 index e803d658713..00000000000 --- a/source/gameengine/Physics/common/PHY_IMotionState.h +++ /dev/null @@ -1,68 +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. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file PHY_IMotionState.h - * \ingroup phys - */ - -#ifndef __PHY_IMOTIONSTATE_H__ -#define __PHY_IMOTIONSTATE_H__ - -#ifdef WITH_CXX_GUARDEDALLOC -#include "MEM_guardedalloc.h" -#endif - -/** - * PHY_IMotionState is the Interface to explicitly synchronize the world transformation. - * Default implementations for mayor graphics libraries like OpenGL and DirectX can be provided. - */ -class PHY_IMotionState - -{ - public: - virtual ~PHY_IMotionState() {}; - - virtual void GetWorldPosition(float& posX,float& posY,float& posZ)=0; - virtual void GetWorldScaling(float& scaleX,float& scaleY,float& scaleZ)=0; - virtual void GetWorldOrientation(float& quatIma0,float& quatIma1,float& quatIma2,float& quatReal)=0; - // ori = array 12 floats, [0..3] = first column + 0, [4..7] = second column, [8..11] = third column - virtual void GetWorldOrientation(float* ori)=0; - virtual void SetWorldOrientation(const float* ori)=0; - - virtual void SetWorldPosition(float posX,float posY,float posZ)=0; - virtual void SetWorldOrientation(float quatIma0,float quatIma1,float quatIma2,float quatReal)=0; - - - virtual void CalculateWorldTransformations()=0; - - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_IMotionState") -#endif -}; - -#endif /* __PHY_IMOTIONSTATE_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IPhysicsController.h b/source/gameengine/Physics/common/PHY_IPhysicsController.h deleted file mode 100644 index 4c6e8c71ef7..00000000000 --- a/source/gameengine/Physics/common/PHY_IPhysicsController.h +++ /dev/null @@ -1,154 +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. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file PHY_IPhysicsController.h - * \ingroup phys - */ - -#ifndef __PHY_IPHYSICSCONTROLLER_H__ -#define __PHY_IPHYSICSCONTROLLER_H__ - -#include <vector> -#include "PHY_IController.h" - -class PHY_IMotionState; -class PHY_IPhysicsEnvironment; - -class MT_Vector3; -class MT_Point3; -class MT_Matrix3x3; - -class KX_GameObject; -class RAS_MeshObject; - -/** - * PHY_IPhysicsController is the abstract simplified Interface to a physical object. - * It contains the IMotionState and IDeformableMesh Interfaces. - */ -class PHY_IPhysicsController : public PHY_IController -{ - - public: - virtual ~PHY_IPhysicsController() {}; - /** - * SynchronizeMotionStates ynchronizes dynas, kinematic and deformable entities (and do 'late binding') - */ - virtual bool SynchronizeMotionStates(float time)=0; - /** - * WriteMotionStateToDynamics ynchronizes dynas, kinematic and deformable entities (and do 'late binding') - */ - - virtual void WriteMotionStateToDynamics(bool nondynaonly)=0; - virtual void WriteDynamicsToMotionState()=0; - virtual class PHY_IMotionState* GetMotionState() = 0; - // controller replication - virtual void PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl)=0; - virtual void SetPhysicsEnvironment(class PHY_IPhysicsEnvironment *env)=0; - - // kinematic methods - virtual void RelativeTranslate(const MT_Vector3& dloc,bool local)=0; - virtual void RelativeRotate(const MT_Matrix3x3&,bool local)=0; - virtual MT_Matrix3x3 GetOrientation()=0; - virtual void SetOrientation(const MT_Matrix3x3& orn)=0; - virtual void SetPosition(const MT_Vector3& pos)=0; - virtual void GetPosition(MT_Vector3& pos) const=0; - virtual void SetScaling(const MT_Vector3& scale)=0; - virtual void SetTransform()=0; - - virtual MT_Scalar GetMass()=0; - virtual void SetMass(MT_Scalar newmass)=0; - - // physics methods - virtual void ApplyImpulse(const MT_Point3& attach, const MT_Vector3& impulse,bool local)=0; - virtual void ApplyTorque(const MT_Vector3& torque,bool local)=0; - virtual void ApplyForce(const MT_Vector3& force,bool local)=0; - virtual void SetAngularVelocity(const MT_Vector3& ang_vel,bool local)=0; - virtual void SetLinearVelocity(const MT_Vector3& lin_vel,bool local)=0; - virtual void ResolveCombinedVelocities(float linvelX,float linvelY,float linvelZ,float angVelX,float angVelY,float angVelZ) = 0; - - virtual float GetLinearDamping() const=0; - virtual float GetAngularDamping() const=0; - virtual void SetLinearDamping(float damping)=0; - virtual void SetAngularDamping(float damping)=0; - virtual void SetDamping(float linear, float angular)=0; - - virtual void RefreshCollisions() = 0; - virtual void SuspendDynamics(bool ghost=false)=0; - virtual void RestoreDynamics()=0; - - virtual void SetActive(bool active)=0; - - // reading out information from physics - virtual MT_Vector3 GetLinearVelocity()=0; - virtual MT_Vector3 GetAngularVelocity()=0; - virtual MT_Vector3 GetVelocity(const MT_Point3& pos)=0; - virtual MT_Vector3 GetLocalInertia()=0; - - // dyna's that are rigidbody are free in orientation, dyna's with non-rigidbody are restricted - virtual void SetRigidBody(bool rigid)=0; - - virtual PHY_IPhysicsController* GetReplica() {return 0;} - virtual PHY_IPhysicsController* GetReplicaForSensors() {return 0;} - - virtual void CalcXform() =0; - virtual void SetMargin(float margin) =0; - virtual float GetMargin() const=0; - virtual float GetRadius() const=0; - virtual void SetRadius(float margin) = 0; - - virtual float GetLinVelocityMin() const=0; - virtual void SetLinVelocityMin(float val) = 0; - virtual float GetLinVelocityMax() const=0; - virtual void SetLinVelocityMax(float val) = 0; - - virtual void SetAngularVelocityMin(float val) = 0; - virtual float GetAngularVelocityMin() const = 0; - virtual void SetAngularVelocityMax(float val) = 0; - virtual float GetAngularVelocityMax() const = 0; - - MT_Vector3 GetWorldPosition(MT_Vector3& localpos); - - // Shape control - virtual void AddCompoundChild(PHY_IPhysicsController* child) = 0; - virtual void RemoveCompoundChild(PHY_IPhysicsController* child) = 0; - - - virtual bool IsDynamic() = 0; - virtual bool IsCompound() = 0; - virtual bool IsSuspended() const = 0; - - virtual bool ReinstancePhysicsShape(KX_GameObject *from_gameobj, RAS_MeshObject* from_meshobj) = 0; - - /* Method to replicate rigid body joint contraints for group instances. */ - virtual void ReplicateConstraints(KX_GameObject *gameobj, std::vector<KX_GameObject*> constobj) = 0; - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_IPhysicsController") -#endif -}; - -#endif /* __PHY_IPHYSICSCONTROLLER_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h deleted file mode 100644 index 72ec7b1edd0..00000000000 --- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h +++ /dev/null @@ -1,226 +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. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file PHY_IPhysicsEnvironment.h - * \ingroup phys - */ - -#ifndef __PHY_IPHYSICSENVIRONMENT_H__ -#define __PHY_IPHYSICSENVIRONMENT_H__ - -#include "PHY_DynamicTypes.h" -#include "MT_Vector2.h" -#include "MT_Vector3.h" -#include "MT_Vector4.h" - -#ifdef WITH_CXX_GUARDEDALLOC -#include "MEM_guardedalloc.h" -#endif - -class PHY_IVehicle; -class PHY_ICharacter; -class RAS_MeshObject; -class PHY_IPhysicsController; - - -class RAS_MeshObject; -struct DerivedMesh; -class KX_GameObject; -class KX_Scene; - -struct PHY_ShapeProps; -struct PHY_MaterialProps; -class PHY_IMotionState; -struct bRigidBodyJointConstraint; - -/** - * pass back information from rayTest - */ -struct PHY_RayCastResult -{ - PHY_IPhysicsController* m_controller; - MT_Vector3 m_hitPoint; - MT_Vector3 m_hitNormal; - const RAS_MeshObject* m_meshObject; // !=NULL for mesh object (only for Bullet controllers) - int m_polygon; // index of the polygon hit by the ray, - // only if m_meshObject != NULL - int m_hitUVOK; // !=0 if UV coordinate in m_hitUV is valid - MT_Vector2 m_hitUV; // UV coordinates of hit point -}; - -/** - * This class replaces the ignoreController parameter of rayTest function. - * It allows more sophisticated filtering on the physics controller before computing the ray intersection to save CPU. - * It is only used to its full extend by the Ccd physics environment (Bullet). - */ -class PHY_IRayCastFilterCallback -{ -public: - PHY_IPhysicsController* m_ignoreController; - bool m_faceNormal; - bool m_faceUV; - - virtual ~PHY_IRayCastFilterCallback() - { - } - - virtual bool needBroadphaseRayCast(PHY_IPhysicsController* controller) - { - return true; - } - - virtual void reportHit(PHY_RayCastResult* result) = 0; - - PHY_IRayCastFilterCallback(PHY_IPhysicsController* ignoreController, bool faceNormal=false, bool faceUV=false) - :m_ignoreController(ignoreController), - m_faceNormal(faceNormal), - m_faceUV(faceUV) - { - } - - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_IRayCastFilterCallback") -#endif -}; - -/** - * Physics Environment takes care of stepping the simulation and is a container for physics entities - * (rigidbodies,constraints, materials etc.) - * A derived class may be able to 'construct' entities by loading and/or converting - */ -class PHY_IPhysicsEnvironment -{ - public: - virtual ~PHY_IPhysicsEnvironment() {} - virtual void BeginFrame() = 0; - virtual void EndFrame() = 0; - /// Perform an integration step of duration 'timeStep'. - virtual bool ProceedDeltaTime(double curTime,float timeStep,float interval)=0; - ///draw debug lines (make sure to call this during the render phase, otherwise lines are not drawn properly) - virtual void DebugDrawWorld() {} - virtual void SetFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep)=0; - //returns 0.f if no fixed timestep is used - virtual float GetFixedTimeStep()=0; - - ///getDebugMode return the actual debug visualization state - virtual int GetDebugMode()const=0; - ///setDebugMode is used to support several ways of debug lines, contact point visualization - virtual void SetDebugMode(int debugMode) {} - ///setNumIterations set the number of iterations for iterative solvers - virtual void SetNumIterations(int numIter) {} - ///setNumTimeSubSteps set the number of divisions of the timestep. Tradeoff quality versus performance. - virtual void SetNumTimeSubSteps(int numTimeSubSteps) {} - virtual int GetNumTimeSubSteps() {return 0; } - ///setDeactivationTime sets the minimum time that an objects has to stay within the velocity tresholds until it gets fully deactivated - virtual void SetDeactivationTime(float dTime) {} - ///setDeactivationLinearTreshold sets the linear velocity treshold, see setDeactivationTime - virtual void SetDeactivationLinearTreshold(float linTresh) {} - ///setDeactivationAngularTreshold sets the angular velocity treshold, see setDeactivationTime - virtual void SetDeactivationAngularTreshold(float angTresh) {} - ///setContactBreakingTreshold sets tresholds to do with contact point management - virtual void SetContactBreakingTreshold(float contactBreakingTreshold) {} - ///continuous collision detection mode, very experimental for Bullet - virtual void SetCcdMode(int ccdMode) {} - ///successive overrelaxation constant, in case PSOR is used, values in between 1 and 2 guarantee converging behavior - virtual void SetSolverSorConstant(float sor) {} - ///setSolverType, internal setting, chooses solvertype, PSOR, Dantzig, impulse based, penalty based - virtual void SetSolverType(int solverType) {} - ///setTau sets the spring constant of a penalty based solver - virtual void SetSolverTau(float tau) {} - ///setDamping sets the damper constant of a penalty based solver - virtual void SetSolverDamping(float damping) {} - ///linear air damping for rigidbodies - virtual void SetLinearAirDamping(float damping) {} - /// penetrationdepth setting - virtual void SetUseEpa(bool epa) {} - - virtual void SetGravity(float x,float y,float z)=0; - virtual void GetGravity(MT_Vector3& grav) = 0; - - virtual int CreateConstraint(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsController* ctrl2,PHY_ConstraintType type, - float pivotX,float pivotY,float pivotZ, - float axis0X,float axis0Y,float axis0Z, - float axis1X=0,float axis1Y=0,float axis1Z=0, - float axis2X=0,float axis2Y=0,float axis2Z=0,int flag=0 - )=0; - virtual void RemoveConstraintById(int constraintid) = 0; - virtual float GetAppliedImpulse(int constraintid) { return 0.0f; } - - - //complex constraint for vehicles - virtual PHY_IVehicle* GetVehicleConstraint(int constraintId) =0; - - // Character physics wrapper - virtual PHY_ICharacter* GetCharacterController(class KX_GameObject* ob) =0; - - virtual PHY_IPhysicsController* RayTest(PHY_IRayCastFilterCallback &filterCallback, float fromX,float fromY,float fromZ, float toX,float toY,float toZ)=0; - - //culling based on physical broad phase - // the plane number must be set as follow: near, far, left, right, top, botton - // the near plane must be the first one and must always be present, it is used to get the direction of the view - virtual bool CullingTest(PHY_CullingCallback callback, void *userData, MT_Vector4* planeNormals, int planeNumber, int occlusionRes, const int *viewport, float modelview[16], float projection[16]) = 0; - - //Methods for gamelogic collision/physics callbacks - //todo: - virtual void AddSensor(PHY_IPhysicsController* ctrl)=0; - virtual void RemoveSensor(PHY_IPhysicsController* ctrl)=0; - virtual void AddTouchCallback(int response_class, PHY_ResponseCallback callback, void *user)=0; - virtual bool RequestCollisionCallback(PHY_IPhysicsController* ctrl)=0; - virtual bool RemoveCollisionCallback(PHY_IPhysicsController* ctrl)=0; - //These two methods are *solely* used to create controllers for sensor! Don't use for anything else - virtual PHY_IPhysicsController* CreateSphereController(float radius,const MT_Vector3& position) =0; - virtual PHY_IPhysicsController* CreateConeController(float coneradius,float coneheight)=0; - - virtual void SetConstraintParam(int constraintId,int param,float value,float value1) = 0; - virtual float GetConstraintParam(int constraintId,int param) = 0; - - virtual void ExportFile(const char* filename) {}; - - virtual void MergeEnvironment(PHY_IPhysicsEnvironment *other_env) = 0; - - virtual void ConvertObject(KX_GameObject* gameobj, - RAS_MeshObject* meshobj, - DerivedMesh* dm, - KX_Scene* kxscene, - PHY_ShapeProps* shapeprops, - PHY_MaterialProps* smmaterial, - PHY_IMotionState *motionstate, - int activeLayerBitInfo, - bool isCompoundChild, - bool hasCompoundChildren) = 0; - - /* Set the rigid body joints constraints values for converted objects and replicated group instances. */ - virtual void SetupObjectConstraints(KX_GameObject *obj_src, KX_GameObject *obj_dest, - bRigidBodyJointConstraint *dat) {} - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_IPhysicsEnvironment") -#endif -}; - -#endif /* __PHY_IPHYSICSENVIRONMENT_H__ */ diff --git a/source/gameengine/Physics/common/PHY_IVehicle.h b/source/gameengine/Physics/common/PHY_IVehicle.h deleted file mode 100644 index 7e4a49e923e..00000000000 --- a/source/gameengine/Physics/common/PHY_IVehicle.h +++ /dev/null @@ -1,69 +0,0 @@ - -/** \file PHY_IVehicle.h - * \ingroup phys - */ - -#ifndef __PHY_IVEHICLE_H__ -#define __PHY_IVEHICLE_H__ - -//PHY_IVehicle provides a generic interface for (raycast based) vehicles. Mostly targetting 4 wheel cars and 2 wheel motorbikes. - -class PHY_IMotionState; -#include "PHY_DynamicTypes.h" - -#ifdef WITH_CXX_GUARDEDALLOC -#include "MEM_guardedalloc.h" -#endif - -class PHY_IVehicle -{ -public: - virtual ~PHY_IVehicle() {}; - - virtual void AddWheel( - PHY_IMotionState* motionState, - MT_Vector3 connectionPoint, - MT_Vector3 downDirection, - MT_Vector3 axleDirection, - float suspensionRestLength, - float wheelRadius, - bool hasSteering - ) = 0; - - - virtual int GetNumWheels() const = 0; - - virtual void GetWheelPosition(int wheelIndex,float& posX,float& posY,float& posZ) const = 0; - virtual void GetWheelOrientationQuaternion(int wheelIndex,float& quatX,float& quatY,float& quatZ,float& quatW) const = 0; - virtual float GetWheelRotation(int wheelIndex) const = 0; - - virtual int GetUserConstraintId() const =0; - virtual int GetUserConstraintType() const =0; - - //some basic steering/braking/tuning/balancing (bikes) - - virtual void SetSteeringValue(float steering,int wheelIndex) = 0; - - virtual void ApplyEngineForce(float force,int wheelIndex) = 0; - - virtual void ApplyBraking(float braking,int wheelIndex) = 0; - - virtual void SetWheelFriction(float friction,int wheelIndex) = 0; - - virtual void SetSuspensionStiffness(float suspensionStiffness,int wheelIndex) = 0; - - virtual void SetSuspensionDamping(float suspensionStiffness,int wheelIndex) = 0; - - virtual void SetSuspensionCompression(float suspensionStiffness,int wheelIndex) = 0; - - virtual void SetRollInfluence(float rollInfluence,int wheelIndex) = 0; - - virtual void SetCoordinateSystem(int rightIndex,int upIndex,int forwardIndex) =0; - - -#ifdef WITH_CXX_GUARDEDALLOC - MEM_CXX_CLASS_ALLOC_FUNCS("GE:PHY_IVehicle") -#endif -}; - -#endif /* __PHY_IVEHICLE_H__ */ diff --git a/source/gameengine/Physics/common/PHY_Pro.h b/source/gameengine/Physics/common/PHY_Pro.h deleted file mode 100644 index bfe574e73cb..00000000000 --- a/source/gameengine/Physics/common/PHY_Pro.h +++ /dev/null @@ -1,68 +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. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file PHY_Pro.h - * \ingroup phys - */ - -#ifndef __PHY_PRO_H__ -#define __PHY_PRO_H__ - -#include <MT_Scalar.h> - -// Properties of dynamic objects -struct PHY_ShapeProps { - MT_Scalar m_mass; // Total mass - MT_Scalar m_inertia; // Inertia, should be a tensor some time - MT_Scalar m_lin_drag; // Linear drag (air, water) 0 = concrete, 1 = vacuum, inverted and called dampening in blenders UI - MT_Scalar m_ang_drag; // Angular drag, inverted and called dampening in blenders UI - MT_Scalar m_friction_scaling[3]; // Scaling for anisotropic friction. Component in range [0, 1] - MT_Scalar m_clamp_vel_min; // Clamp the minimum velocity, this ensures an object moves at a minimum speed unless its stationary - MT_Scalar m_clamp_vel_max; // Clamp max velocity - MT_Scalar m_clamp_angvel_min; // Clamp the minimum angular velocity. - MT_Scalar m_clamp_angvel_max; // Clamp the maximum angular velocity. - bool m_do_anisotropic; // Should I do anisotropic friction? - bool m_do_fh; // Should the object have a linear Fh spring? - bool m_do_rot_fh; // Should the object have an angular Fh spring? - MT_Scalar m_step_height; // Max height of climbable steps (Character) - MT_Scalar m_jump_speed; // Velocity of jumps (Character) - MT_Scalar m_fall_speed; // Max velocity of falling (Character) - unsigned char m_max_jumps; // Max ammount of jumps (Character) -}; - - -// Properties of collidable objects (non-ghost objects) -struct PHY_MaterialProps { - MT_Scalar m_restitution; // restitution of energie after a collision 0 = inelastic, 1 = elastic - MT_Scalar m_friction; // Coulomb friction (= ratio between the normal en maximum friction force) - MT_Scalar m_fh_spring; // Spring constant (both linear and angular) - MT_Scalar m_fh_damping; // Damping factor (linear and angular) in range [0, 1] - MT_Scalar m_fh_distance; // The range above the surface where Fh is active. - bool m_fh_normal; // Should the object slide off slopes? -}; - -#endif /* __PHY_PRO_H__ */ |