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

📄 landscape.cpp

📁 使用stl技术,(还没看,是听说的)
💻 CPP
字号:
#include "Landscape.h"

#if OGRE_PLATFORM == PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#if OGRE_PLATFORM == PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char *argv[])
#endif
{
    LandscapeApplication app;

    SET_TERM_HANDLER;
    
    try 
	{
		app.go();
    } 
	catch( Ogre::Exception& e )
	{
#if OGRE_PLATFORM == PLATFORM_WIN32
        MessageBox( 0, 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;
}

LandscapeFrameListener::LandscapeFrameListener(RenderWindow* win, Camera* cam,Real time_step,OgreOde::Vehicle *vehicle,Root *root) : ExampleFrameListener(win, cam)
{
	// Reduce move speed
    mMoveSpeed = 25;

	// Create something that will step the world automatically
	_stepper = new OgreOde::ForwardFixedQuickStepper(time_step);
	_stepper->setAutomatic(OgreOde::Stepper::AutoMode_PostFrame,root);

	_vehicle = vehicle;

	_ray_query = mCamera->getSceneManager()->createRayQuery(Ray());
}

LandscapeFrameListener::~LandscapeFrameListener()
{
	delete _stepper;
	mCamera->getSceneManager()->destroyQuery(_ray_query);
}

bool LandscapeFrameListener::frameStarted(const FrameEvent& evt)
{
	Real time = evt.timeSinceLastFrame;

    bool ret = ExampleFrameListener::frameStarted(evt);

	if(mInputDevice->isKeyDown(KC_U)) _stepper->pause(false);
	if(mInputDevice->isKeyDown(KC_P)) _stepper->pause(true);

	if(!_stepper->isPaused())
	{
		_vehicle->setInputs(mInputDevice->isKeyDown(KC_J),mInputDevice->isKeyDown(KC_L),mInputDevice->isKeyDown(KC_I),mInputDevice->isKeyDown(KC_K));
		_vehicle->update(time);
	}

	// Thanks to Ahmed!
	const Real followFactor = 0.05; 
	const Real camHeight = 5.0; 
	const Real camDistance = 9.0; 
	const Real camLookAhead = 6.0;

	Quaternion q = _vehicle->getSceneNode()->getOrientation(); 
	Vector3 toCam = _vehicle->getSceneNode()->getPosition(); 

	toCam.y += camHeight; 
	toCam.z -= camDistance * q.zAxis().z; 
	toCam.x -= camDistance * q.zAxis().x; 
      
	mCamera->move( (toCam - mCamera->getPosition()) * followFactor ); 
	mCamera->lookAt(_vehicle->getSceneNode()->getPosition() + ((_vehicle->getSceneNode()->getOrientation() * Vector3::UNIT_Z) * camLookAhead));

	static Ray ray;
    ray.setOrigin(mCamera->getPosition() - Vector3(0,5,0));
    ray.setDirection(Vector3::UNIT_Y);
    _ray_query->setRay(ray);
    RaySceneQueryResult& result = _ray_query->execute();
    RaySceneQueryResult::iterator i = result.begin();
    if (i != result.end() && i->worldFragment)
    {
        SceneQuery::WorldFragment* wf = i->worldFragment;
        mCamera->setPosition(mCamera->getPosition().x,i->worldFragment->singleIntersection.y + 5.0,mCamera->getPosition().z);
    }

	return ret;
}

LandscapeApplication::LandscapeApplication()
{
	_world = 0;
	_time_step = 0.01;
	_vehicle = 0;
	_terrain = 0;
}

void LandscapeApplication::chooseSceneManager(void)
{
    mSceneMgr = mRoot->getSceneManager( ST_EXTERIOR_CLOSE );
}

void LandscapeApplication::setupResources(void)
{
	ExampleApplication::setupResources();
	ResourceManager::addCommonArchiveEx("../../../../OgreOde/demos/Media/OgreOdeDemos.zip","Zip");		
}

void LandscapeApplication::createCamera(void)
{
    // Create the camera
    mCamera = mSceneMgr->createCamera("PlayerCam");

    mCamera->setPosition(Vector3(128,25,128));
    mCamera->lookAt(Vector3(0,0,-300));
    mCamera->setNearClipDistance( 1 );
    mCamera->setFarClipDistance( 1000 );
}
   
// Just override the mandatory create scene method
void LandscapeApplication::createScene(void)
{
    Plane waterPlane;

    // Set ambient light
    mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));

    // Create a light
    Light* l = mSceneMgr->createLight("MainLight");

	// Accept default settings: point light, white diffuse, just set position
    // NB I could attach the light to a SceneNode if I wanted it to move automatically with
    //  other objects, but I don't
    l->setPosition(20,80,50);

    // Fog
    // NB it's VERY important to set this before calling setWorldGeometry 
    // because the vertex program picked will be different
    ColourValue fadeColour(0.93, 0.86, 0.76);
    mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
    mWindow->getViewport(0)->setBackgroundColour(fadeColour);

	// Set up the terrain according to our own settings
	String config_file("../../../../OgreOde/demos/Media/landscape.cfg");
    mSceneMgr -> setWorldGeometry( config_file );

    // Infinite far plane?
    if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
    {
		mCamera->setFarClipDistance(0);
    }

    // Define the required skyplane
    Plane plane;
    
	plane.d = 5000;
    plane.normal = -Vector3::UNIT_Y;

    // Set a nice viewpoint
    mCamera->setPosition(707,15,528);
    mCamera->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));

	_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);

	_vehicle = new OgreOde::Vehicle("Jeep","Jeep_Body.mesh",3,Vector3(0,-1,0));

	// Move the vehicle
	Vector3 v_pos = mCamera->getPosition() + (mCamera->getDirection() * 10.0);
	_vehicle->setPosition(v_pos);

