diff --git a/Demos/CharacterDemo/CharacterDemo.cpp b/Demos/CharacterDemo/CharacterDemo.cpp index 00ea47309..ebb2bc968 100644 --- a/Demos/CharacterDemo/CharacterDemo.cpp +++ b/Demos/CharacterDemo/CharacterDemo.cpp @@ -1,522 +1,531 @@ -/* -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()); - - - -} - +/* +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()); + + btTransform startTransform; + startTransform.setIdentity (); + startTransform.setOrigin (btVector3(0.0, 2.0, 0.0)); + + m_character->getRigidBody()->getMotionState()->setWorldTransform(startTransform); + m_character->getRigidBody()->setLinearVelocity(btVector3(0,0,0)); + m_character->getRigidBody()->setAngularVelocity(btVector3(0,0,0)); + +} + +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_F1: + { + 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/ConcaveDemo/ConcaveDemo.h b/Demos/ConcaveDemo/ConcaveDemo.h index 00be1139f..989673f48 100644 --- a/Demos/ConcaveDemo/ConcaveDemo.h +++ b/Demos/ConcaveDemo/ConcaveDemo.h @@ -49,7 +49,7 @@ class ConcaveDemo : public DemoApplication public: - ConcaveDemo() : m_animatedMesh(false) + ConcaveDemo() : m_animatedMesh(true) { } diff --git a/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp b/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp index d61ddc797..10a187a3d 100644 --- a/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp +++ b/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp @@ -315,12 +315,33 @@ void ConcaveDemo::clientMoveAndDisplay() static float offset=0.f; offset+=0.01f; - setVertexPositions(waveheight,offset); + // setVertexPositions(waveheight,offset); + + int i; + int j; + btVector3 aabbMin(1e30,1e30,1e30); + btVector3 aabbMax(-1e30,-1e30,-1e30); - btVector3 worldMin(-1000,-1000,-1000); - btVector3 worldMax(1000,1000,1000); + for ( i=NUM_VERTS_X/2-3;irefitTree(worldMin,worldMax); + } + } + + trimeshShape->partialRefitTree(aabbMin,aabbMax); //clear all contact points involving mesh proxy. Note: this is a slow/unoptimized operation. m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); diff --git a/Demos/Jamfile b/Demos/Jamfile index 3d929c1b4..ef2fb992d 100644 --- a/Demos/Jamfile +++ b/Demos/Jamfile @@ -71,6 +71,7 @@ SubInclude TOP Demos BspDemo ; SubInclude TOP Demos BasicDemo ; SubInclude TOP Demos ConvexDecompositionDemo ; SubInclude TOP Demos ColladaDemo ; +SubInclude TOP Demos CharacterDemo ; SubInclude TOP Demos VehicleDemo ; SubInclude TOP Demos CollisionDemo ; SubInclude TOP Demos CollisionInterfaceDemo ; diff --git a/Demos/OpenGL/Jamfile b/Demos/OpenGL/Jamfile index 4dc3473ec..5290dff04 100644 --- a/Demos/OpenGL/Jamfile +++ b/Demos/OpenGL/Jamfile @@ -12,7 +12,7 @@ if $(GLUT.AVAILABLE) = "yes" CFlags bulletopenglsupport : [ FIncludes $(TOP)/Extras/ConvexHull ] ; - MsvcIncDirs $(<) : + MsvcIncDirs bulletopenglsupport : "../../Extras/ConvexHull" ; bulletopenglsupport.CFLAGS = [ FIncludes $(TOP)/Extras/ConvexHull ] ;