⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simplescenesapplication.cpp

📁 使用stl技术,(还没看,是听说的)
💻 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 + -