Changeset 1783 for GTP/trunk/App/Demos/Geom/Demo_LodTrees
- Timestamp:
- 11/23/06 12:11:35 (18 years ago)
- Location:
- GTP/trunk/App/Demos/Geom/Demo_LodTrees
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/App/Demos/Geom/Demo_LodTrees/README.txt
r1540 r1783 2 2 -------- 3 3 4 This demo shows an example of the LodTree model in action. The trees in the scene5 are associated to a LodTree object that manage their level of detail of both the6 trunk and the leaves. The level of detail of the objects depend on the distance to 7 the camera. When the camera goes away from them, the level of detail decreases, and8 when the camera gets closer to them the level of detail increases to restore the9 originalgeometry of the model.4 This demo shows an example of the LodTree model in action. The scene is composed of 5 several tree groups which are associated to a LodTree object that manage the level 6 of detail of both their trunk and leaves. The level of detail of the objects depends 7 on the distance to the camera. When the camera goes away from them, the level of detail 8 decreases, and when the camera gets closer to them increases to restore the original 9 geometry of the model. 10 10 11 The level of detail begins to decrease at a certain distance of the forest, and stops11 The level of detail begins to decrease at a certain distance of each group, and stops 12 12 decreasing when the objects reach the their minimum LOD. This 'lodding' distance is 13 13 customizable from the source code of the demo. 14 15 The user can compare the differences in performance disabling the LOD management while 16 maintaining pressed F2. -
GTP/trunk/App/Demos/Geom/Demo_LodTrees/build/Release/terrain.cfg
r1540 r1783 1 1 # The main world texture (if you wish the terrain manager to create a material for you) 2 WorldTexture= terrain_texture.jpg2 WorldTexture=grass_1024.jpg 3 3 4 4 # The detail texture (if you wish the terrain manager to create a material for you) 5 DetailTexture= terrain_detail.jpg5 DetailTexture=grass.png 6 6 7 7 #number of times the detail texture will tile in a terrain tile 8 DetailTile= 38 DetailTile=8 9 9 10 10 # Heightmap source … … 12 12 13 13 # Heightmap-source specific settings 14 Heightmap.image= terrain.png14 Heightmap.image=noise2.jpg 15 15 16 16 # If you use RAW, fill in the below too … … 23 23 24 24 # How large is a page of tiles (in vertices)? Must be (2^n)+1 25 PageSize= 51325 PageSize=33 26 26 27 27 # How large is each tile? Must be (2^n)+1 and be smaller than PageSize 28 TileSize= 6528 TileSize=17 29 29 30 30 # The maximum error allowed when determining which LOD to use … … 35 35 PageWorldZ=1500 36 36 # Maximum height of the terrain 37 MaxHeight=1 0037 MaxHeight=120 38 38 39 39 # Upper LOD limit … … 69 69 70 70 # The name of the material you will define to shade the terrain 71 CustomMaterialName= TestTerrainMaterial71 CustomMaterialName=Demos/TerrainMixed 72 72 73 73 -
GTP/trunk/App/Demos/Geom/Demo_LodTrees/main.cpp
r1561 r1783 18 18 19 19 // Distance values 20 #define dist_min 300 21 #define dist_max 900 22 23 // Model name 24 #define model_name "arbol" 25 20 #define dist_min 40 21 #define dist_max 800 26 22 27 23 //Global variables 28 Entity* entity;29 Geometry::LodTreeLibrary* myTrees;30 Ogre::Mesh *ogreMesh=NULL;31 24 Geometry::GeoMeshLoader *meshloader=NULL; 32 25 bool force_maxLODfactor = false; 33 34 Ogre::Vector3 forest_center;26 const int num_tree_types=10; 27 Vector3 *centers=NULL; 35 28 36 29 ColourValue color=ColourValue::Red; … … 44 37 45 38 char HelpString[]="(F1) Help\n" 46 "This demo shows an example of the LodTree model in action. The trees in the scene\n" 47 "are associated to a LodTree object that manage their level of detail of both the\n" 48 "trunk and the leaves. The level of detail of the objects depend on the distance to\n" 49 "the camera. When the camera goes away from them, the level of detail decreases, and\n" 50 "when the camera gets closer to them the level of detail increases to restore the\n" 51 "original geometry of the model.\n" 52 "The current level of detail can be seen in real-time in the top-left corner of the screen.\n" 53 "The level of detail begins to decrease at a certain distance of the forest, and stops\n" 39 "This demo shows an example of the LodTree model in action. The scene is composed of\n" 40 "several tree groups which are associated to a LodTree object that manage the level\n" 41 "of detail of both their trunk and leaves. The level of detail of the objects depends\n" 42 "on the distance to the camera. When the camera goes away from them, the level of detail\n" 43 "decreases, and when the camera gets closer to them increases to restore the original\n" 44 "geometry of the model.\n" 45 "The level of detail begins to decrease at a certain distance of each group, and stops\n" 54 46 "decreasing when the objects reach the their minimum LOD. This 'lodding' distance is\n" 55 "customizable from the source code of the demo."; 47 "customizable from the source code of the demo.\n" 48 "The user can compare the differences in performance disabling the LOD management while\n" 49 "maintaining pressed F2."; 56 50 57 51 char NoHelpString[]="(F1) Help\n"; … … 62 56 { 63 57 int manage; 58 Ogre::RaySceneQuery * raySceneQuery; 59 float *lodfactorBefore; // one lodfactor per LOD object type 60 Geometry::LodTreeLibrary **lod_tree_types; 64 61 65 62 public: 66 63 67 LodTreeFrameListener(RenderWindow* win, Camera* cam)64 LodTreeFrameListener(RenderWindow* win, Camera* cam,RaySceneQuery *rsq,Geometry::LodTreeLibrary **lod_trees) 68 65 : ExampleFrameListener(win, cam, false, false) 69 66 { 70 67 manage=1; 68 raySceneQuery=rsq; 69 lodfactorBefore=new float[num_tree_types]; 70 for (int i=0; i<num_tree_types; i++) 71 lodfactorBefore[i]=-1; 72 lod_tree_types=lod_trees; 71 73 } 72 74 … … 74 76 { 75 77 Vector3 dist; 76 int distance=0,inc2=0,d;78 int inc2=0,d; 77 79 unsigned int nlod,diflods; 78 80 79 81 // Move upto 80 units/second 80 Real MoveFactor = 1 80.0 * evt.timeSinceLastFrame;82 Real MoveFactor = 120.0 * evt.timeSinceLastFrame; 81 83 82 84 // Copy the current state of the input devices … … 103 105 104 106 //LOD selection 105 int difdist = dist_max - dist_min; 106 107 int i=0; 108 109 dist = forest_center - mCamera->getPosition(); 110 distance =dist.length(); 111 112 float lodfactor = (float)(distance - dist_min) / (float)(dist_max - dist_min); 113 lodfactor = 1.0f - lodfactor; 114 115 if (lodfactor<0.0f) 116 lodfactor=0.0f; 117 if (lodfactor>1.0f) 118 lodfactor=1.0f; 119 120 if (force_maxLODfactor) 121 lodfactor=1.0f; 122 123 static float lodfactorBefore = -1.0f; 124 if (fabsf(lodfactorBefore-lodfactor)>0.1f) 125 { 126 myTrees->GoToLod(lodfactor); 127 // DumpDataToOgreBuffers(ogreMesh,myTrees); 128 lodfactorBefore=lodfactor; 107 for (int i=0; i<num_tree_types; i++) 108 { 109 dist = centers[i] - mCamera->getPosition(); 110 int distance = dist.length(); 111 112 float lodfactor = 0.0f; 113 if (distance < dist_min) 114 lodfactor = 1.0f; 115 else if (distance > dist_max) 116 lodfactor = 0.0f; 117 else 118 { 119 lodfactor = (float)(distance - dist_min) / (float)(dist_max - dist_min); 120 lodfactor = 1.0f - lodfactor; 121 } 122 123 assert(lodfactor>=0.0f); 124 assert(lodfactor<=1.0f); 125 126 if (force_maxLODfactor) 127 lodfactor=1.0f; 128 129 if (fabsf(lodfactorBefore[i]-lodfactor)>0.1f) 130 { 131 lod_tree_types[i]->GoToLod(lodfactor); 132 lodfactorBefore[i]=lodfactor; 133 } 129 134 } 130 135 … … 148 153 mTranslateVector.x = mMoveScale; 149 154 150 // Instead of moving the ship left and right, rotate it using yaw()151 155 if(mInputDevice->isKeyDown(Ogre::KC_LEFT)) 152 156 mCamera->yaw(mRotScale); … … 173 177 174 178 if(mInputDevice->isKeyDown(Ogre::KC_ESCAPE)) 175 {176 //delete myTrees;177 179 return false; 178 }179 180 180 181 if( mInputDevice->getMouseButton( 1 ) ) … … 189 190 } 190 191 191 192 char cadena[256];193 194 195 sprintf(cadena,"Distance: %d",distance);196 197 mInfo->setCaption(cadena);198 199 sprintf(cadena,"LOD factor: %f",lodfactor);200 201 mInfo2->setCaption(cadena);202 203 192 mCamera->yaw(mRotX); 204 193 mCamera->pitch(mRotY); 205 194 mCamera->moveRelative(mTranslateVector); 195 196 // make the camera walk onto the ground 197 Ogre::Ray ray(mCamera->getPosition()+Ogre::Vector3(0.0f,200.0f,0.0f), Ogre::Vector3::NEGATIVE_UNIT_Y); 198 raySceneQuery->setRay(ray); 199 RaySceneQueryResult &rayRes = raySceneQuery->execute(); 200 RaySceneQueryResult::iterator itr = rayRes.begin(); 201 if (itr != rayRes.end() && itr->worldFragment) 202 mCamera->setPosition(itr->worldFragment->singleIntersection+Ogre::Vector3(0.0f,15.0f,0.0f)); 206 203 207 204 return true; … … 230 227 } 231 228 virtual void SetIndex(unsigned int i, unsigned int index){ 232 pIdx[i] = index; //lodStripsLib->dataRetrievalInterface->GetIndex(k+offset);229 pIdx[i] = index; 233 230 } 234 231 virtual void End(){ … … 244 241 protected: 245 242 public: 246 LodTreeApplication(){} 243 LodTreeApplication(){ 244 raySceneQuery=NULL; 245 centers=new Vector3[num_tree_types]; // one center per object 246 } 247 247 ~LodTreeApplication(){} 248 249 Ogre::RaySceneQuery * raySceneQuery; 250 Geometry::LodTreeLibrary **lod_tree_types; 248 251 249 252 protected: 250 253 254 void chooseSceneManager(void) 255 { 256 // Get the SceneManager, in this case a generic one 257 mSceneMgr = mRoot->getSceneManager(Ogre::ST_EXTERIOR_CLOSE); 258 } 251 259 252 260 … … 254 262 void createScene(void) 255 263 { 256 // mat = new MaterialPtr[1];257 258 264 theCam = mCamera; 259 theCam->setPosition( 0,20,dist_min-40);265 theCam->setPosition(500,100,dist_min+600); 260 266 // Set ambient light 261 267 mSceneMgr->setAmbientLight(ColourValue(0.4, 0.4, 0.4)); 262 268 theCam->setNearClipDistance(0.1f); 263 269 270 mSceneMgr->setFog( FOG_EXP, Ogre::ColourValue(0.4f,0.5f,0.6f), 0.001 ); 271 264 272 // Create a directional light 265 273 Light* l = mSceneMgr->createLight("MainLight"); 266 274 l->setType(Light::LT_DIRECTIONAL); 267 l->setDirection(0. 0,-1.0,0.0);275 l->setDirection(0.1,-1.0,-0.2); 268 276 269 // Define a floor plane mesh 270 Plane plane( Vector3::UNIT_Y, 0 ); 271 272 MeshManager::getSingleton().createPlane("ground", 273 ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 274 1500,1500,20,20,true,1,5,5,Vector3::UNIT_Z); 275 276 Entity* suelo = mSceneMgr->createEntity( "GroundEntity", "ground" ); 277 mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(suelo); 278 279 280 suelo->setMaterialName("Examples/GrassFloor"); 281 suelo->setCastShadows(false); 282 283 277 // terrain 278 mSceneMgr->setWorldGeometry( "terrain.cfg" ); 279 280 284 281 mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox"); 285 282 … … 287 284 SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); 288 285 289 std::string model_file=model_name; 290 model_file.append(".mesh"); 291 292 //Models 293 entity = mSceneMgr->createEntity(model_name, "../../../OgreStuff/media/GT/ML11.mesh"); 294 295 ogreMesh = entity->getMesh().getPointer(); 296 297 // load LOD info from the object 298 meshloader=new Geometry::GeoMeshLoader; 299 Geometry::Mesh *themesh = meshloader->load("../../../OgreStuff/media/GT/ML11.mesh"); 300 301 if (!meshloader->GetLodStripsData()) 302 OGRE_EXCEPT(1, "The loaded mesh does not contain LOD info for the trunk","LOD Demo"); 303 if (!meshloader->GetTreeSimpSeq()) 304 OGRE_EXCEPT(1, "The loaded mesh does not contain LOD info for the foliage","LOD Demo"); 305 306 myTrees = new Geometry::LodTreeLibrary( meshloader->GetLodStripsData(), 307 meshloader->GetTreeSimpSeq(), 308 themesh, 309 new CustomIndexData(ogreMesh)); 310 311 entity->setNormaliseNormals(true); 312 313 for (int submesh=0; submesh < ogreMesh->getNumSubMeshes(); submesh++) 314 { 315 bool istrunk = myTrees->GetLeavesSubMesh()!=submesh; 316 if (istrunk) 317 entity->getSubEntity(submesh)->setMaterialName("Examples/ML11/trunk"); 318 else 319 entity->getSubEntity(submesh)->setMaterialName("Examples/ML11/leaf"); 320 } 321 322 forest_center=Ogre::Vector3(150.0f,0.0f,0.0f); 323 for (int i=1; i<5; i++) // 20 324 for (int j=1; j<5; j++) // 20 325 { 326 char newTreeName[16]=""; 327 sprintf(newTreeName,"arbol_%d_%d",i,j); 328 Ogre::SceneNode * auxnode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); 329 Ogre::Entity *auxent = entity->clone(newTreeName); 330 auxnode->attachObject( auxent ); 331 auxnode->scale(4.0f,4.0f,4.0f); 332 auxnode->rotate(Ogre::Vector3(0,0,1),Ogre::Degree(rand()%360)); 333 auxnode->rotate(Ogre::Vector3(1,0,0),Ogre::Radian(-3.14159f*0.5f),Ogre::Node::TS_WORLD); 334 float randomsepx = (float)((rand()%38)-19); 335 float randomsepy = (float)((rand()%32)-12); 336 auxnode->translate(i*80.0f+randomsepx,0.0f,-j*80.0f-randomsepx); 337 auxent->setNormaliseNormals(true); 338 } 339 340 if (!meshloader->GetLodStripsData() || !meshloader->GetTreeSimpSeq()) 341 OGRE_EXCEPT(1, "The loaded mesh does not contain any LOD info","LOD Demo"); 342 286 // initialize the rayscene queryer 287 raySceneQuery = mSceneMgr->createRayQuery(Ray()); 288 289 // the blacksmith 290 Vector3 BS_center=Ogre::Vector3(780.0f,200.0f,650.0f); 291 Ogre::Ray ray(BS_center, Ogre::Vector3::NEGATIVE_UNIT_Y); 292 raySceneQuery->setRay(ray); 293 RaySceneQueryResult &rayRes = raySceneQuery->execute(); 294 RaySceneQueryResult::iterator itr = rayRes.begin(); 295 if (itr != rayRes.end() && itr->worldFragment) 296 BS_center=itr->worldFragment->singleIntersection-Ogre::Vector3(0.0f,1.0f,0.0f); 297 298 Ogre::Entity *entBS = mSceneMgr->createEntity("blacksmith","../../../OgreStuff/media/models/blacksmith.mesh"); 299 Ogre::SceneNode * nodeBS = mSceneMgr->getRootSceneNode()->createChildSceneNode(); 300 nodeBS->attachObject(entBS); 301 nodeBS->translate(BS_center); 302 nodeBS->scale(0.1f,0.1f,0.1f); 303 304 lod_tree_types = new Geometry::LodTreeLibrary*[num_tree_types]; 305 306 // trees 307 lod_tree_types[0] = CreateLODTrees("../../../OgreStuff/media/GT/ML06a_01.mesh",5,780,630,200,200,centers[0], 4.0f); 308 lod_tree_types[1] = CreateLODTrees("../../../OgreStuff/media/GT/ML13a_02.mesh",4,150,150,200,200,centers[1], 2.0f); 309 lod_tree_types[2] = CreateLODTrees("../../../OgreStuff/media/GT/ML15a_03.mesh",10,300,400,200,200,centers[2], 6.0f); 310 lod_tree_types[3] = CreateLODTrees("../../../OgreStuff/media/GT/ML06a_01.mesh",5,330,900,500,500,centers[3], 3.0f); 311 lod_tree_types[4] = CreateLODTrees("../../../OgreStuff/media/GT/ML13a_02.mesh",5,1100,900,300,300,centers[4], 2.0f); 312 lod_tree_types[5] = CreateLODTrees("../../../OgreStuff/media/GT/ML15a_03.mesh",10,1100,300,200,200,centers[5], 6.0f); 313 lod_tree_types[6] = CreateLODTrees("../../../OgreStuff/media/GT/ML06a_01.mesh",7,900,500,300,300,centers[6], 2.0f); 314 lod_tree_types[7] = CreateLODTrees("../../../OgreStuff/media/GT/ML13a_02.mesh",5,500,950,200,200,centers[7], 3.0f); 315 lod_tree_types[8] = CreateLODTrees("../../../OgreStuff/media/GT/ML15a_03.mesh",9,600,400,200,200,centers[8], 6.0f); 316 lod_tree_types[9] = CreateLODTrees("../../../OgreStuff/media/GT/ML06a_01.mesh",7,950,1100,200,200,centers[9], 2.5f); 343 317 344 318 // show overlay … … 350 324 pOver->show(); 351 325 326 mInfo->setCaption("Maintain F2 to disable LOD"); 327 352 328 } 329 330 void destroyScene(void) 331 { 332 if (raySceneQuery) 333 delete raySceneQuery; 334 delete[] lod_tree_types; 335 } 353 336 354 337 void createFrameListener(void) 355 338 { 356 mFrameListener= new LodTreeFrameListener(mWindow, mCamera );339 mFrameListener= new LodTreeFrameListener(mWindow, mCamera, raySceneQuery, lod_tree_types); 357 340 mFrameListener->showDebugOverlay(true); 358 341 mRoot->addFrameListener(mFrameListener); 359 342 } 343 344 Geometry::LodTreeLibrary *CreateLODTrees(const char *filename, int numObjs, float cx, float cz, float w, float h, Vector3 &outcenter, float scale) 345 { 346 static int iname = 0; 347 char newMeshName[16]=""; 348 sprintf(newMeshName,"tree_%d",iname); 349 350 351 // load LOD info from the object 352 meshloader=new Geometry::GeoMeshLoader; 353 Geometry::Mesh *themesh = meshloader->load((char*)filename); 354 355 if (!meshloader->GetLodStripsData()) 356 OGRE_EXCEPT(1, "The loaded mesh does not contain LOD info for the trunk","LOD Demo"); 357 if (!meshloader->GetTreeSimpSeq()) 358 OGRE_EXCEPT(1, "The loaded mesh does not contain LOD info for the foliage","LOD Demo"); 359 360 Ogre::Entity *entity = mSceneMgr->createEntity(newMeshName,filename); 361 if (!entity->getMesh().unique()) 362 { 363 static int iclone = 0; 364 char newCloneMesh[16]=""; 365 sprintf(newCloneMesh,"clonetree_%d",iclone++); 366 entity->getMesh() = entity->getMesh()->clone(newCloneMesh); 367 } 368 Ogre::Mesh *ogreMesh = entity->getMesh().getPointer(); 369 entity->setNormaliseNormals(true); 370 371 Geometry::LodTreeLibrary *mytree = new Geometry::LodTreeLibrary( 372 meshloader->GetLodStripsData(), 373 meshloader->GetTreeSimpSeq(), 374 themesh, 375 new CustomIndexData(ogreMesh) ); 376 377 outcenter=Vector3::ZERO; 378 379 for (int i=0; i<numObjs; i++) 380 { 381 char newTreeName[16]=""; 382 sprintf(newTreeName,"arbol_%d_%d",iname,i); 383 Ogre::SceneNode * auxnode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); 384 Ogre::Entity *auxent = entity->clone(newTreeName); 385 auxnode->attachObject( auxent ); 386 387 float kx = (rand()%100)/100.0f; 388 float kz = (rand()%100)/100.0f; 389 390 Ogre::Vector3 treepos(kx*(cx-w*0.5f) + (1.0f-kx)*(cx+w*0.5f), 200.0f, 391 kz*(cz-h*0.5f) + (1.0f-kz)*(cz+h*0.5f)); 392 393 Ogre::Ray ray(treepos,Ogre::Vector3::NEGATIVE_UNIT_Y); 394 raySceneQuery->setRay(ray); 395 RaySceneQueryResult &rayRes = raySceneQuery->execute(); 396 RaySceneQueryResult::iterator itr = rayRes.begin(); 397 if (itr != rayRes.end() && itr->worldFragment) 398 treepos = itr->worldFragment->singleIntersection; 399 400 auxnode->translate(treepos); 401 auxnode->scale(scale,scale,scale); 402 auxnode->rotate(Ogre::Vector3(0,1,0),Ogre::Degree(rand()%360)); 403 auxent->setNormaliseNormals(true); 404 outcenter+=treepos; 405 } 406 outcenter/=numObjs; 407 iname++; 408 409 return mytree; 410 } 411 412 float Rand(float minN, float maxN) 413 { 414 return (((rand()%1000)/1000.0f)*(maxN-minN))+minN; 415 } 360 416 361 417 };
Note: See TracChangeset
for help on using the changeset viewer.