📄 landscape.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 + -