[61] | 1 | #include <OgreNoMemoryMacros.h>
|
---|
| 2 | #include <CEGUI/CEGUI.h>
|
---|
| 3 | #include <../CEGUIRenderer/include/OgreCEGUIRenderer.h>
|
---|
| 4 | #include <../CEGUIRenderer/include/OgreCEGUIResourceProvider.h>
|
---|
| 5 | #include <../CEGUIRenderer/include/OgreCEGUITexture.h>
|
---|
| 6 | #include <OgreMemoryMacros.h>
|
---|
| 7 |
|
---|
[100] | 8 | #include <Ogre.h>
|
---|
[866] | 9 | #include <direct.h> // for getcwd
|
---|
[115] | 10 | //#include "OgreReferenceAppLayer.h"
|
---|
[100] | 11 | //#include "OgreRefAppWorld.h"
|
---|
[61] | 12 | #include "TestCullingTerrainApplication.h"
|
---|
[173] | 13 | #include "TerrainFrameListener.h"
|
---|
[61] | 14 |
|
---|
[866] | 15 | #include "IVReader.h"
|
---|
| 16 |
|
---|
[61] | 17 | #define WIN32_LEAN_AND_MEAN
|
---|
[94] | 18 | #include <windows.h>
|
---|
[61] | 19 |
|
---|
[160] | 20 |
|
---|
[866] | 21 | bool TestCullingTerrainApplication::msShowHillyTerrain = false;
|
---|
[164] | 22 |
|
---|
[866] | 23 | /******************************************************/
|
---|
| 24 | /* EntityState implementation */
|
---|
| 25 | /******************************************************/
|
---|
[173] | 26 |
|
---|
[866] | 27 |
|
---|
[164] | 28 | Vector3 EntityState::msMinPos = Vector3::ZERO;
|
---|
| 29 | Vector3 EntityState::msMaxPos = Vector3::ZERO;
|
---|
| 30 |
|
---|
[161] | 31 | EntityState::EntityState(Entity *ent, State entityState, Real speed):
|
---|
| 32 | mEntity(ent), mState(entityState), mAnimationSpeed(speed)
|
---|
| 33 | {
|
---|
| 34 | switch(entityState)
|
---|
| 35 | {
|
---|
| 36 | case MOVING:
|
---|
| 37 | mAnimationState = mEntity->getAnimationState("Walk");
|
---|
| 38 | break;
|
---|
| 39 | case WAITING:
|
---|
| 40 | mAnimationState = mEntity->getAnimationState("Idle");
|
---|
| 41 | break;
|
---|
| 42 | case STOP:
|
---|
| 43 | mAnimationState = NULL;
|
---|
| 44 | break;
|
---|
| 45 | default:
|
---|
| 46 | break;
|
---|
| 47 | }
|
---|
| 48 | // enable animation state
|
---|
| 49 | if (mAnimationState)
|
---|
| 50 | {
|
---|
| 51 | mAnimationState->setLoop(true);
|
---|
| 52 | mAnimationState->setEnabled(true);
|
---|
| 53 | }
|
---|
| 54 | mTimeElapsed = Math::RangeRandom(1, 5);
|
---|
| 55 | }
|
---|
| 56 | //-----------------------------------------------------------------------
|
---|
[164] | 57 | EntityState::~EntityState()
|
---|
| 58 | {
|
---|
| 59 | mAnimationState = NULL;
|
---|
| 60 | mEntity = NULL;
|
---|
| 61 | }
|
---|
| 62 | //-----------------------------------------------------------------------
|
---|
[161] | 63 | Entity *EntityState::GetEntity()
|
---|
| 64 | {
|
---|
| 65 | return mEntity;
|
---|
| 66 | }
|
---|
| 67 | //-----------------------------------------------------------------------
|
---|
| 68 | EntityState::State EntityState::GetState()
|
---|
| 69 | {
|
---|
| 70 | return mState;
|
---|
| 71 | }
|
---|
| 72 | //-----------------------------------------------------------------------
|
---|
| 73 | void EntityState::update(Real timeSinceLastFrame)
|
---|
| 74 | {
|
---|
| 75 | mTimeElapsed -= timeSinceLastFrame * mAnimationSpeed;
|
---|
[164] | 76 |
|
---|
| 77 | if (!mEntity || !mAnimationState)
|
---|
| 78 | return;
|
---|
[161] | 79 |
|
---|
| 80 | if (mState == MOVING) // toggle between moving (longer) and waiting (short)
|
---|
| 81 | {
|
---|
| 82 | SceneNode *parent = mEntity->getParentSceneNode();
|
---|
[164] | 83 |
|
---|
| 84 | if (!parent)
|
---|
| 85 | return;
|
---|
[161] | 86 |
|
---|
| 87 | if (mTimeElapsed <= 0) // toggle animation state
|
---|
| 88 | {
|
---|
| 89 | if (mAnimationState->getAnimationName() == "Idle")
|
---|
| 90 | {
|
---|
| 91 | SetAnimationState("Walk", true);
|
---|
[164] | 92 |
|
---|
| 93 | mTimeElapsed = walk_duration; // walk for mTimeElapsed units
|
---|
[161] | 94 |
|
---|
[164] | 95 | // choose random rotation
|
---|
| 96 | Radian rnd = Radian(Math::UnitRandom() * Math::PI * rotate_factor);
|
---|
[161] | 97 |
|
---|
| 98 | //mEntity->getParentSceneNode()->rotate();
|
---|
| 99 | parent->yaw(rnd);
|
---|
| 100 | }
|
---|
| 101 | else
|
---|
| 102 | {
|
---|
| 103 | SetAnimationState("Idle", true);
|
---|
[164] | 104 | mTimeElapsed = wait_duration; // wait for mTimeElapsed seconds
|
---|
[161] | 105 | }
|
---|
| 106 | }
|
---|
| 107 |
|
---|
[164] | 108 | if (mAnimationState->getAnimationName() == "Walk") // move forward
|
---|
[161] | 109 | {
|
---|
[164] | 110 | // store old position, just in case we get out of bounds
|
---|
[161] | 111 | Vector3 oldPos = parent->getPosition();
|
---|
[164] | 112 | parent->translate(parent->getLocalAxes(), Vector3(move_factor * mAnimationSpeed, 0, 0));
|
---|
[161] | 113 |
|
---|
[164] | 114 | // HACK: if out of bounds => reset to old position and set animationstate to idle
|
---|
[161] | 115 | if (OutOfBounds(parent))
|
---|
| 116 | {
|
---|
| 117 | parent->setPosition(oldPos);
|
---|
[164] | 118 | SetAnimationState("Idle", true);
|
---|
[161] | 119 |
|
---|
[164] | 120 | mTimeElapsed = wait_duration;
|
---|
[161] | 121 | }
|
---|
| 122 | }
|
---|
| 123 | }
|
---|
| 124 |
|
---|
[164] | 125 | // add time to drive animation
|
---|
| 126 | mAnimationState->addTime(timeSinceLastFrame * mAnimationSpeed);
|
---|
[161] | 127 | }
|
---|
| 128 | //-----------------------------------------------------------------------
|
---|
| 129 | void EntityState::SetAnimationState(String stateStr, bool loop)
|
---|
| 130 | {
|
---|
[164] | 131 | if (!mEntity)
|
---|
| 132 | return;
|
---|
| 133 |
|
---|
[161] | 134 | mAnimationState = mEntity->getAnimationState(stateStr);
|
---|
| 135 | mAnimationState->setLoop(loop);
|
---|
| 136 | mAnimationState->setEnabled(true);
|
---|
| 137 | }
|
---|
| 138 | //-----------------------------------------------------------------------
|
---|
| 139 | bool EntityState::OutOfBounds(SceneNode *node)
|
---|
| 140 | {
|
---|
| 141 | Vector3 pos = node->getPosition();
|
---|
| 142 |
|
---|
| 143 | if ((pos > msMinPos) && (pos < msMaxPos))
|
---|
[164] | 144 | return false;
|
---|
[161] | 145 |
|
---|
[164] | 146 | return true;
|
---|
[161] | 147 | }
|
---|
[164] | 148 |
|
---|
| 149 |
|
---|
| 150 |
|
---|
[160] | 151 | /*********************************************************/
|
---|
| 152 | /* TestCullingTerrainApplication implementation */
|
---|
| 153 | /*********************************************************/
|
---|
| 154 |
|
---|
| 155 |
|
---|
[145] | 156 | TestCullingTerrainApplication::TestCullingTerrainApplication():
|
---|
[164] | 157 | mTerrainContentGenerator(NULL), mRayQueryExecutor(NULL)
|
---|
[145] | 158 | {
|
---|
| 159 | }
|
---|
[100] | 160 | //-----------------------------------------------------------------------
|
---|
[61] | 161 | TestCullingTerrainApplication::~TestCullingTerrainApplication()
|
---|
| 162 | {
|
---|
[161] | 163 | OGRE_DELETE(mTerrainContentGenerator);
|
---|
| 164 | OGRE_DELETE(mRayQueryExecutor);
|
---|
[866] | 165 | OGRE_DELETE(mIVReader);
|
---|
[164] | 166 |
|
---|
[657] | 167 | deleteEntityStates();
|
---|
[161] | 168 | }
|
---|
| 169 | //-----------------------------------------------------------------------
|
---|
| 170 | void TestCullingTerrainApplication::deleteEntityStates()
|
---|
| 171 | {
|
---|
| 172 | for (int i = 0; i < (int)mEntityStates.size(); ++i)
|
---|
[122] | 173 | {
|
---|
[164] | 174 | OGRE_DELETE(mEntityStates[i]);
|
---|
[122] | 175 | }
|
---|
[164] | 176 |
|
---|
[161] | 177 | mEntityStates.clear();
|
---|
[61] | 178 | }
|
---|
| 179 | //-----------------------------------------------------------------------
|
---|
[93] | 180 | void TestCullingTerrainApplication::createCamera()
|
---|
[61] | 181 | {
|
---|
[99] | 182 | // create the camera
|
---|
[103] | 183 | mCamera = mSceneMgr->createCamera("PlayerCam");
|
---|
[93] | 184 |
|
---|
[100] | 185 | /** set a nice viewpoint
|
---|
| 186 | * we use a camera node here and apply all transformations on it instead
|
---|
| 187 | * of applying all transformations directly to the camera
|
---|
| 188 | * because then the camera is displayed correctly in the visualization
|
---|
| 189 | */
|
---|
[866] | 190 | if (msShowHillyTerrain)
|
---|
| 191 | {
|
---|
| 192 | mCamNode = mSceneMgr->getRootSceneNode()->
|
---|
[137] | 193 | createChildSceneNode("CamNode1", Vector3(707, 5000, 528));
|
---|
[866] | 194 | }
|
---|
| 195 | else
|
---|
| 196 | {
|
---|
| 197 | mCamNode = mSceneMgr->getRootSceneNode()->
|
---|
| 198 | createChildSceneNode("CamNode1", Vector3(0, -100, -200));
|
---|
| 199 | }
|
---|
| 200 |
|
---|
[100] | 201 | mCamNode->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
|
---|
| 202 | mCamNode->attachObject(mCamera);
|
---|
[61] | 203 |
|
---|
[100] | 204 | //-- create visualization camera
|
---|
| 205 | mVizCamera = mSceneMgr->createCamera("VizCam");
|
---|
| 206 | mVizCamera->setPosition(mCamNode->getPosition());
|
---|
| 207 |
|
---|
| 208 | mVizCamera->setNearClipDistance(1);
|
---|
[93] | 209 | mCamera->setNearClipDistance(1);
|
---|
[61] | 210 |
|
---|
[99] | 211 | // infinite far plane?
|
---|
[93] | 212 | if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
|
---|
| 213 | {
|
---|
[100] | 214 | mVizCamera->setFarClipDistance(0);
|
---|
[93] | 215 | mCamera->setFarClipDistance(0);
|
---|
| 216 | }
|
---|
| 217 | else
|
---|
| 218 | {
|
---|
[104] | 219 | mVizCamera->setFarClipDistance(20000);
|
---|
| 220 | mCamera->setFarClipDistance(20000);
|
---|
[99] | 221 | }
|
---|
[61] | 222 | }
|
---|
[99] | 223 |
|
---|
[61] | 224 | //-----------------------------------------------------------------------
|
---|
[99] | 225 | bool TestCullingTerrainApplication::setup()
|
---|
| 226 | {
|
---|
[145] | 227 | bool carryOn = ExampleApplication::setup();
|
---|
[99] | 228 |
|
---|
[145] | 229 | if (carryOn)
|
---|
[144] | 230 | createRenderTargetListener();
|
---|
[99] | 231 |
|
---|
[145] | 232 | return carryOn;
|
---|
[99] | 233 | }
|
---|
| 234 | //-----------------------------------------------------------------------
|
---|
| 235 | void TestCullingTerrainApplication::createRenderTargetListener()
|
---|
| 236 | {
|
---|
| 237 | mWindow->addListener(new VisualizationRenderTargetListener(mSceneMgr));
|
---|
| 238 | }
|
---|
| 239 | //-----------------------------------------------------------------------
|
---|
[866] | 240 | void TestCullingTerrainApplication::LoadWorldGeometry()
|
---|
| 241 | {
|
---|
| 242 | mIVReader = new IVReader();
|
---|
| 243 |
|
---|
| 244 | // _MAX_PATH is the maximum length allowed for a path
|
---|
| 245 | char currentPath[_MAX_PATH];
|
---|
| 246 | // use the function to get the path
|
---|
| 247 | getcwd(currentPath, _MAX_PATH);
|
---|
| 248 | std::stringstream d;
|
---|
| 249 | d << "current path: " << currentPath;
|
---|
| 250 | //E:\ogre_versions\ogre-win32-v1-0-3p1\ogrenew\Samples\Common\bin\Release
|
---|
| 251 | Ogre::LogManager::getSingleton().logMessage(d.str());
|
---|
| 252 | //String path = "E:/svn/gametools/trunk/VUT/Ogre/resources/";
|
---|
| 253 | String path = "E:/svn/gametools/OGRE/trunk/resources/";
|
---|
| 254 |
|
---|
| 255 | SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node1");
|
---|
| 256 | SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node2");
|
---|
| 257 | SceneNode *node3 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node3");
|
---|
| 258 | SceneNode *node4 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node4");
|
---|
| 259 | SceneNode *node5 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node5");
|
---|
| 260 | SceneNode *node6 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node6");
|
---|
| 261 | SceneNode *node7 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node7");
|
---|
| 262 | SceneNode *node8 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node8");
|
---|
| 263 | SceneNode *node9 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Node9");
|
---|
| 264 |
|
---|
| 265 |
|
---|
| 266 | node1->translate(Vector3(-500, 0, 750));
|
---|
| 267 | node2->translate(Vector3(-400, 0, 750));
|
---|
| 268 | node3->scale(Vector3(100, 100 ,100));
|
---|
| 269 | node3->pitch(Radian(3 * Math::HALF_PI));
|
---|
| 270 | node4->translate(Vector3(-100, 0, 0));
|
---|
| 271 | node5->translate(Vector3(0, 300, 0));
|
---|
| 272 |
|
---|
| 273 | node6->scale(Vector3(100, 100 ,100));
|
---|
| 274 | node6->pitch(Radian(3 * Math::HALF_PI));
|
---|
| 275 | node6->roll(Radian(Math::HALF_PI));
|
---|
| 276 | node6->translate(Vector3(0, -100, 0));
|
---|
| 277 |
|
---|
| 278 | node7->scale(Vector3(100, 100 ,100));
|
---|
| 279 | node7->pitch(Radian(3 * Math::HALF_PI));
|
---|
| 280 | node7->roll(Radian(Math::HALF_PI));
|
---|
| 281 | node7->translate(Vector3(100, 0, 0));
|
---|
| 282 |
|
---|
| 283 | node8->translate(Vector3(-300, -300, 0));
|
---|
| 284 |
|
---|
| 285 | Log *log = LogManager::getSingleton().createLog("IVLog.log");
|
---|
| 286 | mIVReader->setLog(log);
|
---|
| 287 | #if 1
|
---|
| 288 | String fileName = path + "media\\house_test1.iv";
|
---|
| 289 |
|
---|
| 290 | if (mIVReader->loadFile(fileName.c_str()))
|
---|
| 291 | {
|
---|
| 292 | mIVReader->buildTree(mSceneMgr, node1);
|
---|
| 293 | mIVReader->buildTree(mSceneMgr, node2);
|
---|
| 294 | }
|
---|
| 295 |
|
---|
| 296 | /*if (mIVReader->loadFile("media\\anhk.wrl"))
|
---|
| 297 | {
|
---|
| 298 | mIVReader->buildTree(mSceneMgr, node3);
|
---|
| 299 | }
|
---|
| 300 | if (mIVReader->loadFile("media\\ant.wrl"))
|
---|
| 301 | {
|
---|
| 302 | mIVReader->buildTree(mSceneMgr, node4);
|
---|
| 303 | }
|
---|
| 304 | if (mIVReader->loadFile("media\\zepplin0.wrl"))
|
---|
| 305 | {
|
---|
| 306 | mIVReader->buildTree(mSceneMgr, node5);
|
---|
| 307 | }
|
---|
| 308 | if (mIVReader->loadFile("media\\warbird.wrl"))
|
---|
| 309 | {
|
---|
| 310 | mIVReader->buildTree(mSceneMgr, node6);
|
---|
| 311 | }
|
---|
| 312 | if (mIVReader->loadFile("media\\z_wing.wrl"))
|
---|
| 313 | {
|
---|
| 314 | mIVReader->buildTree(mSceneMgr, node7);
|
---|
| 315 | }*/
|
---|
| 316 | #else
|
---|
| 317 |
|
---|
| 318 | String fileName = path + "media\\city1500_flat_1.iv";
|
---|
| 319 |
|
---|
| 320 | if (mIVReader->loadFile(fileName.c_str()))
|
---|
| 321 | {
|
---|
| 322 | mIVReader->buildTree(mSceneMgr, node8);
|
---|
| 323 | }
|
---|
| 324 |
|
---|
| 325 | fileName = path + "media\\roofs_1500.iv";
|
---|
| 326 | if (mIVReader->loadFile(fileName.c_str()))
|
---|
| 327 | {
|
---|
| 328 | mIVReader->buildTree(mSceneMgr, node8);
|
---|
| 329 | }
|
---|
| 330 |
|
---|
| 331 | fileName = path + "media\\CityRoads60.iv";
|
---|
| 332 | if (mIVReader->loadFile(fileName.c_str()))
|
---|
| 333 | {
|
---|
| 334 | mIVReader->buildTree(mSceneMgr, node8);
|
---|
| 335 | }
|
---|
| 336 |
|
---|
| 337 | fileName = path + "media\\CityPlane60.iv";
|
---|
| 338 | if (mIVReader->loadFile(fileName.c_str()))
|
---|
| 339 | {
|
---|
| 340 | mIVReader->buildTree(mSceneMgr, node8);
|
---|
| 341 | }
|
---|
| 342 |
|
---|
| 343 | fileName = path + "media\\test.iv";
|
---|
| 344 | if (mIVReader->loadFile(fileName.c_str()))
|
---|
| 345 | {
|
---|
| 346 | mIVReader->buildTree(mSceneMgr, node9);
|
---|
| 347 | }
|
---|
| 348 | #endif
|
---|
| 349 | mIVReader->collapse();
|
---|
| 350 | }
|
---|
| 351 |
|
---|
| 352 | //-----------------------------------------------------------------------
|
---|
[75] | 353 | void TestCullingTerrainApplication::createScene()
|
---|
[61] | 354 | {
|
---|
[866] | 355 | if (!msShowHillyTerrain)
|
---|
| 356 | LoadWorldGeometry();
|
---|
| 357 |
|
---|
[61] | 358 | // Set ambient light
|
---|
[417] | 359 | mAmbientLight = ColourValue(0.5, 0.5, 0.5);
|
---|
[139] | 360 | mSceneMgr->setAmbientLight(mAmbientLight);
|
---|
[113] | 361 |
|
---|
[110] | 362 | //-- create light
|
---|
[111] | 363 | mSunLight = mSceneMgr->createLight("SunLight");
|
---|
| 364 | mSunLight->setType(Light::LT_DIRECTIONAL);
|
---|
| 365 | //mSunLight->setType(Light::LT_SPOTLIGHT);
|
---|
[112] | 366 | //mSunLight->setSpotlightRange(Degree(30), Degree(50));
|
---|
| 367 |
|
---|
[111] | 368 | mSunLight->setPosition(707, 2000, 500);
|
---|
| 369 | mSunLight->setCastShadows(true);
|
---|
| 370 |
|
---|
[173] | 371 | // set light angle not too small over the surface, otherwise shadows textures will be broken
|
---|
[113] | 372 | Vector3 dir(0.5, 1, 0.5);
|
---|
[110] | 373 | dir.normalise();
|
---|
[112] | 374 | mSunLight->setDirection(dir);
|
---|
| 375 | //mSunLight->setDirection(Vector3::NEGATIVE_UNIT_Y);
|
---|
[111] | 376 | mSunLight->setDiffuseColour(1, 1, 1);
|
---|
| 377 | mSunLight->setSpecularColour(1, 1, 1);
|
---|
[110] | 378 |
|
---|
[137] | 379 | // -- Fog
|
---|
[61] | 380 | // NB it's VERY important to set this before calling setWorldGeometry
|
---|
| 381 | // because the vertex program picked will be different
|
---|
| 382 | ColourValue fadeColour(0.93, 0.86, 0.76);
|
---|
| 383 | mWindow->getViewport(0)->setBackgroundColour(fadeColour);
|
---|
| 384 | //mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
|
---|
[94] | 385 |
|
---|
[61] | 386 | // Create a skybox
|
---|
[175] | 387 | mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox", 5000, true);
|
---|
[103] | 388 |
|
---|
[866] | 389 | if (msShowHillyTerrain)
|
---|
| 390 | {
|
---|
| 391 | std::string terrain_cfg("terrain.cfg");
|
---|
[61] | 392 | #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
|
---|
[866] | 393 | terrain_cfg = mResourcePath + terrain_cfg;
|
---|
[61] | 394 | #endif
|
---|
[866] | 395 | mSceneMgr->setWorldGeometry(terrain_cfg);
|
---|
| 396 | }
|
---|
[75] | 397 |
|
---|
[161] | 398 |
|
---|
[100] | 399 | //-- CEGUI setup
|
---|
[61] | 400 | setupGui();
|
---|
[100] | 401 |
|
---|
[159] | 402 | /* // occluder plane to test visibility
|
---|
[160] | 403 | Plane plane; plane.normal = Vector3::UNIT_Y; plane.d = -60;
|
---|
[111] | 404 | MeshManager::getSingleton().createPlane("Myplane",
|
---|
| 405 | ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
|
---|
| 406 | 5000,5000,100,100,true,1,5,5,Vector3::UNIT_Z);
|
---|
| 407 | Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" );
|
---|
| 408 | pPlaneEnt->setMaterialName("Examples/Rockwall");
|
---|
| 409 | pPlaneEnt->setCastShadows(true);
|
---|
[159] | 410 | mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt); */
|
---|
| 411 |
|
---|
[866] | 412 | // Warning: In GL since we can't go higher than the window res
|
---|
[648] | 413 | mSceneMgr->setShadowTextureSettings(1024, 2);
|
---|
[173] | 414 |
|
---|
[112] | 415 | mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
|
---|
[159] | 416 |
|
---|
[111] | 417 |
|
---|
[100] | 418 | //-- terrain content setup
|
---|
| 419 |
|
---|
[80] | 420 | // HACK: necessary to call once before the content creation for
|
---|
| 421 | // terrain initialisation
|
---|
| 422 | mSceneMgr->_renderScene(mCamera, mWindow->getViewport(0), true);
|
---|
[74] | 423 |
|
---|
[164] | 424 | // ray query executor: needed to clamp to terrain
|
---|
| 425 | mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
|
---|
| 426 |
|
---|
| 427 | mTerrainMinPos = EntityState::msMinPos = Vector3(0, 0, 0);
|
---|
[346] | 428 | mTerrainMaxPos = EntityState::msMaxPos = Vector3(5000, 5000, 5000);
|
---|
[164] | 429 |
|
---|
[82] | 430 | mTerrainContentGenerator = new TerrainContentGenerator(mSceneMgr);
|
---|
[110] | 431 |
|
---|
[866] | 432 |
|
---|
[160] | 433 | // if no objects in file, we generate new objects
|
---|
[866] | 434 | if (msShowHillyTerrain && !mTerrainContentGenerator->LoadObjects("objects.out"))
|
---|
[346] | 435 | {
|
---|
[160] | 436 | // the objects are generated randomly distributed over the terrain
|
---|
[723] | 437 | if (1) generateScene(500, 0); // create robots
|
---|
| 438 | if (0) generateScene(100, 1); // create trees
|
---|
| 439 | if (0) generateScene(100, 2); // create ninjas
|
---|
[346] | 440 | }
|
---|
[61] | 441 | }
|
---|
| 442 | //-----------------------------------------------------------------------
|
---|
[160] | 443 | void TestCullingTerrainApplication::generateScene(int num, int objectType)
|
---|
| 444 | {
|
---|
[345] | 445 | float val = TerrainFrameListener::msObjectScales[objectType];
|
---|
| 446 | Vector3 scale(val, val, val);
|
---|
[347] | 447 | const float maxHeight = 75;
|
---|
[417] | 448 |
|
---|
| 449 | // In order to provide much occlusion,
|
---|
[347] | 450 | // height is restricted to maxHeight => no objects are created on peaks
|
---|
[175] | 451 | mTerrainContentGenerator->SetMinPos(Vector3(mTerrainMinPos));
|
---|
[346] | 452 | mTerrainContentGenerator->SetMaxPos(Vector3(mTerrainMaxPos.x, maxHeight, mTerrainMaxPos.z));
|
---|
[417] | 453 |
|
---|
| 454 | //std::stringstream d; d << "objscale: " << scale[0];
|
---|
| 455 | //Ogre::LogManager::getSingleton().logMessage(d.str());
|
---|
| 456 |
|
---|
[173] | 457 | mTerrainContentGenerator->SetScale(scale);
|
---|
| 458 | mTerrainContentGenerator->SetOffset(TerrainFrameListener::msObjectTerrainOffsets[objectType]);
|
---|
| 459 | mTerrainContentGenerator->GenerateScene(num, TerrainFrameListener::msObjectCaptions[objectType]);
|
---|
| 460 |
|
---|
[160] | 461 | if (objectType != 0) // from our objects, only robot has animation phases
|
---|
| 462 | return;
|
---|
| 463 |
|
---|
| 464 | EntityList *entList = mTerrainContentGenerator->GetGeneratedEntities();
|
---|
| 465 |
|
---|
| 466 | //-- add animation state for new robots (located at the end of the list)
|
---|
[175] | 467 | for (int i = (int)entList->size() - num; i < (int)entList->size(); ++i)
|
---|
[160] | 468 | {
|
---|
[161] | 469 | mEntityStates.push_back(new EntityState((*entList)[i],
|
---|
| 470 | EntityState::WAITING, Math::RangeRandom(0.5, 1.5)));
|
---|
[160] | 471 | }
|
---|
[175] | 472 |
|
---|
[347] | 473 | // release limitations on height => it is possible for the user to put single
|
---|
| 474 | // objects on peaks of the terrain (will be only few, not relevant for occlusion)
|
---|
[175] | 475 | mTerrainContentGenerator->SetMaxPos(mTerrainMaxPos);
|
---|
[160] | 476 | }
|
---|
| 477 | //-----------------------------------------------------------------------
|
---|
[161] | 478 | void TestCullingTerrainApplication::updateAnimations(Real timeSinceLastFrame)
|
---|
[160] | 479 | {
|
---|
[161] | 480 | for (int i = 0; i < (int)mEntityStates.size(); ++i)
|
---|
| 481 | {
|
---|
[164] | 482 | SceneNode *sn = mEntityStates[i]->GetEntity()->getParentSceneNode();
|
---|
[161] | 483 |
|
---|
| 484 | mEntityStates[i]->update(timeSinceLastFrame);
|
---|
| 485 |
|
---|
| 486 | if (mEntityStates[i]->GetState() == EntityState::MOVING)
|
---|
| 487 | {
|
---|
[164] | 488 | Clamp2Terrain(sn, 0); //sn->setNodeVisible(false);
|
---|
[161] | 489 | }
|
---|
| 490 | }
|
---|
[160] | 491 | }
|
---|
| 492 | //-----------------------------------------------------------------------
|
---|
[161] | 493 | EntityStates &TestCullingTerrainApplication::getEntityStates()
|
---|
[160] | 494 | {
|
---|
[161] | 495 | return mEntityStates;
|
---|
[160] | 496 | }
|
---|
| 497 | //-----------------------------------------------------------------------
|
---|
[80] | 498 | void TestCullingTerrainApplication::setupGui()
|
---|
[61] | 499 | {
|
---|
[75] | 500 | mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY,
|
---|
| 501 | false, 3000, ST_EXTERIOR_CLOSE);
|
---|
[61] | 502 | mGUISystem = new CEGUI::System(mGUIRenderer);
|
---|
| 503 |
|
---|
| 504 | // Mouse
|
---|
| 505 | CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme");
|
---|
| 506 | CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
|
---|
[133] | 507 | mGUISystem->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook",
|
---|
| 508 | (CEGUI::utf8*)"MouseArrow");
|
---|
[61] | 509 |
|
---|
[418] | 510 | CEGUI::MouseCursor::getSingleton().hide();
|
---|
[61] | 511 | }
|
---|
| 512 | //-----------------------------------------------------------------------
|
---|
[80] | 513 | void TestCullingTerrainApplication::createFrameListener()
|
---|
[61] | 514 | {
|
---|
[133] | 515 | mTerrainFrameListener = new TerrainFrameListener(mWindow, mCamera, mSceneMgr,
|
---|
[160] | 516 | mGUIRenderer, mTerrainContentGenerator, mVizCamera, mCamNode, mSunLight, this);
|
---|
[120] | 517 |
|
---|
[115] | 518 | mRoot->addFrameListener(mTerrainFrameListener);
|
---|
[61] | 519 | }
|
---|
| 520 | //-----------------------------------------------------------------------
|
---|
[80] | 521 | void TestCullingTerrainApplication::chooseSceneManager()
|
---|
[61] | 522 | {
|
---|
[866] | 523 | if (msShowHillyTerrain)
|
---|
| 524 | {
|
---|
| 525 | // Terrain scene manager
|
---|
| 526 | mSceneMgr = mRoot->getSceneManager(ST_EXTERIOR_CLOSE);
|
---|
| 527 | }
|
---|
| 528 | else
|
---|
| 529 | { // octree scene manager
|
---|
| 530 | mSceneMgr = mRoot->getSceneManager(ST_GENERIC);
|
---|
| 531 | }
|
---|
[61] | 532 | }
|
---|
[161] | 533 | //-----------------------------------------------------------------------
|
---|
| 534 | bool TestCullingTerrainApplication::Clamp2Terrain(SceneNode *node, int terrainOffs)
|
---|
| 535 | {
|
---|
| 536 | // clamp scene node to terrain
|
---|
| 537 | Vector3 pos = node->getPosition();
|
---|
| 538 | Vector3 queryResult;
|
---|
| 539 |
|
---|
| 540 | if (mRayQueryExecutor->executeRayQuery(&queryResult,
|
---|
| 541 | Vector3(pos.x, MAX_HEIGHT, pos.z), Vector3::NEGATIVE_UNIT_Y))
|
---|
| 542 | {
|
---|
| 543 | node->setPosition(pos.x, queryResult.y + terrainOffs, pos.z);
|
---|
| 544 | return true;
|
---|
| 545 | }
|
---|
| 546 |
|
---|
| 547 | return false;
|
---|
| 548 | }
|
---|
| 549 |
|
---|
[866] | 550 | //-----------------------------------------------------------------------
|
---|
| 551 | bool TestCullingTerrainApplication::Clamp2FloorPlane()
|
---|
| 552 | {
|
---|
| 553 | // clamp to floor plane
|
---|
| 554 | RaySceneQuery *raySceneQuery = mSceneMgr->createRayQuery(
|
---|
| 555 | Ray(mCamNode->getPosition(), Vector3::NEGATIVE_UNIT_Y));
|
---|
[161] | 556 |
|
---|
[866] | 557 | RaySceneQueryResult& qryResult = raySceneQuery->execute();
|
---|
| 558 |
|
---|
| 559 | RaySceneQueryResult::iterator rit = qryResult.begin();
|
---|
| 560 |
|
---|
| 561 | while (rit != qryResult.end() && rit->movable)
|
---|
| 562 | {
|
---|
| 563 | if (rit->movable->getName() != "PlayerCam")
|
---|
| 564 | {
|
---|
| 565 | mCamNode->setPosition(mCamNode->getPosition().x,
|
---|
| 566 | rit->movable->getWorldBoundingBox().getCenter().y + 2,
|
---|
| 567 | mCamNode->getPosition().z);
|
---|
| 568 |
|
---|
| 569 | /*std::stringstream d;
|
---|
| 570 | d << "World: " << it->movable->getWorldBoundingBox().getCenter().y <<
|
---|
| 571 | ", Object: " << it->movable->getBoundingBox().getCenter().y <<
|
---|
| 572 | ", Camera: " << mCamera->getDerivedPosition();
|
---|
| 573 |
|
---|
| 574 | LogManager::getSingleton().logMessage(d.str());*/
|
---|
| 575 |
|
---|
| 576 | return true;
|
---|
| 577 | }
|
---|
| 578 |
|
---|
| 579 | ++ rit;
|
---|
| 580 | }
|
---|
| 581 |
|
---|
| 582 | OGRE_DELETE(raySceneQuery);
|
---|
| 583 | return false;
|
---|
| 584 | }
|
---|
| 585 |
|
---|
| 586 |
|
---|
| 587 |
|
---|
| 588 | /**********************************************************************/
|
---|
| 589 | /* VisualizationRenderTargetListener implementation */
|
---|
| 590 | /**********************************************************************/
|
---|
| 591 |
|
---|
| 592 |
|
---|
[107] | 593 | //-----------------------------------------------------------------------
|
---|
[99] | 594 | VisualizationRenderTargetListener::VisualizationRenderTargetListener(SceneManager *sceneMgr)
|
---|
| 595 | :RenderTargetListener(), mSceneMgr(sceneMgr)
|
---|
| 596 | {
|
---|
| 597 | }
|
---|
[61] | 598 | //-----------------------------------------------------------------------
|
---|
[99] | 599 | void VisualizationRenderTargetListener::preViewportUpdate(const RenderTargetViewportEvent &evt)
|
---|
| 600 | {
|
---|
[133] | 601 | // visualization viewport
|
---|
| 602 | const bool showViz = evt.source->getZOrder() == VIZ_VIEWPORT_Z_ORDER;
|
---|
[100] | 603 | const bool nShowViz = !showViz;
|
---|
| 604 |
|
---|
[139] | 605 | mSavedShadowTechnique = mSceneMgr->getShadowTechnique();
|
---|
| 606 | mSavedAmbientLight = mSceneMgr->getAmbientLight();
|
---|
| 607 |
|
---|
| 608 | // -- ambient light must be full for visualization, shadows disabled
|
---|
[113] | 609 | if (showViz)
|
---|
| 610 | {
|
---|
| 611 | mSceneMgr->setAmbientLight(ColourValue(1, 1, 1));
|
---|
[139] | 612 | mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
|
---|
[113] | 613 | }
|
---|
[139] | 614 |
|
---|
| 615 | mSceneMgr->setOption("PrepareVisualization", &showViz);
|
---|
[100] | 616 | mSceneMgr->setOption("SkyBoxEnabled", &nShowViz);
|
---|
| 617 | //mSceneMgr->setOption("SkyPlaneEnabled", &showViz);
|
---|
[99] | 618 |
|
---|
| 619 | RenderTargetListener::preViewportUpdate(evt);
|
---|
| 620 | }
|
---|
| 621 | //-----------------------------------------------------------------------
|
---|
| 622 | void VisualizationRenderTargetListener::postRenderTargetUpdate(const RenderTargetEvent &evt)
|
---|
| 623 | {
|
---|
[139] | 624 | // reset values
|
---|
| 625 | mSceneMgr->setShadowTechnique(mSavedShadowTechnique);
|
---|
| 626 | mSceneMgr->setAmbientLight(mSavedAmbientLight);
|
---|
| 627 |
|
---|
[99] | 628 | RenderTargetListener::postRenderTargetUpdate(evt);
|
---|
| 629 | }
|
---|
| 630 | //-----------------------------------------------------------------------
|
---|
[61] | 631 | INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
|
---|
| 632 | {
|
---|
| 633 | // Create application object
|
---|
| 634 | TestCullingTerrainApplication app;
|
---|
| 635 |
|
---|
| 636 | try
|
---|
| 637 | {
|
---|
| 638 | app.go();
|
---|
| 639 | }
|
---|
| 640 | catch( Ogre::Exception& e )
|
---|
| 641 | {
|
---|
[75] | 642 | MessageBox( NULL, e.getFullDescription().c_str(),
|
---|
| 643 | "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
|
---|
[61] | 644 | }
|
---|
| 645 |
|
---|
| 646 | return 0;
|
---|
[160] | 647 | }
|
---|