From 6a59432ee811e21a5365e65e7708fe4b97e2d8ff Mon Sep 17 00:00:00 2001 From: johnmccutchan Date: Wed, 27 Feb 2008 19:49:25 +0000 Subject: [PATCH] Initial version of character controller and demo --- Demos/CMakeLists.txt | 2 +- Demos/CharacterDemo/CMakeLists.txt | 65 +++ Demos/CharacterDemo/CharacterController.cpp | 191 +++++++ Demos/CharacterDemo/CharacterController.h | 47 ++ Demos/CharacterDemo/CharacterDemo.cpp | 522 ++++++++++++++++++++ Demos/CharacterDemo/CharacterDemo.h | 85 ++++ Demos/CharacterDemo/main.cpp | 15 + 7 files changed, 926 insertions(+), 1 deletion(-) create mode 100644 Demos/CharacterDemo/CMakeLists.txt create mode 100644 Demos/CharacterDemo/CharacterController.cpp create mode 100644 Demos/CharacterDemo/CharacterController.h create mode 100644 Demos/CharacterDemo/CharacterDemo.cpp create mode 100644 Demos/CharacterDemo/CharacterDemo.h create mode 100644 Demos/CharacterDemo/main.cpp diff --git a/Demos/CMakeLists.txt b/Demos/CMakeLists.txt index 44a560400..252112a20 100644 --- a/Demos/CMakeLists.txt +++ b/Demos/CMakeLists.txt @@ -1,2 +1,2 @@ -SUBDIRS( OpenGL AllBulletDemos ConvexDecompositionDemo HelloWorld MultiThreadedDemo CcdPhysicsDemo ConstraintDemo GenericJointDemo RagdollDemo BasicDemo BspDemo MovingConcaveDemo VehicleDemo ColladaDemo UserCollisionAlgorithm ) +SUBDIRS( OpenGL AllBulletDemos ConvexDecompositionDemo HelloWorld MultiThreadedDemo CcdPhysicsDemo ConstraintDemo GenericJointDemo RagdollDemo BasicDemo BspDemo MovingConcaveDemo VehicleDemo ColladaDemo UserCollisionAlgorithm CharacterDemo ) diff --git a/Demos/CharacterDemo/CMakeLists.txt b/Demos/CharacterDemo/CMakeLists.txt new file mode 100644 index 000000000..8be183864 --- /dev/null +++ b/Demos/CharacterDemo/CMakeLists.txt @@ -0,0 +1,65 @@ +# This is basically the overall name of the project in Visual Studio this is the name of the Solution File + + +# For every executable you have with a main method you should have an add_executable line below. +# For every add executable line you should list every .cpp and .h file you have associated with that executable. + + +# This is the variable for Windows. I use this to define the root of my directory structure. +SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) + +# You shouldn't have to modify anything below this line +######################################################## + + +# This is the shortcut to finding GLU, GLUT and OpenGL if they are properly installed on your system +# This should be the case. +INCLUDE (${CMAKE_ROOT}/Modules/FindGLU.cmake) +INCLUDE (${CMAKE_ROOT}/Modules/FindGLUT.cmake) +INCLUDE (${CMAKE_ROOT}/Modules/FindOpenGL.cmake) + + +IF (WIN32) + # This is the Windows code for which Opengl, and Glut are not properly installed + # since I can't install them I must cheat and copy libraries around + INCLUDE_DIRECTORIES(${GLUT_ROOT}) + # LINK_DIRECTORIES(${GLUT_ROOT}\\lib) + IF (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") + SET(GLUT_glut_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glut32.lib) + # LINK_LIBRARIES(${GLUT_ROOT}\\lib\\glut32 ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) + # TARGET_LINK_LIBRARIES(table ${GLUT_ROOT}\\lib\\glut32) +# +# ADD_CUSTOM_COMMAND(TARGET table POST_BUILD COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2005\\Debug +# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs2003\\Debug +# COMMAND copy ${GLUT_ROOT}\\lib\\glut32.dll ${GLUT_ROOT}\\bin\\vs6\\Debug) + ELSE (${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") +# LINK_LIBRARIES(${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) +# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY}) + ENDIF(${GLUT_glut_LIBRARY} MATCHES "GLUT_glut_LIBRARY-NOTFOUND") +# TARGET_LINK_LIBRARIES(table ${OPENGL_gl_LIBRARY}) +# TARGET_LINK_LIBRARIES(table ${OPENGL_glu_LIBRARY}) +ELSE (WIN32) + # This is the lines for linux. This should always work if everything is installed and working fine. +# SET(CMAKE_BUILD_TYPE Debug) +# SET(CMAKE_CXX_FLAGS_DEBUG "-g") + INCLUDE_DIRECTORIES(/usr/include /usr/local/include ${GLUT_INCLUDE_DIR}) +# TARGET_LINK_LIBRARIES(table ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) +# TARGET_LINK_LIBRARIES(checker ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glU_LIBRARY}) +ENDIF (WIN32) + +INCLUDE_DIRECTORIES( +${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL } +) + +LINK_LIBRARIES( + LibOpenGLSupport LibConvexHull LibBulletDynamics LibBulletCollision LibLinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} +) + +ADD_EXECUTABLE(CharacterDemo + CharacterController.cpp + CharacterController.h + CharacterDemo.cpp + CharacterDemo.h + main.cpp +) + diff --git a/Demos/CharacterDemo/CharacterController.cpp b/Demos/CharacterDemo/CharacterController.cpp new file mode 100644 index 000000000..f5b868323 --- /dev/null +++ b/Demos/CharacterDemo/CharacterController.cpp @@ -0,0 +1,191 @@ +#include "BulletCollision/CollisionShapes/btMultiSphereShape.h" +#include "BulletDynamics/Dynamics/btRigidBody.h" +#include "BulletDynamics/Dynamics/btDynamicsWorld.h" +#include "LinearMath/btDefaultMotionState.h" +#include "CharacterController.h" + +CharacterController::CharacterController () +{ + m_rayLambda[0] = 1.0; + m_rayLambda[1] = 1.0; + m_halfHeight = 1.0; + m_turnAngle = 0.0; + m_maxLinearVelocity = 10.0; + m_walkVelocity = 8.0; // meters/sec + m_turnVelocity = 1.0; // radians/sec + m_shape = NULL; + m_rigidBody = NULL; +} + +CharacterController::~CharacterController () +{ +} + +void CharacterController::setup (btDynamicsWorld* dynamicsWorld, btScalar height, btScalar width) +{ + btVector3 spherePositions[2]; + btScalar sphereRadii[2]; + + sphereRadii[0] = width; + sphereRadii[1] = width; + spherePositions[0] = btVector3 (0.0, (height/btScalar(2.0) - width), 0.0); + spherePositions[1] = btVector3 (0.0, (-height/btScalar(2.0) + width), 0.0); + + m_halfHeight = height/btScalar(2.0); + + m_shape = new btMultiSphereShape (btVector3(width/btScalar(2.0), height/btScalar(2.0), width/btScalar(2.0)), &spherePositions[0], &sphereRadii[0], 2); + + btTransform startTransform; + startTransform.setIdentity (); + startTransform.setOrigin (btVector3(0.0, 2.0, 0.0)); + btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); + btRigidBody::btRigidBodyConstructionInfo cInfo(1.0, myMotionState, m_shape); + m_rigidBody = new btRigidBody(cInfo); + // kinematic vs. static doesn't work + //m_rigidBody->setCollisionFlags( m_rigidBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + m_rigidBody->setSleepingThresholds (0.0, 0.0); + m_rigidBody->setAngularFactor (0.0); + dynamicsWorld->addRigidBody (m_rigidBody); +} + +void CharacterController::destroy (btDynamicsWorld* dynamicsWorld) +{ + if (m_shape) + { + delete m_shape; + } + + if (m_rigidBody) + { + dynamicsWorld->removeRigidBody (m_rigidBody); + delete m_rigidBody; + } +} + +btRigidBody* CharacterController::getRigidBody () +{ + return m_rigidBody; +} + +void CharacterController::preStep (btDynamicsWorld* dynamicsWorld) +{ + btTransform xform; + m_rigidBody->getMotionState()->getWorldTransform (xform); + btVector3 down = -xform.getBasis()[1]; + btVector3 forward = xform.getBasis()[2]; + down.normalize (); + forward.normalize(); + + m_raySource[0] = xform.getOrigin(); + m_raySource[1] = xform.getOrigin(); + + m_rayTarget[0] = m_raySource[0] + down * m_halfHeight * btScalar(1.1); + m_rayTarget[1] = m_raySource[1] + forward * m_halfHeight * btScalar(1.1); + + class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback + { + public: + ClosestNotMe (btRigidBody* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) + { + m_me = me; + } + + virtual btScalar AddSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) + { + if (rayResult.m_collisionObject == m_me) + return 1.0; + + return btCollisionWorld::ClosestRayResultCallback::AddSingleResult (rayResult, normalInWorldSpace + ); + } + protected: + btRigidBody* m_me; + }; + + ClosestNotMe rayCallback(m_rigidBody); + + int i = 0; + for (i = 0; i < 2; i++) + { + rayCallback.m_closestHitFraction = 1.0; + dynamicsWorld->rayTest (m_raySource[i], m_rayTarget[i], rayCallback); + if (rayCallback.HasHit()) + { + m_rayLambda[i] = rayCallback.m_closestHitFraction; + } else { + m_rayLambda[i] = 1.0; + } + } +} + +void CharacterController::playerStep (btScalar dt, + int forward, + int backward, + int left, + int right) +{ + btTransform xform; + m_rigidBody->getMotionState()->getWorldTransform (xform); + + /* Handle turning */ + if (left) + m_turnAngle -= dt * m_turnVelocity; + if (right) + m_turnAngle += dt * m_turnVelocity; + + xform.setRotation (btQuaternion (btVector3(0.0, 1.0, 0.0), m_turnAngle)); + + btVector3 linearVelocity = m_rigidBody->getLinearVelocity(); + btScalar speed = m_rigidBody->getLinearVelocity().length(); + + btVector3 forwardDir = xform.getBasis()[2]; + forwardDir.normalize (); + btVector3 walkDirection = btVector3(0.0, 0.0, 0.0); + btScalar walkSpeed = m_walkVelocity * dt; + + if (forward) + walkDirection += forwardDir; + if (backward) + walkDirection -= forwardDir; + + + + if (!forward && !backward && onGround()) + { + /* Dampen when on the ground and not being moved by the player */ + linearVelocity *= 0.2; + m_rigidBody->setLinearVelocity (linearVelocity); + } else { + if (speed < m_maxLinearVelocity) + { + btVector3 velocity = linearVelocity + walkDirection * walkSpeed; + m_rigidBody->setLinearVelocity (velocity); + } + } + + m_rigidBody->getMotionState()->setWorldTransform (xform); + m_rigidBody->setCenterOfMassTransform (xform); +} + +bool CharacterController::canJump () const +{ + return onGround(); +} + +void CharacterController::jump () +{ + if (!canJump()) + return; + + btTransform xform; + m_rigidBody->getMotionState()->getWorldTransform (xform); + btVector3 up = xform.getBasis()[1]; + up.normalize (); + btScalar magnitude = (btScalar(1.0)/m_rigidBody->getInvMass()) * btScalar(8.0); + m_rigidBody->applyCentralImpulse (up * magnitude); +} + +bool CharacterController::onGround () const +{ + return m_rayLambda[0] < btScalar(1.0); +} \ No newline at end of file diff --git a/Demos/CharacterDemo/CharacterController.h b/Demos/CharacterDemo/CharacterController.h new file mode 100644 index 000000000..b18c068d6 --- /dev/null +++ b/Demos/CharacterDemo/CharacterController.h @@ -0,0 +1,47 @@ +#ifndef CHARACTER_CONTROLLER_H +#define CHARACTER_CONTROLLER_H + +#include "LinearMath/btVector3.h" + +class btCollisionShape; +class btRigidBody; +class btDynamicsWorld; + +class CharacterController +{ +protected: + btScalar m_halfHeight; + btCollisionShape* m_shape; + btRigidBody* m_rigidBody; + + btVector3 m_raySource[2]; + btVector3 m_rayTarget[2]; + btScalar m_rayLambda[2]; + btVector3 m_rayNormal[2]; + + btScalar m_turnAngle; + + btScalar m_maxLinearVelocity; + btScalar m_walkVelocity; + btScalar m_turnVelocity; +public: + CharacterController (); + ~CharacterController (); + void setup (btDynamicsWorld* dynamicsWorld, btScalar height = 2.0, btScalar width = 0.25); + void destroy (btDynamicsWorld* dynamicsWorld); + + btRigidBody* getRigidBody (); + + void preStep (btDynamicsWorld* dynamicsWorld); + void playerStep (btScalar dt, + int forward, + int backward, + int left, + int right); + bool canJump () const; + void jump (); + + bool onGround () const; +}; + +#endif diff --git a/Demos/CharacterDemo/CharacterDemo.cpp b/Demos/CharacterDemo/CharacterDemo.cpp new file mode 100644 index 000000000..00ea47309 --- /dev/null +++ b/Demos/CharacterDemo/CharacterDemo.cpp @@ -0,0 +1,522 @@ +/* +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. +*/ + +/// September 2006: CharacterDemo is work in progress, this file is mostly just a placeholder +/// This CharacterDemo file is very early in development, please check it later +/// One todo is a basic engine model: +/// A function that maps user input (throttle) into torque/force applied on the wheels +/// with gears etc. +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h" + +#include "GLDebugDrawer.h" +#include //printf debugging + +#include "GL_ShapeDrawer.h" + +#include "GlutStuff.h" +#include "CharacterDemo.h" +#include "CharacterController.h" + +const int maxProxies = 32766; +const int maxOverlap = 65535; + +static int gForward = 0; +static int gBackward = 0; +static int gLeft = 0; +static int gRight = 0; +static int gJump = 0; + +CharacterDemo::CharacterDemo() +: +m_cameraHeight(4.f), +m_minCameraDistance(3.f), +m_maxCameraDistance(10.f), +m_indexVertexArrays(0), +m_vertices(0) +{ + m_character = 0; + m_cameraPosition = btVector3(30,30,30); +} + +CharacterDemo::~CharacterDemo() +{ + //cleanup in the reverse order of creation/initialization + if (m_character) + m_character->destroy (m_dynamicsWorld); + + //remove the rigidbodies from the dynamics world and delete them + int i; + for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) + { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int j=0;jsetGravity(btVector3(0,0,0)); + btTransform tr; + tr.setIdentity(); + +//either use heightfield or triangle mesh +#define USE_TRIMESH_GROUND 1 +#ifdef USE_TRIMESH_GROUND + int i; + +const float TRIANGLE_SIZE=20.f; + + //create a triangle-mesh ground + int vertStride = sizeof(btVector3); + int indexStride = 3*sizeof(int); + + const int NUM_VERTS_X = 20; + const int NUM_VERTS_Y = 20; + const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y; + + const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1); + + m_vertices = new btVector3[totalVerts]; + int* gIndices = new int[totalTriangles*3]; + + + + for ( i=0;isetUseDiamondSubdivision(true); + + btVector3 localScaling(20,20,20); + localScaling[upIndex]=1.f; + groundShape->setLocalScaling(localScaling); + + tr.setOrigin(btVector3(0,-64.5f,0)); + +#endif // + + m_collisionShapes.push_back(groundShape); + //create ground object + localCreateRigidBody(0,tr,groundShape); + + m_character = new CharacterController (); + m_character->setup (m_dynamicsWorld); + +#define CUBE_HALF_EXTENTS 0.5 +#define EXTRA_HEIGHT 10.0 + btBoxShape* boxShape = new btBoxShape (btVector3(1.0, 1.0, 1.0)); + m_collisionShapes.push_back (boxShape); +#define DO_WALL +#ifdef DO_WALL + for (i=0;i<50;i++) + { + btCollisionShape* shape = boxShape; + //shape->setMargin(gCollisionMargin); + + bool isDyna = i>0; + + btTransform trans; + trans.setIdentity(); + + if (i>0) + { + //stack them + int colsize = 10; + int row = (i*CUBE_HALF_EXTENTS*2)/(colsize*2*CUBE_HALF_EXTENTS); + int row2 = row; + int col = (i)%(colsize)-colsize/2; + + + if (col>3) + { + col=11; + row2 |=1; + } + + btVector3 pos(col*2*CUBE_HALF_EXTENTS + (row2%2)*CUBE_HALF_EXTENTS, + row*2*CUBE_HALF_EXTENTS+CUBE_HALF_EXTENTS+EXTRA_HEIGHT,0); + + trans.setOrigin(pos); + } else + { + trans.setOrigin(btVector3(0,EXTRA_HEIGHT-CUBE_HALF_EXTENTS,0)); + } + + float mass = 1.f; + + if (!isDyna) + mass = 0.f; + + btRigidBody* body = localCreateRigidBody(mass,trans,shape); +#ifdef USE_KINEMATIC_GROUND + if (mass == 0.f) + { + body->setCollisionFlags( body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); + body->setActivationState(DISABLE_DEACTIVATION); + } +#endif //USE_KINEMATIC_GROUND + + } +#endif + + clientResetScene(); + + setCameraDistance(26.f); + +} + + +//to be implemented by the demo +void CharacterDemo::renderme() +{ + + updateCamera(); + + btScalar m[16]; + int i; + DemoApplication::renderme(); +} + +void CharacterDemo::clientMoveAndDisplay() +{ + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + float dt = getDeltaTimeMicroseconds() * 0.000001f; + + /* Character stuff &*/ + if (m_character) + { + m_character->preStep (m_dynamicsWorld); + m_character->playerStep (dt, gForward, gBackward, gLeft, gRight); + if (gJump) + { + gJump = 0; + m_character->jump (); + } + } + + if (m_dynamicsWorld) + { + //during idle mode, just run 1 simulation step maximum + int maxSimSubSteps = m_idle ? 1 : 2; + if (m_idle) + dt = 1.0/420.f; + + int numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + + +//#define VERBOSE_FEEDBACK +#ifdef VERBOSE_FEEDBACK + if (!numSimSteps) + printf("Interpolated transforms\n"); + else + { + if (numSimSteps > maxSimSubSteps) + { + //detect dropping frames + printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps); + } else + { + printf("Simulated (%i) steps\n",numSimSteps); + } + } +#endif //VERBOSE_FEEDBACK + + } + + + + + + + +#ifdef USE_QUICKPROF + btProfiler::beginBlock("render"); +#endif //USE_QUICKPROF + + + renderme(); + +#ifdef USE_QUICKPROF + btProfiler::endBlock("render"); +#endif + + + glFlush(); + glutSwapBuffers(); + +} + + + +void CharacterDemo::displayCallback(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + + glFlush(); + glutSwapBuffers(); +} + + + +void CharacterDemo::clientResetScene() +{ + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_character->getRigidBody()->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); +} + +void CharacterDemo::specialKeyboardUp(int key, int x, int y) +{ + switch (key) + { + case GLUT_KEY_UP: + { + gForward = 0; + } + break; + case GLUT_KEY_DOWN: + { + gBackward = 0; + } + break; + case GLUT_KEY_LEFT: + { + gLeft = 0; + } + break; + case GLUT_KEY_RIGHT: + { + gRight = 0; + } + break; + default: + DemoApplication::specialKeyboardUp(key,x,y); + break; + } +} + + +void CharacterDemo::specialKeyboard(int key, int x, int y) +{ + +// printf("key = %i x=%i y=%i\n",key,x,y); + + switch (key) + { + case GLUT_KEY_UP: + { + gForward = 1; + } + break; + case GLUT_KEY_DOWN: + { + gBackward = 1; + } + break; + case GLUT_KEY_LEFT: + { + gLeft = 1; + } + break; + case GLUT_KEY_RIGHT: + { + gRight = 1; + } + break; + case GLUT_KEY_END: + { + if (m_character && m_character->canJump()) + gJump = 1; + } + break; + default: + DemoApplication::specialKeyboard(key,x,y); + break; + } + +// glutPostRedisplay(); + + +} + +void CharacterDemo::updateCamera() +{ + +//#define DISABLE_CAMERA 1 +#ifdef DISABLE_CAMERA + DemoApplication::updateCamera(); + return; +#endif //DISABLE_CAMERA + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + btTransform characterWorldTrans; + + //look at the vehicle + m_character->getRigidBody()->getMotionState()->getWorldTransform(characterWorldTrans); + btVector3 up = characterWorldTrans.getBasis()[1]; + btVector3 backward = -characterWorldTrans.getBasis()[2]; + up.normalize (); + backward.normalize (); + + m_cameraTargetPosition = characterWorldTrans.getOrigin(); + m_cameraPosition = m_cameraTargetPosition + up * 5.0 + backward * 5.0; + + //update OpenGL camera settings + glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 10000.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + gluLookAt(m_cameraPosition[0],m_cameraPosition[1],m_cameraPosition[2], + m_cameraTargetPosition[0],m_cameraTargetPosition[1], m_cameraTargetPosition[2], + m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ()); + + + +} + diff --git a/Demos/CharacterDemo/CharacterDemo.h b/Demos/CharacterDemo/CharacterDemo.h new file mode 100644 index 000000000..44f2e3df5 --- /dev/null +++ b/Demos/CharacterDemo/CharacterDemo.h @@ -0,0 +1,85 @@ +/* +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 CHARACTER_DEMO_H +#define CHARACTER_DEMO_H + +class CharacterController; + +class btCollisionShape; + + +#include "DemoApplication.h" + +///CharacterDemo shows how to setup and use the built-in raycast vehicle +class CharacterDemo : public DemoApplication +{ + public: + + CharacterController* m_character; + + btAlignedObjectArray m_collisionShapes; + + class btBroadphaseInterface* m_overlappingPairCache; + + class btCollisionDispatcher* m_dispatcher; + + class btConstraintSolver* m_constraintSolver; + + class btDefaultCollisionConfiguration* m_collisionConfiguration; + + class btTriangleIndexVertexArray* m_indexVertexArrays; + + btVector3* m_vertices; + + + float m_cameraHeight; + + float m_minCameraDistance; + float m_maxCameraDistance; + + + CharacterDemo(); + + virtual ~CharacterDemo(); + + virtual void clientMoveAndDisplay(); + + virtual void clientResetScene(); + + virtual void displayCallback(); + + ///a very basic camera following the vehicle + virtual void updateCamera(); + + virtual void specialKeyboard(int key, int x, int y); + + virtual void specialKeyboardUp(int key, int x, int y); + + void renderme(); + + void initPhysics(); + + static DemoApplication* Create() + { + CharacterDemo* demo = new CharacterDemo(); + demo->myinit(); + demo->initPhysics(); + return demo; + } +}; + +#endif //CHARACTER_DEMO_H + + diff --git a/Demos/CharacterDemo/main.cpp b/Demos/CharacterDemo/main.cpp new file mode 100644 index 000000000..b60016ccd --- /dev/null +++ b/Demos/CharacterDemo/main.cpp @@ -0,0 +1,15 @@ + +#include "CharacterDemo.h" +#include "GlutStuff.h" + + +int main(int argc,char** argv) +{ + + CharacterDemo* characterDemo = new CharacterDemo; + + characterDemo->initPhysics(); + + return glutmain(argc, argv,640,480,"Bullet Character Demo. http://www.continuousphysics.com/Bullet/phpBB2/", characterDemo); +} +