Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreTerrainSceneManager.cpp

Go to the documentation of this file.
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