From f9aa7f3b53e3742e85ff0536de745c2b3699af0d Mon Sep 17 00:00:00 2001 From: "erwin.coumans" Date: Sat, 8 Nov 2008 21:01:20 +0000 Subject: [PATCH] Add Character control to btDiscreteDynamicsWorld (moved btCharacterControllerInterface/btKinematicCharacterController functionality from demo) Remove ibmsdk from CcdPhysicsDemo and CollisionDemo --- Demos/CcdPhysicsDemo/ibmsdk/Makefile | 73 ----------- .../CharacterControllerInterface.h | 32 ----- Demos/CharacterDemo/CharacterDemo.cpp | 50 +++++--- Demos/CharacterDemo/CharacterDemo.h | 13 +- .../DynamicCharacterController.h | 4 +- .../KinematicCharacterController.h | 85 ------------- Demos/CollisionDemo/ibmsdk/Makefile | 68 ----------- .../btCharacterControllerInterface.h | 43 +++++++ .../btKinematicCharacterController.cpp | 115 +++++++----------- .../btKinematicCharacterController.h | 103 ++++++++++++++++ .../Dynamics/btDiscreteDynamicsWorld.cpp | 31 ++++- .../Dynamics/btDiscreteDynamicsWorld.h | 19 ++- src/BulletDynamics/Dynamics/btDynamicsWorld.h | 6 + 13 files changed, 289 insertions(+), 353 deletions(-) delete mode 100755 Demos/CcdPhysicsDemo/ibmsdk/Makefile delete mode 100644 Demos/CharacterDemo/CharacterControllerInterface.h delete mode 100644 Demos/CharacterDemo/KinematicCharacterController.h delete mode 100755 Demos/CollisionDemo/ibmsdk/Makefile create mode 100644 src/BulletDynamics/Character/btCharacterControllerInterface.h rename Demos/CharacterDemo/KinematicCharacterController.cpp => src/BulletDynamics/Character/btKinematicCharacterController.cpp (72%) create mode 100644 src/BulletDynamics/Character/btKinematicCharacterController.h diff --git a/Demos/CcdPhysicsDemo/ibmsdk/Makefile b/Demos/CcdPhysicsDemo/ibmsdk/Makefile deleted file mode 100755 index 2039e8b73..000000000 --- a/Demos/CcdPhysicsDemo/ibmsdk/Makefile +++ /dev/null @@ -1,73 +0,0 @@ -# --------------------------------------------------------------- -# PLEASE DO NOT MODIFY THIS SECTION -# This prolog section is automatically generated. -# -# (C) Copyright 2001,2006, -# International Business Machines Corporation, -# -# All Rights Reserved. -# --------------------------------------------------------------- -# -------------------------------------------------------------- -# PROLOG END TAG zYx - -######################################################################## -# Source Code -######################################################################## -VPATH = ../ -######################################################################## -# Target -######################################################################## -ROOT = ../../.. -HOSTINC = /usr/include -PROGRAM_ppu := CcdPhysicsDemo - -####################################################################### -# Objs -###################################################################### -OBJS = CcdPhysicsDemo.o main.o - - -######################################################################## -# Libraries, Include paths, Defines -######################################################################## -INCLUDE = -DUSE_LIBSPE2 \ - -I$(CELL_SYSROOT)/usr/include \ - -I../ \ - -I$(ROOT)/src \ - -I$(ROOT)/Demos/OpenGL \ - -I$(HOSTINC) -SYS_LIBS := -lspe2 -lglut -lGLU -lGL -lm -lXext -lXmu -lX11 - -IMPORTS = $(ROOT)/lib/ibmsdk/bulletmultithreaded.a \ - $(ROOT)/lib/ibmsdk/bulletopenglsupport.a \ - $(ROOT)/lib/ibmsdk/bulletdynamics.a \ - $(ROOT)/lib/ibmsdk/bulletconvexhull.a \ - $(ROOT)/lib/ibmsdk/bulletcollision.a \ - $(ROOT)/lib/ibmsdk/bulletmath.a - -####################################################################### -# Install files/dirs -####################################################################### -INSTALL_DIR = $(ROOT)/ibmsdk -INSTALL_FILES = $(PROGRAM_ppu) -######################################################################## -# make.footer -######################################################################## - -IBM_CELLSDK_VERSION := $(shell if [ -d /opt/cell ]; then echo "3.0"; fi) - -ifeq ("$(IBM_CELLSDK_VERSION)","3.0") - CELL_TOP ?= /opt/cell/sdk -# CELL_SYSROOT = $(CELL_TOP); - include $(CELL_TOP)/buildutils/make.footer -else - CELL_TOP ?= /opt/ibm/cell-sdk/prototype - CELL_SYSROOT = $(CELL_TOP)/sysroot - include $(CELL_TOP)/make.footer -endif - -$(PPMS): - cp textures/$@ . - -cleanlocal: - rm -f $(PPMS) diff --git a/Demos/CharacterDemo/CharacterControllerInterface.h b/Demos/CharacterDemo/CharacterControllerInterface.h deleted file mode 100644 index cd043f3dd..000000000 --- a/Demos/CharacterDemo/CharacterControllerInterface.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef CHARACTER_CONTROLLER_INTERFACE_H -#define CHARACTER_CONTROLLER_INTERFACE_H - -#include "LinearMath/btVector3.h" - -class btCollisionShape; -class btRigidBody; -class btCollisionWorld; - -class CharacterControllerInterface -{ -public: - CharacterControllerInterface () {}; - virtual ~CharacterControllerInterface () {}; - - virtual void reset () = 0; - virtual void warp (const btVector3& origin) = 0; - - virtual void preStep ( btCollisionWorld* collisionWorld) = 0; - virtual void playerStep (btCollisionWorld* collisionWorld, btScalar dt, - int forward, - int backward, - int left, - int right, - int jump) = 0; - virtual bool canJump () const = 0; - virtual void jump () = 0; - - virtual bool onGround () const = 0; -}; - -#endif diff --git a/Demos/CharacterDemo/CharacterDemo.cpp b/Demos/CharacterDemo/CharacterDemo.cpp index 8b32ffdd8..1c360403c 100644 --- a/Demos/CharacterDemo/CharacterDemo.cpp +++ b/Demos/CharacterDemo/CharacterDemo.cpp @@ -27,7 +27,7 @@ subject to the following restrictions: #ifdef DYNAMIC_CHARACTER_CONTROLLER #include "DynamicCharacterController.h" #else -#include "KinematicCharacterController.h" +#include "BulletDynamics/Character/btKinematicCharacterController.h" #endif const int maxProxies = 32766; @@ -39,15 +39,7 @@ static int gLeft = 0; static int gRight = 0; static int gJump = 0; -///playerStepCallback is the main function that is updating the character. -///Register this callback using: m_dynamicsWorld->setInternalTickCallback(playerStepCallback,m_character); -///This function will be called at the end of each internal simulation time step -void playerStepCallback(btDynamicsWorld* dynamicsWorld, btScalar timeStep) -{ - CharacterControllerInterface* characterInterface= (CharacterControllerInterface*) dynamicsWorld->getWorldUserInfo(); - characterInterface->preStep (dynamicsWorld); - characterInterface->playerStep (dynamicsWorld, timeStep, gForward, gBackward, gLeft, gRight, gJump); -} + CharacterDemo::CharacterDemo() @@ -95,16 +87,14 @@ void CharacterDemo::initPhysics() m_ghostObject->setCollisionFlags (btCollisionObject::CF_CHARACTER_OBJECT); btScalar stepHeight = btScalar(0.35); - m_character = new KinematicCharacterController (m_ghostObject,capsule,stepHeight); + m_character = new btKinematicCharacterController (m_ghostObject,capsule,stepHeight); #endif - m_dynamicsWorld->setInternalTickCallback(playerStepCallback,m_character); - - ///only collide with static for now (no interaction with dynamic objects) m_dynamicsWorld->addCollisionObject(m_ghostObject,btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter); + m_dynamicsWorld->addCharacter(m_character); //////////////// @@ -231,6 +221,38 @@ void CharacterDemo::clientMoveAndDisplay() if (m_idle) dt = 1.0/420.f; + ///set walkDirection for our character + btTransform xform; + xform = m_ghostObject->getWorldTransform (); + + btVector3 forwardDir = xform.getBasis()[2]; + // printf("forwardDir=%f,%f,%f\n",forwardDir[0],forwardDir[1],forwardDir[2]); + btVector3 upDir = xform.getBasis()[1]; + btVector3 strafeDir = xform.getBasis()[0]; + forwardDir.normalize (); + upDir.normalize (); + strafeDir.normalize (); + + btVector3 walkDirection = btVector3(0.0, 0.0, 0.0); + btScalar walkVelocity = btScalar(1.1) * 4.0; // 4 km/h -> 1.1 m/s + btScalar walkSpeed = walkVelocity * dt; + + if (gLeft) + walkDirection += strafeDir; + + if (gRight) + walkDirection -= strafeDir; + + if (gForward) + walkDirection += forwardDir; + + if (gBackward) + walkDirection -= forwardDir; + + + m_character->setWalkDirection(walkDirection*walkSpeed); + + int numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps); //optional but useful: debug drawing diff --git a/Demos/CharacterDemo/CharacterDemo.h b/Demos/CharacterDemo/CharacterDemo.h index 2b8af58da..d6d162085 100644 --- a/Demos/CharacterDemo/CharacterDemo.h +++ b/Demos/CharacterDemo/CharacterDemo.h @@ -16,14 +16,14 @@ subject to the following restrictions: #define CHARACTER_DEMO_H -///DYNAMIC_CHARACTER_CONTROLLER is not at the moment +///DYNAMIC_CHARACTER_CONTROLLER is not fully implemented yet at the moment //#define DYNAMIC_CHARACTER_CONTROLLER 1 #include "BulletCollision/CollisionShapes/btConvexHullShape.h" -class CharacterControllerInterface; -class DynamicCharacterController; -class KinematicCharacterController; +class btCharacterControllerInterface; +class btDynamicCharacterController; +class btKinematicCharacterController; class btCollisionShape; @@ -36,12 +36,13 @@ class CharacterDemo : public DemoApplication public: #ifdef DYNAMIC_CHARACTER_CONTROLLER - CharacterControllerInterface* m_character; + btCharacterControllerInterface* m_character; #else - KinematicCharacterController* m_character; + btKinematicCharacterController* m_character; class btPairCachingGhostObject* m_ghostObject; #endif + btAlignedObjectArray m_collisionShapes; class btBroadphaseInterface* m_overlappingPairCache; diff --git a/Demos/CharacterDemo/DynamicCharacterController.h b/Demos/CharacterDemo/DynamicCharacterController.h index f2c80b59a..e054f59e2 100644 --- a/Demos/CharacterDemo/DynamicCharacterController.h +++ b/Demos/CharacterDemo/DynamicCharacterController.h @@ -3,14 +3,14 @@ #include "LinearMath/btVector3.h" -#include "CharacterControllerInterface.h" +#include "BulletDynamics/Character/btCharacterControllerInterface.h" class btCollisionShape; class btRigidBody; class btCollisionWorld; ///DynamicCharacterController is obsolete/unsupported at the moment -class DynamicCharacterController : public CharacterControllerInterface +class DynamicCharacterController : public btCharacterControllerInterface { protected: btScalar m_halfHeight; diff --git a/Demos/CharacterDemo/KinematicCharacterController.h b/Demos/CharacterDemo/KinematicCharacterController.h deleted file mode 100644 index 23a203882..000000000 --- a/Demos/CharacterDemo/KinematicCharacterController.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef KINEMATIC_CHARACTER_CONTROLLER_H -#define KINEMATIC_CHARACTER_CONTROLLER_H - -#include "LinearMath/btVector3.h" - -#include "CharacterControllerInterface.h" - -class btCollisionShape; -class btRigidBody; -class btCollisionWorld; -class btCollisionDispatcher; -class btPairCachingGhostObject; - -///KinematicCharacterController is a collision object with support for sliding motion in a world. -///It uses the convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations. -///Interaction between KinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user. -class KinematicCharacterController : public CharacterControllerInterface -{ -protected: - btScalar m_halfHeight; - - btPairCachingGhostObject* m_ghostObject; - btConvexShape* m_convexShape;//is also in m_ghostObject, but it needs to be convex, so we store it here to avoid upcast - - btScalar m_fallSpeed; - btScalar m_jumpSpeed; - btScalar m_maxJumpHeight; - - btScalar m_turnAngle; - btScalar m_walkVelocity; - - btScalar m_stepHeight; - - btVector3 m_upDirection; - btVector3 m_forwardDirection; - btVector3 m_strafeDirection; - - btVector3 m_currentPosition; - btScalar m_currentStepOffset; - btVector3 m_targetPosition; - - btManifoldArray m_manifoldArray; - - bool m_touchingContact; - btVector3 m_touchingNormal; - - bool m_useGhostObjectSweepTest; - - bool recoverFromPenetration (btCollisionWorld* collisionWorld); - void stepUp (btCollisionWorld* collisionWorld); - void updateTargetPositionBasedOnCollision (const btVector3& hit_normal, btScalar tangentMag = btScalar(0.0), btScalar normalMag = btScalar(1.0)); - void stepForwardAndStrafe (btCollisionWorld* collisionWorld, const btVector3& walkMove); - void stepDown (btCollisionWorld* collisionWorld, btScalar dt); -public: - KinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight); - ~KinematicCharacterController (); - - - btPairCachingGhostObject* getGhostObject(); - - void reset (); - void warp (const btVector3& origin); - - void preStep ( btCollisionWorld* collisionWorld); - void playerStep (btCollisionWorld* collisionWorld, btScalar dt, - int forward, - int backward, - int left, - int right, - int jump); - - void setFallSpeed (btScalar fallSpeed); - void setJumpSpeed (btScalar jumpSpeed); - void setMaxJumpHeight (btScalar maxJumpHeight); - bool canJump () const; - void jump (); - void setUseGhostSweepTest(bool useGhostObjectSweepTest) - { - m_useGhostObjectSweepTest = useGhostObjectSweepTest; - } - - bool onGround () const; -}; - -#endif // KINEMATIC_CHARACTER_CONTROLLER_H diff --git a/Demos/CollisionDemo/ibmsdk/Makefile b/Demos/CollisionDemo/ibmsdk/Makefile deleted file mode 100755 index e2a935293..000000000 --- a/Demos/CollisionDemo/ibmsdk/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -# --------------------------------------------------------------- -# PLEASE DO NOT MODIFY THIS SECTION -# This prolog section is automatically generated. -# -# (C) Copyright 2001,2006, -# International Business Machines Corporation, -# -# All Rights Reserved. -# --------------------------------------------------------------- -# -------------------------------------------------------------- -# PROLOG END TAG zYx - -######################################################################## -# Source Code -######################################################################## -VPATH = ../ -######################################################################## -# Target -######################################################################## -ROOT = ../../.. -HOSTINC = /usr/include -PROGRAM_ppu := CollisionDemo - -####################################################################### -# Objs -###################################################################### -OBJS = CollisionDemo.o - -######################################################################## -# Libraries, Include paths, Defines -######################################################################## -INCLUDE = \ - -I../ \ - -I$(ROOT)/src \ - -I$(ROOT)/Demos/OpenGL \ - -I$(HOSTINC) -SYS_LIBS := -lglut -lGLU -lGL -lm -lXext -lXmu -lX11 - -IMPORTS = $(ROOT)/lib/ibmsdk/bulletopenglsupport.a \ - $(ROOT)/lib/ibmsdk/bulletdynamics.a \ - $(ROOT)/lib/ibmsdk/bulletconvexhull.a \ - $(ROOT)/lib/ibmsdk/bulletcollision.a \ - $(ROOT)/lib/ibmsdk/bulletmath.a - -####################################################################### -# Install files/dirs -####################################################################### -INSTALL_DIR = $(ROOT)/ibmsdk -INSTALL_FILES = $(PROGRAM_ppu) -######################################################################## -# make.footer -######################################################################## - -IBM_CELLSDK_VERSION := $(shell if [ -d /opt/cell ]; then echo "3.0"; fi) - -ifeq ("$(IBM_CELLSDK_VERSION)","3.0") - CELL_TOP ?= /opt/cell/sdk - include $(CELL_TOP)/buildutils/make.footer -else - CELL_TOP ?= /opt/ibm/cell-sdk/prototype - include $(CELL_TOP)/make.footer -endif - -$(PPMS): - cp textures/$@ . - -cleanlocal: - rm -f $(PPMS) diff --git a/src/BulletDynamics/Character/btCharacterControllerInterface.h b/src/BulletDynamics/Character/btCharacterControllerInterface.h new file mode 100644 index 000000000..ba4995d5f --- /dev/null +++ b/src/BulletDynamics/Character/btCharacterControllerInterface.h @@ -0,0 +1,43 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com + +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 CHARACTER_CONTROLLER_INTERFACE_H +#define CHARACTER_CONTROLLER_INTERFACE_H + +#include "LinearMath/btVector3.h" + +class btCollisionShape; +class btRigidBody; +class btCollisionWorld; + +class btCharacterControllerInterface +{ +public: + btCharacterControllerInterface () {}; + virtual ~btCharacterControllerInterface () {}; + + virtual void setWalkDirection(const btVector3& walkDirection) = 0; + virtual void reset () = 0; + virtual void warp (const btVector3& origin) = 0; + + virtual void preStep ( btCollisionWorld* collisionWorld) = 0; + virtual void playerStep (btCollisionWorld* collisionWorld, btScalar dt) = 0; + virtual bool canJump () const = 0; + virtual void jump () = 0; + + virtual bool onGround () const = 0; +}; + +#endif diff --git a/Demos/CharacterDemo/KinematicCharacterController.cpp b/src/BulletDynamics/Character/btKinematicCharacterController.cpp similarity index 72% rename from Demos/CharacterDemo/KinematicCharacterController.cpp rename to src/BulletDynamics/Character/btKinematicCharacterController.cpp index 51ef378df..1df041779 100644 --- a/Demos/CharacterDemo/KinematicCharacterController.cpp +++ b/src/BulletDynamics/Character/btKinematicCharacterController.cpp @@ -1,12 +1,26 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com -#include "GLDebugDrawer.h" +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 "LinearMath/btIDebugDraw.h" #include "BulletCollision/CollisionDispatch/btGhostObject.h" #include "BulletCollision/CollisionShapes/btMultiSphereShape.h" #include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h" #include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" #include "BulletCollision/CollisionDispatch/btCollisionWorld.h" #include "LinearMath/btDefaultMotionState.h" -#include "KinematicCharacterController.h" +#include "btKinematicCharacterController.h" ///@todo Interact with dynamic objects, ///Ride kinematicly animated platforms properly @@ -14,10 +28,10 @@ /// -> Should integrate falling velocity manually and use that in stepDown() ///Support jumping ///Support ducking -class ClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback +class btClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback { public: - ClosestNotMeRayResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) + btClosestNotMeRayResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) { m_me = me; } @@ -33,10 +47,10 @@ protected: btCollisionObject* m_me; }; -class ClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback +class btClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback { public: - ClosestNotMeConvexResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) + btClosestNotMeConvexResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) { m_me = me; } @@ -57,7 +71,7 @@ protected: * * from: http://www-cs-students.stanford.edu/~adityagp/final/node3.html */ -btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal) +btVector3 btKinematicCharacterController::computeReflectionDirection (const btVector3& direction, const btVector3& normal) { return direction - (btScalar(2.0) * direction.dot(normal)) * normal; } @@ -65,7 +79,7 @@ btVector3 computeReflectionDirection (const btVector3& direction, const btVector /* * Returns the portion of 'direction' that is parallel to 'normal' */ -btVector3 parallelComponent (const btVector3& direction, const btVector3& normal) +btVector3 btKinematicCharacterController::parallelComponent (const btVector3& direction, const btVector3& normal) { btScalar magnitude = direction.dot(normal); return normal * magnitude; @@ -74,33 +88,33 @@ btVector3 parallelComponent (const btVector3& direction, const btVector3& normal /* * Returns the portion of 'direction' that is perpindicular to 'normal' */ -btVector3 perpindicularComponent (const btVector3& direction, const btVector3& normal) +btVector3 btKinematicCharacterController::perpindicularComponent (const btVector3& direction, const btVector3& normal) { return direction - parallelComponent(direction, normal); } -KinematicCharacterController::KinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight) +btKinematicCharacterController::btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight) { + m_walkDirection.setValue(0,0,0); m_useGhostObjectSweepTest = true; m_ghostObject = ghostObject; m_stepHeight = stepHeight; m_turnAngle = btScalar(0.0); - m_walkVelocity = btScalar(1.1) * 4.0; // 4 km/h -> 1.1 m/s m_convexShape=convexShape; } -KinematicCharacterController::~KinematicCharacterController () +btKinematicCharacterController::~btKinematicCharacterController () { } -btPairCachingGhostObject* KinematicCharacterController::getGhostObject() +btPairCachingGhostObject* btKinematicCharacterController::getGhostObject() { return m_ghostObject; } -bool KinematicCharacterController::recoverFromPenetration (btCollisionWorld* collisionWorld) +bool btKinematicCharacterController::recoverFromPenetration (btCollisionWorld* collisionWorld) { bool penetration = false; @@ -153,7 +167,7 @@ bool KinematicCharacterController::recoverFromPenetration (btCollisionWorld* col return penetration; } -void KinematicCharacterController::stepUp ( btCollisionWorld* world) +void btKinematicCharacterController::stepUp ( btCollisionWorld* world) { // phase 1: up btTransform start, end; @@ -166,7 +180,7 @@ void KinematicCharacterController::stepUp ( btCollisionWorld* world) start.setOrigin (m_currentPosition + btVector3(btScalar(0.0), btScalar(0.1), btScalar(0.0))); end.setOrigin (m_targetPosition); - ClosestNotMeConvexResultCallback callback (m_ghostObject); + btClosestNotMeConvexResultCallback callback (m_ghostObject); callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; @@ -190,7 +204,7 @@ void KinematicCharacterController::stepUp ( btCollisionWorld* world) } } -void KinematicCharacterController::updateTargetPositionBasedOnCollision (const btVector3& hitNormal, btScalar tangentMag, btScalar normalMag) +void btKinematicCharacterController::updateTargetPositionBasedOnCollision (const btVector3& hitNormal, btScalar tangentMag, btScalar normalMag) { btVector3 movementDirection = m_targetPosition - m_currentPosition; btScalar movementLength = movementDirection.length(); @@ -226,7 +240,7 @@ void KinematicCharacterController::updateTargetPositionBasedOnCollision (const b } } -void KinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* collisionWorld, const btVector3& walkMove) +void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* collisionWorld, const btVector3& walkMove) { btVector3 originalDir = walkMove.normalized(); @@ -258,7 +272,7 @@ void KinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* coll start.setOrigin (m_currentPosition); end.setOrigin (m_targetPosition); - ClosestNotMeConvexResultCallback callback (m_ghostObject); + btClosestNotMeConvexResultCallback callback (m_ghostObject); callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; @@ -322,7 +336,7 @@ void KinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* coll } } -void KinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, btScalar dt) +void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, btScalar dt) { btTransform start, end; @@ -337,7 +351,7 @@ void KinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, start.setOrigin (m_currentPosition); end.setOrigin (m_targetPosition); - ClosestNotMeConvexResultCallback callback (m_ghostObject); + btClosestNotMeConvexResultCallback callback (m_ghostObject); callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; @@ -360,11 +374,11 @@ void KinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, } } -void KinematicCharacterController::reset () +void btKinematicCharacterController::reset () { } -void KinematicCharacterController::warp (const btVector3& origin) +void btKinematicCharacterController::warp (const btVector3& origin) { btTransform xform; xform.setIdentity(); @@ -373,7 +387,7 @@ void KinematicCharacterController::warp (const btVector3& origin) } -void KinematicCharacterController::preStep ( btCollisionWorld* collisionWorld) +void btKinematicCharacterController::preStep ( btCollisionWorld* collisionWorld) { int numPenetrationLoops = 0; @@ -388,51 +402,16 @@ void KinematicCharacterController::preStep ( btCollisionWorld* collisionWorld) break; } } - btTransform xform; - xform = m_ghostObject->getWorldTransform (); - btVector3 forwardDir = xform.getBasis()[2]; -// printf("forwardDir=%f,%f,%f\n",forwardDir[0],forwardDir[1],forwardDir[2]); - btVector3 upDir = xform.getBasis()[1]; - btVector3 strafeDir = xform.getBasis()[0]; - forwardDir.normalize (); - upDir.normalize (); - strafeDir.normalize (); - - m_upDirection = upDir; - m_forwardDirection = forwardDir; - m_strafeDirection = strafeDir; - - m_currentPosition = xform.getOrigin(); + m_currentPosition = m_ghostObject->getWorldTransform().getOrigin(); m_targetPosition = m_currentPosition; // printf("m_targetPosition=%f,%f,%f\n",m_targetPosition[0],m_targetPosition[1],m_targetPosition[2]); } -void KinematicCharacterController::playerStep ( btCollisionWorld* collisionWorld, - btScalar dt, - int forward, - int backward, - int left, - int right, - int jump) +void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWorld, btScalar dt) { - btVector3 walkDirection = btVector3(0.0, 0.0, 0.0); - btScalar walkSpeed = m_walkVelocity * dt; - - if (left) - walkDirection += m_strafeDirection; - - if (right) - walkDirection -= m_strafeDirection; - - if (forward) - walkDirection += m_forwardDirection; - - if (backward) - walkDirection -= m_forwardDirection; - btTransform xform; xform = m_ghostObject->getWorldTransform (); @@ -440,34 +419,34 @@ void KinematicCharacterController::playerStep ( btCollisionWorld* collisionWorld // printf("walkSpeed=%f\n",walkSpeed); stepUp (collisionWorld); - stepForwardAndStrafe (collisionWorld, walkDirection * walkSpeed); + stepForwardAndStrafe (collisionWorld, m_walkDirection); stepDown (collisionWorld, dt); xform.setOrigin (m_currentPosition); m_ghostObject->setWorldTransform (xform); } -void KinematicCharacterController::setFallSpeed (btScalar fallSpeed) +void btKinematicCharacterController::setFallSpeed (btScalar fallSpeed) { m_fallSpeed = fallSpeed; } -void KinematicCharacterController::setJumpSpeed (btScalar jumpSpeed) +void btKinematicCharacterController::setJumpSpeed (btScalar jumpSpeed) { m_jumpSpeed = jumpSpeed; } -void KinematicCharacterController::setMaxJumpHeight (btScalar maxJumpHeight) +void btKinematicCharacterController::setMaxJumpHeight (btScalar maxJumpHeight) { m_maxJumpHeight = maxJumpHeight; } -bool KinematicCharacterController::canJump () const +bool btKinematicCharacterController::canJump () const { return onGround(); } -void KinematicCharacterController::jump () +void btKinematicCharacterController::jump () { if (!canJump()) return; @@ -483,7 +462,7 @@ void KinematicCharacterController::jump () #endif } -bool KinematicCharacterController::onGround () const +bool btKinematicCharacterController::onGround () const { return true; } diff --git a/src/BulletDynamics/Character/btKinematicCharacterController.h b/src/BulletDynamics/Character/btKinematicCharacterController.h new file mode 100644 index 000000000..d03f8f9de --- /dev/null +++ b/src/BulletDynamics/Character/btKinematicCharacterController.h @@ -0,0 +1,103 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com + +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 KINEMATIC_CHARACTER_CONTROLLER_H +#define KINEMATIC_CHARACTER_CONTROLLER_H + +#include "LinearMath/btVector3.h" + +#include "btCharacterControllerInterface.h" + +class btCollisionShape; +class btRigidBody; +class btCollisionWorld; +class btCollisionDispatcher; +class btPairCachingGhostObject; + +///btKinematicCharacterController is an object that supports a sliding motion in a world. +///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations. +///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user. +class btKinematicCharacterController : public btCharacterControllerInterface +{ +protected: + btScalar m_halfHeight; + + btPairCachingGhostObject* m_ghostObject; + btConvexShape* m_convexShape;//is also in m_ghostObject, but it needs to be convex, so we store it here to avoid upcast + + btScalar m_fallSpeed; + btScalar m_jumpSpeed; + btScalar m_maxJumpHeight; + + btScalar m_turnAngle; + + btScalar m_stepHeight; + + ///this is the desired walk direction, set by the user + btVector3 m_walkDirection; + + //some internal variables + btVector3 m_currentPosition; + btScalar m_currentStepOffset; + btVector3 m_targetPosition; + + ///keep track of the contact manifolds + btManifoldArray m_manifoldArray; + + bool m_touchingContact; + btVector3 m_touchingNormal; + + bool m_useGhostObjectSweepTest; + + btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal); + btVector3 parallelComponent (const btVector3& direction, const btVector3& normal); + btVector3 perpindicularComponent (const btVector3& direction, const btVector3& normal); + + bool recoverFromPenetration (btCollisionWorld* collisionWorld); + void stepUp (btCollisionWorld* collisionWorld); + void updateTargetPositionBasedOnCollision (const btVector3& hit_normal, btScalar tangentMag = btScalar(0.0), btScalar normalMag = btScalar(1.0)); + void stepForwardAndStrafe (btCollisionWorld* collisionWorld, const btVector3& walkMove); + void stepDown (btCollisionWorld* collisionWorld, btScalar dt); +public: + btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight); + ~btKinematicCharacterController (); + + virtual void setWalkDirection(const btVector3& walkDirection) + { + m_walkDirection = walkDirection; + } + + void reset (); + void warp (const btVector3& origin); + + void preStep ( btCollisionWorld* collisionWorld); + void playerStep (btCollisionWorld* collisionWorld, btScalar dt); + + void setFallSpeed (btScalar fallSpeed); + void setJumpSpeed (btScalar jumpSpeed); + void setMaxJumpHeight (btScalar maxJumpHeight); + bool canJump () const; + void jump (); + + btPairCachingGhostObject* getGhostObject(); + void setUseGhostSweepTest(bool useGhostObjectSweepTest) + { + m_useGhostObjectSweepTest = useGhostObjectSweepTest; + } + + bool onGround () const; +}; + +#endif // KINEMATIC_CHARACTER_CONTROLLER_H diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp index f67a8228a..1af3a19bb 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -51,6 +51,9 @@ subject to the following restrictions: #include "BulletDynamics/Vehicle/btRaycastVehicle.h" #include "BulletDynamics/Vehicle/btVehicleRaycaster.h" #include "BulletDynamics/Vehicle/btWheelInfo.h" +//character +#include "BulletDynamics/Character/btCharacterControllerInterface.h" + #include "LinearMath/btIDebugDraw.h" #include "LinearMath/btQuickprof.h" #include "LinearMath/btMotionState.h" @@ -403,7 +406,8 @@ void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) ///update vehicle simulation updateVehicles(timeStep); - + + updateCharacters(timeStep); updateActivationState( timeStep ); @@ -479,6 +483,20 @@ void btDiscreteDynamicsWorld::updateVehicles(btScalar timeStep) } } +void btDiscreteDynamicsWorld::updateCharacters(btScalar timeStep) +{ + BT_PROFILE("updateCharacters"); + + for ( int i=0;ipreStep (this); + character->playerStep (this,timeStep); + } +} + + + void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep) { BT_PROFILE("updateActivationState"); @@ -543,6 +561,17 @@ void btDiscreteDynamicsWorld::removeVehicle(btRaycastVehicle* vehicle) m_vehicles.remove(vehicle); } +void btDiscreteDynamicsWorld::addCharacter(btCharacterControllerInterface* character) +{ + m_characters.push_back(character); +} + +void btDiscreteDynamicsWorld::removeCharacter(btCharacterControllerInterface* character) +{ + m_characters.remove(character); +} + + SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs) { int islandId; diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h index 724f19a49..129db78a4 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h @@ -26,6 +26,7 @@ class btTypedConstraint; class btRaycastVehicle; +class btCharacterControllerInterface; class btIDebugDraw; #include "LinearMath/btAlignedObjectArray.h" @@ -53,6 +54,9 @@ protected: btAlignedObjectArray m_vehicles; + + btAlignedObjectArray m_characters; + int m_profileTimings; @@ -68,6 +72,8 @@ protected: void updateVehicles(btScalar timeStep); + void updateCharacters(btScalar timeStep); + void startProfiling(btScalar timeStep); virtual void internalSingleStepSimulation( btScalar timeStep); @@ -95,13 +101,18 @@ public: ///this can be useful to synchronize a single rigid body -> graphics object void synchronizeSingleMotionState(btRigidBody* body); - void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false); + virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false); - void removeConstraint(btTypedConstraint* constraint); + virtual void removeConstraint(btTypedConstraint* constraint); - void addVehicle(btRaycastVehicle* vehicle); + virtual void addVehicle(btRaycastVehicle* vehicle); - void removeVehicle(btRaycastVehicle* vehicle); + virtual void removeVehicle(btRaycastVehicle* vehicle); + + virtual void addCharacter(btCharacterControllerInterface* character); + + virtual void removeCharacter(btCharacterControllerInterface* character); + btSimulationIslandManager* getSimulationIslandManager() { diff --git a/src/BulletDynamics/Dynamics/btDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDynamicsWorld.h index 334966102..2346deba1 100644 --- a/src/BulletDynamics/Dynamics/btDynamicsWorld.h +++ b/src/BulletDynamics/Dynamics/btDynamicsWorld.h @@ -23,6 +23,7 @@ class btTypedConstraint; class btRaycastVehicle; class btConstraintSolver; class btDynamicsWorld; +class btCharacterControllerInterface; /// Type for the callback for each tick typedef void (*btInternalTickCallback)(btDynamicsWorld *world, btScalar timeStep); @@ -75,6 +76,11 @@ public: virtual void removeVehicle(btRaycastVehicle* vehicle) {(void)vehicle;} + virtual void addCharacter(btCharacterControllerInterface* character) {(void)character;} + + virtual void removeCharacter(btCharacterControllerInterface* character) {(void)character;} + + //once a rigidbody is added to the dynamics world, it will get this gravity assigned //existing rigidbodies in the world get gravity assigned too, during this method virtual void setGravity(const btVector3& gravity) = 0;