//to be implemented by the demo void VehicleDemo::renderme() { updateCamera(); btScalar m[16]; int i; btVector3 wheelColor(1,0,0); btVector3 worldBoundsMin,worldBoundsMax; getDynamicsWorld()->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax); for (i=0;i<m_vehicle->getNumWheels();i++) { //synchronize the wheels with the (interpolated) chassis worldtransform m_vehicle->updateWheelTransform(i,true); //draw wheels (cylinders) m_vehicle->getWheelInfo(i).m_worldTransform.getOpenGLMatrix(m); m_shapeDrawer->drawOpenGL(m,m_wheelShape,wheelColor,getDebugMode(),worldBoundsMin,worldBoundsMax); } DemoApplication::renderme(); }
void CcdPhysicsDemo::clientMoveAndDisplay() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //simple dynamics world doesn't handle fixed-time-stepping //float ms = getDeltaTimeMicroseconds(); ///step the simulation if (m_dynamicsWorld) { m_dynamicsWorld->stepSimulation(1./60.,0);//ms / 1000000.f); //optional but useful: debug drawing m_dynamicsWorld->debugDrawWorld(); } renderme(); displayText(); #if 0 for (int i=0;i<debugContacts.size();i++) { getDynamicsWorld()->getDebugDrawer()->drawContactPoint(debugContacts[i],debugNormals[i],0,0,btVector3(1,0,0)); } #endif glFlush(); swapBuffers(); }
mmdpiMatrix mmdpiBullet::get_matrix( mmdpiMatrix *mOut, int object_id ) { mmdpiMatrix matrix, matrix_t; //btCollisionObject* obj = getDiscreteDynamicsWorld()->getCollisionObjectArray()[ rigidbody_id ]; btCollisionObject* obj = getDynamicsWorld()->getCollisionObjectArray()[ object_id ]; btTransform trans; // bulletから情報を取得 btRigidBody* body = btRigidBody::upcast( obj ); body->getMotionState()->getWorldTransform( trans ); // 行列取得 //float m[ 16 ]; //trans.getOpenGLMatrix( m ); //dxo_ConvertMatrixOpenGLToDirectx( ( float * )&matrix, m ); //trans.getOpenGLMatrix( ( btScalar * )&matrix ); //btMatrix3x3 rot = trans.getBasis(); //btVector3 euler; //rot.getEulerZYX( euler[ 2 ], euler[ 1 ], euler[ 0 ] ); //dxo_MatrixTransRotate( &matrix, // trans.getOrigin().getX(), trans.getOrigin().getY(), trans.getOrigin().getZ(), // euler[ 0 ], euler[ 1 ], euler[ 2 ] ); trans.getOpenGLMatrix( ( btScalar * )&matrix[ 0 ] ); if( mOut ) *mOut = matrix; return matrix; }
//to be implemented by the demo void ForkLiftDemo::renderme() { updateCamera(); btScalar m[16]; int i; btVector3 wheelColor(1,0,0); btVector3 worldBoundsMin,worldBoundsMax; getDynamicsWorld()->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax); for (i=0;i<m_vehicle->getNumWheels();i++) { //synchronize the wheels with the (interpolated) chassis worldtransform m_vehicle->updateWheelTransform(i,true); //draw wheels (cylinders) m_vehicle->getWheelInfo(i).m_worldTransform.getOpenGLMatrix(m); m_shapeDrawer->drawOpenGL(m,m_wheelShape,wheelColor,getDebugMode(),worldBoundsMin,worldBoundsMax); } int lineWidth=250; int xStart = m_glutScreenWidth - lineWidth; int yStart = 20; if((getDebugMode() & btIDebugDraw::DBG_NoHelpText)==0) { setOrthographicProjection(); glDisable(GL_LIGHTING); glColor3f(0, 0, 0); char buf[124]; glRasterPos3f(xStart, yStart, 0); sprintf(buf,"SHIFT+Cursor Left/Right - rotate lift"); GLDebugDrawString(xStart,20,buf); yStart+=20; glRasterPos3f(xStart, yStart, 0); sprintf(buf,"SHIFT+Cursor UP/Down - move fork up/down"); yStart+=20; GLDebugDrawString(xStart,yStart,buf); glRasterPos3f(xStart, yStart, 0); sprintf(buf,"F5 - toggle camera mode"); yStart+=20; GLDebugDrawString(xStart,yStart,buf); glRasterPos3f(xStart, yStart, 0); sprintf(buf,"Click inside this window for keyboard focus"); yStart+=20; GLDebugDrawString(xStart,yStart,buf); resetPerspectiveProjection(); glEnable(GL_LIGHTING); } DemoApplication::renderme(); }
int mmdpiBullet::advance_time_physical( int fps, float frametime ) { // 1ループにかかった時間を計測 float wait_time_local = 1.0f / fps; float fMilliSec = frametime * 1000.0f * wait_time_local; getDynamicsWorld()->stepSimulation( fMilliSec, _MMDPI_BULLET_STEP_/*, wait_time_local / 1000.0f*/ ); return 0; }
void DemoApplication::clientResetScene() { #ifdef SHOW_NUM_DEEP_PENETRATIONS gNumDeepPenetrationChecks = 0; gNumGjkChecks = 0; #endif //SHOW_NUM_DEEP_PENETRATIONS gNumClampedCcdMotions = 0; int numObjects = 0; int i; if (m_dynamicsWorld) { numObjects = m_dynamicsWorld->getNumCollisionObjects(); ///create a copy of the array, not a reference! btCollisionObjectArray copyArray = m_dynamicsWorld->getCollisionObjectArray(); for (i=0;i<numObjects;i++) { btCollisionObject* colObj = copyArray[i]; btRigidBody* body = btRigidBody::upcast(colObj); if (body) { if (body->getMotionState()) { btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); myMotionState->m_graphicsWorldTrans = myMotionState->m_startWorldTrans; body->setCenterOfMassTransform( myMotionState->m_graphicsWorldTrans ); colObj->setInterpolationWorldTransform( myMotionState->m_startWorldTrans ); colObj->forceActivationState(ACTIVE_TAG); colObj->activate(); colObj->setDeactivationTime(0); //colObj->setActivationState(WANTS_DEACTIVATION); } //removed cached contact points (this is not necessary if all objects have been removed from the dynamics world) //m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(colObj->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); btRigidBody* body = btRigidBody::upcast(colObj); if (body && !body->isStaticObject()) { btRigidBody::upcast(colObj)->setLinearVelocity(btVector3(0,0,0)); btRigidBody::upcast(colObj)->setAngularVelocity(btVector3(0,0,0)); } } } ///reset some internal cached data in the broadphase m_dynamicsWorld->getBroadphase()->resetPool(getDynamicsWorld()->getDispatcher()); m_dynamicsWorld->getConstraintSolver()->reset(); } }
int mmdpiBullet::set_matrix( int object_id, mmdpiMatrix *mIn ) { //btCollisionObject* obj = getDiscreteDynamicsWorld()->getCollisionObjectArray()[ rigidbody_id ]; btCollisionObject* obj = getDynamicsWorld()->getCollisionObjectArray()[ object_id ]; btTransform trans; // bulletから情報を取得 btRigidBody* body = btRigidBody::upcast( obj ); //mmdpiMatrix m = *mIn; //m._43 = m._43; body->getMotionState()->setWorldTransform( matrix_to_btTransMatrix( mIn ) ); return 0; }
mmdpiBullet::~mmdpiBullet() { // ボディー for( int i = 0; i < getDiscreteDynamicsWorld()->getNumCollisionObjects() - 1; i ++ ) { btCollisionObject* obj = getDiscreteDynamicsWorld()->getCollisionObjectArray()[ i ]; btRigidBody* body = btRigidBody::upcast( obj ); getDiscreteDynamicsWorld()->removeCollisionObject( obj ); delete obj; } for( int j = 0; j < collisionShapes.size(); j ++ ) { btCollisionShape* shape = collisionShapes[ j ]; delete shape; } // ジョイント for( int i = 0; i < getDynamicsWorld()->getNumConstraints(); i ++ ) { btTypedConstraint* p2p = getDynamicsWorld()->getConstraint( i ); //getDynamicsWorld()->removeConstraint( p2p ); delete p2p; } collisionShapes.clear(); //delete dynamics world delete dynamicsWorld; //delete solver delete solver; //delete broadphase delete overlappingPairCache; //delete dispatcher delete dispatcher; delete collisionConfiguration; ///-----cleanup_end----- }
btRigidBody* Physics::addRigidBody(Ogre::Entity* entity, Ogre::SceneNode* node, btCollisionShape *rigidShape, btScalar mass, btScalar rest, btVector3 localInertia, btVector3 origin, btQuaternion *rotation) { btTransform startTransform; startTransform.setIdentity(); startTransform.setOrigin(origin); if (rotation) { startTransform.setRotation(*rotation); } rigidShape->calculateLocalInertia(mass, localInertia); // Instantiate the body and add it to the dynamics world btDefaultMotionState *myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, rigidShape, localInertia); btRigidBody *body = new btRigidBody(rbInfo); body->setRestitution(rest); body->setUserPointer(node); getDynamicsWorld()->addRigidBody(body); return body; }
void CcdPhysicsDemo::displayCallback(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); renderme(); displayText(); //optional but useful: debug drawing to detect problems if (m_dynamicsWorld) { m_dynamicsWorld->debugDrawWorld(); } #if 0 for (int i=0;i<debugContacts.size();i++) { getDynamicsWorld()->getDebugDrawer()->drawContactPoint(debugContacts[i],debugNormals[i],0,0,btVector3(1,0,0)); } #endif glFlush(); swapBuffers(); }
void gkScene::createInstanceImpl(void) { if (m_objects.empty()) { gkPrintf("Scene: '%s' Has no creatable objects.\n", m_name.getName().c_str()); m_instanceState = ST_ERROR; return; } if (!m_window) setDisplayWindow(gkWindowSystem::getSingleton().getMainWindow()); // generic for now, but later scene properties will be used // to extract more detailed management information m_manager = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC, m_name.getFullName()); #if OGREKIT_USE_RTSHADER_SYSTEM Ogre::RTShader::ShaderGenerator::getSingleton().addSceneManager(m_manager); #endif m_skybox = gkMaterialLoader::loadSceneSkyMaterial(this, m_baseProps.m_material); // create the world (void)getDynamicsWorld(); gkGameObjectHashMap::Iterator it = m_objects.iterator(); while (it.hasMoreElements()) { gkGameObject* gobj = it.getNext().second; if (!gobj->isInstanced()) { // Skip creation of inactive layers if (m_layers & gobj->getLayer()) { // call builder gobj->createInstance(); } } } // Build groups. gkGroupManager::getSingleton().createGameObjectInstances(this); if (gkEngine::getSingleton().getUserDefs().buildStaticGeometry) gkGroupManager::getSingleton().createStaticBatches(this); // Build parent / child hierarchy. _applyBuiltinParents(m_instanceObjects); // Build physics. _applyBuiltinPhysics(m_instanceObjects); if (!m_viewport) { // setMainCamera has not been called, try to call if (m_startCam) setMainCamera(m_startCam); else { if (!m_cameras.empty()) setMainCamera(m_cameras.at(0)); else { m_startCam = createCamera(" -- No Camera -- "); m_startCam->getProperties().m_transform.set( gkVector3(0, -5, 0), gkEuler(90.f, 0.f, 0.f).toQuaternion(), gkVector3(1.f, 1.f, 1.f) ); m_startCam->createInstance(); setMainCamera(m_startCam); } } } GK_ASSERT(m_viewport); m_viewport->getViewport()->setBackgroundColour(m_baseProps.m_material.m_horizon); m_manager->setAmbientLight(m_baseProps.m_material.m_ambient); #if OGRE_NO_VIEWPORT_ORIENTATIONMODE != 0 const gkString& iparam = gkEngine::getSingleton().getUserDefs().viewportOrientation; if (!iparam.empty()) { int oparam = Ogre::OR_PORTRAIT; if (iparam == "landscaperight") //viewport orientation is reversed. { oparam = Ogre::OR_LANDSCAPELEFT; // gkLogger::write("Set Orientation: OR_LANDSCAPELEFT",true); } else if (iparam == "landscapeleft") { oparam = Ogre::OR_LANDSCAPERIGHT; // gkLogger::write("Set Orientation: OR_LANDSCAPERIGHT",true); } try{ m_viewport->getViewport()->setOrientationMode((Ogre::OrientationMode)oparam); } catch (...) { gkLogger::write("Problem setting Viewport Orientation"); } } #endif if (m_baseProps.m_fog.m_mode != gkFogParams::FM_NONE) { m_manager->setFog( m_baseProps.m_fog.m_mode == gkFogParams::FM_QUAD ? Ogre::FOG_EXP2 : m_baseProps.m_fog.m_mode == gkFogParams::FM_LIN ? Ogre::FOG_LINEAR : Ogre::FOG_EXP, m_baseProps.m_fog.m_color, m_baseProps.m_fog.m_intensity, m_baseProps.m_fog.m_start, m_baseProps.m_fog.m_end); } //Enable Shadows setShadows(); #ifdef OGREKIT_OPENAL_SOUND // Set sound scene. gkSoundManager& sndMgr = gkSoundManager::getSingleton(); sndMgr.getProperties() = m_soundScene; sndMgr.updateSoundProperties(); #endif // notify main scene gkEngine::getSingleton().registerActiveScene(this); }
//------------------------------------------------------------------------------ void GimpactConcaveDemo::renderme() { updateCamera(); btScalar m[16]; if (m_dynamicsWorld) { btVector3 worldBoundsMin,worldBoundsMax; getDynamicsWorld()->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax); int numObjects = m_dynamicsWorld->getNumCollisionObjects(); btVector3 wireColor(1,0,0); for (int i=0;i<numObjects;i++) { btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[i]; btRigidBody* body = btRigidBody::upcast(colObj); if (body && body->getMotionState()) { btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m); } else { colObj->getWorldTransform().getOpenGLMatrix(m); } btVector3 wireColor(1.f,1.0f,0.5f); //wants deactivation if (i & 1) { wireColor = btVector3(0.f,0.0f,1.f); } ///color differently for active, sleeping, wantsdeactivation states if (colObj->getActivationState() == 1) //active { if (i & 1) { wireColor += btVector3 (0.8f,0.1f,0.1f); } else { wireColor += btVector3 (0.5f,0.f,0.f); } } if (colObj->getActivationState() == 2) //ISLAND_SLEEPING { if (i & 1) { wireColor += btVector3 (0.5f,0.8f, 0.5f); } else { wireColor += btVector3 (0.f,0.5f,0.f); } } m_shapeDrawer->drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode(),worldBoundsMin,worldBoundsMax); } float xOffset = 10.f; float yStart = 20.f; float yIncr = 20.f; char buf[124]; glColor3f(0, 0, 0); setOrthographicProjection(); glRasterPos3f(xOffset,yStart,0); sprintf(buf,"mouse to interact"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; /* glRasterPos3f(xOffset,yStart,0); sprintf(buf,"space to reset"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; */ glRasterPos3f(xOffset,yStart,0); sprintf(buf,"cursor keys and z,x to navigate"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"i to toggle simulation, s single step"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"q to quit"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,". to shoot TRIMESH (dot)"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; // not yet hooked up again after refactoring... /* glRasterPos3f(xOffset,yStart,0); sprintf(buf,"d to toggle deactivation"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; */ /* glRasterPos3f(xOffset,yStart,0); sprintf(buf,"a to draw temporal AABBs"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; */ glRasterPos3f(xOffset,yStart,0); sprintf(buf,"h to toggle help text"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; //bool useBulletLCP = !(getDebugMode() & btIDebugDraw::DBG_DisableBulletLCP); bool useCCD = ((getDebugMode() & btIDebugDraw::DBG_EnableCCD) != 0); glRasterPos3f(xOffset,yStart,0); sprintf(buf,"1 CCD mode (adhoc) = %i",useCCD); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"+- shooting speed = %10.2f",m_ShootBoxInitialSpeed); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; #ifdef SHOW_NUM_DEEP_PENETRATIONS glRasterPos3f(xOffset,yStart,0); sprintf(buf,"gNumDeepPenetrationChecks = %d",gNumDeepPenetrationChecks); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"gNumSplitImpulseRecoveries= %d",gNumSplitImpulseRecoveries); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"gNumGjkChecks= %d",gNumGjkChecks); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; #endif //SHOW_NUM_DEEP_PENETRATIONS resetPerspectiveProjection(); } }
void SerializeDemo::initPhysics() { setTexturing(true); setShadows(false);//true); setCameraDistance(btScalar(SCALING*30.)); setupEmptyDynamicsWorld(); #ifdef DESERIALIZE_SOFT_BODIES m_fileLoader = new MySoftBulletWorldImporter((btSoftRigidDynamicsWorld*)m_dynamicsWorld); #else m_fileLoader = new btBulletWorldImporter(m_dynamicsWorld); #endif //DESERIALIZE_SOFT_BODIES m_fileLoader->setVerboseMode(m_verboseMode); if (!m_fileLoader->loadFile("testFile.bullet")) // if (!m_fileLoader->loadFile("../SoftDemo/testFile.bullet")) { ///create a few basic rigid bodies and save them to testFile.bullet btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); btCollisionObject* groundObject = 0; m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-50,0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); groundObject = body; } { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance int numSpheres = 2; btVector3 positions[2] = {btVector3(0.1f,0.2f,0.3f),btVector3(0.4f,0.5f,0.6f)}; btScalar radii[2] = {0.3f,0.4f}; btMultiSphereShape* colShape = new btMultiSphereShape(positions,radii,numSpheres); //btCollisionShape* colShape = new btCapsuleShapeZ(SCALING*1,SCALING*1); //btCollisionShape* colShape = new btCylinderShapeZ(btVector3(SCALING*1,SCALING*1,SCALING*1)); //btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,SCALING*1)); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); float start_x = START_POS_X - ARRAY_SIZE_X/2; float start_y = START_POS_Y; float start_z = START_POS_Z - ARRAY_SIZE_Z/2; for (int k=0;k<ARRAY_SIZE_Y;k++) { for (int i=0;i<ARRAY_SIZE_X;i++) { for(int j = 0;j<ARRAY_SIZE_Z;j++) { startTransform.setOrigin(SCALING*btVector3( btScalar(2.0*i + start_x), btScalar(20+2.0*k + start_y), btScalar(2.0*j + start_z))); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body); //body->setActivationState(ISLAND_SLEEPING); } } } } int maxSerializeBufferSize = 1024*1024*5; btDefaultSerializer* serializer = new btDefaultSerializer(maxSerializeBufferSize); static const char* groundName = "GroundName"; serializer->registerNameForPointer(groundObject, groundName); for (int i=0;i<m_collisionShapes.size();i++) { char* name = new char[20]; sprintf(name,"name%d",i); serializer->registerNameForPointer(m_collisionShapes[i],name); } btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*(btRigidBody*)getDynamicsWorld()->getCollisionObjectArray()[2],btVector3(0,1,0)); m_dynamicsWorld->addConstraint(p2p); const char* name = "constraintje"; serializer->registerNameForPointer(p2p,name); m_dynamicsWorld->serialize(serializer); #if 1 FILE* f2 = fopen("testFile.bullet","wb"); fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2); fclose(f2); #endif } //clientResetScene(); }
void SerializeDemo::keyboardCallback(unsigned char key, int x, int y) { btAlignedObjectArray<btRigidBody*> bodies; if (key == 'g') { int numManifolds = getDynamicsWorld()->getDispatcher()->getNumManifolds(); for (int i=0;i<numManifolds;i++) { btPersistentManifold* manifold = getDynamicsWorld()->getDispatcher()->getManifoldByIndexInternal(i); if (!manifold->getNumContacts()) continue; btScalar minDist = 1e30f; int minIndex = -1; for (int v=0;v<manifold->getNumContacts();v++) { if (minDist >manifold->getContactPoint(v).getDistance()) { minDist = manifold->getContactPoint(v).getDistance(); minIndex = v; } } if (minDist>0.) continue; btCollisionObject* colObj0 = (btCollisionObject*)manifold->getBody0(); btCollisionObject* colObj1 = (btCollisionObject*)manifold->getBody1(); // int tag0 = (colObj0)->getIslandTag(); // int tag1 = (colObj1)->getIslandTag(); btRigidBody* body0 = btRigidBody::upcast(colObj0); btRigidBody* body1 = btRigidBody::upcast(colObj1); if (bodies.findLinearSearch(body0)==bodies.size()) bodies.push_back(body0); if (bodies.findLinearSearch(body1)==bodies.size()) bodies.push_back(body1); if (body0 && body1) { if (!colObj0->isStaticOrKinematicObject() && !colObj1->isStaticOrKinematicObject()) { if (body0->checkCollideWithOverride(body1)) { { btTransform trA,trB; trA.setIdentity(); trB.setIdentity(); btVector3 contactPosWorld = manifold->getContactPoint(minIndex).m_positionWorldOnA; btTransform globalFrame; globalFrame.setIdentity(); globalFrame.setOrigin(contactPosWorld); trA = body0->getWorldTransform().inverse()*globalFrame; trB = body1->getWorldTransform().inverse()*globalFrame; btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*body0,*body1,trA,trB,true); dof6->setOverrideNumSolverIterations(100); dof6->setBreakingImpulseThreshold(35); for (int i=0;i<6;i++) dof6->setLimit(i,0,0); getDynamicsWorld()->addConstraint(dof6,true); } } } } } for (int i=0;i<bodies.size();i++) { getDynamicsWorld()->removeRigidBody(bodies[i]); getDynamicsWorld()->addRigidBody(bodies[i]); } }else { PlatformDemoApplication::keyboardCallback(key,x,y); } }
void InternalEdgeDemo::initPhysics() { setTexturing(true); setShadows(false);//true); #define TRISIZE 10.f gContactAddedCallback = CustomMaterialCombinerCallback; #define USE_TRIMESH_SHAPE 1 #ifdef USE_TRIMESH_SHAPE int vertStride = sizeof(btVector3); int indexStride = 3*sizeof(int); const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1); gVertices = new btVector3[totalVerts]; gIndices = new int[totalTriangles*3]; int i; setVertexPositions(waveheight,0.f); //gVertices[1].setY(21.1); //gVertices[1].setY(121.1); gVertices[1].setY(.1f); #ifdef ROTATE_GROUND //gVertices[1].setY(-1.1); #else //gVertices[1].setY(0.1); //gVertices[1].setY(-0.1); //gVertices[1].setY(-20.1); //gVertices[1].setY(-20); #endif int index=0; for ( i=0;i<NUM_VERTS_X-1;i++) { for (int j=0;j<NUM_VERTS_Y-1;j++) { #ifdef SWAP_WINDING #ifdef SHIFT_INDICES gIndices[index++] = j*NUM_VERTS_X+i; gIndices[index++] = (j+1)*NUM_VERTS_X+i+1; gIndices[index++] = j*NUM_VERTS_X+i+1; gIndices[index++] = j*NUM_VERTS_X+i; gIndices[index++] = (j+1)*NUM_VERTS_X+i; gIndices[index++] = (j+1)*NUM_VERTS_X+i+1; #else gIndices[index++] = (j+1)*NUM_VERTS_X+i+1; gIndices[index++] = j*NUM_VERTS_X+i+1; gIndices[index++] = j*NUM_VERTS_X+i; gIndices[index++] = (j+1)*NUM_VERTS_X+i; gIndices[index++] = (j+1)*NUM_VERTS_X+i+1; gIndices[index++] = j*NUM_VERTS_X+i; #endif //SHIFT_INDICES #else //SWAP_WINDING #ifdef SHIFT_INDICES gIndices[index++] = (j+1)*NUM_VERTS_X+i+1; gIndices[index++] = j*NUM_VERTS_X+i; gIndices[index++] = j*NUM_VERTS_X+i+1; #ifdef TEST_INCONSISTENT_WINDING gIndices[index++] = j*NUM_VERTS_X+i; gIndices[index++] = (j+1)*NUM_VERTS_X+i; gIndices[index++] = (j+1)*NUM_VERTS_X+i+1; #else //TEST_INCONSISTENT_WINDING gIndices[index++] = (j+1)*NUM_VERTS_X+i; gIndices[index++] = j*NUM_VERTS_X+i; gIndices[index++] = (j+1)*NUM_VERTS_X+i+1; #endif //TEST_INCONSISTENT_WINDING #else //SHIFT_INDICES gIndices[index++] = j*NUM_VERTS_X+i; gIndices[index++] = j*NUM_VERTS_X+i+1; gIndices[index++] = (j+1)*NUM_VERTS_X+i+1; gIndices[index++] = j*NUM_VERTS_X+i; gIndices[index++] = (j+1)*NUM_VERTS_X+i+1; gIndices[index++] = (j+1)*NUM_VERTS_X+i; #endif //SHIFT_INDICES #endif //SWAP_WINDING } } m_indexVertexArrays = new btTriangleIndexVertexArray(totalTriangles, gIndices, indexStride, totalVerts,(btScalar*) &gVertices[0].x(),vertStride); bool useQuantizedAabbCompression = true; //comment out the next line to read the BVH from disk (first run the demo once to create the BVH) #define SERIALIZE_TO_DISK 1 #ifdef SERIALIZE_TO_DISK btVector3 aabbMin(-1000,-1000,-1000),aabbMax(1000,1000,1000); trimeshShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,aabbMin,aabbMax); m_collisionShapes.push_back(trimeshShape); ///we can serialize the BVH data void* buffer = 0; int numBytes = trimeshShape->getOptimizedBvh()->calculateSerializeBufferSize(); buffer = btAlignedAlloc(numBytes,16); bool swapEndian = false; trimeshShape->getOptimizedBvh()->serialize(buffer,numBytes,swapEndian); #ifdef __QNX__ FILE* file = fopen("app/native/bvh.bin","wb"); #else FILE* file = fopen("bvh.bin","wb"); #endif fwrite(buffer,1,numBytes,file); fclose(file); btAlignedFree(buffer); #else trimeshShape = new btBvhTriangleMeshShape(m_indexVertexArrays,useQuantizedAabbCompression,false); char* fileName = "bvh.bin"; #ifdef __QNX__ char* fileName = "app/native/bvh.bin"; #else char* fileName = "bvh.bin"; #endif int size=0; btOptimizedBvh* bvh = 0; if (fseek(file, 0, SEEK_END) || (size = ftell(file)) == EOF || fseek(file, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */ printf("Error: cannot get filesize from %s\n", fileName); exit(0); } else { fseek(file, 0, SEEK_SET); int buffersize = size+btOptimizedBvh::getAlignmentSerializationPadding(); void* buffer = btAlignedAlloc(buffersize,16); int read = fread(buffer,1,size,file); fclose(file); bool swapEndian = false; bvh = btOptimizedBvh::deSerializeInPlace(buffer,buffersize,swapEndian); } trimeshShape->setOptimizedBvh(bvh); #endif btCollisionShape* groundShape = trimeshShape; btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap(); btGenerateInternalEdgeInfo(trimeshShape,triangleInfoMap); #else btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50)); m_collisionShapes.push_back(groundShape); #endif //USE_TRIMESH_SHAPE m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_broadphase = new btDbvtBroadphase(); m_solver = new btSequentialImpulseConstraintSolver(); m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); /* m_dynamicsWorld->getSolverInfo().m_splitImpulse = true; m_dynamicsWorld->getSolverInfo().m_splitImpulsePenetrationThreshold = 1e30f; m_dynamicsWorld->getSolverInfo().m_maxErrorReduction = 1e30f; m_dynamicsWorld->getSolverInfo().m_erp =1.f; m_dynamicsWorld->getSolverInfo().m_erp2 = 1.f; */ m_dynamicsWorld->setGravity(btVector3(0,-10,0)); float mass = 0.f; btTransform startTransform; startTransform.setIdentity(); startTransform.setOrigin(btVector3(0,-2,0)); btConvexHullShape* colShape = new btConvexHullShape(); for (int i=0;i<TaruVtxCount;i++) { btVector3 vtx(TaruVtx[i*3],TaruVtx[i*3+1],TaruVtx[i*3+2]); colShape->addPoint(vtx); } //this will enable polyhedral contact clipping, better quality, slightly slower colShape->initializePolyhedralFeatures(); //the polyhedral contact clipping can use either GJK or SAT test to find the separating axis m_dynamicsWorld->getDispatchInfo().m_enableSatConvex=false; m_collisionShapes.push_back(colShape); { for (int i=0;i<1;i++) { startTransform.setOrigin(btVector3(-10.f+i*3.f,2.2f+btScalar(i)*0.1f,-1.3f)); btRigidBody* body = localCreateRigidBody(10, startTransform,colShape); body->setActivationState(DISABLE_DEACTIVATION); body->setLinearVelocity(btVector3(0,0,-1)); //body->setContactProcessingThreshold(0.f); } } { btBoxShape* colShape = new btBoxShape(btVector3(1,1,1)); colShape->initializePolyhedralFeatures(); m_collisionShapes.push_back(colShape); startTransform.setOrigin(btVector3(-16.f+i*3.f,1.f+btScalar(i)*0.1f,-1.3f)); btRigidBody* body = localCreateRigidBody(10, startTransform,colShape); body->setActivationState(DISABLE_DEACTIVATION); body->setLinearVelocity(btVector3(0,0,-1)); } startTransform.setIdentity(); #ifdef ROTATE_GROUND btQuaternion orn(btVector3(0,0,1),SIMD_PI); startTransform.setOrigin(btVector3(-20,0,0)); startTransform.setRotation(orn); #endif //ROTATE_GROUND staticBody = localCreateRigidBody(mass, startTransform,groundShape); //staticBody->setContactProcessingThreshold(-0.031f); staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);//STATIC_OBJECT); //enable custom material callback staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); setDebugMode(btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_NoHelpText+btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW btSetDebugDrawer(&gDebugDrawer); #endif //BT_INTERNAL_EDGE_DEBUG_DRAW }
void BasicDemo::initPhysics() { setTexturing(false); setShadows(false); #if OECAKE_LOADER setCameraDistance(80.); m_cameraTargetPosition.setValue(50, 10, 0); #else #if LARGE_DEMO setCameraDistance(btScalar(SCALING*100.)); #else setCameraDistance(btScalar(SCALING*20.)); #endif m_cameraTargetPosition.setValue(START_POS_X, -START_POS_Y-20, START_POS_Z); #endif m_azi = btScalar(0.f); m_ele = btScalar(0.f); ///collision configuration contains default setup for memory, collision setup btDefaultCollisionConstructionInfo dci; dci.m_defaultMaxPersistentManifoldPoolSize=50000; dci.m_defaultMaxCollisionAlgorithmPoolSize=50000; m_collisionConfiguration = new btDefaultCollisionConfiguration(dci); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_dispatcher->registerCollisionCreateFunc(BOX_SHAPE_PROXYTYPE,BOX_SHAPE_PROXYTYPE,new btEmptyAlgorithm::CreateFunc); m_dispatcher->setNearCallback(cudaDemoNearCallback); #if USE_CUDA_DEMO_PAIR_CASHE gPairCache = new (btAlignedAlloc(sizeof(btGpuDemoPairCache),16)) btGpuDemoPairCache(MAX_PROXIES, 24, MAX_SMALL_PROXIES); #else gPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16))btHashedOverlappingPairCache(); #endif // btVector3 numOfCells = (gWorldMax - gWorldMin) / (2. * SCALING); // btVector3 numOfCells = (gWorldMax - gWorldMin) / CELL_SIZE; // int numOfCellsX = (int)numOfCells[0]; // int numOfCellsY = (int)numOfCells[1]; // int numOfCellsZ = (int)numOfCells[2]; // if(!numOfCellsX) numOfCellsX = 1; // if(!numOfCellsY) numOfCellsY = 1; // if(!numOfCellsZ) numOfCellsZ = 1; btScalar maxDiam = 2.0f * SCALING; btVector3 cellSize(maxDiam, maxDiam, maxDiam); btVector3 numOfCells = (gWorldMax - gWorldMin) / cellSize; int numOfCellsX = btGpu3DGridBroadphase::getFloorPowOfTwo((int)numOfCells[0]); int numOfCellsY = btGpu3DGridBroadphase::getFloorPowOfTwo((int)numOfCells[1]); int numOfCellsZ = btGpu3DGridBroadphase::getFloorPowOfTwo((int)numOfCells[2]); // m_broadphase = new btAxisSweep3(gWorldMin, gWorldMax, MAX_PROXIES,gPairCache); // m_broadphase = new btDbvtBroadphase(gPairCache); // m_broadphase = new btGpu3DGridBroadphase(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,20,24,24, 1.0f/1.5f); // m_broadphase = new btCudaBroadphase(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,10,24,24); // m_broadphase = new bt3dGridBroadphaseOCL(gPairCache, gWorldMin, gWorldMax,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,20,24,24,1./1.5); m_broadphase = new bt3dGridBroadphaseOCL(gPairCache, cellSize,numOfCellsX, numOfCellsY, numOfCellsZ,MAX_SMALL_PROXIES,20,24,10.f, 24); ///the default constraint solver m_solver = new btSequentialImpulseConstraintSolver(); btGpuDemoDynamicsWorld* pDdw = new btGpuDemoDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration, MAX_PROXIES); m_dynamicsWorld = pDdw; m_pWorld = pDdw; pDdw->getSimulationIslandManager()->setSplitIslands(true); pDdw->setObjRad(SCALING); pDdw->setWorldMin(gWorldMin); pDdw->setWorldMax(gWorldMax); // gUseCPUSolver = true; pDdw->setUseCPUSolver(gUseCPUSolver); gUseBulletNarrowphase = false; pDdw->setUseBulletNarrowphase(gUseBulletNarrowphase); // m_dynamicsWorld->setGravity(btVector3(0,0,0)); m_dynamicsWorld->setGravity(btVector3(0,-10.,0)); m_dynamicsWorld->getSolverInfo().m_numIterations = 4; { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance #if 1 #define SPRADIUS btScalar(SCALING*0.1f) #define SPRPOS btScalar(SCALING*0.05f) static btVector3 sSphPos[8]; for (int k=0;k<8;k++) { sSphPos[k].setValue((k-4)*0.25*SCALING,0,0); } btVector3 inertiaHalfExtents(SPRADIUS, SPRADIUS, SPRADIUS); static btScalar sSphRad[8] = { // SPRADIUS, SPRADIUS, SPRADIUS, SPRADIUS,SPRADIUS, SPRADIUS, SPRADIUS, 0.3 SPRADIUS, SPRADIUS, SPRADIUS, SPRADIUS,SPRADIUS, SPRADIUS, SPRADIUS, SPRADIUS }; // sSphPos[0].setX(sSphPos[0].getX()-0.15); #undef SPR btMultiSphereShape* colShape[2]; colShape[0] = new btMultiSphereShape( sSphPos, sSphRad, 8); colShape[1] = new btMultiSphereShape( sSphPos, sSphRad, 2); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); m_collisionShapes.push_back(colShape[0]); m_collisionShapes.push_back(colShape[1]); #endif /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(0.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); #if OECAKE_LOADER BasicDemoOecakeLoader loader(this); if (!loader.processFile("test1.oec")) { loader.processFile("../../../../../Demos/Gpu2dDemo/test.oec"); } #if 0 // perfomance test : work-in-progress { // add more object, but share their shapes int numNewObjects = 500; mass = 1.f; for(int n_obj = 0; n_obj < numNewObjects; n_obj++) { btDefaultMotionState* myMotionState= 0; btVector3 localInertia(0,0,0); btTransform worldTransform; worldTransform.setIdentity(); btScalar fx = fRandMinMax(-30., 30.); btScalar fy = fRandMinMax(5., 30.); worldTransform.setOrigin(btVector3(fx, fy, 0.f)); int sz = m_collisionShapes.size(); btMultiSphereShape* multiSphere = (btMultiSphereShape*)m_collisionShapes[1]; myMotionState = new btDefaultMotionState(worldTransform); multiSphere->calculateLocalInertia(mass, localInertia); btRigidBody* body = new btRigidBody(mass,myMotionState,multiSphere,localInertia); body->setLinearFactor(btVector3(1,1,0)); body->setAngularFactor(btVector3(0,0,1)); body->setWorldTransform(worldTransform); getDynamicsWorld()->addRigidBody(body); } } #endif #else #if (!SPEC_TEST) float start_x = START_POS_X - ARRAY_SIZE_X * SCALING; float start_y = START_POS_Y - ARRAY_SIZE_Y * SCALING; float start_z = START_POS_Z - ARRAY_SIZE_Z * SCALING; int collisionShapeIndex = 0; for (int k=0;k<ARRAY_SIZE_Y;k++) { for (int i=0;i<ARRAY_SIZE_X;i++) { for(int j = 0;j<ARRAY_SIZE_Z;j++) { float offs = (2. * (float)rand() / (float)RAND_MAX - 1.f) * 0.05f; startTransform.setOrigin(SCALING*btVector3( 2.0*SCALING*i + start_x + offs, 2.0*SCALING*k + start_y + offs, 2.0*SCALING*j + start_z)); if (isDynamic) colShape[collisionShapeIndex]->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects //btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape[collisionShapeIndex],localInertia); collisionShapeIndex = 1 - collisionShapeIndex; rbInfo.m_startWorldTransform=startTransform; btRigidBody* body = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body); } } } #else//SPEC_TEST // narrowphase test - 2 bodies at the same position float start_x = START_POS_X; // float start_y = START_POS_Y; float start_y = gWorldMin[1] + SCALING * 0.7f + 5.f; float start_z = START_POS_Z; startTransform.setOrigin(SCALING*btVector3(start_x,start_y,start_z)); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,0,colShape[0],localInertia); rbInfo.m_startWorldTransform=startTransform; btRigidBody* body = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body); btPoint2PointConstraint * p2pConstr = new btPoint2PointConstraint(*body, btVector3(1., 0., 0.)); m_dynamicsWorld->addConstraint(p2pConstr); startTransform.setOrigin(SCALING*btVector3(start_x-2.f, start_y,start_z)); rbInfo.m_startWorldTransform=startTransform; btRigidBody* body1 = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body1); p2pConstr = new btPoint2PointConstraint(*body, *body1, btVector3(-1., 0., 0.), btVector3(1., 0., 0.)); m_dynamicsWorld->addConstraint(p2pConstr); #endif//SPEC_TEST #endif //OE_CAKE_LOADER } // now set Ids used by collision detector and constraint solver int numObjects = m_dynamicsWorld->getNumCollisionObjects(); btCollisionObjectArray& collisionObjects = m_dynamicsWorld->getCollisionObjectArray(); for(int i = 0; i < numObjects; i++) { btCollisionObject* colObj = collisionObjects[i]; colObj->setCompanionId(i+1); // 0 reserved for the "world" object btCollisionShape* pShape = colObj->getCollisionShape(); int shapeType = pShape->getShapeType(); if(shapeType == MULTI_SPHERE_SHAPE_PROXYTYPE) { btMultiSphereShape* pMs = (btMultiSphereShape*)pShape; int numSpheres = pMs->getSphereCount(); pDdw->addMultiShereObject(numSpheres, i + 1); for(int j = 0; j < numSpheres; j++) { btVector3 sphPos = pMs->getSpherePosition(j); float sphRad = pMs->getSphereRadius(j); pDdw->addSphere(sphPos, sphRad); } } else { btAssert(0); } } #if OECAKE_LOADER clientResetScene(); #endif }
void VoronoiFractureDemo::attachFixedConstraints() { btAlignedObjectArray<btRigidBody*> bodies; int numManifolds = getDynamicsWorld()->getDispatcher()->getNumManifolds(); for (int i=0;i<numManifolds;i++) { btPersistentManifold* manifold = getDynamicsWorld()->getDispatcher()->getManifoldByIndexInternal(i); if (!manifold->getNumContacts()) continue; btScalar minDist = 1e30f; int minIndex = -1; for (int v=0;v<manifold->getNumContacts();v++) { if (minDist >manifold->getContactPoint(v).getDistance()) { minDist = manifold->getContactPoint(v).getDistance(); minIndex = v; } } if (minDist>0.) continue; btCollisionObject* colObj0 = (btCollisionObject*)manifold->getBody0(); btCollisionObject* colObj1 = (btCollisionObject*)manifold->getBody1(); // int tag0 = (colObj0)->getIslandTag(); // int tag1 = (colObj1)->getIslandTag(); btRigidBody* body0 = btRigidBody::upcast(colObj0); btRigidBody* body1 = btRigidBody::upcast(colObj1); if (bodies.findLinearSearch(body0)==bodies.size()) bodies.push_back(body0); if (bodies.findLinearSearch(body1)==bodies.size()) bodies.push_back(body1); if (body0 && body1) { if (!colObj0->isStaticOrKinematicObject() && !colObj1->isStaticOrKinematicObject()) { if (body0->checkCollideWithOverride(body1)) { { btTransform trA,trB; trA.setIdentity(); trB.setIdentity(); btVector3 contactPosWorld = manifold->getContactPoint(minIndex).m_positionWorldOnA; btTransform globalFrame; globalFrame.setIdentity(); globalFrame.setOrigin(contactPosWorld); trA = body0->getWorldTransform().inverse()*globalFrame; trB = body1->getWorldTransform().inverse()*globalFrame; float totalMass = 1.f/body0->getInvMass() + 1.f/body1->getInvMass(); if (useGenericConstraint) { btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*body0,*body1,trA,trB,true); dof6->setOverrideNumSolverIterations(30); dof6->setBreakingImpulseThreshold(BREAKING_THRESHOLD*totalMass); for (int i=0;i<6;i++) dof6->setLimit(i,0,0); getDynamicsWorld()->addConstraint(dof6,true); } else { btFixedConstraint* fixed = new btFixedConstraint(*body0,*body1,trA,trB); fixed->setBreakingImpulseThreshold(BREAKING_THRESHOLD*totalMass); fixed ->setOverrideNumSolverIterations(30); getDynamicsWorld()->addConstraint(fixed,true); } } } } } } for (int i=0;i<bodies.size();i++) { getDynamicsWorld()->removeRigidBody(bodies[i]); getDynamicsWorld()->addRigidBody(bodies[i]); } }
void DemoApplication::setDebugMode(int mode) { m_debugMode = mode; if (getDynamicsWorld() && getDynamicsWorld()->getDebugDrawer()) getDynamicsWorld()->getDebugDrawer()->setDebugMode(mode); }
void CharacterDemo::clientResetScene() { m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_ghostObject->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); m_character->reset (m_dynamicsWorld); ///WTF m_character->warp (btVector3(10.210001,-2.0306311,16.576973)); }
void ConcaveRaycastDemo::clientMoveAndDisplay() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); float dt = getDeltaTimeMicroseconds() * 0.000001f; if (m_animatedMesh) { static float offset=0.f; offset+=0.01f; setVertexPositions(waveheight,offset); btVector3 worldMin(-1000,-1000,-1000); btVector3 worldMax(1000,1000,1000); trimeshShape->refitTree(worldMin,worldMax); //clear all contact points involving mesh proxy. Note: this is a slow/unoptimized operation. m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); } m_dynamicsWorld->stepSimulation(1./60.,0); //optional but useful: debug drawing m_dynamicsWorld->debugDrawWorld(); raycastBar.move (dt); raycastBar.cast (m_dynamicsWorld); renderme(); raycastBar.draw (); glFlush(); glutSwapBuffers(); }
void TPhySystem::processCollision( TPhyBody& body ) { btManifoldArray manifoldArray; btBroadphasePairArray& pairArray = body.getOverlappingPairCache()->getOverlappingPairArray(); int numPairs = pairArray.size(); for (int i=0;i<numPairs;i++) { manifoldArray.clear(); const btBroadphasePair& pair = pairArray[i]; if ( pair.m_pProxy0->m_clientObject == &body && pair.m_pProxy0->getUid() < pair.m_pProxy1->getUid() ) { PhyRigidBody* rigidbody = (PhyRigidBody*) pair.m_pProxy1->m_clientObject; if ( TPhyBody::upcast( rigidbody ) != NULL ) continue; } btBroadphasePair* collisionPair ; { TPROFILE("findPair"); //unless we manually perform collision detection on this pair, the contacts are in the dynamics world paircache: collisionPair = getDynamicsWorld()->getPairCache()->findPair(pair.m_pProxy0,pair.m_pProxy1); } if (!collisionPair) continue; { TPROFILE("getAllContactManifolds"); if (collisionPair->m_algorithm) collisionPair->m_algorithm->getAllContactManifolds(manifoldArray); } TPROFILE("manifoldArray"); for (int j=0;j<manifoldArray.size();j++) { btPersistentManifold* manifold = manifoldArray[j]; int numContacts = 0; Vec3D avgPtA(0,0,0); Vec3D avgPtB(0,0,0); Vec3D avgNormalOnB(0,0,0); Float avgDepth = 0; btCollisionObject* objA = static_cast<btCollisionObject*>( manifold->getBody0() ); btCollisionObject* objB = static_cast<btCollisionObject*>( manifold->getBody1() ); TPhyEntity* entityA = static_cast< TPhyEntity* >( objA->getUserPointer() ); TPhyEntity* entityB = static_cast< TPhyEntity* >( objB->getUserPointer() ); bool haveTerrain = ( entityA == NULL || entityB == NULL ); for (int p=0;p<manifold->getNumContacts();p++ ) { const btManifoldPoint& pt = manifold->getContactPoint(p); if ( pt.getDistance() < 0.0f ) { ++numContacts; if ( haveTerrain ) break; avgPtA += pt.getPositionWorldOnA(); avgPtB += pt.getPositionWorldOnB(); avgNormalOnB += pt.m_normalWorldOnB; avgDepth -= pt.getDistance(); break; /// work here } } if ( numContacts > 0 ) { if ( haveTerrain ) { if ( entityA ) entityA->OnCollisionTerrain(); if ( entityB ) entityB->OnCollisionTerrain(); } else { avgPtA /= numContacts; avgPtB /= numContacts; avgDepth /= numContacts; avgNormalOnB.normalize(); entityA->OnCollision( entityB , avgDepth , avgPtA , avgPtB , avgNormalOnB ); entityB->OnCollision( entityA , avgDepth , avgPtB , avgPtA , -avgNormalOnB ); } break; } } } }
void TPhySystem::removeEntity( TPhyEntity* entity ) { getDynamicsWorld()->removeRigidBody( entity->getPhyBody() ); entity->testCollision( false ); }
void BasicDemo::outputDebugInfo(int & xOffset,int & yStart, int yIncr) { char buf[124]; glDisable(GL_LIGHTING); glColor3f(0, 0, 0); sprintf(buf,"mouse move+buttons to interact"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; sprintf(buf,"space to reset"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; sprintf(buf,"cursor keys and z,x to navigate"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; sprintf(buf,"i to toggle simulation, s single step"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; sprintf(buf,"q to quit"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; sprintf(buf,"h to toggle help text"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; sprintf(buf,"p to toggle profiling (+results to file)"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; sprintf(buf,"c to toggle constraint drawing"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; sprintf(buf,"b to draw single constraint batch"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; sprintf(buf,"u to toggle between CPU and OpenCL solvers"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; sprintf(buf,"d to toggle between different batch builders"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; if (getDynamicsWorld()) { sprintf(buf,"# objects = %d",getDynamicsWorld()->getNumCollisionObjects()); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; sprintf(buf,"# pairs = %d",getDynamicsWorld()->getBroadphase()->getOverlappingPairCache()->getNumOverlappingPairs()); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; } } // BasicDemo::outputDebugInfo()
void ConcaveDemo::clientMoveAndDisplay() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); float dt = getDeltaTimeMicroseconds() * 0.000001f; if (m_animatedMesh) { static float offset=0.f; offset+=dt; // setVertexPositions(waveheight,offset); int i; int j; btVector3 aabbMin(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); btVector3 aabbMax(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT); for ( i=NUM_VERTS_X/2-3;i<NUM_VERTS_X/2+2;i++) { for (j=NUM_VERTS_X/2-3;j<NUM_VERTS_Y/2+2;j++) { aabbMax.setMax(gVertices[i+j*NUM_VERTS_X]); aabbMin.setMin(gVertices[i+j*NUM_VERTS_X]); gVertices[i+j*NUM_VERTS_X].setValue((i-NUM_VERTS_X*0.5f)*TRIANGLE_SIZE, //0.f, waveheight*sinf((float)i+offset)*cosf((float)j+offset), (j-NUM_VERTS_Y*0.5f)*TRIANGLE_SIZE); aabbMin.setMin(gVertices[i+j*NUM_VERTS_X]); aabbMax.setMax(gVertices[i+j*NUM_VERTS_X]); } } 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()); } m_dynamicsWorld->stepSimulation(dt); //optional but useful: debug drawing m_dynamicsWorld->debugDrawWorld(); renderme(); glFlush(); swapBuffers(); }
//to be implemented by the demo void Hinge2Vehicle::renderScene() { m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld); #if 0 for (int i=0;i<m_vehicle->getNumWheels();i++) { //synchronize the wheels with the (interpolated) chassis worldtransform m_vehicle->updateWheelTransform(i,true); CommonRenderInterface* renderer = m_guiHelper->getRenderInterface(); if (renderer) { btTransform tr = m_vehicle->getWheelInfo(i).m_worldTransform; btVector3 pos=tr.getOrigin(); btQuaternion orn = tr.getRotation(); renderer->writeSingleInstanceTransformToCPU(pos,orn,m_wheelInstances[i]); } } #endif m_guiHelper->render(m_dynamicsWorld); btVector3 wheelColor(1,0,0); btVector3 worldBoundsMin,worldBoundsMax; getDynamicsWorld()->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax); #if 0 int lineWidth=400; int xStart = m_glutScreenWidth - lineWidth; int yStart = 20; if((getDebugMode() & btIDebugDraw::DBG_NoHelpText)==0) { setOrthographicProjection(); glDisable(GL_LIGHTING); glColor3f(0, 0, 0); char buf[124]; sprintf(buf,"SHIFT+Cursor Left/Right - rotate lift"); GLDebugDrawString(xStart,20,buf); yStart+=20; sprintf(buf,"SHIFT+Cursor UP/Down - fork up/down"); yStart+=20; GLDebugDrawString(xStart,yStart,buf); if (m_useDefaultCamera) { sprintf(buf,"F5 - camera mode (free)"); } else { sprintf(buf,"F5 - camera mode (follow)"); } yStart+=20; GLDebugDrawString(xStart,yStart,buf); yStart+=20; if (m_dynamicsWorld->getConstraintSolver()->getSolverType()==BT_MLCP_SOLVER) { sprintf(buf,"F6 - solver (direct MLCP)"); } else { sprintf(buf,"F6 - solver (sequential impulse)"); } GLDebugDrawString(xStart,yStart,buf); btDiscreteDynamicsWorld* world = (btDiscreteDynamicsWorld*) m_dynamicsWorld; if (world->getLatencyMotionStateInterpolation()) { sprintf(buf,"F7 - motionstate interpolation (on)"); } else { sprintf(buf,"F7 - motionstate interpolation (off)"); } yStart+=20; GLDebugDrawString(xStart,yStart,buf); sprintf(buf,"Click window for keyboard focus"); yStart+=20; GLDebugDrawString(xStart,yStart,buf); resetPerspectiveProjection(); glEnable(GL_LIGHTING); } #endif }
void ConvexDecompositionDemo::initPhysics(const char* filename) { gContactAddedCallback = &MyContactCallback; setupEmptyDynamicsWorld(); getDynamicsWorld()->setDebugDrawer(&gDebugDrawer); setTexturing(true); setShadows(true); setCameraDistance(26.f); #ifndef NO_OBJ_TO_BULLET ConvexDecomposition::WavefrontObj wo; tcount = 0; const char* prefix[]={"./","../","../../","../../../","../../../../", "ConvexDecompositionDemo/", "Demos/ConvexDecompositionDemo/", "../Demos/ConvexDecompositionDemo/","../../Demos/ConvexDecompositionDemo/"}; int numPrefixes = sizeof(prefix)/sizeof(const char*); char relativeFileName[1024]; for (int i=0;i<numPrefixes;i++) { sprintf(relativeFileName,"%s%s",prefix[i],filename); tcount = wo.loadObj(relativeFileName); if (tcount) break; } btTransform startTransform; startTransform.setIdentity(); startTransform.setOrigin(btVector3(0,-4.5,0)); btCollisionShape* boxShape = new btBoxShape(btVector3(30,2,30)); m_collisionShapes.push_back(boxShape); localCreateRigidBody(0.f,startTransform,boxShape); class MyConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface { ConvexDecompositionDemo* m_convexDemo; public: btAlignedObjectArray<btConvexHullShape*> m_convexShapes; btAlignedObjectArray<btVector3> m_convexCentroids; MyConvexDecomposition (FILE* outputFile,ConvexDecompositionDemo* demo) :m_convexDemo(demo), mBaseCount(0), mHullCount(0), mOutputFile(outputFile) { } virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result) { btTriangleMesh* trimesh = new btTriangleMesh(); m_convexDemo->m_trimeshes.push_back(trimesh); btVector3 localScaling(6.f,6.f,6.f); //export data to .obj printf("ConvexResult. "); if (mOutputFile) { fprintf(mOutputFile,"## Hull Piece %d with %d vertices and %d triangles.\r\n", mHullCount, result.mHullVcount, result.mHullTcount ); fprintf(mOutputFile,"usemtl Material%i\r\n",mBaseCount); fprintf(mOutputFile,"o Object%i\r\n",mBaseCount); for (unsigned int i=0; i<result.mHullVcount; i++) { const float *p = &result.mHullVertices[i*3]; fprintf(mOutputFile,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] ); } //calc centroid, to shift vertices around center of mass centroid.setValue(0,0,0); btAlignedObjectArray<btVector3> vertices; if ( 1 ) { //const unsigned int *src = result.mHullIndices; for (unsigned int i=0; i<result.mHullVcount; i++) { btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]); vertex *= localScaling; centroid += vertex; } } centroid *= 1.f/(float(result.mHullVcount) ); if ( 1 ) { //const unsigned int *src = result.mHullIndices; for (unsigned int i=0; i<result.mHullVcount; i++) { btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]); vertex *= localScaling; vertex -= centroid ; vertices.push_back(vertex); } } if ( 1 ) { const unsigned int *src = result.mHullIndices; for (unsigned int i=0; i<result.mHullTcount; i++) { unsigned int index0 = *src++; unsigned int index1 = *src++; unsigned int index2 = *src++; btVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]); btVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]); btVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]); vertex0 *= localScaling; vertex1 *= localScaling; vertex2 *= localScaling; vertex0 -= centroid; vertex1 -= centroid; vertex2 -= centroid; trimesh->addTriangle(vertex0,vertex1,vertex2); index0+=mBaseCount; index1+=mBaseCount; index2+=mBaseCount; fprintf(mOutputFile,"f %d %d %d\r\n", index0+1, index1+1, index2+1 ); } } // float mass = 1.f; //this is a tools issue: due to collision margin, convex objects overlap, compensate for it here: //#define SHRINK_OBJECT_INWARDS 1 #ifdef SHRINK_OBJECT_INWARDS float collisionMargin = 0.01f; btAlignedObjectArray<btVector3> planeEquations; btGeometryUtil::getPlaneEquationsFromVertices(vertices,planeEquations); btAlignedObjectArray<btVector3> shiftedPlaneEquations; for (int p=0;p<planeEquations.size();p++) { btVector3 plane = planeEquations[p]; plane[3] += collisionMargin; shiftedPlaneEquations.push_back(plane); } btAlignedObjectArray<btVector3> shiftedVertices; btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,shiftedVertices); btConvexHullShape* convexShape = new btConvexHullShape(&(shiftedVertices[0].getX()),shiftedVertices.size()); #else //SHRINK_OBJECT_INWARDS btConvexHullShape* convexShape = new btConvexHullShape(&(vertices[0].getX()),vertices.size()); #endif if (sEnableSAT) convexShape->initializePolyhedralFeatures(); convexShape->setMargin(0.01f); m_convexShapes.push_back(convexShape); m_convexCentroids.push_back(centroid); m_convexDemo->m_collisionShapes.push_back(convexShape); mBaseCount+=result.mHullVcount; // advance the 'base index' counter. } } int mBaseCount; int mHullCount; FILE* mOutputFile; }; if (tcount) { btTriangleMesh* trimesh = new btTriangleMesh(); m_trimeshes.push_back(trimesh); btVector3 localScaling(6.f,6.f,6.f); int i; for ( i=0;i<wo.mTriCount;i++) { int index0 = wo.mIndices[i*3]; int index1 = wo.mIndices[i*3+1]; int index2 = wo.mIndices[i*3+2]; btVector3 vertex0(wo.mVertices[index0*3], wo.mVertices[index0*3+1],wo.mVertices[index0*3+2]); btVector3 vertex1(wo.mVertices[index1*3], wo.mVertices[index1*3+1],wo.mVertices[index1*3+2]); btVector3 vertex2(wo.mVertices[index2*3], wo.mVertices[index2*3+1],wo.mVertices[index2*3+2]); vertex0 *= localScaling; vertex1 *= localScaling; vertex2 *= localScaling; trimesh->addTriangle(vertex0,vertex1,vertex2); } btConvexShape* tmpConvexShape = new btConvexTriangleMeshShape(trimesh); printf("old numTriangles= %d\n",wo.mTriCount); printf("old numIndices = %d\n",wo.mTriCount*3); printf("old numVertices = %d\n",wo.mVertexCount); printf("reducing vertices by creating a convex hull\n"); //create a hull approximation btShapeHull* hull = new btShapeHull(tmpConvexShape); btScalar margin = tmpConvexShape->getMargin(); hull->buildHull(margin); tmpConvexShape->setUserPointer(hull); printf("new numTriangles = %d\n", hull->numTriangles ()); printf("new numIndices = %d\n", hull->numIndices ()); printf("new numVertices = %d\n", hull->numVertices ()); btConvexHullShape* convexShape = new btConvexHullShape(); bool updateLocalAabb = false; for (i=0;i<hull->numVertices();i++) { convexShape->addPoint(hull->getVertexPointer()[i],updateLocalAabb); } convexShape->recalcLocalAabb(); if (sEnableSAT) convexShape->initializePolyhedralFeatures(); delete tmpConvexShape; delete hull; m_collisionShapes.push_back(convexShape); float mass = 1.f; btTransform startTransform; startTransform.setIdentity(); startTransform.setOrigin(btVector3(0,2,14)); localCreateRigidBody(mass, startTransform,convexShape); bool useQuantization = true; btCollisionShape* concaveShape = new btBvhTriangleMeshShape(trimesh,useQuantization); startTransform.setOrigin(convexDecompositionObjectOffset); localCreateRigidBody(0.f,startTransform,concaveShape); m_collisionShapes.push_back (concaveShape); } if (tcount) { //----------------------------------- // Bullet Convex Decomposition //----------------------------------- char outputFileName[512]; strcpy(outputFileName,filename); char *dot = strstr(outputFileName,"."); if ( dot ) *dot = 0; strcat(outputFileName,"_convex.obj"); FILE* outputFile = fopen(outputFileName,"wb"); unsigned int depth = 5; float cpercent = 5; float ppercent = 15; unsigned int maxv = 16; float skinWidth = 0.0; printf("WavefrontObj num triangles read %i\n",tcount); ConvexDecomposition::DecompDesc desc; desc.mVcount = wo.mVertexCount; desc.mVertices = wo.mVertices; desc.mTcount = wo.mTriCount; desc.mIndices = (unsigned int *)wo.mIndices; desc.mDepth = depth; desc.mCpercent = cpercent; desc.mPpercent = ppercent; desc.mMaxVertices = maxv; desc.mSkinWidth = skinWidth; MyConvexDecomposition convexDecomposition(outputFile,this); desc.mCallback = &convexDecomposition; //----------------------------------------------- // HACD //----------------------------------------------- std::vector< HACD::Vec3<HACD::Real> > points; std::vector< HACD::Vec3<long> > triangles; for(int i=0; i<wo.mVertexCount; i++ ) { int index = i*3; HACD::Vec3<HACD::Real> vertex(wo.mVertices[index], wo.mVertices[index+1],wo.mVertices[index+2]); points.push_back(vertex); } for(int i=0;i<wo.mTriCount;i++) { int index = i*3; HACD::Vec3<long> triangle(wo.mIndices[index], wo.mIndices[index+1], wo.mIndices[index+2]); triangles.push_back(triangle); } HACD::HACD myHACD; myHACD.SetPoints(&points[0]); myHACD.SetNPoints(points.size()); myHACD.SetTriangles(&triangles[0]); myHACD.SetNTriangles(triangles.size()); myHACD.SetCompacityWeight(0.1); myHACD.SetVolumeWeight(0.0); // HACD parameters // Recommended parameters: 2 100 0 0 0 0 size_t nClusters = 2; double concavity = 100; bool invert = false; bool addExtraDistPoints = false; bool addNeighboursDistPoints = false; bool addFacesPoints = false; myHACD.SetNClusters(nClusters); // minimum number of clusters myHACD.SetNVerticesPerCH(100); // max of 100 vertices per convex-hull myHACD.SetConcavity(concavity); // maximum concavity myHACD.SetAddExtraDistPoints(addExtraDistPoints); myHACD.SetAddNeighboursDistPoints(addNeighboursDistPoints); myHACD.SetAddFacesPoints(addFacesPoints); myHACD.Compute(); nClusters = myHACD.GetNClusters(); myHACD.Save("output.wrl", false); //convexDecomposition.performConvexDecomposition(desc); // ConvexBuilder cb(desc.mCallback); // cb.process(desc); //now create some bodies if (1) { btCompoundShape* compound = new btCompoundShape(); m_collisionShapes.push_back (compound); btTransform trans; trans.setIdentity(); for (int c=0;c<nClusters;c++) { //generate convex result size_t nPoints = myHACD.GetNPointsCH(c); size_t nTriangles = myHACD.GetNTrianglesCH(c); float* vertices = new float[nPoints*3]; unsigned int* triangles = new unsigned int[nTriangles*3]; HACD::Vec3<HACD::Real> * pointsCH = new HACD::Vec3<HACD::Real>[nPoints]; HACD::Vec3<long> * trianglesCH = new HACD::Vec3<long>[nTriangles]; myHACD.GetCH(c, pointsCH, trianglesCH); // points for(size_t v = 0; v < nPoints; v++) { vertices[3*v] = pointsCH[v].X(); vertices[3*v+1] = pointsCH[v].Y(); vertices[3*v+2] = pointsCH[v].Z(); } // triangles for(size_t f = 0; f < nTriangles; f++) { triangles[3*f] = trianglesCH[f].X(); triangles[3*f+1] = trianglesCH[f].Y(); triangles[3*f+2] = trianglesCH[f].Z(); } delete [] pointsCH; delete [] trianglesCH; ConvexResult r(nPoints, vertices, nTriangles, triangles); convexDecomposition.ConvexDecompResult(r); } for (int i=0;i<convexDecomposition.m_convexShapes.size();i++) { btVector3 centroid = convexDecomposition.m_convexCentroids[i]; trans.setOrigin(centroid); btConvexHullShape* convexShape = convexDecomposition.m_convexShapes[i]; compound->addChildShape(trans,convexShape); btRigidBody* body; body = localCreateRigidBody( 1.0, trans,convexShape); } /* for (int i=0;i<convexDecomposition.m_convexShapes.size();i++) { btVector3 centroid = convexDecomposition.m_convexCentroids[i]; trans.setOrigin(centroid); btConvexHullShape* convexShape = convexDecomposition.m_convexShapes[i]; compound->addChildShape(trans,convexShape); btRigidBody* body; body = localCreateRigidBody( 1.0, trans,convexShape); }*/ #if 1 btScalar mass=10.f; trans.setOrigin(-convexDecompositionObjectOffset); btRigidBody* body = localCreateRigidBody( mass, trans,compound); body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); convexDecompositionObjectOffset.setZ(6); trans.setOrigin(-convexDecompositionObjectOffset); body = localCreateRigidBody( mass, trans,compound); body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); convexDecompositionObjectOffset.setZ(-6); trans.setOrigin(-convexDecompositionObjectOffset); body = localCreateRigidBody( mass, trans,compound); body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); #endif } if (outputFile) fclose(outputFile); } #ifdef TEST_SERIALIZATION //test serializing this int maxSerializeBufferSize = 1024*1024*5; btDefaultSerializer* serializer = new btDefaultSerializer(maxSerializeBufferSize); m_dynamicsWorld->serialize(serializer); FILE* f2 = fopen("testFile.bullet","wb"); fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2); fclose(f2); exitPhysics(); //now try again from the loaded file setupEmptyDynamicsWorld(); #endif //TEST_SERIALIZATION #endif //NO_OBJ_TO_BULLET #ifdef TEST_SERIALIZATION btBulletWorldImporter* fileLoader = new btBulletWorldImporter(m_dynamicsWorld); //fileLoader->setVerboseMode(true); fileLoader->loadFile("testFile.bullet"); //fileLoader->loadFile("testFile64Double.bullet"); //fileLoader->loadFile("testFile64Single.bullet"); //fileLoader->loadFile("testFile32Single.bullet"); #endif //TEST_SERIALIZATION }
void VehicleDemo::clientResetScene() { gVehicleSteering = 0.f; m_carChassis->setCenterOfMassTransform(btTransform::getIdentity()); m_carChassis->setLinearVelocity(btVector3(0,0,0)); m_carChassis->setAngularVelocity(btVector3(0,0,0)); m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_carChassis->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); if (m_vehicle) { m_vehicle->resetSuspension(); for (int i=0;i<m_vehicle->getNumWheels();i++) { //synchronize the wheels with the (interpolated) chassis worldtransform m_vehicle->updateWheelTransform(i,true); } } }
void BasicDemo3D::outputDebugInfo(int & xOffset,int & yStart, int yIncr) { char buf[124]; glDisable(GL_LIGHTING); glColor3f(0, 0, 0); glRasterPos3f(xOffset,yStart,0); sprintf(buf,"mouse to interact"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"space to reset"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"cursor keys and z,x to navigate"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"i to toggle simulation, s single step"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"q to quit"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"h to toggle help text"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"p to toggle profiling (+results to file)"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"w to toggle wireframe/solid rendering"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"c to toggle constraint drawing"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"b to draw single constraint batch"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"u to toggle between CPU and CUDA solvers"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"d to toggle between different batch builders"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"m to toggle between CUDA / CPU motion integrators"); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; if (getDynamicsWorld()) { glRasterPos3f(xOffset,yStart,0); sprintf(buf,"# objects = %d",getDynamicsWorld()->getNumCollisionObjects()); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"# pairs = %d",getDynamicsWorld()->getBroadphase()->getOverlappingPairCache()->getNumOverlappingPairs()); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"# skipped collisions=%d",gSkippedCol); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); sprintf(buf,"# processed collisions=%d",gProcessedCol); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; glRasterPos3f(xOffset,yStart,0); btScalar fract = (gProcessedCol+gSkippedCol)? btScalar(gSkippedCol)/(gProcessedCol+gSkippedCol) : 0.f; sprintf(buf,"culled narrowphase collisions=%f",fract); GLDebugDrawString(xOffset,yStart,buf); yStart += yIncr; gProcessedCol = 0; gSkippedCol = 0; } } // BasicDemo3D::outputDebugInfo()
void ForkLiftDemo::clientResetScene() { gVehicleSteering = 0.f; gBreakingForce = defaultBreakingForce; gEngineForce = 0.f; m_carChassis->setCenterOfMassTransform(btTransform::getIdentity()); m_carChassis->setLinearVelocity(btVector3(0,0,0)); m_carChassis->setAngularVelocity(btVector3(0,0,0)); m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_carChassis->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); if (m_vehicle) { m_vehicle->resetSuspension(); for (int i=0;i<m_vehicle->getNumWheels();i++) { //synchronize the wheels with the (interpolated) chassis worldtransform m_vehicle->updateWheelTransform(i,true); } } btTransform liftTrans; liftTrans.setIdentity(); liftTrans.setOrigin(m_liftStartPos); m_liftBody->activate(); m_liftBody->setCenterOfMassTransform(liftTrans); m_liftBody->setLinearVelocity(btVector3(0,0,0)); m_liftBody->setAngularVelocity(btVector3(0,0,0)); btTransform forkTrans; forkTrans.setIdentity(); forkTrans.setOrigin(m_forkStartPos); m_forkBody->activate(); m_forkBody->setCenterOfMassTransform(forkTrans); m_forkBody->setLinearVelocity(btVector3(0,0,0)); m_forkBody->setAngularVelocity(btVector3(0,0,0)); // m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); m_liftHinge->setLimit(0.0f, 0.0f); m_liftHinge->enableAngularMotor(false, 0, 0); m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(0.1f); m_forkSlider->setPoweredLinMotor(false); btTransform loadTrans; loadTrans.setIdentity(); loadTrans.setOrigin(m_loadStartPos); m_loadBody->activate(); m_loadBody->setCenterOfMassTransform(loadTrans); m_loadBody->setLinearVelocity(btVector3(0,0,0)); m_loadBody->setAngularVelocity(btVector3(0,0,0)); }
void DemoApplication::keyboardCallback(unsigned char key, int x, int y) { (void)x; (void)y; m_lastKey = 0; #ifndef BT_NO_PROFILE if (key >= 0x31 && key <= 0x39) { int child = key-0x31; m_profileIterator->Enter_Child(child); } if (key==0x30) { m_profileIterator->Enter_Parent(); } #endif //BT_NO_PROFILE switch (key) { case 'q' : #ifdef BT_USE_FREEGLUT //return from glutMainLoop(), detect memory leaks etc. glutLeaveMainLoop(); #else exit(0); #endif break; case 'l' : stepLeft(); break; case 'r' : stepRight(); break; case 'f' : stepFront(); break; case 'b' : stepBack(); break; case 'z' : zoomIn(); break; case 'x' : zoomOut(); break; case 'i' : toggleIdle(); break; case 'g' : m_enableshadows=!m_enableshadows;break; case 'u' : m_shapeDrawer->enableTexture(!m_shapeDrawer->enableTexture(false));break; case 'h': if (m_debugMode & btIDebugDraw::DBG_NoHelpText) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoHelpText); else m_debugMode |= btIDebugDraw::DBG_NoHelpText; break; case 'w': if (m_debugMode & btIDebugDraw::DBG_DrawWireframe) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawWireframe); else m_debugMode |= btIDebugDraw::DBG_DrawWireframe; break; case 'p': if (m_debugMode & btIDebugDraw::DBG_ProfileTimings) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_ProfileTimings); else m_debugMode |= btIDebugDraw::DBG_ProfileTimings; break; case '=': { int maxSerializeBufferSize = 1024*1024*5; btDefaultSerializer* serializer = new btDefaultSerializer(maxSerializeBufferSize); //serializer->setSerializationFlags(BT_SERIALIZE_NO_DUPLICATE_ASSERT); m_dynamicsWorld->serialize(serializer); FILE* f2 = fopen("testFile.bullet","wb"); fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2); fclose(f2); delete serializer; break; } case 'm': if (m_debugMode & btIDebugDraw::DBG_EnableSatComparison) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_EnableSatComparison); else m_debugMode |= btIDebugDraw::DBG_EnableSatComparison; break; case 'n': if (m_debugMode & btIDebugDraw::DBG_DisableBulletLCP) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DisableBulletLCP); else m_debugMode |= btIDebugDraw::DBG_DisableBulletLCP; break; case 't' : if (m_debugMode & btIDebugDraw::DBG_DrawText) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawText); else m_debugMode |= btIDebugDraw::DBG_DrawText; break; case 'y': if (m_debugMode & btIDebugDraw::DBG_DrawFeaturesText) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawFeaturesText); else m_debugMode |= btIDebugDraw::DBG_DrawFeaturesText; break; case 'a': if (m_debugMode & btIDebugDraw::DBG_DrawAabb) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawAabb); else m_debugMode |= btIDebugDraw::DBG_DrawAabb; break; case 'c' : if (m_debugMode & btIDebugDraw::DBG_DrawContactPoints) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawContactPoints); else m_debugMode |= btIDebugDraw::DBG_DrawContactPoints; break; case 'C' : if (m_debugMode & btIDebugDraw::DBG_DrawConstraints) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawConstraints); else m_debugMode |= btIDebugDraw::DBG_DrawConstraints; break; case 'L' : if (m_debugMode & btIDebugDraw::DBG_DrawConstraintLimits) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawConstraintLimits); else m_debugMode |= btIDebugDraw::DBG_DrawConstraintLimits; break; case 'd' : if (m_debugMode & btIDebugDraw::DBG_NoDeactivation) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoDeactivation); else m_debugMode |= btIDebugDraw::DBG_NoDeactivation; if (m_debugMode & btIDebugDraw::DBG_NoDeactivation) { gDisableDeactivation = true; } else { gDisableDeactivation = false; } break; case 'o' : { m_ortho = !m_ortho;//m_stepping = !m_stepping; break; } case 's' : clientMoveAndDisplay(); break; // case ' ' : newRandom(); break; case ' ': clientResetScene(); break; case '1': { if (m_debugMode & btIDebugDraw::DBG_EnableCCD) m_debugMode = m_debugMode & (~btIDebugDraw::DBG_EnableCCD); else m_debugMode |= btIDebugDraw::DBG_EnableCCD; break; } case '.': { shootBox(getRayTo(x,y));//getCameraTargetPosition()); break; } case '+': { m_ShootBoxInitialSpeed += 10.f; break; } case '-': { m_ShootBoxInitialSpeed -= 10.f; break; } default: // std::cout << "unused key : " << key << std::endl; break; } if (getDynamicsWorld() && getDynamicsWorld()->getDebugDrawer()) getDynamicsWorld()->getDebugDrawer()->setDebugMode(m_debugMode); }