Back to index

supertuxkart  0.5+dfsg1
DemoApplication.cpp
Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 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.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 
00017 #include "DemoApplication.h"
00018 #include "LinearMath/btIDebugDraw.h"
00019 #include "BulletDynamics/Dynamics/btDynamicsWorld.h"
00020 
00021 #include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"//picking
00022 #include "BulletCollision/CollisionShapes/btCollisionShape.h"
00023 #include "BulletCollision/CollisionShapes/btBoxShape.h"
00024 #include "BulletCollision/CollisionShapes/btSphereShape.h"
00025 #include "BulletCollision/CollisionShapes/btCompoundShape.h"
00026 #include "BulletCollision/CollisionShapes/btUniformScalingShape.h"
00027 
00028 #include "GL_ShapeDrawer.h"
00029 #include "LinearMath/btQuickprof.h"
00030 #include "LinearMath/btDefaultMotionState.h"
00031 
00032 
00033 #include "BMF_Api.h"
00034 
00035 extern bool gDisableDeactivation;
00036 int numObjects = 0;
00037 const int maxNumObjects = 16384;
00038 btTransform startTransforms[maxNumObjects];
00039 btCollisionShape* gShapePtr[maxNumObjects];//1 rigidbody has 1 shape (no re-use of shapes)
00040 #define SHOW_NUM_DEEP_PENETRATIONS 1
00041 
00042 #ifdef SHOW_NUM_DEEP_PENETRATIONS 
00043 extern int gNumDeepPenetrationChecks;
00044 extern int gNumGjkChecks;
00045 extern int gNumAlignedAllocs;
00046 extern int gNumAlignedFree;
00047 extern int gTotalBytesAlignedAllocs;
00048 
00049 #endif //
00050 
00051 
00052 DemoApplication::DemoApplication()
00053               //see btIDebugDraw.h for modes
00054 :
00055 m_dynamicsWorld(0),
00056 m_pickConstraint(0),
00057 m_shootBoxShape(0),
00058        m_cameraDistance(15.0),
00059        m_debugMode(0),
00060        m_ele(20.f),
00061        m_azi(0.f),
00062        m_cameraPosition(0.f,0.f,0.f),
00063        m_cameraTargetPosition(0.f,0.f,0.f),
00064        m_scaleBottom(0.5f),
00065        m_scaleFactor(2.f),
00066        m_cameraUp(0,1,0),
00067        m_forwardAxis(2),    
00068        m_glutScreenWidth(0),
00069        m_glutScreenHeight(0),
00070        m_ShootBoxInitialSpeed(40.f),
00071        m_stepping(true),
00072        m_singleStep(false),
00073        m_idle(false)
00074 {
00075 #ifndef BT_NO_PROFILE
00076        m_profileIterator = CProfileManager::Get_Iterator();
00077 #endif //BT_NO_PROFILE
00078 }
00079 
00080 
00081 
00082 DemoApplication::~DemoApplication()
00083 {
00084 #ifndef BT_NO_PROFILE
00085        CProfileManager::Release_Iterator(m_profileIterator);
00086 #endif //BT_NO_PROFILE
00087 
00088        if (m_shootBoxShape)
00089               delete m_shootBoxShape;
00090 
00091 }
00092 
00093 
00094 void DemoApplication::myinit(void)
00095 {
00096 
00097     GLfloat light_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
00098     GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
00099     GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
00100     /* light_position is NOT default value       */
00101     GLfloat light_position0[] = { 1.0, 10.0, 1.0, 0.0 };
00102     GLfloat light_position1[] = { -1.0, -10.0, -1.0, 0.0 };
00103   
00104     glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
00105     glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
00106     glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
00107     glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
00108   
00109     glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
00110     glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
00111     glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
00112     glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
00113 
00114     glEnable(GL_LIGHTING);
00115     glEnable(GL_LIGHT0);
00116     glEnable(GL_LIGHT1);
00117  
00118 
00119     glShadeModel(GL_SMOOTH);
00120     glEnable(GL_DEPTH_TEST);
00121     glDepthFunc(GL_LESS);
00122 
00123               glClearColor(0.7,0.7,0.7,0);
00124 
00125     //  glEnable(GL_CULL_FACE);
00126     //  glCullFace(GL_BACK);
00127 }
00128 
00129 
00130 void   DemoApplication::setCameraDistance(float dist)
00131 {
00132        m_cameraDistance  = dist;
00133 }
00134 
00135 float  DemoApplication::getCameraDistance()
00136 {
00137        return m_cameraDistance;
00138 }
00139 
00140 
00141 
00142 void DemoApplication::toggleIdle() {
00143     if (m_idle) {
00144         m_idle = false;
00145     }
00146     else {
00147         m_idle = true;
00148     }
00149 }
00150 
00151 
00152 
00153 
00154 void DemoApplication::updateCamera() {
00155 
00156        
00157        glMatrixMode(GL_PROJECTION);
00158        glLoadIdentity();
00159        float rele = m_ele * 0.01745329251994329547;// rads per deg
00160        float razi = m_azi * 0.01745329251994329547;// rads per deg
00161        
00162 
00163        btQuaternion rot(m_cameraUp,razi);
00164 
00165 
00166        btVector3 eyePos(0,0,0);
00167        eyePos[m_forwardAxis] = -m_cameraDistance;
00168 
00169        btVector3 forward(eyePos[0],eyePos[1],eyePos[2]);
00170        if (forward.length2() < SIMD_EPSILON)
00171        {
00172               forward.setValue(1.f,0.f,0.f);
00173        }
00174        btVector3 right = m_cameraUp.cross(forward);
00175        btQuaternion roll(right,-rele);
00176 
00177        eyePos = btMatrix3x3(rot) * btMatrix3x3(roll) * eyePos;
00178 
00179        m_cameraPosition[0] = eyePos.getX();
00180        m_cameraPosition[1] = eyePos.getY();
00181        m_cameraPosition[2] = eyePos.getZ();
00182 
00183        if (m_glutScreenWidth > m_glutScreenHeight) 
00184        {
00185               btScalar aspect = m_glutScreenWidth / (btScalar)m_glutScreenHeight;
00186               glFrustum (-aspect, aspect, -1.0, 1.0, 1.0, 10000.0);
00187        } else 
00188        {
00189               btScalar aspect = m_glutScreenHeight / (btScalar)m_glutScreenWidth;
00190               glFrustum (-1.0, 1.0, -aspect, aspect, 1.0, 10000.0);
00191        }
00192 
00193 
00194     glMatrixMode(GL_MODELVIEW);
00195        glLoadIdentity();
00196        gluLookAt(m_cameraPosition[0], m_cameraPosition[1], m_cameraPosition[2], 
00197               m_cameraTargetPosition[0], m_cameraTargetPosition[1], m_cameraTargetPosition[2], 
00198                        m_cameraUp.getX(),m_cameraUp.getY(),m_cameraUp.getZ());
00199 }
00200 
00201 
00202 
00203 const float STEPSIZE = 5;
00204 
00205 void DemoApplication::stepLeft() 
00206 { 
00207        m_azi -= STEPSIZE; if (m_azi < 0) m_azi += 360; updateCamera(); 
00208 }
00209 void DemoApplication::stepRight() 
00210 { 
00211        m_azi += STEPSIZE; if (m_azi >= 360) m_azi -= 360; updateCamera(); 
00212 }
00213 void DemoApplication::stepFront() 
00214 { 
00215        m_ele += STEPSIZE; if (m_ele >= 360) m_ele -= 360; updateCamera(); 
00216 }
00217 void DemoApplication::stepBack() 
00218 { 
00219        m_ele -= STEPSIZE; if (m_ele < 0) m_ele += 360; updateCamera(); 
00220 }
00221 void DemoApplication::zoomIn() 
00222 { 
00223        m_cameraDistance -= 0.4; updateCamera(); 
00224        if (m_cameraDistance < 0.1)
00225               m_cameraDistance = 0.1;
00226 
00227 }
00228 void DemoApplication::zoomOut() 
00229 { 
00230        m_cameraDistance += 0.4; updateCamera(); 
00231        
00232 }
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242        
00243 void DemoApplication::reshape(int w, int h) 
00244 {
00245        m_glutScreenWidth = w;
00246        m_glutScreenHeight = h;
00247        
00248        glViewport(0, 0, w, h);
00249        updateCamera();
00250 }
00251 
00252 
00253 void DemoApplication::keyboardCallback(unsigned char key, int x, int y)
00254 {
00255        (void)x;
00256        (void)y;
00257 
00258               m_lastKey = 0;
00259 
00260 #ifndef BT_NO_PROFILE
00261         if (key >= 0x31 && key < 0x37)
00262         {
00263                 int child = key-0x31;
00264                 m_profileIterator->Enter_Child(child);
00265         }
00266         if (key==0x30)
00267         {
00268                 m_profileIterator->Enter_Parent();
00269         }
00270 #endif //BT_NO_PROFILE
00271 
00272     switch (key) 
00273     {
00274     case 'q' : 
00275 #ifdef BT_USE_FREEGLUT
00276               //return from glutMainLoop(), detect memory leaks etc.
00277               glutLeaveMainLoop();
00278 #else
00279               exit(0);
00280 #endif
00281               break;
00282 
00283     case 'l' : stepLeft(); break;
00284     case 'r' : stepRight(); break;
00285     case 'f' : stepFront(); break;
00286     case 'b' : stepBack(); break;
00287     case 'z' : zoomIn(); break;
00288     case 'x' : zoomOut(); break;
00289     case 'i' : toggleIdle(); break;
00290        case 'h':
00291                      if (m_debugMode & btIDebugDraw::DBG_NoHelpText)
00292                             m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoHelpText);
00293                      else
00294                             m_debugMode |= btIDebugDraw::DBG_NoHelpText;
00295                      break;
00296 
00297        case 'w':
00298                      if (m_debugMode & btIDebugDraw::DBG_DrawWireframe)
00299                             m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawWireframe);
00300                      else
00301                             m_debugMode |= btIDebugDraw::DBG_DrawWireframe;
00302                  break;
00303 
00304    case 'p':
00305           if (m_debugMode & btIDebugDraw::DBG_ProfileTimings)
00306               m_debugMode = m_debugMode & (~btIDebugDraw::DBG_ProfileTimings);
00307        else
00308               m_debugMode |= btIDebugDraw::DBG_ProfileTimings;
00309    break;
00310 
00311    case 'm':
00312           if (m_debugMode & btIDebugDraw::DBG_EnableSatComparison)
00313               m_debugMode = m_debugMode & (~btIDebugDraw::DBG_EnableSatComparison);
00314        else
00315               m_debugMode |= btIDebugDraw::DBG_EnableSatComparison;
00316    break;
00317 
00318    case 'n':
00319           if (m_debugMode & btIDebugDraw::DBG_DisableBulletLCP)
00320               m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DisableBulletLCP);
00321        else
00322               m_debugMode |= btIDebugDraw::DBG_DisableBulletLCP;
00323    break;
00324 
00325        case 't' : 
00326                      if (m_debugMode & btIDebugDraw::DBG_DrawText)
00327                             m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawText);
00328                      else
00329                             m_debugMode |= btIDebugDraw::DBG_DrawText;
00330                  break;
00331        case 'y':            
00332                      if (m_debugMode & btIDebugDraw::DBG_DrawFeaturesText)
00333                             m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawFeaturesText);
00334                      else
00335                             m_debugMode |= btIDebugDraw::DBG_DrawFeaturesText;
00336               break;
00337        case 'a':     
00338               if (m_debugMode & btIDebugDraw::DBG_DrawAabb)
00339                             m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawAabb);
00340                      else
00341                             m_debugMode |= btIDebugDraw::DBG_DrawAabb;
00342                      break;
00343               case 'c' : 
00344                      if (m_debugMode & btIDebugDraw::DBG_DrawContactPoints)
00345                             m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawContactPoints);
00346                      else
00347                             m_debugMode |= btIDebugDraw::DBG_DrawContactPoints;
00348                      break;
00349 
00350               case 'd' : 
00351                      if (m_debugMode & btIDebugDraw::DBG_NoDeactivation)
00352                             m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoDeactivation);
00353                      else
00354                             m_debugMode |= btIDebugDraw::DBG_NoDeactivation;
00355                      if (m_debugMode & btIDebugDraw::DBG_NoDeactivation)
00356                      {
00357                             gDisableDeactivation = true;
00358                      } else
00359                      {
00360                             gDisableDeactivation = false;
00361                      }
00362                      break;
00363                      
00364 
00365               
00366 
00367        case 'o' :
00368               {
00369                      m_stepping = !m_stepping;
00370                      break;
00371               }
00372        case 's' : clientMoveAndDisplay(); break;
00373 //    case ' ' : newRandom(); break;
00374        case ' ':
00375               clientResetScene();
00376                      break;
00377        case '1':
00378               {
00379                      if (m_debugMode & btIDebugDraw::DBG_EnableCCD)
00380                             m_debugMode = m_debugMode & (~btIDebugDraw::DBG_EnableCCD);
00381                      else
00382                             m_debugMode |= btIDebugDraw::DBG_EnableCCD;
00383                      break;
00384               }
00385 
00386               case '.':
00387               {
00388                      shootBox(getCameraTargetPosition());
00389                      break;
00390               }
00391 
00392               case '+':
00393               {
00394                      m_ShootBoxInitialSpeed += 10.f;
00395                      break;
00396               }
00397               case '-':
00398               {
00399                      m_ShootBoxInitialSpeed -= 10.f;
00400                      break;
00401               }
00402 
00403     default:
00404 //        std::cout << "unused key : " << key << std::endl;
00405         break;
00406     }
00407 
00408        if (getDynamicsWorld() && getDynamicsWorld()->getDebugDrawer())
00409               getDynamicsWorld()->getDebugDrawer()->setDebugMode(m_debugMode);
00410 
00411        glutPostRedisplay();
00412 
00413 }
00414        
00415 void   DemoApplication::setDebugMode(int mode)
00416 {
00417        m_debugMode = mode;
00418        if (getDynamicsWorld() && getDynamicsWorld()->getDebugDrawer())
00419               getDynamicsWorld()->getDebugDrawer()->setDebugMode(mode);
00420 }
00421 
00422 
00423 void DemoApplication::specialKeyboardUp(int key, int x, int y)
00424 {
00425 
00426               glutPostRedisplay();
00427 
00428 }
00429 
00430 void DemoApplication::specialKeyboard(int key, int x, int y)   
00431 {
00432        (void)x;
00433        (void)y;
00434 
00435     switch (key) 
00436     {
00437        case GLUT_KEY_F1:
00438               {
00439 
00440                      break;
00441               }
00442 
00443        case GLUT_KEY_F2:
00444        {
00445 
00446               break;
00447        }
00448 
00449 
00450        case GLUT_KEY_END:
00451               {
00452                      int numObj = getDynamicsWorld()->getNumCollisionObjects();
00453                      if (numObj)
00454                      {
00455                             btCollisionObject* obj = getDynamicsWorld()->getCollisionObjectArray()[numObj-1];
00456                             
00457                             getDynamicsWorld()->removeCollisionObject(obj);
00458                             btRigidBody* body = btRigidBody::upcast(obj);
00459                             if (body && body->getMotionState())
00460                             {
00461                                    delete body->getMotionState();                                 
00462                             }
00463                             delete obj;
00464                             
00465 
00466                      }
00467                      break;
00468               }
00469     case GLUT_KEY_LEFT : stepLeft(); break;
00470     case GLUT_KEY_RIGHT : stepRight(); break;
00471     case GLUT_KEY_UP : stepFront(); break;
00472     case GLUT_KEY_DOWN : stepBack(); break;
00473     case GLUT_KEY_PAGE_UP : zoomIn(); break;
00474     case GLUT_KEY_PAGE_DOWN : zoomOut(); break;
00475     case GLUT_KEY_HOME : toggleIdle(); break;
00476     default:
00477 //        std::cout << "unused (special) key : " << key << std::endl;
00478         break;
00479     }
00480 
00481        glutPostRedisplay();
00482 
00483 }
00484 
00485 
00486 
00487 void DemoApplication::moveAndDisplay()
00488 {
00489        if (!m_idle)
00490               clientMoveAndDisplay();
00491 }
00492 
00493 
00494 
00495        
00496 void DemoApplication::displayCallback()
00497 {
00498 }
00499 
00500 
00501 
00502 
00503 void   DemoApplication::shootBox(const btVector3& destination)
00504 {
00505 
00506        if (m_dynamicsWorld)
00507        {
00508               float mass = 10.f;
00509               btTransform startTransform;
00510               startTransform.setIdentity();
00511               btVector3 camPos = getCameraPosition();
00512               startTransform.setOrigin(camPos);
00513 
00514               if (!m_shootBoxShape)
00515               {
00516               //#define TEST_UNIFORM_SCALING_SHAPE 1
00517 #ifdef TEST_UNIFORM_SCALING_SHAPE
00518               btConvexShape* childShape = new btBoxShape(btVector3(1.f,1.f,1.f));
00519               m_shootBoxShape = new btUniformScalingShape(childShape,0.5f);
00520 #else
00521               m_shootBoxShape = new btBoxShape(btVector3(1.f,1.f,1.f));
00522 #endif//
00523               }
00524 
00525               btRigidBody* body = this->localCreateRigidBody(mass, startTransform,m_shootBoxShape);
00526 
00527               btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]);
00528               linVel.normalize();
00529               linVel*=m_ShootBoxInitialSpeed;
00530 
00531               body->getWorldTransform().setOrigin(camPos);
00532               body->getWorldTransform().setRotation(btQuaternion(0,0,0,1));
00533               body->setLinearVelocity(linVel);
00534               body->setAngularVelocity(btVector3(0,0,0));
00535        }
00536 
00537 }
00538 
00539 
00540 int gPickingConstraintId = 0;
00541 btVector3 gOldPickingPos;
00542 float gOldPickingDist  = 0.f;
00543 btRigidBody* pickedBody = 0;//for deactivation state
00544 
00545 
00546 btVector3     DemoApplication::getRayTo(int x,int y)
00547 {
00548 
00549               float top = 1.f;
00550        float bottom = -1.f;
00551        float nearPlane = 1.f;
00552        float tanFov = (top-bottom)*0.5f / nearPlane;
00553        float fov = 2.0 * atanf (tanFov);
00554 
00555        btVector3     rayFrom = getCameraPosition();
00556        btVector3 rayForward = (getCameraTargetPosition()-getCameraPosition());
00557        rayForward.normalize();
00558        float farPlane = 10000.f;
00559        rayForward*= farPlane;
00560 
00561        btVector3 rightOffset;
00562        btVector3 vertical = m_cameraUp;
00563 
00564        btVector3 hor;
00565        hor = rayForward.cross(vertical);
00566        hor.normalize();
00567        vertical = hor.cross(rayForward);
00568        vertical.normalize();
00569 
00570        float tanfov = tanf(0.5f*fov);
00571        
00572        btScalar aspect = m_glutScreenHeight / (btScalar)m_glutScreenWidth;
00573 
00574        hor *= 2.f * farPlane * tanfov;
00575        vertical *= 2.f * farPlane * tanfov;
00576 
00577        if (aspect<1)
00578        {
00579               hor/=aspect;
00580        } else
00581        {
00582               vertical*=aspect;
00583        }
00584 
00585        btVector3 rayToCenter = rayFrom + rayForward;
00586        btVector3 dHor = hor * 1.f/float(m_glutScreenWidth);
00587        btVector3 dVert = vertical * 1.f/float(m_glutScreenHeight);
00588        
00589 
00590        btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
00591        rayTo += x * dHor;
00592        rayTo -= y * dVert;
00593        return rayTo;
00594 }
00595 
00596 
00597 void DemoApplication::mouseFunc(int button, int state, int x, int y)
00598 {
00599        //printf("button %i, state %i, x=%i,y=%i\n",button,state,x,y);
00600        //button 0, state 0 means left mouse down
00601 
00602        btVector3 rayTo = getRayTo(x,y);
00603 
00604        switch (button)
00605        {
00606        case 2:
00607               {
00608                      if (state==0)
00609                      {
00610 
00611                             shootBox(rayTo);
00612                      }
00613                      break;
00614               };
00615        case 1:
00616               {
00617 
00618 
00619                      if (state==0)
00620                      {
00621                             
00622 
00623                             //apply an impulse
00624                             if (m_dynamicsWorld)
00625                             {
00626                                    btCollisionWorld::ClosestRayResultCallback rayCallback(m_cameraPosition,rayTo);
00627                                    m_dynamicsWorld->rayTest(m_cameraPosition,rayTo,rayCallback);
00628                                    if (rayCallback.HasHit())
00629                                    {
00630                                           
00631                                           btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
00632                                           if (body)
00633                                           {
00634                                                         body->setActivationState(ACTIVE_TAG);
00635                                                         btVector3 impulse = rayTo;
00636                                                         impulse.normalize();
00637                                                         float impulseStrength = 10.f;
00638                                                         impulse *= impulseStrength;
00639                                                         btVector3 relPos = rayCallback.m_hitPointWorld - body->getCenterOfMassPosition();
00640                                                         body->applyImpulse(impulse,relPos);
00641                                                  }
00642                                    }
00643                             }
00644 
00645                             
00646 
00647                      } else
00648                      {
00649 
00650                      }
00651                      break; 
00652               }
00653        case 0:
00654               {
00655                      if (state==0)
00656                      {
00657               
00658 
00659                             //add a point to point constraint for picking
00660                             if (m_dynamicsWorld)
00661                             {
00662                                    btCollisionWorld::ClosestRayResultCallback rayCallback(m_cameraPosition,rayTo);
00663                                    m_dynamicsWorld->rayTest(m_cameraPosition,rayTo,rayCallback);
00664                                    if (rayCallback.HasHit())
00665                                    {
00666                                           
00667                                           
00668                                           btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
00669                                           if (body)
00670                                           {
00671                                                  //other exclusions?
00672                                                  if (!(body->isStaticObject() || body->isKinematicObject()))
00673                                                  {
00674                                                         pickedBody = body;
00675                                                         pickedBody->setActivationState(DISABLE_DEACTIVATION);
00676 
00677                                                         
00678                                                         btVector3 pickPos = rayCallback.m_hitPointWorld;
00679 
00680                                                         btVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos;
00681 
00682                                                         btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body,localPivot);
00683                                                         m_dynamicsWorld->addConstraint(p2p);
00684                                                         m_pickConstraint = p2p;
00685                                                         
00686                                                         //save mouse position for dragging
00687                                                         gOldPickingPos = rayTo;
00688 
00689                                                         btVector3 eyePos(m_cameraPosition[0],m_cameraPosition[1],m_cameraPosition[2]);
00690 
00691                                                         gOldPickingDist  = (pickPos-eyePos).length();
00692 
00693                                                         //very weak constraint for picking
00694                                                         p2p->m_setting.m_tau = 0.1f;
00695                                                  }
00696                                           }
00697                                    }
00698                             }
00699 
00700                      } else
00701                      {
00702 
00703                             if (m_pickConstraint && m_dynamicsWorld)
00704                             {
00705                                    m_dynamicsWorld->removeConstraint(m_pickConstraint);
00706                                    delete m_pickConstraint;
00707                                    //printf("removed constraint %i",gPickingConstraintId);
00708                                    m_pickConstraint = 0;
00709                                    pickedBody->forceActivationState(ACTIVE_TAG);
00710                                    pickedBody->setDeactivationTime( 0.f );
00711                                    pickedBody = 0;
00712                             }
00713 
00714                             
00715                      }
00716 
00717                      break;
00718 
00719               }
00720        default:
00721               {
00722               }
00723        }
00724 
00725 }
00726 
00727 void   DemoApplication::mouseMotionFunc(int x,int y)
00728 {
00729 
00730        if (m_pickConstraint)
00731        {
00732               //move the constraint pivot
00733               btPoint2PointConstraint* p2p = static_cast<btPoint2PointConstraint*>(m_pickConstraint);
00734               if (p2p)
00735               {
00736                      //keep it at the same picking distance
00737 
00738                      btVector3 newRayTo = getRayTo(x,y);
00739                      btVector3 eyePos(m_cameraPosition[0],m_cameraPosition[1],m_cameraPosition[2]);
00740                      btVector3 dir = newRayTo-eyePos;
00741                      dir.normalize();
00742                      dir *= gOldPickingDist;
00743 
00744                      btVector3 newPos = eyePos + dir;
00745                      p2p->setPivotB(newPos);
00746               }
00747 
00748        }
00749 
00750        
00751 }
00752 
00753 
00754 
00755 btRigidBody*  DemoApplication::localCreateRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape)
00756 {
00757        //rigidbody is dynamic if and only if mass is non zero, otherwise static
00758        bool isDynamic = (mass != 0.f);
00759 
00760        btVector3 localInertia(0,0,0);
00761        if (isDynamic)
00762               shape->calculateLocalInertia(mass,localInertia);
00763 
00764        //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
00765 
00766 #define USE_MOTIONSTATE 1
00767 #ifdef USE_MOTIONSTATE
00768        btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
00769 
00770        btRigidBody::btRigidBodyConstructionInfo cInfo(mass,myMotionState,shape,localInertia);
00771 
00772        btRigidBody* body = new btRigidBody(cInfo);
00773 
00774 #else
00775        btRigidBody* body = new btRigidBody(mass,0,shape,localInertia);       
00776        body->setWorldTransform(startTransform);
00777 #endif//
00778 
00779        m_dynamicsWorld->addRigidBody(body);
00780        
00781        return body;
00782 }
00783 
00784 //See http://www.lighthouse3d.com/opengl/glut/index.php?bmpfontortho
00785 void DemoApplication::setOrthographicProjection() 
00786 {
00787 
00788        // switch to projection mode
00789        glMatrixMode(GL_PROJECTION);
00790 
00791        // save previous matrix which contains the 
00792        //settings for the perspective projection
00793        glPushMatrix();
00794        // reset matrix
00795        glLoadIdentity();
00796        // set a 2D orthographic projection
00797        gluOrtho2D(0, m_glutScreenWidth, 0, m_glutScreenHeight);
00798        glMatrixMode(GL_MODELVIEW);
00799        glLoadIdentity();
00800 
00801        // invert the y axis, down is positive
00802        glScalef(1, -1, 1);
00803        // mover the origin from the bottom left corner
00804        // to the upper left corner
00805        glTranslatef(0, -m_glutScreenHeight, 0);
00806 
00807 }
00808 
00809 void DemoApplication::resetPerspectiveProjection() 
00810 {
00811 
00812        glMatrixMode(GL_PROJECTION);
00813        glPopMatrix();
00814        glMatrixMode(GL_MODELVIEW);
00815        updateCamera();
00816 }
00817 
00818 
00819 
00820 
00821 extern CProfileIterator * m_profileIterator;
00822 
00823 void DemoApplication::displayProfileString(int xOffset,int yStart,char* message)
00824 {
00825        glRasterPos3f(xOffset,yStart,0);
00826        BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),message);
00827 }
00828 
00829 
00830 void DemoApplication::showProfileInfo(float& xOffset,float& yStart, float yIncr)
00831 {
00832 #ifndef BT_NO_PROFILE
00833 
00834        static double time_since_reset = 0.f;
00835        if (!m_idle)
00836        {
00837                      time_since_reset = CProfileManager::Get_Time_Since_Reset();
00838        }
00839 
00840 
00841        {
00842               //recompute profiling data, and store profile strings
00843 
00844               char blockTime[128];
00845 
00846               double totalTime = 0;
00847               
00848               int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
00849 
00850               m_profileIterator->First();
00851 
00852               double parent_time = m_profileIterator->Is_Root() ? time_since_reset : m_profileIterator->Get_Current_Parent_Total_Time();
00853 
00854               {
00855                      sprintf(blockTime,"--- Profiling: %s (total running time: %.3f ms) ---",     m_profileIterator->Get_Current_Parent_Name(), parent_time );
00856                      displayProfileString(xOffset,yStart,blockTime);
00857                      yStart += yIncr;
00858                      sprintf(blockTime,"press number (1,2...) to display child timings, or 0 to go up to parent" );
00859                      displayProfileString(xOffset,yStart,blockTime);
00860                      yStart += yIncr;
00861 
00862               }
00863 
00864 
00865               double accumulated_time = 0.f;
00866 
00867               for (int i = 0; !m_profileIterator->Is_Done(); m_profileIterator->Next())
00868               {
00869                      double current_total_time = m_profileIterator->Get_Current_Total_Time();
00870                      accumulated_time += current_total_time;
00871                      double fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
00872 
00873                      sprintf(blockTime,"%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)",
00874                             ++i, m_profileIterator->Get_Current_Name(), fraction,
00875                             (current_total_time / (double)frames_since_reset),m_profileIterator->Get_Current_Total_Calls());
00876                      displayProfileString(xOffset,yStart,blockTime);
00877                      yStart += yIncr;
00878                      totalTime += current_total_time;
00879               }
00880 
00881               sprintf(blockTime,"%s (%.3f %%) :: %.3f ms", "Unaccounted",
00882                      // (min(0, time_since_reset - totalTime) / time_since_reset) * 100);
00883                      parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
00884 
00885               displayProfileString(xOffset,yStart,blockTime);
00886               yStart += yIncr;
00887 
00888 
00889 
00890               sprintf(blockTime,"-------------------------------------------------");
00891               displayProfileString(xOffset,yStart,blockTime);
00892               yStart += yIncr;
00893 
00894        }
00895 #endif//BT_NO_PROFILE
00896 
00897 
00898 
00899 
00900 }
00901 
00902 
00903 void DemoApplication::renderme()
00904 {
00905        updateCamera();
00906 
00907        btScalar m[16];
00908 
00909        if (m_dynamicsWorld)
00910        {
00911               int numObjects = m_dynamicsWorld->getNumCollisionObjects();
00912               btVector3 wireColor(1,0,0);
00913               for (int i=0;i<numObjects;i++)
00914               {
00915                      btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[i];
00916                      btRigidBody* body = btRigidBody::upcast(colObj);
00917 
00918                      if (body && body->getMotionState())
00919                      {
00920                             btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState();
00921                             myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m);
00922                      } else
00923                      {
00924                             colObj->getWorldTransform().getOpenGLMatrix(m);
00925                      }
00926 
00927                      btVector3 wireColor(1.f,1.0f,0.5f); //wants deactivation
00928                      if (i & 1)
00929                      {
00930                             wireColor = btVector3(0.f,0.0f,1.f);
00931                      }
00933                      if (colObj->getActivationState() == 1) //active
00934                      {
00935                             if (i & 1)
00936                             {
00937                                    wireColor += btVector3 (1.f,0.f,0.f);
00938                             } else
00939                             {                    
00940                                    wireColor += btVector3 (.5f,0.f,0.f);
00941                             }
00942                      }
00943                      if (colObj->getActivationState() == 2) //ISLAND_SLEEPING
00944                      {
00945                             if (i & 1)
00946                             {
00947                                    wireColor += btVector3 (0.f,1.f, 0.f);
00948                             } else
00949                             {
00950                                    wireColor += btVector3 (0.f,0.5f,0.f);
00951                             }
00952                      }
00953 
00954                      m_shapeDrawer.drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode());
00955               }
00956 
00957 
00958                      float xOffset = 10.f;
00959                      float yStart = 20.f;
00960                      float yIncr = 20.f;
00961                      char buf[124];
00962 
00963                      glDisable(GL_LIGHTING);
00964                      glColor3f(0, 0, 0);
00965 
00966                      if ((m_debugMode & btIDebugDraw::DBG_NoHelpText)==0)
00967                             {
00968                             setOrthographicProjection();
00969 
00970                             showProfileInfo(xOffset,yStart,yIncr);
00971 
00972        #ifdef USE_QUICKPROF
00973 
00974 
00975                      if ( getDebugMode() & btIDebugDraw::DBG_ProfileTimings)
00976                      {
00977                             static int counter = 0;
00978                             counter++;
00979                             std::map<std::string, hidden::ProfileBlock*>::iterator iter;
00980                             for (iter = btProfiler::mProfileBlocks.begin(); iter != btProfiler::mProfileBlocks.end(); ++iter)
00981                             {
00982                                    char blockTime[128];
00983                                    sprintf(blockTime, "%s: %lf",&((*iter).first[0]),btProfiler::getBlockTime((*iter).first, btProfiler::BLOCK_CYCLE_SECONDS));//BLOCK_TOTAL_PERCENT));
00984                                    glRasterPos3f(xOffset,yStart,0);
00985                                    BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),blockTime);
00986                                    yStart += yIncr;
00987 
00988                             }
00989 
00990                      }
00991        #endif //USE_QUICKPROF
00992 
00993                      
00994                             glRasterPos3f(xOffset,yStart,0);
00995                             sprintf(buf,"mouse to interact");
00996                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
00997                             yStart += yIncr;
00998 
00999                             glRasterPos3f(xOffset,yStart,0);
01000                             sprintf(buf,"space to reset");
01001                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01002                             yStart += yIncr;
01003                      
01004                             glRasterPos3f(xOffset,yStart,0);
01005                             sprintf(buf,"cursor keys and z,x to navigate");
01006                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01007                             yStart += yIncr;
01008 
01009                             glRasterPos3f(xOffset,yStart,0);
01010                             sprintf(buf,"i to toggle simulation, s single step");
01011                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01012                             yStart += yIncr;
01013 
01014                             glRasterPos3f(xOffset,yStart,0);
01015                             sprintf(buf,"q to quit");
01016                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01017                             yStart += yIncr;
01018 
01019                             glRasterPos3f(xOffset,yStart,0);
01020                             sprintf(buf,". to shoot box");
01021                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01022                             yStart += yIncr;
01023 
01024                             // not yet hooked up again after refactoring...
01025 
01026                             glRasterPos3f(xOffset,yStart,0);
01027                             sprintf(buf,"d to toggle deactivation");
01028                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01029                             yStart += yIncr;
01030 
01031                             
01032                             glRasterPos3f(xOffset,yStart,0);
01033                             sprintf(buf,"g to toggle mesh animation (ConcaveDemo)");
01034                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01035                             yStart += yIncr;
01036                      
01037 
01038                             glRasterPos3f(xOffset,yStart,0);
01039                             sprintf(buf,"h to toggle help text");
01040                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01041                             yStart += yIncr;
01042 
01043                             
01044                             glRasterPos3f(xOffset,yStart,0);
01045                             sprintf(buf,"p to toggle profiling (+results to file)");
01046                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01047                             yStart += yIncr;
01048 
01049 
01050                             //bool useBulletLCP = !(getDebugMode() & btIDebugDraw::DBG_DisableBulletLCP);
01051                             //bool useCCD = (getDebugMode() & btIDebugDraw::DBG_EnableCCD);
01052                             //glRasterPos3f(xOffset,yStart,0);
01053                             //sprintf(buf,"1 CCD mode (adhoc) = %i",useCCD);
01054                             //BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01055                             //yStart += yIncr;
01056 
01057 
01058                             glRasterPos3f(xOffset,yStart,0);
01059                             sprintf(buf,"+- shooting speed = %10.2f",m_ShootBoxInitialSpeed);
01060                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01061                             yStart += yIncr;
01062 
01063 #ifdef SHOW_NUM_DEEP_PENETRATIONS
01064                             
01065 
01066                             glRasterPos3f(xOffset,yStart,0);
01067                             sprintf(buf,"gNumDeepPenetrationChecks = %d",gNumDeepPenetrationChecks);
01068                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01069                             yStart += yIncr;
01070 
01071                             glRasterPos3f(xOffset,yStart,0);
01072                             sprintf(buf,"gNumGjkChecks= %d",gNumGjkChecks);
01073                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01074                             yStart += yIncr;
01075 
01076                             
01077                             glRasterPos3f(xOffset,yStart,0);
01078                             sprintf(buf,"gNumAlignedAllocs = %d",gNumAlignedAllocs);
01079                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01080                             yStart += yIncr;
01081 
01082                             glRasterPos3f(xOffset,yStart,0);
01083                             sprintf(buf,"gNumAlignedFree= %d",gNumAlignedFree);
01084                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01085                             yStart += yIncr;
01086 
01087                             glRasterPos3f(xOffset,yStart,0);
01088                             sprintf(buf,"# alloc-free = %d",gNumAlignedAllocs-gNumAlignedFree);
01089                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01090                             yStart += yIncr;
01091 
01092 //enable BT_DEBUG_MEMORY_ALLOCATIONS define in Bullet/src/LinearMath/btAlignedAllocator.h for memory leak detection
01093 #ifdef BT_DEBUG_MEMORY_ALLOCATIONS
01094                             glRasterPos3f(xOffset,yStart,0);
01095                             sprintf(buf,"gTotalBytesAlignedAllocs = %d",gTotalBytesAlignedAllocs);
01096                             BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01097                             yStart += yIncr;
01098 #endif //BT_DEBUG_MEMORY_ALLOCATIONS
01099 
01100                             if (getDynamicsWorld())
01101                             {
01102                                    glRasterPos3f(xOffset,yStart,0);
01103                                    sprintf(buf,"# objects = %d",getDynamicsWorld()->getNumCollisionObjects());
01104                                    BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01105                                    yStart += yIncr;
01106                                    glRasterPos3f(xOffset,yStart,0);
01107                                    sprintf(buf,"# pairs = %d",getDynamicsWorld()->getBroadphase()->getOverlappingPairCache()->getNumOverlappingPairs());
01108                                    BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
01109                                    yStart += yIncr;
01110 
01111                             }
01112 
01113 
01114 #endif //SHOW_NUM_DEEP_PENETRATIONS
01115 
01116                             resetPerspectiveProjection();
01117                      }
01118 
01119                      glEnable(GL_LIGHTING);
01120 
01121               
01122        }
01123 
01124        updateCamera();
01125 
01126 }
01127 
01128 void   DemoApplication::clientResetScene()
01129 {
01130 #ifdef SHOW_NUM_DEEP_PENETRATIONS
01131        gNumDeepPenetrationChecks = 0;
01132        gNumGjkChecks = 0;
01133 #endif //SHOW_NUM_DEEP_PENETRATIONS
01134 
01135        int numObjects = 0;
01136        if (m_dynamicsWorld)
01137        {
01138               m_dynamicsWorld->stepSimulation(1.f/60.f,0);
01139               numObjects = m_dynamicsWorld->getNumCollisionObjects();
01140        }
01141        
01142        for (int i=0;i<numObjects;i++)
01143        {
01144               btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[i];
01145               btRigidBody* body = btRigidBody::upcast(colObj);
01146               if (body)
01147               {
01148                      if (body->getMotionState())
01149                      {
01150                             btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState();
01151                             myMotionState->m_graphicsWorldTrans = myMotionState->m_startWorldTrans;
01152                             colObj->setWorldTransform( myMotionState->m_graphicsWorldTrans );
01153                             colObj->setInterpolationWorldTransform( myMotionState->m_startWorldTrans );
01154                             colObj->activate();
01155                      }
01156                      //removed cached contact points
01157                      m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(colObj->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher());
01158 
01159                      btRigidBody* body = btRigidBody::upcast(colObj);
01160                      if (body && !body->isStaticObject())
01161                      {
01162                             btRigidBody::upcast(colObj)->setLinearVelocity(btVector3(0,0,0));
01163                             btRigidBody::upcast(colObj)->setAngularVelocity(btVector3(0,0,0));
01164                      }
01165               }
01166 
01167        /*
01168        //quickly search some issue at a certain simulation frame, pressing space to reset
01169               int fixed=18;
01170               for (int i=0;i<fixed;i++)
01171               {
01172                      getDynamicsWorld()->stepSimulation(1./60.f,1);
01173               }
01174        */
01175        }
01176 }