[21] | 1 | #include "Landscape.h" |
---|
| 2 | |
---|
| 3 | |
---|
| 4 | |
---|
| 5 | |
---|
| 6 | //enable this to test it against PLSM2 instead of TSM. |
---|
| 7 | //#define _PLSM2 |
---|
| 8 | // |
---|
| 9 | #ifndef _PLSM2 |
---|
| 10 | |
---|
| 11 | static String config_file ("terrainOgreOde.cfg");// OgreSDK terrain, very small tris |
---|
| 12 | //static String config_file ("landscape.cfg");landy average |
---|
| 13 | //static String config_file("landscape1.cfg");// near flat |
---|
| 14 | //static String config_file("landscape2.cfg");// totally flat + cliffs + small tris |
---|
| 15 | //static String config_file("landscape3.cfg");// same as landy average but huge |
---|
| 16 | //static String config_file("landscape4.cfg");// same as landy average |
---|
| 17 | //static String config_file("landscape5.cfg");// landy average, but very picky |
---|
| 18 | //static String config_file("landscape6.cfg");// near flat |
---|
| 19 | #else //_PLSM2 |
---|
| 20 | static String config_file ("paginglandscape2.cfg"); |
---|
| 21 | #endif //_PLSM2 |
---|
| 22 | |
---|
| 23 | |
---|
| 24 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 |
---|
| 25 | #define WIN32_LEAN_AND_MEAN |
---|
| 26 | #include "windows.h" |
---|
| 27 | |
---|
| 28 | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) |
---|
| 29 | #else |
---|
| 30 | int main(int argc, char *argv[]) |
---|
| 31 | #endif |
---|
| 32 | { |
---|
| 33 | LandscapeApplication app; |
---|
| 34 | |
---|
| 35 | try |
---|
| 36 | { |
---|
| 37 | app.go(); |
---|
| 38 | } |
---|
| 39 | catch( Ogre::Exception& e ) |
---|
| 40 | { |
---|
| 41 | #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 |
---|
| 42 | MessageBox( 0, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL); |
---|
| 43 | #else |
---|
| 44 | std::cerr << "An exception has occured: " << e.getFullDescription().c_str() << std::endl; |
---|
| 45 | #endif |
---|
| 46 | } |
---|
| 47 | |
---|
| 48 | return 0; |
---|
| 49 | } |
---|
| 50 | |
---|
| 51 | using namespace Ogre; |
---|
| 52 | using namespace OgreOde; |
---|
| 53 | using namespace OgreOde_Prefab; |
---|
| 54 | using namespace OgreOde_Loader; |
---|
| 55 | |
---|
| 56 | //------------------------------------------------------------------------------------------------ |
---|
| 57 | static const String carNames[] = { |
---|
| 58 | "Jeep", |
---|
| 59 | "JeepSway", |
---|
| 60 | "Subaru" |
---|
| 61 | }; |
---|
| 62 | static const String carFileNames[] = { |
---|
| 63 | "jeep.ogreode", |
---|
| 64 | "jeep.ogreode", |
---|
| 65 | "subaru.ogreode" |
---|
| 66 | }; |
---|
| 67 | static int sSelectedCar = 0; |
---|
| 68 | static int maxNumCar = 3; |
---|
| 69 | |
---|
| 70 | |
---|
| 71 | //------------------------------------------------------------------------------------------------ |
---|
| 72 | LandscapeFrameListener::LandscapeFrameListener(RenderWindow* win, Camera* cam, |
---|
| 73 | Root *root) : |
---|
| 74 | ExampleFrameListener(win, cam), |
---|
| 75 | mSceneMgr (mCamera->getSceneManager()), |
---|
| 76 | _world (new OgreOde::World(mSceneMgr)), |
---|
| 77 | _terrain(0), |
---|
| 78 | _vehicle(0), |
---|
| 79 | _time_step (0.01) |
---|
| 80 | { |
---|
| 81 | |
---|
| 82 | _world->setGravity(Vector3(0,-9.80665,0)); |
---|
| 83 | _world->setCFM(10e-5); |
---|
| 84 | _world->setERP(0.8); |
---|
| 85 | _world->setAutoSleep(true); |
---|
| 86 | _world->setContactCorrectionVelocity(1.0); |
---|
| 87 | |
---|
| 88 | dotOgreOdeLoader = new OgreOde_Loader::DotLoader (_world); |
---|
| 89 | |
---|
| 90 | |
---|
| 91 | |
---|
| 92 | StepHandler::StepModeType stepModeType; |
---|
| 93 | |
---|
| 94 | const int _stepper_mode_choice = 2; |
---|
| 95 | switch(_stepper_mode_choice) |
---|
| 96 | { |
---|
| 97 | case 0: stepModeType = StepHandler::BasicStep; break; |
---|
| 98 | case 1: stepModeType = StepHandler::FastStep; break; |
---|
| 99 | case 2: stepModeType = StepHandler::QuickStep; break; |
---|
| 100 | |
---|
| 101 | default: stepModeType = StepHandler::QuickStep; break; |
---|
| 102 | } |
---|
| 103 | |
---|
| 104 | const int _stepper_choice = 0; |
---|
| 105 | const Ogre::Real time_scale = Ogre::Real(1.0); |
---|
| 106 | const Ogre::Real max_frame_time = Ogre::Real(1.0 / 4); |
---|
| 107 | const Ogre::Real frame_rate = Ogre::Real(1.0 / 60); |
---|
| 108 | switch (_stepper_choice) |
---|
| 109 | { |
---|
| 110 | case 0: |
---|
| 111 | _stepper = new OgreOde::StepHandler(_world, |
---|
| 112 | StepHandler::QuickStep, |
---|
| 113 | _time_step, |
---|
| 114 | max_frame_time, |
---|
| 115 | time_scale); |
---|
| 116 | |
---|
| 117 | break; |
---|
| 118 | case 1: |
---|
| 119 | _stepper = new OgreOde::ExactVariableStepHandler(_world, |
---|
| 120 | stepModeType, |
---|
| 121 | _time_step, |
---|
| 122 | max_frame_time, |
---|
| 123 | time_scale); |
---|
| 124 | |
---|
| 125 | break; |
---|
| 126 | case 2: |
---|
| 127 | _stepper = new OgreOde::ForwardFixedStepHandler(_world, |
---|
| 128 | stepModeType, |
---|
| 129 | _time_step, |
---|
| 130 | max_frame_time, |
---|
| 131 | time_scale); |
---|
| 132 | |
---|
| 133 | break; |
---|
| 134 | case 3: |
---|
| 135 | default: |
---|
| 136 | _stepper = new OgreOde::ForwardFixedInterpolatedStepHandler (_world, |
---|
| 137 | stepModeType, |
---|
| 138 | _time_step, |
---|
| 139 | frame_rate, |
---|
| 140 | max_frame_time, |
---|
| 141 | time_scale); |
---|
| 142 | break; |
---|
| 143 | } |
---|
| 144 | |
---|
| 145 | _stepper->setAutomatic(OgreOde::StepHandler::AutoMode_PostFrame,root); |
---|
| 146 | |
---|
| 147 | |
---|
| 148 | bool does_center_is_corner = false; |
---|
| 149 | Ogre::Vector3 scale = Ogre::Vector3::ZERO; |
---|
| 150 | int nodes_per_side = 0; |
---|
| 151 | int nodes_per_side_all_pagesW = 0; |
---|
| 152 | int nodes_per_side_all_pagesH = 0; |
---|
| 153 | bool center; |
---|
| 154 | // Terrain Scene Manager should support those... |
---|
| 155 | mSceneMgr->getOption("Scale", &scale); |
---|
| 156 | mSceneMgr->getOption("PageSize", &nodes_per_side); |
---|
| 157 | |
---|
| 158 | Ogre::Real worldWidth, worldHeight; |
---|
| 159 | #ifndef _PLSM2 |
---|
| 160 | if (nodes_per_side == 0) |
---|
| 161 | { |
---|
| 162 | Ogre::ConfigFile config; |
---|
| 163 | Ogre::String val; |
---|
| 164 | |
---|
| 165 | config.load(config_file, "OgreOde", "=", true); |
---|
| 166 | |
---|
| 167 | val = config.getSetting( "PageSize" ); |
---|
| 168 | assert( !val.empty() ); |
---|
| 169 | nodes_per_side = atoi( val.c_str() ); |
---|
| 170 | |
---|
| 171 | val = config.getSetting( "PageWorldX" ); |
---|
| 172 | assert( !val.empty() ); |
---|
| 173 | scale.x = atof( val.c_str() ) / nodes_per_side; |
---|
| 174 | |
---|
| 175 | val = config.getSetting( "MaxHeight" ); |
---|
| 176 | assert( !val.empty() ); |
---|
| 177 | scale.y = atof( val.c_str() ); |
---|
| 178 | |
---|
| 179 | val = config.getSetting( "PageWorldZ" ); |
---|
| 180 | assert( !val.empty() ); |
---|
| 181 | scale.z = atof( val.c_str() ) / nodes_per_side; |
---|
| 182 | |
---|
| 183 | } |
---|
| 184 | center = false; |
---|
| 185 | worldWidth = scale.x * (nodes_per_side - 1); |
---|
| 186 | worldHeight = scale.z * (nodes_per_side - 1); |
---|
| 187 | nodes_per_side_all_pagesW = nodes_per_side; |
---|
| 188 | nodes_per_side_all_pagesH = nodes_per_side; |
---|
| 189 | #else |
---|
| 190 | center = true; |
---|
| 191 | |
---|
| 192 | int w=0; |
---|
| 193 | int h=0; |
---|
| 194 | |
---|
| 195 | mSceneMgr->getOption("Width", &w); |
---|
| 196 | mSceneMgr->getOption("Height", &h); |
---|
| 197 | |
---|
| 198 | |
---|
| 199 | worldWidth = w * (nodes_per_side - 1) * scale.x; |
---|
| 200 | worldHeight = h * (nodes_per_side - 1) * scale.z; |
---|
| 201 | |
---|
| 202 | nodes_per_side_all_pagesW = w * (nodes_per_side); |
---|
| 203 | nodes_per_side_all_pagesH = h * (nodes_per_side); |
---|
| 204 | |
---|
| 205 | bool noInterpolation = true; |
---|
| 206 | mSceneMgr->setOption("queryNoInterpolation", &noInterpolation); |
---|
| 207 | mSceneMgr->setOption("LoadNow", 0); |
---|
| 208 | #endif |
---|
| 209 | |
---|
| 210 | _terrain = new OgreOde::TerrainGeometry(_world, |
---|
| 211 | _world->getDefaultSpace(), |
---|
| 212 | scale, |
---|
| 213 | nodes_per_side_all_pagesW, |
---|
| 214 | nodes_per_side_all_pagesH, |
---|
| 215 | worldWidth, |
---|
| 216 | worldHeight, |
---|
| 217 | center); |
---|
| 218 | //_terrain->setHeightListener(this); |
---|
| 219 | _world->setCollisionListener(this); |
---|
| 220 | |
---|
| 221 | // Create some boxes to play with |
---|
| 222 | #ifdef _DEBUG |
---|
| 223 | const Ogre::Real boxspace = 24.0; |
---|
| 224 | #else |
---|
| 225 | const Ogre::Real boxspace = 12.0; |
---|
| 226 | #endif |
---|
| 227 | for(Real z = -12.0;z <= 12.0;z += boxspace) |
---|
| 228 | { |
---|
| 229 | for(Real x = -12.0;x <= 12.0;x += boxspace) |
---|
| 230 | { |
---|
| 231 | // Create the Ogre box |
---|
| 232 | String name = String("Box_") + StringConverter::toString(x) + "_" + StringConverter::toString(z); |
---|
| 233 | Entity* box = mSceneMgr->createEntity(name,"crate.mesh"); |
---|
| 234 | box->setCastShadows(true); |
---|
| 235 | |
---|
| 236 | SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(name); |
---|
| 237 | node->attachObject(box); |
---|
| 238 | node->setScale(0.15,0.15,0.15); |
---|
| 239 | |
---|
| 240 | // Set the position |
---|
| 241 | Ogre::Vector3 pos(50 + x,130,50 + z); |
---|
| 242 | node->setPosition(pos); |
---|
| 243 | |
---|
| 244 | // Create a box for ODE and attach it to the Ogre version |
---|
| 245 | OgreOde::Body* body = new OgreOde::Body(_world); |
---|
| 246 | node->attachObject(body); |
---|
| 247 | body->setMass(OgreOde::BoxMass(0.5,Vector3(1.5,1.5,1.5))); |
---|
| 248 | |
---|
| 249 | OgreOde::BoxGeometry* geom = new OgreOde::BoxGeometry(Vector3(1.5,1.5,1.5), _world, _world->getDefaultSpace()); |
---|
| 250 | geom->setBody(body); |
---|
| 251 | |
---|
| 252 | } |
---|
| 253 | } |
---|
| 254 | |
---|
| 255 | |
---|
| 256 | // Reduce move speed |
---|
| 257 | mMoveSpeed = 25; |
---|
| 258 | |
---|
| 259 | |
---|
| 260 | _ray_query = mCamera->getSceneManager()->createRayQuery(ray); |
---|
| 261 | _ray_query->setQueryTypeMask(Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK ); |
---|
| 262 | _ray_query->setWorldFragmentType(Ogre::SceneQuery::WFT_SINGLE_INTERSECTION); |
---|
| 263 | ray.setDirection(Vector3::NEGATIVE_UNIT_Y); |
---|
| 264 | |
---|
| 265 | |
---|
| 266 | Root::getSingleton().setFrameSmoothingPeriod(5.0f); |
---|
| 267 | |
---|
| 268 | changeCar(); |
---|
| 269 | |
---|
| 270 | // Load up our UI and display it |
---|
| 271 | Overlay* pOver = (Overlay*)OverlayManager::getSingleton().getByName("OgreOdeDemos/Overlay"); |
---|
| 272 | OverlayManager::getSingleton().getOverlayElement("OgreOdeDemos/Name")->setCaption(String("Name: ") + "Landscape (Terrain + vehicle + box)"); |
---|
| 273 | OverlayManager::getSingleton().getOverlayElement("OgreOdeDemos/Keys")->setCaption(String("Keys: ") + "I/K - Accelerate/Brake, J/L - Turn, X - Change drive mode, N - Change Car"); |
---|
| 274 | OverlayManager::getSingleton().getOverlayElement("OgreOdeDemos/OtherKeys")->setCaption(String("Extra: ") + "E - Debug Object"); |
---|
| 275 | pOver->show(); |
---|
| 276 | |
---|
| 277 | |
---|
| 278 | } |
---|
| 279 | |
---|
| 280 | LandscapeFrameListener::~LandscapeFrameListener() |
---|
| 281 | { |
---|
| 282 | delete _stepper; |
---|
| 283 | mCamera->getSceneManager()->destroyQuery(_ray_query); |
---|
| 284 | delete _terrain; |
---|
| 285 | delete _world; |
---|
| 286 | } |
---|
| 287 | |
---|
| 288 | //------------------------------------------------------------------------------------------------ |
---|
| 289 | void LandscapeFrameListener::changeCar() |
---|
| 290 | { |
---|
| 291 | sSelectedCar = (sSelectedCar + 1) % maxNumCar; |
---|
| 292 | |
---|
| 293 | delete _vehicle; |
---|
| 294 | //_vehicle = new OgreOde_Prefab::Vehicle(carNames[sSelectedCar]); |
---|
| 295 | //_vehicle->load(carFileNames[sSelectedCar]); |
---|
| 296 | _vehicle = static_cast <OgreOde_Prefab::Vehicle *> (dotOgreOdeLoader->loadObject (carFileNames[sSelectedCar], carNames[sSelectedCar])); |
---|
| 297 | // Initially (i.e. in the config file) it's rear wheel drive |
---|
| 298 | _drive = 'R'; |
---|
| 299 | |
---|
| 300 | // Move the vehicle |
---|
| 301 | Vector3 v_pos = mCamera->getPosition() + (mCamera->getDirection() * 15.0); |
---|
| 302 | |
---|
| 303 | v_pos.y += 50.0; |
---|
| 304 | { |
---|
| 305 | ray.setOrigin(v_pos); |
---|
| 306 | _ray_query->setRay(ray); |
---|
| 307 | RaySceneQueryResult& result = _ray_query->execute(); |
---|
| 308 | RaySceneQueryResult::iterator i = result.begin(); |
---|
| 309 | if (i != result.end() && i->worldFragment) |
---|
| 310 | { |
---|
| 311 | const Ogre::Real height = i->worldFragment->singleIntersection.y; |
---|
| 312 | if (v_pos.y < height) |
---|
| 313 | v_pos.y = height + 7.0; |
---|
| 314 | |
---|
| 315 | } |
---|
| 316 | } |
---|
| 317 | |
---|
| 318 | _vehicle->setPosition(v_pos); |
---|
| 319 | |
---|
| 320 | updateInfo(); |
---|
| 321 | } |
---|
| 322 | //------------------------------------------------------------------------------------------------ |
---|
| 323 | void LandscapeFrameListener::updateInfo() |
---|
| 324 | { |
---|
| 325 | Overlay* pOver = (Overlay*)OverlayManager::getSingleton().getByName("OgreOdeDemos/Overlay"); |
---|
| 326 | String newInfo (String("Info: ") + carNames[sSelectedCar]); |
---|
| 327 | switch(_drive) |
---|
| 328 | { |
---|
| 329 | // Switch from rear to front |
---|
| 330 | case 'R': |
---|
| 331 | newInfo = newInfo + " & Front wheel drive"; |
---|
| 332 | break; |
---|
| 333 | |
---|
| 334 | // Switch from front to all |
---|
| 335 | case 'F': |
---|
| 336 | newInfo = newInfo + " & All wheel drive"; |
---|
| 337 | break; |
---|
| 338 | |
---|
| 339 | // Switch from all to rear |
---|
| 340 | case '4': |
---|
| 341 | newInfo = newInfo + " & Rear wheel drive"; |
---|
| 342 | break; |
---|
| 343 | } |
---|
| 344 | OverlayManager::getSingleton().getOverlayElement("OgreOdeDemos/Info")->setCaption(newInfo); |
---|
| 345 | } |
---|
| 346 | //------------------------------------------------------------------------------------------------ |
---|
| 347 | bool LandscapeFrameListener::frameStarted(const FrameEvent& evt) |
---|
| 348 | { |
---|
| 349 | Real time = evt.timeSinceLastFrame; |
---|
| 350 | |
---|
| 351 | bool ret = ExampleFrameListener::frameStarted(evt); |
---|
| 352 | |
---|
| 353 | if (mTimeUntilNextToggle <= 0) |
---|
| 354 | { |
---|
| 355 | // Switch debugging objects on or off |
---|
| 356 | if (mKeyboard->isKeyDown(OIS::KC_E)) |
---|
| 357 | { |
---|
| 358 | _world->setShowDebugGeometries(!_world->getShowDebugGeometries()); |
---|
| 359 | mTimeUntilNextToggle = 0.5; |
---|
| 360 | } |
---|
| 361 | // Switch debugging Contacts on or off |
---|
| 362 | if (mKeyboard->isKeyDown(OIS::KC_B)) |
---|
| 363 | { |
---|
| 364 | _world->setShowDebugContact(!_world->getShowDebugContact()); |
---|
| 365 | mTimeUntilNextToggle = 0.5; |
---|
| 366 | } |
---|
| 367 | |
---|
| 368 | |
---|
| 369 | if(mKeyboard->isKeyDown(OIS::KC_N)) |
---|
| 370 | { |
---|
| 371 | changeCar(); |
---|
| 372 | mTimeUntilNextToggle = 0.5; |
---|
| 373 | } |
---|
| 374 | |
---|
| 375 | if(mKeyboard->isKeyDown(OIS::KC_U)) |
---|
| 376 | { |
---|
| 377 | _stepper->pause(false); |
---|
| 378 | mTimeUntilNextToggle = 0.5; |
---|
| 379 | } |
---|
| 380 | if(mKeyboard->isKeyDown(OIS::KC_P)) |
---|
| 381 | { |
---|
| 382 | _stepper->pause(true); |
---|
| 383 | mTimeUntilNextToggle = 0.5; |
---|
| 384 | } |
---|
| 385 | // Change the drive mode between front, rear and 4wd |
---|
| 386 | if ((mKeyboard->isKeyDown(OIS::KC_X)) && _vehicle) |
---|
| 387 | { |
---|
| 388 | switch(_drive) |
---|
| 389 | { |
---|
| 390 | // Switch from rear to front |
---|
| 391 | case 'R': |
---|
| 392 | _drive = 'F'; |
---|
| 393 | |
---|
| 394 | _vehicle->getWheel(0)->setPowerFactor(1); |
---|
| 395 | _vehicle->getWheel(1)->setPowerFactor(1); |
---|
| 396 | _vehicle->getWheel(2)->setPowerFactor(0); |
---|
| 397 | _vehicle->getWheel(3)->setPowerFactor(0); |
---|
| 398 | |
---|
| 399 | updateInfo(); |
---|
| 400 | break; |
---|
| 401 | |
---|
| 402 | // Switch from front to all |
---|
| 403 | case 'F': |
---|
| 404 | _drive = '4'; |
---|
| 405 | |
---|
| 406 | _vehicle->getWheel(0)->setPowerFactor(0.6); |
---|
| 407 | _vehicle->getWheel(1)->setPowerFactor(0.6); |
---|
| 408 | _vehicle->getWheel(2)->setPowerFactor(0.4); |
---|
| 409 | _vehicle->getWheel(3)->setPowerFactor(0.4); |
---|
| 410 | |
---|
| 411 | updateInfo(); |
---|
| 412 | break; |
---|
| 413 | |
---|
| 414 | // Switch from all to rear |
---|
| 415 | case '4': |
---|
| 416 | _drive = 'R'; |
---|
| 417 | |
---|
| 418 | _vehicle->getWheel(0)->setPowerFactor(0); |
---|
| 419 | _vehicle->getWheel(1)->setPowerFactor(0); |
---|
| 420 | _vehicle->getWheel(2)->setPowerFactor(1); |
---|
| 421 | _vehicle->getWheel(3)->setPowerFactor(1); |
---|
| 422 | |
---|
| 423 | updateInfo(); |
---|
| 424 | break; |
---|
| 425 | } |
---|
| 426 | mTimeUntilNextToggle = 0.5; |
---|
| 427 | } |
---|
| 428 | } |
---|
| 429 | |
---|
| 430 | if(!_stepper->isPaused() && _vehicle) |
---|
| 431 | { |
---|
| 432 | _vehicle->setInputs(mKeyboard->isKeyDown(OIS::KC_J), |
---|
| 433 | mKeyboard->isKeyDown(OIS::KC_L), |
---|
| 434 | mKeyboard->isKeyDown(OIS::KC_I), |
---|
| 435 | mKeyboard->isKeyDown(OIS::KC_K)); |
---|
| 436 | _vehicle->update(time); |
---|
| 437 | } |
---|
| 438 | |
---|
| 439 | |
---|
| 440 | // Thanks to Ahmed! |
---|
| 441 | if (_vehicle) |
---|
| 442 | { |
---|
| 443 | const Ogre::Real followFactor = 0.05; |
---|
| 444 | const Ogre::Real camHeight = 5.0; |
---|
| 445 | const Ogre::Real camDistance = 10.0; |
---|
| 446 | const Ogre::Real camLookAhead = 6.0; |
---|
| 447 | |
---|
| 448 | Quaternion q = _vehicle->getSceneNode()->getOrientation(); |
---|
| 449 | Vector3 toCam = _vehicle->getSceneNode()->getPosition(); |
---|
| 450 | |
---|
| 451 | toCam.y += camHeight; |
---|
| 452 | toCam.z -= camDistance * q.zAxis().z; |
---|
| 453 | toCam.x -= camDistance * q.zAxis().x; |
---|
| 454 | |
---|
| 455 | mCamera->move( (toCam - mCamera->getPosition()) * followFactor ); |
---|
| 456 | mCamera->lookAt(_vehicle->getSceneNode()->getPosition() + ((_vehicle->getSceneNode()->getOrientation() * Ogre::Vector3::UNIT_Z) * camLookAhead)); |
---|
| 457 | } |
---|
| 458 | if (_average_num_query == 0) |
---|
| 459 | _average_num_query = _terrain->getNumQueries(); |
---|
| 460 | _average_num_query = (_average_num_query*99 + _terrain->getNumQueries()) / 100; |
---|
| 461 | |
---|
| 462 | mDebugText =( |
---|
| 463 | (_vehicle?"Vehicle Pos: " + StringConverter::toString(_vehicle->getSceneNode()->getPosition()):String("")) + |
---|
| 464 | " nQueries: " + StringConverter::toString(_average_num_query)); |
---|
| 465 | |
---|
| 466 | _terrain->resetNumQueries(); |
---|
| 467 | |
---|
| 468 | return ret; |
---|
| 469 | } |
---|
| 470 | |
---|
| 471 | //------------------------------------------------------------------------------------------------ |
---|
| 472 | Real LandscapeFrameListener::heightAt(const Ogre::Vector3& position) |
---|
| 473 | { |
---|
| 474 | return _terrain->getHeightAt(position); //this is the get height function |
---|
| 475 | } |
---|
| 476 | |
---|
| 477 | |
---|
| 478 | //------------------------------------------------------------------------------------------------ |
---|
| 479 | bool LandscapeFrameListener::collision(OgreOde::Contact* contact) |
---|
| 480 | { |
---|
| 481 | Geometry * const g1 = contact->getFirstGeometry (); |
---|
| 482 | Geometry * const g2 = contact->getSecondGeometry (); |
---|
| 483 | const bool isg1Sphere = g1 && g1->getClass () != Geometry::Class_Sphere; |
---|
| 484 | const bool isg2Sphere = g2 && g2->getClass () != Geometry::Class_Sphere; |
---|
| 485 | |
---|
| 486 | if((isg1Sphere || isg2Sphere) && |
---|
| 487 | OgreOde_Prefab::Vehicle::handleTyreCollision(contact)) |
---|
| 488 | { |
---|
| 489 | //handled by Vehicle. |
---|
| 490 | } |
---|
| 491 | else |
---|
| 492 | { |
---|
| 493 | contact->setBouncyness(0.0); |
---|
| 494 | contact->setCoulombFriction(18.0); |
---|
| 495 | } |
---|
| 496 | |
---|
| 497 | return true; |
---|
| 498 | } |
---|
| 499 | |
---|
| 500 | //------------------------------------------------------------------------------------------------ |
---|
| 501 | LandscapeApplication::LandscapeApplication() |
---|
| 502 | { |
---|
| 503 | } |
---|
| 504 | |
---|
| 505 | //------------------------------------------------------------------------------------------------ |
---|
| 506 | bool LandscapeApplication::setup(void) |
---|
| 507 | { |
---|
| 508 | #ifndef _PLSM2 |
---|
| 509 | mRoot = new Root("plugins.cfg", "ogre.cfg", "ogreode_landscape_tsm.log"); |
---|
| 510 | #else //_PLSM2 |
---|
| 511 | mRoot = new Root("plugins_plsm2.cfg", "plsm2_display.cfg", "ogreode_landscape_plsm2.log"); |
---|
| 512 | #endif //_PLSM2 |
---|
| 513 | |
---|
| 514 | setupResources(); |
---|
| 515 | |
---|
| 516 | bool carryOn = configure(); |
---|
| 517 | if (!carryOn) return false; |
---|
| 518 | |
---|
| 519 | chooseSceneManager(); |
---|
| 520 | createCamera(); |
---|
| 521 | createViewports(); |
---|
| 522 | |
---|
| 523 | // Set default mipmap level (NB some APIs ignore this) |
---|
| 524 | TextureManager::getSingleton().setDefaultNumMipmaps(20); |
---|
| 525 | |
---|
| 526 | // Create any resource listeners (for loading screens) |
---|
| 527 | createResourceListener(); |
---|
| 528 | // Load resources |
---|
| 529 | loadResources(); |
---|
| 530 | |
---|
| 531 | // Create the scene |
---|
| 532 | createScene(); |
---|
| 533 | |
---|
| 534 | createFrameListener(); |
---|
| 535 | |
---|
| 536 | return true; |
---|
| 537 | |
---|
| 538 | } |
---|
| 539 | |
---|
| 540 | //------------------------------------------------------------------------------------------------ |
---|
| 541 | void LandscapeApplication::chooseSceneManager(void) |
---|
| 542 | { |
---|
| 543 | #ifndef _PLSM2 |
---|
| 544 | mSceneMgr = mRoot->createSceneManager( ST_EXTERIOR_CLOSE, "basicsm" ); |
---|
| 545 | #else //_PLSM2 |
---|
| 546 | mSceneMgr = mRoot->createSceneManager( "PagingLandScapeSceneManager", "basicsm" ); |
---|
| 547 | assert(mSceneMgr); |
---|
| 548 | #endif //_PLSM2 |
---|
| 549 | } |
---|
| 550 | |
---|
| 551 | //------------------------------------------------------------------------------------------------ |
---|
| 552 | void LandscapeApplication::setupResources(void) |
---|
| 553 | { |
---|
| 554 | ExampleApplication::setupResources(); |
---|
| 555 | |
---|
| 556 | ResourceGroupManager *rsm = ResourceGroupManager::getSingletonPtr(); |
---|
| 557 | StringVector groups = rsm->getResourceGroups(); |
---|
| 558 | if (std::find(groups.begin(), groups.end(), String("OgreOde")) == groups.end()) |
---|
| 559 | { |
---|
| 560 | FileInfoListPtr finfo = ResourceGroupManager::getSingleton().findResourceFileInfo ( |
---|
| 561 | "Bootstrap", "axes.mesh"); |
---|
| 562 | |
---|
| 563 | const bool isSDK = (!finfo->empty()) && |
---|
| 564 | StringUtil::startsWith (finfo->begin()->archive->getName(), "../../media/packs/ogrecore.zip", true); |
---|
| 565 | |
---|
| 566 | rsm->createResourceGroup("OgreOde"); |
---|
| 567 | if (isSDK) |
---|
| 568 | { |
---|
| 569 | rsm->addResourceLocation("../../../ogreode/demos/Media","FileSystem", "OgreOde"); |
---|
| 570 | } |
---|
| 571 | else |
---|
| 572 | { |
---|
| 573 | rsm->addResourceLocation("../../../../../ogreaddons/ogreode/demos/Media","FileSystem", "OgreOde"); |
---|
| 574 | } |
---|
| 575 | } |
---|
| 576 | #ifdef _PLSM2 |
---|
| 577 | if (std::find(groups.begin(), groups.end(), String("PLSM2")) == groups.end()) |
---|
| 578 | { |
---|
| 579 | rsm->createResourceGroup("PLSM2"); |
---|
| 580 | if (isSDK) |
---|
| 581 | { |
---|
| 582 | rsm->addResourceLocation("../../../paginglandscape/Samples/Media/paginglandscape2","FileSystem", "PLSM2"); |
---|
| 583 | |
---|
| 584 | rsm->addResourceLocation("../../../paginglandscape/Samples/Media/paginglandscape2/models","FileSystem", "PLSM2"); |
---|
| 585 | rsm->addResourceLocation("../../../paginglandscape/Samples/Media/paginglandscape2/overlays","FileSystem", "PLSM2"); |
---|
| 586 | rsm->addResourceLocation("../../../paginglandscape/Samples/Media/paginglandscape2/materials","FileSystem", "PLSM2"); |
---|
| 587 | |
---|
| 588 | rsm->addResourceLocation("../../../paginglandscape/Samples/Media/paginglandscape2/materials/scripts","FileSystem", "PLSM2"); |
---|
| 589 | rsm->addResourceLocation("../../../paginglandscape/Samples/Media/paginglandscape2/materials/textures","FileSystem", "PLSM2"); |
---|
| 590 | rsm->addResourceLocation("../../../paginglandscape/Samples/Media/paginglandscape2/materials/programs","FileSystem", "PLSM2"); |
---|
| 591 | |
---|
| 592 | rsm->addResourceLocation("../../../paginglandscape/Samples/Media/paginglandscape2/datasrcs","FileSystem", "PLSM2"); |
---|
| 593 | rsm->addResourceLocation("../../../paginglandscape/Samples/Media/paginglandscape2/terrains","FileSystem", "PLSM2"); |
---|
| 594 | } |
---|
| 595 | else |
---|
| 596 | { |
---|
| 597 | rsm->addResourceLocation("../../../../../ogreaddons/paginglandscape/Samples/Media/paginglandscape2","FileSystem", "PLSM2"); |
---|
| 598 | |
---|
| 599 | rsm->addResourceLocation("../../../../../ogreaddons/paginglandscape/Samples/Media/paginglandscape2/models","FileSystem", "PLSM2"); |
---|
| 600 | rsm->addResourceLocation("../../../../../ogreaddons/paginglandscape/Samples/Media/paginglandscape2/overlays","FileSystem", "PLSM2"); |
---|
| 601 | rsm->addResourceLocation("../../../../../ogreaddons/paginglandscape/Samples/Media/paginglandscape2/materials","FileSystem", "PLSM2"); |
---|
| 602 | |
---|
| 603 | rsm->addResourceLocation("../../../../../ogreaddons/paginglandscape/Samples/Media/paginglandscape2/materials/scripts","FileSystem", "PLSM2"); |
---|
| 604 | rsm->addResourceLocation("../../../../../ogreaddons/paginglandscape/Samples/Media/paginglandscape2/materials/textures","FileSystem", "PLSM2"); |
---|
| 605 | rsm->addResourceLocation("../../../../../ogreaddons/paginglandscape/Samples/Media/paginglandscape2/materials/programs","FileSystem", "PLSM2"); |
---|
| 606 | |
---|
| 607 | rsm->addResourceLocation("../../../../../ogreaddons/paginglandscape/Samples/Media/paginglandscape2/datasrcs","FileSystem", "PLSM2"); |
---|
| 608 | rsm->addResourceLocation("../../../../../ogreaddons/paginglandscape/Samples/Media/paginglandscape2/terrains","FileSystem", "PLSM2"); |
---|
| 609 | } |
---|
| 610 | } |
---|
| 611 | #endif //_PLSM2 |
---|
| 612 | } |
---|
| 613 | |
---|
| 614 | //------------------------------------------------------------------------------------------------ |
---|
| 615 | void LandscapeApplication::createCamera(void) |
---|
| 616 | { |
---|
| 617 | // Create the camera |
---|
| 618 | mCamera = mSceneMgr->createCamera("PlayerCam"); |
---|
| 619 | |
---|
| 620 | // Set a nice viewpoint |
---|
| 621 | mCamera->setPosition(25,15,25); |
---|
| 622 | mCamera->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329)); |
---|
| 623 | |
---|
| 624 | mCamera->setNearClipDistance( 1 ); |
---|
| 625 | mCamera->setFarClipDistance( 1000 ); |
---|
| 626 | } |
---|
| 627 | |
---|
| 628 | //------------------------------------------------------------------------------------------------ |
---|
| 629 | // Just override the mandatory create scene method |
---|
| 630 | void LandscapeApplication::createScene(void) |
---|
| 631 | { |
---|
| 632 | // Set ambient light |
---|
| 633 | mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5)); |
---|
| 634 | |
---|
| 635 | // Create a light |
---|
| 636 | Light* l = mSceneMgr->createLight("MainLight"); |
---|
| 637 | |
---|
| 638 | // Accept default settings: point light, white diffuse, just set position |
---|
| 639 | // NB I could attach the light to a SceneNode if I wanted it to move automatically with |
---|
| 640 | // other objects, but I don't |
---|
| 641 | l->setPosition(20,800,50); |
---|
| 642 | l->setSpecularColour(1,0.9,0); |
---|
| 643 | l->setCastShadows(true); |
---|
| 644 | |
---|
| 645 | #ifndef _DEBUG |
---|
| 646 | mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE); |
---|
| 647 | mSceneMgr->setShadowColour(ColourValue(0.5,0.5,0.5)); |
---|
| 648 | #else |
---|
| 649 | mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE); |
---|
| 650 | #endif |
---|
| 651 | |
---|
| 652 | // Fog |
---|
| 653 | // NB it's VERY important to set this before calling setWorldGeometry |
---|
| 654 | // because the vertex program picked will be different |
---|
| 655 | ColourValue fadeColour(0.93, 0.86, 0.76); |
---|
| 656 | mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000); |
---|
| 657 | mWindow->getViewport(0)->setBackgroundColour(fadeColour); |
---|
| 658 | |
---|
| 659 | // Set up the terrain according to our own settings |
---|
| 660 | |
---|
| 661 | DataStreamPtr cfgFile = ResourceGroupManager::getSingleton().openResource (config_file, "OgreOde"); |
---|
| 662 | mSceneMgr -> setWorldGeometry( cfgFile ); |
---|
| 663 | |
---|
| 664 | |
---|
| 665 | //String blank(""); |
---|
| 666 | //mSceneMgr->setOption("CustomMaterialName",&blank); |
---|
| 667 | |
---|
| 668 | // Infinite far plane? |
---|
| 669 | if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE)) |
---|
| 670 | { |
---|
| 671 | mCamera->setFarClipDistance(0); |
---|
| 672 | } |
---|
| 673 | |
---|
| 674 | // Define the required skyplane |
---|
| 675 | Plane plane; |
---|
| 676 | |
---|
| 677 | plane.d = 5000; |
---|
| 678 | plane.normal = -Vector3::UNIT_Y; |
---|
| 679 | |
---|
| 680 | |
---|
| 681 | } |
---|
| 682 | |
---|
| 683 | //------------------------------------------------------------------------------------------------ |
---|
| 684 | // Create new frame listener |
---|
| 685 | void LandscapeApplication::createFrameListener(void) |
---|
| 686 | { |
---|
| 687 | mFrameListener= new LandscapeFrameListener(mWindow, mCamera,mRoot); |
---|
| 688 | mRoot->addFrameListener(mFrameListener); |
---|
| 689 | } |
---|
| 690 | |
---|
| 691 | //------------------------------------------------------------------------------------------------ |
---|
| 692 | LandscapeApplication::~LandscapeApplication() |
---|
| 693 | { |
---|
| 694 | } |
---|