📄 simplescenesapplication.cpp
字号:
/*
SimpleScenesApplication.cpp
--------------------------
The main applicatin that handles switching between the
different scenes in this demo, as well as any common
setup and input handling.
*/
#include "SimpleScenesApplication.h"
// The tests we can display
#include "SimpleScenes_BoxStack.h"
#include "SimpleScenes_Buggy.h"
#include "SimpleScenes_Chain.h"
#include "SimpleScenes_TriMesh.h"
#include "SimpleScenes_Crash.h"
#include "SimpleScenes_Joints.h"
// Windows stuff
#if OGRE_PLATFORM == PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
/*
Windows entry point
*/
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT nCmdShow)
#else
int main(int argc,char* argv[])
#endif
{
// Create the application and try to run it
SimpleScenesApplication app;
SET_TERM_HANDLER;
try
{
app.go();
}
catch(Ogre::Exception& e)
{
#if OGRE_PLATFORM == PLATFORM_WIN32
MessageBox( 0, e.getFullDescription().c_str(), "OgreOde SimpleScenes: Exception", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
std::cerr << "An exception has occured: " << e.getFullDescription().c_str() << std::endl;
#endif
}
return 0;
}
/*
The frame listener is informed before every frame
*/
bool SimpleScenesFrameListener::frameStarted(const FrameEvent& evt)
{
// Do the default demo input handling and keep our UI display
// in sync with the other stuff (frame rate, logo, etc)
bool show = mStatsOn;
bool bOK = ExampleFrameListener::frameStarted(evt);
if(mStatsOn != show)
{
Overlay* pOver = (Overlay*)OverlayManager::getSingleton().getByName("OgreOdeTest/Overlay");
if(mStatsOn) pOver->show();
else pOver->hide();
}
// Tell the demo application that it needs to handle input
_demo->frameStarted(evt,mInputDevice);
// Quit or carry on according to the normal demo input
return bOK;
}
/*
The frame listener is informed after every frame
*/
bool SimpleScenesFrameListener::frameEnded(const FrameEvent& evt)
{
// Tell our demo that the frame's ended before doing default processing
_demo->frameEnded(evt,mInputDevice);
return ExampleFrameListener::frameEnded(evt);;
}
/*
Create the scene from an Ogre point of view
and create the common OgreOde things we'll need
*/
void SimpleScenesApplication::createScene(void)
{
// Set up shadowing
mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
mSceneMgr->setShadowFarDistance(30);
if(StringUtil::startsWith(mRoot->getRenderSystem()->getName(),"direct")) mSceneMgr->setShadowTextureSettings(1024, 2);
else mSceneMgr->setShadowTextureSettings(512, 2);
// Add some default lighting to the scene
mSceneMgr->setAmbientLight(ColourValue(0.25, 0.25, 0.25));
// Create a directional light to shadow and light the bodies
_spot = mSceneMgr->createLight("Spot");
_spot->setType(Light::LT_DIRECTIONAL);
_spot->setDirection(-0.40824828,-0.81649655,-0.40824828);
_spot->setCastShadows(true);
_spot->setSpecularColour(1,1,0.8);
// Give us some sky
mSceneMgr->setSkyBox(true,"kk3d/DesertVII",5000,true);
// Position and orient the camera
mCamera->setPosition(13,4.5,0);
mCamera->lookAt(0,0.5,0);
mCamera->setNearClipDistance(0.5);
// Create the ODE world
_world = new OgreOde::World(mSceneMgr);
_world->setGravity(Vector3(0,-9.80665,0));
_world->setCFM(10e-5);
_world->setERP(0.8);
_world->setAutoSleep(true);
_world->setContactCorrectionVelocity(1.0);
// Create something that will step the world, but don't do it automatically
_stepper = new OgreOde::ForwardFixedQuickStepper(_time_step);
_stepper->setAutomatic(OgreOde::Stepper::AutoMode_NotAutomatic,mRoot);
// Create a default plane to act as the ground
_plane = new OgreOde::InfinitePlaneGeometry(Plane(Vector3(0,1,0),0),_world->getDefaultSpace());
// Use a load of meshes to represent the floor
int i = 0;
for(Real z = -80.0;z <= 80.0;z += 20.0)
{
for(Real x = -80.0;x <= 80.0;x += 20.0)
{
String name = String("Plane_") + StringConverter::toString(i++);
Entity* mPlane = mSceneMgr->createEntity(name, "Plane.mesh");
mPlane->setCastShadows(false);
SceneNode* mPlaneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(name);
mPlaneNode->attachObject(mPlane);
mPlaneNode->setPosition(x,0,z);
}
}
// Load up our UI and display it
Overlay* pOver = (Overlay*)OverlayManager::getSingleton().getByName("OgreOdeDemos/Overlay");
pOver->show();
// Initialise stuff
_test = 0;
_delay = 1.0;
}
/*
The frame listener will notify us when a frame's
about to be started, so we can update stuff
*/
void SimpleScenesApplication::frameStarted(const FrameEvent& evt,InputReader* mInputDevice)
{
// If we're looking at something then adjust the camera
if(_test && _test->getLastNode())
{
if(_looking)
{
mCamera->lookAt(_test->getLastNode()->getPosition());
if(_chasing)
{
// Thanks to Ahmed!
const Real followFactor = 0.1;
const Real camHeight = 5.0;
const Real camDistance = 7.0;
Quaternion q = _test->getLastNode()->getOrientation();
Vector3 toCam = _test->getLastNode()->getPosition();
toCam.y += camHeight;
toCam.z -= camDistance * q.zAxis().z;
toCam.x -= camDistance * q.zAxis().x;
mCamera->move( (toCam - mCamera->getPosition()) * followFactor );
}
}
}
}
/*
The frame listener will let us know when a frame's ended. So we
can do stuff that we can't do in a frame started event
e.g. delete things that we can't delete at the start of a frame,
presumably because some processing has already been done, leaving
things dangling, like particle systems.
*/
void SimpleScenesApplication::frameEnded(const FrameEvent& evt,InputReader* mInputDevice)
{
Real time = evt.timeSinceLastFrame;
// If we're running a test, tell it that a frame's ended
if((_test)&&(!_paused)) _test->frameEnded(time,mInputDevice);
// Step the world, we could get this to do this automatically, but we
// can't be sure of what order the framelisters will fire in
_stepper->step(time);
_delay += time;
if(_delay > 1.0)
{
SimpleScenes* old_test = _test;
// Switch the test we're displaying
if(mInputDevice->isKeyDown(KC_F1))
{
delete _test;
_test = new SimpleScenes_BoxStack();
}
else if(mInputDevice->isKeyDown(KC_F2))
{
delete _test;
_test = new SimpleScenes_Chain();
}
else if(mInputDevice->isKeyDown(KC_F3))
{
delete _test;
_test = new SimpleScenes_Buggy();
}
else if(mInputDevice->isKeyDown(KC_F4))
{
delete _test;
_test = new SimpleScenes_TriMesh();
}
else if(mInputDevice->isKeyDown(KC_F5))
{
delete _test;
_test = new SimpleScenes_Crash();
}
else if(mInputDevice->isKeyDown(KC_F6))
{
delete _test;
_test = new SimpleScenes_Joints();
if(mCamera->getPosition().z < 10.0)
{
Vector3 pos = mCamera->getPosition();
mCamera->setPosition(pos.x,pos.y,10.0);
mCamera->lookAt(0,0,0);
}
}
// If we changed the test...
if((_test)&&(_test != old_test))
{
// Register it with the stepper, so we can (for example) add forces before each step
_stepper->setStepListener(_test);
// Set the UI to show the test's details
GuiManager::getSingleton().getGuiElement("OgreOdeDemos/Name")->setCaption("Name: " + _test->getName());
GuiManager::getSingleton().getGuiElement("OgreOdeDemos/Keys")->setCaption("Keys: " + _test->getKeys());
_delay = 0.0;
}
// Switch shadows on or off
if(mInputDevice->isKeyDown(KC_SPACE))
{
_spot->setCastShadows(!_spot->getCastShadows());
_delay = 0.0;
}
// Look at the last object, chase it, or not
if(mInputDevice->isKeyDown(KC_M))
{
if(_looking)
if(_chasing) _looking = _chasing = false;
else _chasing = true;
else _looking = true;
_delay = 0.0;
}
// Switch debugging objects on or off
if(mInputDevice->isKeyDown(KC_E))
{
_world->setShowDebugObjects(!_world->getShowDebugObjects());
_delay = 0.0;
}
// Pause or unpause the simulation
if(mInputDevice->isKeyDown(KC_P))
{
_paused = !_paused;
_delay = 0.0;
_stepper->pause(_paused);
if(_paused) ParticleSystemManager::getSingleton().setTimeFactor(0.0);
else ParticleSystemManager::getSingleton().setTimeFactor(1.0);
}
}
}
/*
Destructor, delete stuff we created
*/
SimpleScenesApplication::~SimpleScenesApplication(void)
{
delete _test;
delete _plane;
delete _stepper;
delete _world;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -