Table of contents
OgreBullet_Collision_test.h
/* ----------------------------------------------------------------------------- Filename: OgreBullet_Collision_test.h ----------------------------------------------------------------------------- This source file is generated by the Ogre AppWizard. Check out: http://conglomerate.berlios.de/wiki/doku.php?id=ogrewizards Based on the Example Framework for OGRE (Object-oriented Graphics Rendering Engine) Copyright (c) 2000-2007 The OGRE Team For the latest info, see http://www.ogre3d.org/ You may use this sample code for anything you like, it is not covered by the LGPL like the rest of the OGRE engine. ----------------------------------------------------------------------------- */ #ifndef __OgreBullet_Collision_test_h_ #define __OgreBullet_Collision_test_h_ #include "ExampleApplication.h" #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #include "../res/resource.h" #endif #include "OgreBulletDynamicsRigidBody.h" // for OgreBullet #include "Shapes/OgreBulletCollisionsStaticPlaneShape.h" // for static planes #include "Shapes/OgreBulletCollisionsBoxShape.h" // for Boxes class OgreBullet_Collision_testFrameListener : public ExampleFrameListener { private: SceneManager* mSceneMgr; OgreBulletDynamics::DynamicsWorld *mWorld; // OgreBullet World OgreBulletCollisions::DebugDrawer *debugDrawer; int mNumEntitiesInstanced; std::deque<OgreBulletDynamics::RigidBody *> mBodies; std::deque<OgreBulletCollisions::CollisionShape *> mShapes; public: OgreBullet_Collision_testFrameListener( SceneManager *sceneMgr, RenderWindow* win, Camera* cam, Vector3 &gravityVector, AxisAlignedBox &bounds) : ExampleFrameListener(win, cam), mSceneMgr(sceneMgr) { mMoveSpeed = 50; // defined in ExampleFrameListener mNumEntitiesInstanced = 0; // how many shapes are created mSceneMgr = sceneMgr; // Start Bullet mWorld = new OgreBulletDynamics::DynamicsWorld(mSceneMgr, bounds, gravityVector); // add Debug info display tool debugDrawer = new OgreBulletCollisions::DebugDrawer(); debugDrawer->setDrawWireframe(true); // we want to see the Bullet containers mWorld->setDebugDrawer(debugDrawer); mWorld->setShowDebugShapes(true); // enable it if you want to see the Bullet containers SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode("debugDrawer", Ogre::Vector3::ZERO); node->attachObject(static_cast <SimpleRenderable *> (debugDrawer)); // Define a floor plane mesh Entity *ent; Plane p; p.normal = Vector3(0,1,0); p.d = 0; MeshManager::getSingleton().createPlane("FloorPlane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, p, 200000, 200000, 20, 20, true, 1, 9000, 9000, Vector3::UNIT_Z); // Create an entity (the floor) ent = mSceneMgr->createEntity("floor", "FloorPlane"); ent->setMaterialName("Examples/BumpyMetal"); mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent); // add collision detection to it OgreBulletCollisions::CollisionShape *Shape; Shape = new OgreBulletCollisions::StaticPlaneCollisionShape(Ogre::Vector3(0,1,0), 0); // (normal vector, distance) // a body is needed for the shape OgreBulletDynamics::RigidBody *defaultPlaneBody = new OgreBulletDynamics::RigidBody("BasePlane", mWorld); defaultPlaneBody->setStaticShape(Shape, 0.1, 0.8);// (shape, restitution, friction) // push the created objects to the deques mShapes.push_back(Shape); mBodies.push_back(defaultPlaneBody); } ~OgreBullet_Collision_testFrameListener(){ // OgreBullet physic delete - RigidBodies std::deque<OgreBulletDynamics::RigidBody *>::iterator itBody = mBodies.begin(); while (mBodies.end() != itBody) { delete *itBody; ++itBody; } // OgreBullet physic delete - Shapes std::deque<OgreBulletCollisions::CollisionShape *>::iterator itShape = mShapes.begin(); while (mShapes.end() != itShape) { delete *itShape; ++itShape; } mBodies.clear(); mShapes.clear(); delete mWorld->getDebugDrawer(); mWorld->setDebugDrawer(0); delete mWorld; } bool frameStarted(const FrameEvent& evt) { bool ret = ExampleFrameListener::frameStarted(evt); mWorld->stepSimulation(evt.timeSinceLastFrame); // update Bullet Physics animation return ret; } bool frameEnded(const FrameEvent& evt) { bool ret = ExampleFrameListener::frameEnded(evt); mWorld->stepSimulation(evt.timeSinceLastFrame); // update Bullet Physics animation return ret; } virtual bool processUnbufferedKeyInput(const FrameEvent& evt) { bool ret = ExampleFrameListener::processUnbufferedKeyInput(evt); // create and throw a box if 'B' is pressed if(mKeyboard->isKeyDown(OIS::KC_B) && mTimeUntilNextToggle <=0) { Vector3 size = Vector3::ZERO; // size of the box // starting position of the box Vector3 position = (mCamera->getDerivedPosition() + mCamera->getDerivedDirection().normalisedCopy() * 10); // create an ordinary, Ogre mesh with texture Entity *entity = mSceneMgr->createEntity( "Box" + StringConverter::toString(mNumEntitiesInstanced), "cube.mesh"); entity->setCastShadows(true); // we need the bounding box of the box to be able to set the size of the Bullet-box AxisAlignedBox boundingB = entity->getBoundingBox(); size = boundingB.getSize(); size /= 2.0f; // only the half needed size *= 0.95f; // Bullet margin is a bit bigger so we need a smaller size // (Bullet 2.76 Physics SDK Manual page 18) entity->setMaterialName("Examples/BumpyMetal"); SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); node->attachObject(entity); node->scale(0.05f, 0.05f, 0.05f); // the cube is too big for us size *= 0.05f; // don't forget to scale down the Bullet-box too // after that create the Bullet shape with the calculated size OgreBulletCollisions::BoxCollisionShape *sceneBoxShape = new OgreBulletCollisions::BoxCollisionShape(size); // and the Bullet rigid body OgreBulletDynamics::RigidBody *defaultBody = new OgreBulletDynamics::RigidBody( "defaultBoxRigid" + StringConverter::toString(mNumEntitiesInstanced), mWorld); defaultBody->setShape( node, sceneBoxShape, 0.6f, // dynamic body restitution 0.6f, // dynamic body friction 1.0f, // dynamic bodymass position, // starting position of the box Quaternion(0,0,0,1));// orientation of the box mNumEntitiesInstanced++; defaultBody->setLinearVelocity( mCamera->getDerivedDirection().normalisedCopy() * 7.0f ); // shooting speed // push the created objects to the dequese mShapes.push_back(sceneBoxShape); mBodies.push_back(defaultBody); mTimeUntilNextToggle = 0.5; } return ret; } }; class OgreBullet_Collision_testApp : public ExampleApplication { public: OgreBullet_Collision_testApp() {} ~OgreBullet_Collision_testApp() { } protected: virtual void createCamera(void) { // Create the camera mCamera = mSceneMgr->createCamera("PlayerCam"); // Position it at 500 in Z direction mCamera->setPosition(Vector3(0,18,70)); // Look back along -Z mCamera->lookAt(Vector3(0,0,-300)); mCamera->setNearClipDistance(5); } virtual bool configure(void) { // Show the configuration dialog and initialise the system // You can skip this and use root.restoreConfig() to load configuration // settings if you were sure there are valid ones saved in ogre.cfg if(mRoot->showConfigDialog()) { // If returned true, user clicked OK so initialise // Here we choose to let the system create a default rendering window by passing 'true' mWindow = mRoot->initialise(true); // Let's add a nice window icon #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 HWND hwnd; mWindow->getCustomAttribute("WINDOW", (void*)&hwnd); LONG iconID = (LONG)LoadIcon( GetModuleHandle(0), MAKEINTRESOURCE(IDI_APPICON) ); SetClassLong( hwnd, GCL_HICON, iconID ); #endif return true; } else { return false; } } // Just override the mandatory create scene method virtual void createScene(void) { // Set ambient light mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); // Create a light Light* l = mSceneMgr->createLight("MainLight"); l->setPosition(20,80,50); } // Create new frame listener void createFrameListener(void) { mFrameListener= new OgreBullet_Collision_testFrameListener( mSceneMgr, mWindow, mCamera, Vector3(0,-9.81,0), // gravity vector for Bullet AxisAlignedBox (Ogre::Vector3 (-10000, -10000, -10000), //aligned box for Bullet Ogre::Vector3 (10000, 10000, 10000))); mRoot->addFrameListener(mFrameListener); } }; #endif // #ifndef __OgreBullet_Collision_test_h_
OgreBullet_Collision_test.cpp
/* ----------------------------------------------------------------------------- Filename: OgreBullet_Collision_test.cpp ----------------------------------------------------------------------------- This source file is generated by the Ogre AppWizard. Check out: http://conglomerate.berlios.de/wiki/doku.php?id=ogrewizards Based on the Example Framework for OGRE (Object-oriented Graphics Rendering Engine) Copyright (c) 2000-2007 The OGRE Team For the latest info, see http://www.ogre3d.org/ You may use this sample code for anything you like, it is not covered by the LGPL like the rest of the OGRE engine. ----------------------------------------------------------------------------- */ #include "OgreBullet_Collision_test.h" #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include "windows.h" #endif #ifdef __cplusplus extern "C" { #endif #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) #else int main(int argc, char *argv[]) #endif { // Create application object OgreBullet_Collision_testApp app; try { app.go(); } catch( Ogre::Exception& e ) { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL); #else std::cerr << "An exception has occured: " << e.getFullDescription().c_str() << std::endl; #endif } return 0; } #ifdef __cplusplus } #endif