#ifdef OGREODE_TERRAINGEOMETRY
	_terrain = new OgreOde::TerrainGeometry(config_file,_world->getDefaultSpace());
	_terrain->setHeightListener(this);
#else
	_terrain = new OgreOde::InfinitePlaneGeometry(Plane(Vector3(0,1,0),v_pos.y - 2.0),_world->getDefaultSpace());
#endif
			
	// Create all the wheels, using the supplied mesh and with the specified offset
	// realtive to the car. The mass is 0.02 units, in our case that's around 20Kg
	_vehicle->addWheel("Jeep_WheelL.mesh",Vector3(1,-1.1,1.8),0.06);
	_vehicle->addWheel("Jeep_WheelR.mesh",Vector3(-1,-1.1,1.8),0.06);
	_vehicle->addWheel("Jeep_WheelL.mesh",Vector3(1,-1.1,-1.6),0.06);
	_vehicle->addWheel("Jeep_WheelR.mesh",Vector3(-1,-1.1,-1.6),0.06);

	// Set up the suspension spring and damping constants, passing the rate we're going to
	// be stepping the world so it can work out the forces needed each step
	// We could do this per-wheel, like the other factors, but it's easier to do it this way.
	// N.B. You must create the wheels before you can do this!
	_vehicle->setSuspension(50,0.9,_time_step);

	// Set the steer, power and brake factor for each wheel, initially we're rear wheel drive
	_vehicle->getWheel(0)->setFactors(1,1,0.75);
	_vehicle->getWheel(1)->setFactors(1,1,0.75);
	_vehicle->getWheel(2)->setFactors(0,1,0.25);
	_vehicle->getWheel(3)->setFactors(0,1,0.25);

	// Set the engine (and other drivetrain) parameters, lots of work still to do here
	_vehicle->getEngine()->setRevLimit(30.0);
	_vehicle->getEngine()->setTorque(0.5,10.0);
	_vehicle->getEngine()->setBrakeForce(15.0);

	_world->setCollisionListener(this);
}

// Create new frame listener
void LandscapeApplication::createFrameListener(void)
{
    mFrameListener= new LandscapeFrameListener(mWindow, mCamera,_time_step,_vehicle,mRoot);
    mRoot->addFrameListener(mFrameListener);
}

#ifdef OGREODE_TERRAINGEOMETRY
Real LandscapeApplication::heightAt(const Vector3& position)
{
	return _terrain->getHeightAt(position);
}
#endif 

bool LandscapeApplication::collision(OgreOde::Contact* contact)
{
	contact->setBouncyness(0.0);
	contact->setCoulombFriction(18.0);
	return true;
}

LandscapeApplication::~LandscapeApplication()
{
	delete _terrain;
	delete _vehicle;
	delete _world;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -