Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Physics')
-rw-r--r--source/gameengine/Physics/Bullet/CMakeLists.txt73
-rw-r--r--source/gameengine/Physics/Bullet/CcdGraphicController.cpp152
-rw-r--r--source/gameengine/Physics/Bullet/CcdGraphicController.h90
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp2668
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h832
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp3795
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h345
-rw-r--r--source/gameengine/Physics/Dummy/CMakeLists.txt41
-rw-r--r--source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.cpp121
-rw-r--r--source/gameengine/Physics/Dummy/DummyPhysicsEnvironment.h134
-rw-r--r--source/gameengine/Physics/common/PHY_DynamicTypes.h91
-rw-r--r--source/gameengine/Physics/common/PHY_ICharacter.h39
-rw-r--r--source/gameengine/Physics/common/PHY_IController.h63
-rw-r--r--source/gameengine/Physics/common/PHY_IGraphicController.h60
-rw-r--r--source/gameengine/Physics/common/PHY_IMotionState.h68
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsController.h154
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h226
-rw-r--r--source/gameengine/Physics/common/PHY_IVehicle.h69
-rw-r--r--source/gameengine/Physics/common/PHY_Pro.h68
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__ */