History: Ogre Bullet Tutorial 1 - Source Code
Source of version: 1 (current)
Copy to clipboard
{maketoc}
!OgreBullet_Collision_test.h
{CODE(wrap="1", colors="c++")} /*
-----------------------------------------------------------------------------
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_{CODE}
!OgreBullet_Collision_test.cpp
{CODE(wrap="1", colors="c++")} /*
-----------------------------------------------------------------------------
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{CODE}