00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright © 2000-2004 The OGRE Team 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 ----------------------------------------------------------------------------- 00024 */ 00025 /*************************************************************************** 00026 terrainscenemanager.cpp - description 00027 ------------------- 00028 begin : Mon Sep 23 2002 00029 copyright : (C) 2002 by Jon Anderson 00030 email : janders@users.sf.net 00031 00032 Enhancements 2003 - 2004 (C) The OGRE Team 00033 00034 ***************************************************************************/ 00035 #include <OgreTerrainSceneManager.h> 00036 #include <OgreImage.h> 00037 #include <OgreConfigFile.h> 00038 #include <OgreMaterial.h> 00039 #include <OgreTechnique.h> 00040 #include <OgrePass.h> 00041 #include <OgreCamera.h> 00042 #include "OgreException.h" 00043 #include "OgreStringConverter.h" 00044 #include "OgreRenderSystem.h" 00045 #include "OgreRenderSystemCapabilities.h" 00046 #include "OgreGpuProgram.h" 00047 #include "OgreGpuProgramManager.h" 00048 #include "OgreTerrainVertexProgram.h" 00049 #include "OgreTerrainPage.h" 00050 #include "OgreLogManager.h" 00051 00052 #define TERRAIN_MATERIAL_NAME "TerrainSceneManager/Terrain" 00053 00054 namespace Ogre 00055 { 00056 //------------------------------------------------------------------------- 00057 TerrainOptions TerrainSceneManager::mOptions; 00058 //------------------------------------------------------------------------- 00059 //------------------------------------------------------------------------- 00060 TerrainSceneManager::TerrainSceneManager() : OctreeSceneManager( ) 00061 { 00062 //setDisplaySceneNodes( true ); 00063 //setShowBoxes( true ); 00064 00065 mUseCustomMaterial = false; 00066 mUseNamedParameterLodMorph = false; 00067 mLodMorphParamIndex = 3; 00068 mTerrainRoot = 0; 00069 mActivePageSource = 0; 00070 mPagingEnabled = false; 00071 mLivePageMargin = 0; 00072 mBufferedPageMargin = 0; 00073 // Construct listener manager singleton 00074 new TerrainPageSourceListenerManager(); 00075 00076 00077 00078 } 00079 //------------------------------------------------------------------------- 00080 TerrainSceneManager::~TerrainSceneManager() 00081 { 00082 // Make sure the indexes are destroyed during orderly shutdown 00083 // and not when statics are destroyed (may be too late) 00084 TerrainRenderable::_getIndexCache().shutdown(); 00085 00086 // destroy listener manager 00087 delete TerrainPageSourceListenerManager::getSingletonPtr(); 00088 } 00089 //------------------------------------------------------------------------- 00090 void TerrainSceneManager::loadConfig(const String& filename) 00091 { 00092 /* Set up the options */ 00093 ConfigFile config; 00094 String val; 00095 00096 config.load( filename ); 00097 00098 val = config.getSetting( "DetailTile" ); 00099 if ( !val.empty() ) 00100 setDetailTextureRepeat(atoi(val.c_str())); 00101 00102 val = config.getSetting( "MaxMipMapLevel" ); 00103 if ( !val.empty() ) 00104 setMaxGeoMipMapLevel(atoi( val.c_str() )); 00105 00106 00107 val = config.getSetting( "PageSize" ); 00108 if ( !val.empty() ) 00109 setPageSize(atoi( val.c_str() )); 00110 else 00111 Except(Exception::ERR_ITEM_NOT_FOUND, "Missing option 'PageSize'", 00112 "TerrainSceneManager::loadConfig"); 00113 00114 00115 val = config.getSetting( "TileSize" ); 00116 if ( !val.empty() ) 00117 setTileSize(atoi( val.c_str() )); 00118 else 00119 Except(Exception::ERR_ITEM_NOT_FOUND, "Missing option 'TileSize'", 00120 "TerrainSceneManager::loadConfig"); 00121 00122 Vector3 v = Vector3::UNIT_SCALE; 00123 00124 val = config.getSetting( "PageWorldX" ); 00125 if ( !val.empty() ) 00126 v.x = atof( val.c_str() ); 00127 00128 val = config.getSetting( "MaxHeight" ); 00129 if ( !val.empty() ) 00130 v.y = atof( val.c_str() ); 00131 00132 val = config.getSetting( "PageWorldZ" ); 00133 if ( !val.empty() ) 00134 v.z = atof( val.c_str() ); 00135 00136 // Scale x/z relative to pagesize 00137 v.x /= mOptions.pageSize; 00138 v.z /= mOptions.pageSize; 00139 setScale(v); 00140 00141 val = config.getSetting( "MaxPixelError" ); 00142 if ( !val.empty() ) 00143 setMaxPixelError(atoi( val.c_str() )); 00144 00145 mDetailTextureName = config.getSetting( "DetailTexture" ); 00146 00147 mWorldTextureName = config.getSetting( "WorldTexture" ); 00148 00149 if ( config.getSetting( "VertexColours" ) == "yes" ) 00150 mOptions.coloured = true; 00151 00152 if ( config.getSetting( "VertexNormals" ) == "yes" ) 00153 mOptions.lit = true; 00154 00155 if ( config.getSetting( "UseTriStrips" ) == "yes" ) 00156 setUseTriStrips(true); 00157 00158 if ( config.getSetting( "VertexProgramMorph" ) == "yes" ) 00159 setUseLODMorph(true); 00160 00161 val = config.getSetting( "LODMorphStart"); 00162 if ( !val.empty() ) 00163 setLODMorphStart(atof(val.c_str())); 00164 00165 val = config.getSetting( "CustomMaterialName" ); 00166 if ( !val.empty() ) 00167 setCustomMaterial(val); 00168 00169 val = config.getSetting( "MorphLODFactorParamName" ); 00170 if ( !val.empty() ) 00171 setCustomMaterialMorphFactorParam(val); 00172 00173 val = config.getSetting( "MorphLODFactorParamIndex" ); 00174 if ( !val.empty() ) 00175 setCustomMaterialMorphFactorParam(atoi(val.c_str())); 00176 00177 // Now scan through the remaining settings, looking for any PageSource 00178 // prefixed items 00179 String pageSourceName = config.getSetting("PageSource"); 00180 if (pageSourceName == "") 00181 { 00182 Except(Exception::ERR_ITEM_NOT_FOUND, "Missing option 'PageSource'", 00183 "TerrainSceneManager::loadConfig"); 00184 } 00185 TerrainPageSourceOptionList optlist; 00186 ConfigFile::SettingsIterator setIt = config.getSettingsIterator(); 00187 while (setIt.hasMoreElements()) 00188 { 00189 String name = setIt.peekNextKey(); 00190 String value = setIt.getNext(); 00191 if (StringUtil::startsWith(name, pageSourceName, false)) 00192 { 00193 optlist.push_back(TerrainPageSourceOption(name, value)); 00194 } 00195 } 00196 // set the page source 00197 selectPageSource(pageSourceName, optlist); 00198 00199 00200 } 00201 //------------------------------------------------------------------------- 00202 /* 00203 void TerrainSceneManager::loadHeightmap(void) 00204 { 00205 Image image; 00206 00207 image.load( mHeightmapName ); 00208 00209 //check to make sure it's 2^n + 1 size. 00210 if ( image.getWidth() != image.getHeight() || 00211 ! _checkSize( image.getWidth() ) ) 00212 { 00213 String err = "Error: Invalid heightmap size : " + 00214 StringConverter::toString( image.getWidth() ) + 00215 "," + StringConverter::toString( image.getHeight() ) + 00216 ". Should be 2^n+1, 2^n+1"; 00217 Except( Exception::ERR_INVALIDPARAMS, err, "TerrainSceneManager::loadHeightmap" ); 00218 } 00219 00220 int upperRange = 0; 00221 int size = image.getWidth(); 00222 00223 if ( image.getFormat() == PF_L8 ) 00224 { 00225 upperRange = 255; 00226 00227 // Parse the char data into floats 00228 mOptions.heightData = new Real[size*size]; 00229 const uchar* pSrc = image. getData(); 00230 Real* pDest = mOptions.heightData; 00231 for (int i = 0; i < size*size; ++i) 00232 { 00233 *pDest++ = *pSrc++ * mOptions.scale.y; 00234 } 00235 } 00236 else 00237 { 00238 Except( Exception::ERR_INVALIDPARAMS, "Error: Image is not a grayscale image.", 00239 "TerrainSceneManager::setWorldGeometry" ); 00240 } 00241 00242 00243 // set up the octree size. 00244 float max_x = mOptions.scale.x * size; 00245 00246 float max_y = upperRange * mOptions.scale.y; 00247 00248 float max_z = mOptions.scale.z * size; 00249 00250 resize( AxisAlignedBox( 0, 0, 0, max_x, max_y, max_z ) ); 00251 00252 mOptions.pageSize = size; 00253 00254 } 00255 */ 00256 //------------------------------------------------------------------------- 00257 void TerrainSceneManager::setupTerrainMaterial(void) 00258 { 00259 if (mCustomMaterialName == "") 00260 { 00261 // define our own material 00262 mOptions.terrainMaterial = static_cast<Material*>( 00263 MaterialManager::getSingleton().getByName(TERRAIN_MATERIAL_NAME)); 00264 if (!mOptions.terrainMaterial) 00265 { 00266 mOptions.terrainMaterial = createMaterial( "TerrainSceneManager/Terrain" ); 00267 00268 } 00269 else 00270 { 00271 mOptions.terrainMaterial->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); 00272 } 00273 00274 Pass* pass = mOptions.terrainMaterial->getTechnique(0)->getPass(0); 00275 00276 if ( mWorldTextureName != "" ) 00277 { 00278 pass->createTextureUnitState( mWorldTextureName, 0 ); 00279 } 00280 if ( mDetailTextureName != "" ) 00281 { 00282 pass->createTextureUnitState( mDetailTextureName, 1 ); 00283 } 00284 00285 mOptions.terrainMaterial -> setLightingEnabled( mOptions.lit ); 00286 00287 if (mOptions.lodMorph && 00288 mDestRenderSystem->getCapabilities()->hasCapability(RSC_VERTEX_PROGRAM) && 00289 GpuProgramManager::getSingleton().getByName("Terrain/VertexMorph") == 0) 00290 { 00291 // Create & assign LOD morphing vertex program 00292 String syntax; 00293 if (GpuProgramManager::getSingleton().isSyntaxSupported("arbvp1")) 00294 { 00295 syntax = "arbvp1"; 00296 } 00297 else 00298 { 00299 syntax = "vs_1_1"; 00300 } 00301 00302 // Get source, and take into account current fog mode 00303 FogMode fm = getFogMode(); 00304 const String& source = TerrainVertexProgram::getProgramSource( 00305 fm, syntax); 00306 00307 GpuProgram* prog = GpuProgramManager::getSingleton().createProgramFromString( 00308 "Terrain/VertexMorph", source, GPT_VERTEX_PROGRAM, syntax); 00309 00310 // Attach 00311 pass->setVertexProgram("Terrain/VertexMorph"); 00312 00313 // Get params 00314 GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters(); 00315 00316 // worldviewproj 00317 params->setAutoConstant(0, GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); 00318 // morph factor 00319 params->setAutoConstant(4, GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID); 00320 // fog exp density(if relevant) 00321 if (fm == FOG_EXP || fm == FOG_EXP2) 00322 { 00323 params->setConstant(5, Vector3(getFogDensity(), 0, 0)); 00324 // Override scene fog since otherwise it's applied twice 00325 // Set to linear and we derive [0,1] fog value in the shader 00326 pass->setFog(true, FOG_LINEAR, getFogColour(), 0, 1, 0); 00327 } 00328 00329 // Set param index 00330 mLodMorphParamName = ""; 00331 mLodMorphParamIndex = 4; 00332 } 00333 00334 mOptions.terrainMaterial->load(); 00335 00336 } 00337 else 00338 { 00339 // Custom material 00340 mOptions.terrainMaterial = static_cast<Material*>( 00341 MaterialManager::getSingleton().getByName(mCustomMaterialName)); 00342 mOptions.terrainMaterial->load(); 00343 00344 } 00345 00346 // now set up the linkage between vertex program and LOD morph param 00347 if (mOptions.lodMorph) 00348 { 00349 Technique* t = mOptions.terrainMaterial->getBestTechnique(); 00350 for (ushort i = 0; i < t->getNumPasses(); ++i) 00351 { 00352 Pass* p = t->getPass(i); 00353 if (p->hasVertexProgram()) 00354 { 00355 // we have to assume vertex program includes LOD morph capability 00356 GpuProgramParametersSharedPtr params = 00357 p->getVertexProgramParameters(); 00358 // Check to see if custom param is already there 00359 GpuProgramParameters::AutoConstantIterator aci = params->getAutoConstantIterator(); 00360 bool found = false; 00361 while (aci.hasMoreElements()) 00362 { 00363 const GpuProgramParameters::AutoConstantEntry& ace = aci.getNext(); 00364 if (ace.paramType == GpuProgramParameters::ACT_CUSTOM && 00365 ace.data == MORPH_CUSTOM_PARAM_ID) 00366 { 00367 found = true; 00368 } 00369 } 00370 if (!found) 00371 { 00372 if(mLodMorphParamName != "") 00373 { 00374 params->setNamedAutoConstant(mLodMorphParamName, 00375 GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID); 00376 } 00377 else 00378 { 00379 params->setAutoConstant(mLodMorphParamIndex, 00380 GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID); 00381 } 00382 } 00383 00384 } 00385 } 00386 } 00387 00388 } 00389 //------------------------------------------------------------------------- 00390 void TerrainSceneManager::setupTerrainPages(void) 00391 { 00392 00393 //create a root terrain node. 00394 if (!mTerrainRoot) 00395 mTerrainRoot = getRootSceneNode() -> createChildSceneNode( "Terrain" ); 00396 00397 //setup the page array. 00398 unsigned short pageSlots = 1 + (mBufferedPageMargin * 2); 00399 unsigned short i, j; 00400 for (i = 0; i < pageSlots; ++i) 00401 { 00402 mTerrainPages.push_back(TerrainPageRow()); 00403 for (j = 0; j < pageSlots; ++j) 00404 { 00405 mTerrainPages[i].push_back(0); 00406 } 00407 } 00408 00409 00410 00411 } 00412 //------------------------------------------------------------------------- 00413 void TerrainSceneManager::setWorldGeometry( const String& filename ) 00414 { 00415 mTerrainPages.clear(); 00416 // Load the configuration 00417 loadConfig(filename); 00418 00419 // Resize the octree, allow for 1 page for now 00420 float max_x = mOptions.scale.x * mOptions.pageSize; 00421 float max_y = mOptions.scale.y; 00422 float max_z = mOptions.scale.z * mOptions.pageSize; 00423 resize( AxisAlignedBox( 0, 0, 0, max_x, max_y, max_z ) ); 00424 00425 setupTerrainMaterial(); 00426 00427 setupTerrainPages(); 00428 00429 } 00430 //------------------------------------------------------------------------- 00431 void TerrainSceneManager::clearScene(void) 00432 { 00433 OctreeSceneManager::clearScene(); 00434 mTerrainPages.clear(); 00435 // Octree has destroyed our root 00436 mTerrainRoot = 0; 00437 } 00438 //------------------------------------------------------------------------- 00439 void TerrainSceneManager::_renderScene(Camera* cam, Viewport *vp, bool includeOverlays) 00440 { 00441 // For now, no paging and expect immediate response 00442 if (mTerrainPages[0][0] == 0) 00443 { 00444 mActivePageSource->requestPage(0, 0); 00445 } 00446 SceneManager::_renderScene(cam, vp, includeOverlays); 00447 00448 } 00449 //------------------------------------------------------------------------- 00450 void TerrainSceneManager::attachPage(ushort pageX, ushort pageZ, TerrainPage* page) 00451 { 00452 assert(pageX == 0 && pageZ == 0 && "Multiple pages not yet supported"); 00453 00454 assert(mTerrainPages[pageX][pageZ] == 0 && "Page at that index not yet expired!"); 00455 // Insert page into list 00456 mTerrainPages[pageX][pageZ] = page; 00457 // Attach page to terrain root 00458 mTerrainRoot->addChild(page->pageSceneNode); 00459 00460 } 00461 //------------------------------------------------------------------------- 00462 void TerrainSceneManager::_renderVisibleObjects( void ) 00463 { 00464 00465 mDestRenderSystem -> setLightingEnabled( false ); 00466 00467 OctreeSceneManager::_renderVisibleObjects(); 00468 00469 } 00470 //------------------------------------------------------------------------- 00471 float TerrainSceneManager::getHeightAt( float x, float z ) 00472 { 00473 00474 00475 Vector3 pt( x, 0, z ); 00476 00477 TerrainRenderable * t = getTerrainTile( pt ); 00478 00479 if ( t == 0 ) 00480 { 00481 // printf( "No tile found for point\n" ); 00482 return -1; 00483 } 00484 00485 float h = t -> getHeightAt( x, z ); 00486 00487 // printf( "Height is %f\n", h ); 00488 return h; 00489 00490 } 00491 //------------------------------------------------------------------------- 00492 TerrainPage* TerrainSceneManager::getTerrainPage( const Vector3 & pt ) 00493 { 00494 if (mPagingEnabled) 00495 { 00496 // TODO 00497 return 0; 00498 } 00499 else 00500 { 00501 // Single page 00502 return mTerrainPages[0][0]; 00503 } 00504 } 00505 //------------------------------------------------------------------------- 00506 TerrainRenderable * TerrainSceneManager::getTerrainTile( const Vector3 & pt ) 00507 { 00508 TerrainPage* tp = getTerrainPage(pt); 00509 if (!tp) 00510 return NULL; 00511 else 00512 return tp->getTerrainTile(pt); 00513 } 00514 //------------------------------------------------------------------------- 00515 bool TerrainSceneManager::intersectSegment( const Vector3 & start, 00516 const Vector3 & end, Vector3 * result ) 00517 { 00518 TerrainRenderable * t = getTerrainTile( start ); 00519 00520 if ( t == 0 ) 00521 { 00522 *result = Vector3( -1, -1, -1 ); 00523 return false; 00524 } 00525 00526 return t -> intersectSegment( start, end, result ); 00527 } 00528 //------------------------------------------------------------------------- 00529 void TerrainSceneManager::setUseTriStrips(bool useStrips) 00530 { 00531 mOptions.useTriStrips = useStrips; 00532 } 00533 //------------------------------------------------------------------------- 00534 void TerrainSceneManager::setUseLODMorph(bool morph) 00535 { 00536 // Set true only if vertex programs are supported 00537 mOptions.lodMorph = morph && 00538 mDestRenderSystem->getCapabilities()->hasCapability(RSC_VERTEX_PROGRAM); 00539 } 00540 //------------------------------------------------------------------------- 00541 void TerrainSceneManager::setUseVertexNormals(bool useNormals) 00542 { 00543 mOptions.lit = useNormals; 00544 } 00545 //------------------------------------------------------------------------- 00546 void TerrainSceneManager::setUseVertexColours(bool useColours) 00547 { 00548 mOptions.coloured = useColours; 00549 } 00550 //------------------------------------------------------------------------- 00551 void TerrainSceneManager::setWorldTexture(const String& textureName) 00552 { 00553 mWorldTextureName = textureName; 00554 } 00555 //------------------------------------------------------------------------- 00556 void TerrainSceneManager::setDetailTexture(const String& textureName) 00557 { 00558 mDetailTextureName = textureName; 00559 00560 } 00561 //------------------------------------------------------------------------- 00562 void TerrainSceneManager::setDetailTextureRepeat(int repeat) 00563 { 00564 mOptions.detailTile = repeat; 00565 } 00566 //------------------------------------------------------------------------- 00567 void TerrainSceneManager::setTileSize(int size) 00568 { 00569 mOptions.tileSize = size; 00570 } 00571 //------------------------------------------------------------------------- 00572 void TerrainSceneManager::setPageSize(int size) 00573 { 00574 mOptions.pageSize = size; 00575 } 00576 //------------------------------------------------------------------------- 00577 void TerrainSceneManager::setMaxPixelError(int pixelError) 00578 { 00579 mOptions.maxPixelError = pixelError; 00580 } 00581 //------------------------------------------------------------------------- 00582 void TerrainSceneManager::setScale(const Vector3& scale) 00583 { 00584 mOptions.scale = scale; 00585 } 00586 //------------------------------------------------------------------------- 00587 void TerrainSceneManager::setMaxGeoMipMapLevel(int maxMip) 00588 { 00589 mOptions.maxGeoMipMapLevel = maxMip; 00590 } 00591 //------------------------------------------------------------------------- 00592 void TerrainSceneManager::setCustomMaterial(const String& materialName) 00593 { 00594 mCustomMaterialName = materialName; 00595 if (materialName != "") 00596 mUseCustomMaterial = true; 00597 else 00598 mUseCustomMaterial = false; 00599 } 00600 //------------------------------------------------------------------------- 00601 void TerrainSceneManager::setCustomMaterialMorphFactorParam(const String& paramName) 00602 { 00603 mUseNamedParameterLodMorph = true; 00604 mLodMorphParamName = paramName; 00605 00606 } 00607 //------------------------------------------------------------------------- 00608 void TerrainSceneManager::setCustomMaterialMorphFactorParam(size_t paramIndex) 00609 { 00610 mUseNamedParameterLodMorph = false; 00611 mLodMorphParamIndex = paramIndex; 00612 } 00613 //------------------------------------------------------------------------- 00614 void TerrainSceneManager::setLODMorphStart(Real morphStart) 00615 { 00616 mOptions.lodMorphStart = morphStart; 00617 } 00618 //------------------------------------------------------------------------- 00619 Camera* TerrainSceneManager::createCamera( const String &name ) 00620 { 00621 Camera* c = OctreeSceneManager::createCamera(name); 00622 00623 // Set primary camera, if none 00624 if (!mOptions.primaryCamera) 00625 setPrimaryCamera(c); 00626 00627 return c; 00628 00629 } 00630 //------------------------------------------------------------------------- 00631 void TerrainSceneManager::setPrimaryCamera(const Camera* cam) 00632 { 00633 mOptions.primaryCamera = cam; 00634 } 00635 //------------------------------------------------------------------------- 00636 bool TerrainSceneManager::setOption( const String & name, const void *value ) 00637 { 00638 if (name == "PageSize") 00639 { 00640 setPageSize(*static_cast<const int*>(value)); 00641 return true; 00642 } 00643 else if (name == "TileSize") 00644 { 00645 setTileSize(*static_cast<const int*>(value)); 00646 return true; 00647 } 00648 else if (name == "PrimaryCamera") 00649 { 00650 setPrimaryCamera(static_cast<const Camera*>(value)); 00651 return true; 00652 } 00653 else if (name == "MaxMipMapLevel") 00654 { 00655 setMaxGeoMipMapLevel(*static_cast<const int*>(value)); 00656 return true; 00657 } 00658 else if (name == "Scale") 00659 { 00660 setScale(*static_cast<const Vector3*>(value)); 00661 return true; 00662 } 00663 else if (name == "MaxPixelError") 00664 { 00665 setMaxPixelError(*static_cast<const int*>(value)); 00666 return true; 00667 } 00668 else if (name == "UseTriStrips") 00669 { 00670 setUseTriStrips(*static_cast<const bool*>(value)); 00671 return true; 00672 } 00673 else if (name == "VertexProgramMorph") 00674 { 00675 setUseLODMorph(*static_cast<const bool*>(value)); 00676 return true; 00677 } 00678 else if (name == "DetailTile") 00679 { 00680 setDetailTextureRepeat(*static_cast<const int*>(value)); 00681 return true; 00682 } 00683 else if (name == "LodMorphStart") 00684 { 00685 setLODMorphStart(*static_cast<const Real*>(value)); 00686 return true; 00687 } 00688 else if (name == "VertexNormals") 00689 { 00690 setUseVertexNormals(*static_cast<const bool*>(value)); 00691 return true; 00692 } 00693 else if (name == "VertexColours") 00694 { 00695 setUseVertexColours(*static_cast<const bool*>(value)); 00696 return true; 00697 } 00698 else if (name == "MorphLODFactorParamName") 00699 { 00700 setCustomMaterialMorphFactorParam(*static_cast<const String*>(value)); 00701 return true; 00702 } 00703 else if (name == "MorphLODFactorParamIndex") 00704 { 00705 setCustomMaterialMorphFactorParam(*static_cast<const size_t*>(value)); 00706 return true; 00707 } 00708 else if (name == "CustomMaterialName") 00709 { 00710 setCustomMaterial(*static_cast<const String*>(value)); 00711 return true; 00712 } 00713 else if (name == "WorldTexture") 00714 { 00715 setWorldTexture(*static_cast<const String*>(value)); 00716 return true; 00717 } 00718 else if (name == "DetailTexture") 00719 { 00720 setDetailTexture(*static_cast<const String*>(value)); 00721 return true; 00722 } 00723 else 00724 { 00725 return OctreeSceneManager::setOption(name, value); 00726 } 00727 00728 return false; 00729 } 00730 //------------------------------------------------------------------------- 00731 void TerrainSceneManager::registerPageSource(const String& typeName, 00732 TerrainPageSource* source) 00733 { 00734 mPageSources.insert( 00735 PageSourceMap::value_type(typeName, source)); 00736 LogManager::getSingleton().logMessage( 00737 "TerrainSceneManager: Registered a new PageSource for " 00738 "type " + typeName); 00739 } 00740 //------------------------------------------------------------------------- 00741 void TerrainSceneManager::selectPageSource(const String& typeName, 00742 TerrainPageSourceOptionList& optionList) 00743 { 00744 PageSourceMap::iterator i = mPageSources.find(typeName); 00745 if (i == mPageSources.end()) 00746 { 00747 Except(Exception::ERR_ITEM_NOT_FOUND, 00748 "Cannot locate a TerrainPageSource for type " + typeName, 00749 "TerrainSceneManager::selectPageSource"); 00750 } 00751 00752 if (mActivePageSource) 00753 { 00754 mActivePageSource->shutdown(); 00755 } 00756 mActivePageSource = i->second; 00757 mActivePageSource->initialise(this, mOptions.tileSize, mOptions.pageSize, 00758 mPagingEnabled, optionList); 00759 00760 LogManager::getSingleton().logMessage( 00761 "TerrainSceneManager: Activated PageSource " + typeName); 00762 00763 } 00764 //------------------------------------------------------------------------- 00765 int TerrainSceneManager::setDetailTextureRepeat(void) 00766 { 00767 return mOptions.detailTile; 00768 } 00769 //------------------------------------------------------------------------- 00770 int TerrainSceneManager::getTileSize(void) 00771 { 00772 return mOptions.tileSize; 00773 } 00774 //------------------------------------------------------------------------- 00775 int TerrainSceneManager::getPageSize(void) 00776 { 00777 return mOptions.pageSize; 00778 } 00779 //------------------------------------------------------------------------- 00780 int TerrainSceneManager::getMaxPixelError(void) 00781 { 00782 return mOptions.maxPixelError; 00783 } 00784 //------------------------------------------------------------------------- 00785 const Vector3& TerrainSceneManager::getScale(void) 00786 { 00787 return mOptions.scale; 00788 } 00789 //------------------------------------------------------------------------- 00790 int TerrainSceneManager::getMaxGeoMipMapLevel(void) 00791 { 00792 return mOptions.maxGeoMipMapLevel; 00793 } 00794 //------------------------------------------------------------------------- 00795 //------------------------------------------------------------------------- 00796 RaySceneQuery* 00797 TerrainSceneManager::createRayQuery(const Ray& ray, unsigned long mask) 00798 { 00799 TerrainRaySceneQuery *trsq = new TerrainRaySceneQuery(this); 00800 trsq->setRay(ray); 00801 trsq->setQueryMask(mask); 00802 return trsq; 00803 } 00804 //------------------------------------------------------------------------- 00805 TerrainRaySceneQuery::TerrainRaySceneQuery(SceneManager* creator) 00806 :OctreeRaySceneQuery(creator) 00807 { 00808 mSupportedWorldFragments.insert(SceneQuery::WFT_SINGLE_INTERSECTION); 00809 } 00810 //------------------------------------------------------------------------- 00811 TerrainRaySceneQuery::~TerrainRaySceneQuery() 00812 { 00813 } 00814 //------------------------------------------------------------------------- 00815 void TerrainRaySceneQuery::execute(RaySceneQueryListener* listener) 00816 { 00817 static WorldFragment worldFrag; 00818 worldFrag.fragmentType = SceneQuery::WFT_SINGLE_INTERSECTION; 00819 00820 const Vector3& dir = mRay.getDirection(); 00821 const Vector3& origin = mRay.getOrigin(); 00822 // Straight up / down? 00823 if (dir == Vector3::UNIT_Y || dir == Vector3::NEGATIVE_UNIT_Y) 00824 { 00825 Real height = static_cast<TerrainSceneManager*>(mParentSceneMgr)->getHeightAt( 00826 origin.x, origin.z); 00827 if (height != -1 && (height <= origin.y && dir.y < 0) || (height >= origin.y && dir.y > 0)) 00828 { 00829 worldFrag.singleIntersection.x = origin.x; 00830 worldFrag.singleIntersection.z = origin.z; 00831 worldFrag.singleIntersection.y = height; 00832 listener->queryResult(&worldFrag, 00833 (worldFrag.singleIntersection - origin).length()); 00834 } 00835 } 00836 else 00837 { 00838 // Perform arbitrary query 00839 if (static_cast<TerrainSceneManager*>(mParentSceneMgr)->intersectSegment( 00840 origin, origin + (dir * 100000), &worldFrag.singleIntersection)) 00841 { 00842 listener->queryResult(&worldFrag, 00843 (worldFrag.singleIntersection - origin).length()); 00844 } 00845 00846 00847 } 00848 OctreeRaySceneQuery::execute(listener); 00849 00850 } 00851 //------------------------------------------------------------------------- 00852 Material* TerrainSceneManager::getTerrainMaterial(void) 00853 { 00854 return mOptions.terrainMaterial; 00855 } 00856 //------------------------------------------------------------------------- 00857 TerrainSceneManager::PageSourceIterator TerrainSceneManager::getPageSourceIterator(void) 00858 { 00859 return PageSourceIterator(mPageSources.begin(), mPageSources.end()); 00860 } 00861 00862 00863 } //namespace
Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:49 2004