source: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTerrainSceneManager.cpp @ 1816

Revision 1816, 28.3 KB checked in by mattausch, 18 years ago (diff)

changed scenemanager: options are directly given to it

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of the GameTools Project
4http://www.gametools.org
5
6Author: Martin Szydlowski
7-----------------------------------------------------------------------------
8*/
9#include <OgreGpuProgramManager.h>
10#include <OgreConfigFile.h>
11#include <OgreMaterialManager.h>
12#include <OgreLogManager.h>
13
14#include "OgreKdTerrainPage.h"
15#include "OgreKdHeightmapTerrainPageSource.h"
16#include "OgreKdTerrainVertexProgram.h"
17
18#include "OgreKdTerrainSceneManager.h"
19
20#define TERRAIN_MATERIAL_NAME "TerrainSceneManager/Terrain"
21
22namespace Ogre
23{
24
25KdTerrainSceneManager::KdTerrainSceneManager(const String& name, GtpVisibility::VisibilityManager *vm):
26KdTreeSceneManager(name, vm),
27mUseCustomMaterial(false),
28mUseNamedParameterLodMorph(false),
29mLodMorphParamIndex(3),
30mTerrainRoot(0),
31mActivePageSource(0),
32mPagingEnabled(false),
33mLivePageMargin(0),
34mBufferedPageMargin(0)
35{
36
37}
38//-----------------------------------------------------------------------
39KdTerrainSceneManager::~KdTerrainSceneManager()
40{
41        shutdown();
42}
43//-----------------------------------------------------------------------
44const String& KdTerrainSceneManager::getTypeName() const
45{
46        return KdTerrainSceneManagerFactory::FACTORY_TYPE_NAME;
47}
48//-----------------------------------------------------------------------
49void KdTerrainSceneManager::clearScene()
50{
51        KdTreeSceneManager::clearScene();
52
53        // clear terrain
54        mTerrainPages.clear();
55        destroyLevelIndexes();
56        // sm has destroyed our root
57        mTerrainRoot = 0;
58}
59//-----------------------------------------------------------------------
60bool KdTerrainSceneManager::setOption(const String& strKey, const void* pValue)
61{
62        // options for terrain
63        if (strKey == "PageSize")
64        {
65                setPageSize(*static_cast<const int*>(pValue));
66                return true;
67        }
68        else if (strKey == "TileSize")
69        {
70                setTileSize(*static_cast<const int*>(pValue));
71                return true;
72        }
73        else if (strKey == "PrimaryCamera")
74        {
75                setPrimaryCamera(static_cast<const Camera*>(pValue));
76                return true;
77        }
78        else if (strKey == "MaxMipMapLevel")
79        {
80                setMaxGeoMipMapLevel(*static_cast<const int*>(pValue));
81                return true;
82        }
83        else if (strKey == "Scale")
84        {
85                setScale(*static_cast<const Vector3*>(pValue));
86                return true;
87        }
88        else if (strKey == "MaxPixelError")
89        {
90                setMaxPixelError(*static_cast<const int*>(pValue));
91                return true;
92        }
93        else if (strKey == "UseTriStrips")
94        {
95                setUseTriStrips(*static_cast<const bool*>(pValue));
96                return true;
97        }
98        else if (strKey == "VertexProgramMorph")
99        {
100                setUseLODMorph(*static_cast<const bool*>(pValue));
101                return true;
102        }
103        else if (strKey == "DetailTile")
104        {
105                setDetailTextureRepeat(*static_cast<const int*>(pValue));
106                return true;
107        }
108        else if (strKey == "LodMorphStart")
109        {
110                setLODMorphStart(*static_cast<const Real*>(pValue));
111                return true;
112        }
113        else if (strKey == "VertexNormals")
114        {
115                setUseVertexNormals(*static_cast<const bool*>(pValue));
116                return true;
117        }
118        else if (strKey == "VertexColours")
119        {
120                setUseVertexColours(*static_cast<const bool*>(pValue));
121                return true;
122        }
123        else if (strKey == "MorphLODFactorParamName")
124        {
125                setCustomMaterialMorphFactorParam(*static_cast<const String*>(pValue));
126                return true;
127        }
128        else if (strKey == "MorphLODFactorParamIndex")
129        {
130                setCustomMaterialMorphFactorParam(*static_cast<const uint*>(pValue));
131                return true;
132        }
133        else if (strKey == "CustomMaterialName")
134        {
135                setCustomMaterial(*static_cast<const String*>(pValue));
136                return true;
137        }
138        else if (strKey == "WorldTexture")
139        {
140                setWorldTexture(*static_cast<const String*>(pValue));
141                return true;
142        }
143        else if (strKey == "DetailTexture")
144        {
145                setDetailTexture(*static_cast<const String*>(pValue));
146                return true;
147        }
148
149        return KdTreeSceneManager::setOption(strKey, pValue);
150}
151//-----------------------------------------------------------------------
152Camera* KdTerrainSceneManager::createCamera(const String &name )
153{
154        Camera* cam = KdTreeSceneManager::createCamera(name);
155
156        // Set primary camera, if none
157        if (!mOptions.primaryCamera)
158                setPrimaryCamera(cam);
159
160        return cam;
161}
162//-------------------------------------------------------------------------
163//void _findVisibleObjects(Camera *cam, bool onlyShadowCasters)
164//{
165//      KdTreeSceneManager::_findVisibleObjects(cam, onlyShadowCasters);
166//}
167//-------------------------------------------------------------------------
168void KdTerrainSceneManager::_renderScene(Camera* cam, Viewport *vp, bool includeOverlays)
169{
170        // For now, no paging and expect immediate response
171        if (!mTerrainPages.empty() && mTerrainPages[0][0] == 0)
172        {
173                mActivePageSource->requestPage(0, 0);
174        }
175        KdTreeSceneManager::_renderScene(cam, vp, includeOverlays);
176
177}
178//-----------------------------------------------------------------------
179//void KdTerrainSceneManager::_renderVisibleObjects()
180//{
181//      KdTreeSceneManager::_renderVisibleObjects();
182//}
183//-------------------------------------------------------------------------
184void KdTerrainSceneManager::shutdown(void)
185{
186        // Make sure the indexes are destroyed during orderly shutdown
187        // and not when statics are destroyed (may be too late)
188        mIndexCache.shutdown();
189        destroyLevelIndexes();
190
191        // Make sure we free up material (static)
192        mOptions.terrainMaterial.setNull();
193
194}
195//-------------------------------------------------------------------------
196void KdTerrainSceneManager::loadConfig(DataStreamPtr& stream)
197{
198        /* Set up the options */
199        ConfigFile config;
200        String val;
201
202        config.load( stream );
203
204        val = config.getSetting( "DetailTile" );
205        if ( !val.empty() )
206                setDetailTextureRepeat(atoi(val.c_str()));
207
208        val = config.getSetting( "MaxMipMapLevel" );
209        if ( !val.empty() )
210                setMaxGeoMipMapLevel(atoi( val.c_str() ));
211
212
213        val = config.getSetting( "PageSize" );
214        if ( !val.empty() )
215                setPageSize(atoi( val.c_str() ));
216        else
217                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing option 'PageSize'",
218                "TerrainSceneManager::loadConfig");
219
220
221        val = config.getSetting( "TileSize" );
222        if ( !val.empty() )
223                setTileSize(atoi( val.c_str() ));
224        else
225                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing option 'TileSize'",
226                "TerrainSceneManager::loadConfig");
227
228        Vector3 v = Vector3::UNIT_SCALE;
229
230        val = config.getSetting( "PageWorldX" );
231        if ( !val.empty() )
232                v.x = atof( val.c_str() );
233
234        val = config.getSetting( "MaxHeight" );
235        if ( !val.empty() )
236                v.y = atof( val.c_str() );
237
238        val = config.getSetting( "PageWorldZ" );
239        if ( !val.empty() )
240                v.z = atof( val.c_str() );
241
242        // Scale x/z relative to pagesize
243        v.x /= mOptions.pageSize;
244        v.z /= mOptions.pageSize;
245        setScale(v);
246
247        val = config.getSetting( "MaxPixelError" );
248        if ( !val.empty() )
249                setMaxPixelError(atoi( val.c_str() ));
250
251        mDetailTextureName = config.getSetting( "DetailTexture" );
252
253        mWorldTextureName = config.getSetting( "WorldTexture" );
254
255        if ( config.getSetting( "VertexColours" ) == "yes" )
256                mOptions.coloured = true;
257
258        if ( config.getSetting( "VertexNormals" ) == "yes" )
259                mOptions.lit = true;
260
261        if ( config.getSetting( "UseTriStrips" ) == "yes" )
262                setUseTriStrips(true);
263
264        if ( config.getSetting( "VertexProgramMorph" ) == "yes" )
265                setUseLODMorph(true);
266
267        val = config.getSetting( "LODMorphStart");
268        if ( !val.empty() )
269                setLODMorphStart(atof(val.c_str()));
270
271        val = config.getSetting( "CustomMaterialName" );
272        if ( !val.empty() )
273                setCustomMaterial(val);
274
275        val = config.getSetting( "MorphLODFactorParamName" );
276        if ( !val.empty() )
277                setCustomMaterialMorphFactorParam(val);
278
279        val = config.getSetting( "MorphLODFactorParamIndex" );
280        if ( !val.empty() )
281                setCustomMaterialMorphFactorParam(atoi(val.c_str()));
282
283        // Now scan through the remaining settings, looking for any PageSource
284        // prefixed items
285        String pageSourceName = config.getSetting("PageSource");
286        if (pageSourceName == "")
287        {
288                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing option 'PageSource'",
289                        "TerrainSceneManager::loadConfig");
290        }
291        KdTerrainPageSourceOptionList optlist;
292        ConfigFile::SettingsIterator setIt = config.getSettingsIterator();
293        while (setIt.hasMoreElements())
294        {
295                String name = setIt.peekNextKey();
296                String value = setIt.getNext();
297                if (StringUtil::startsWith(name, pageSourceName, false))
298                {
299                        optlist.push_back(KdTerrainPageSourceOption(name, value));
300                }
301        }
302        // set the page source
303        selectPageSource(pageSourceName, optlist);
304}
305//-------------------------------------------------------------------------
306void KdTerrainSceneManager::setupTerrainMaterial(void)
307{
308        if (mCustomMaterialName == "")
309        {
310                // define our own material
311                mOptions.terrainMaterial =
312                        MaterialManager::getSingleton().getByName(TERRAIN_MATERIAL_NAME);
313                if (mOptions.terrainMaterial.isNull())
314                {
315                        // Make unique terrain material name
316                        StringUtil::StrStreamType s;
317                        s << mName << "/Terrain";
318                        mOptions.terrainMaterial = MaterialManager::getSingleton().create(
319                                s.str(),
320                                ResourceGroupManager::getSingleton().getWorldResourceGroupName());
321
322                }
323                else
324                {
325                        mOptions.terrainMaterial->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
326                }
327
328                Pass* pass = mOptions.terrainMaterial->getTechnique(0)->getPass(0);
329
330                if ( mWorldTextureName != "" )
331                {
332                        pass->createTextureUnitState( mWorldTextureName, 0 );
333                }
334                if ( mDetailTextureName != "" )
335                {
336                        pass->createTextureUnitState( mDetailTextureName, 1 );
337                }
338
339                mOptions.terrainMaterial -> setLightingEnabled( mOptions.lit );
340
341                if (mOptions.lodMorph &&
342                        mDestRenderSystem->getCapabilities()->hasCapability(RSC_VERTEX_PROGRAM) &&
343                        GpuProgramManager::getSingleton().getByName("Terrain/VertexMorph").isNull())
344                {
345                        // Create & assign LOD morphing vertex program
346                        String syntax;
347                        if (GpuProgramManager::getSingleton().isSyntaxSupported("arbvp1"))
348                        {
349                                syntax = "arbvp1";
350                        }
351                        else
352                        {
353                                syntax = "vs_1_1";
354                        }
355
356                        // Get source, and take into account current fog mode
357                        FogMode fm = getFogMode();
358                        const String& source = KdTerrainVertexProgram::getProgramSource(
359                                fm, syntax);
360
361                        GpuProgramPtr prog = GpuProgramManager::getSingleton().createProgramFromString(
362                                "Terrain/VertexMorph", ResourceGroupManager::getSingleton().getWorldResourceGroupName(),
363                                source, GPT_VERTEX_PROGRAM, syntax);
364
365                        // Attach
366                        pass->setVertexProgram("Terrain/VertexMorph");
367
368                        // Get params
369                        GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters();
370
371                        // worldviewproj
372                        params->setAutoConstant(0, GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
373                        // morph factor
374                        params->setAutoConstant(4, GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);
375                        // fog exp density(if relevant)
376                        if (fm == FOG_EXP || fm == FOG_EXP2)
377                        {
378                                params->setConstant(5, Vector3(getFogDensity(), 0, 0));
379                                // Override scene fog since otherwise it's applied twice
380                                // Set to linear and we derive [0,1] fog value in the shader
381                                pass->setFog(true, FOG_LINEAR, getFogColour(), 0, 1, 0);
382                        }
383
384                        // Also set shadow receiver program
385                        const String& source2 = KdTerrainVertexProgram::getProgramSource(
386                                fm, syntax, true);
387
388                        prog = GpuProgramManager::getSingleton().createProgramFromString(
389                                "Terrain/VertexMorphShadowReceive",
390                                ResourceGroupManager::getSingleton().getWorldResourceGroupName(),
391                                source2, GPT_VERTEX_PROGRAM, syntax);
392                        pass->setShadowReceiverVertexProgram("Terrain/VertexMorphShadowReceive");
393                        params = pass->getShadowReceiverVertexProgramParameters();
394                        // worldviewproj
395                        params->setAutoConstant(0, GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
396                        // world
397                        params->setAutoConstant(4, GpuProgramParameters::ACT_WORLD_MATRIX);
398                        // texture view / proj
399                        params->setAutoConstant(8, GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX);
400                        // morph factor
401                        params->setAutoConstant(12, GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);
402
403
404                        // Set param index
405                        mLodMorphParamName = "";
406                        mLodMorphParamIndex = 4;
407                }
408
409                mOptions.terrainMaterial->load();
410
411        }
412        else
413        {
414                // Custom material
415                mOptions.terrainMaterial =
416                        MaterialManager::getSingleton().getByName(mCustomMaterialName);
417                mOptions.terrainMaterial->load();
418
419        }
420
421        // now set up the linkage between vertex program and LOD morph param
422        if (mOptions.lodMorph)
423        {
424                Technique* t = mOptions.terrainMaterial->getBestTechnique();
425                for (ushort i = 0; i < t->getNumPasses(); ++i)
426                {
427                        Pass* p = t->getPass(i);
428                        if (p->hasVertexProgram())
429                        {
430                                // we have to assume vertex program includes LOD morph capability
431                                GpuProgramParametersSharedPtr params =
432                                        p->getVertexProgramParameters();
433                                // Check to see if custom param is already there
434                                GpuProgramParameters::AutoConstantIterator aci = params->getAutoConstantIterator();
435                                bool found = false;
436                                while (aci.hasMoreElements())
437                                {
438                                        const GpuProgramParameters::AutoConstantEntry& ace = aci.getNext();
439                                        if (ace.paramType == GpuProgramParameters::ACT_CUSTOM &&
440                                                ace.data == MORPH_CUSTOM_PARAM_ID)
441                                        {
442                                                found = true;
443                                        }
444                                }
445                                if (!found)
446                                {
447                                        if(mLodMorphParamName != "")
448                                        {
449                                                params->setNamedAutoConstant(mLodMorphParamName,
450                                                        GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);
451                                        }
452                                        else
453                                        {
454                                                params->setAutoConstant(mLodMorphParamIndex,
455                                                        GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);
456                                        }
457                                }
458
459                        }
460                }
461        }
462
463}
464//-------------------------------------------------------------------------
465void KdTerrainSceneManager::setupTerrainPages(void)
466{
467
468        //create a root terrain node.
469        if (!mTerrainRoot)
470                mTerrainRoot = getRootSceneNode() -> createChildSceneNode( "Terrain" );
471
472        //setup the page array.
473        unsigned short pageSlots = 1 + (mBufferedPageMargin * 2);
474        unsigned short i, j;
475        for (i = 0; i < pageSlots; ++i)
476        {
477                mTerrainPages.push_back(KdTerrainPageRow());
478                for (j = 0; j < pageSlots; ++j)
479                {
480                        mTerrainPages[i].push_back(0);
481                }
482        }
483
484        // If we're not paging, load immediate for convenience
485        if ( mActivePageSource && !mPagingEnabled )
486                mActivePageSource->requestPage(0,0);
487
488
489}
490//-------------------------------------------------------------------------
491void KdTerrainSceneManager::setWorldGeometry( const String& filename )
492{
493        // try to open in the current folder first
494        std::ifstream fs;
495        fs.open(filename.c_str());
496        if (fs)
497        {
498                // Wrap as a stream
499                DataStreamPtr stream(
500                        new FileStreamDataStream(filename, &fs, false));
501                setWorldGeometry(stream);
502        }
503        else
504        {
505                // otherwise try resource system
506                DataStreamPtr stream =
507                        ResourceGroupManager::getSingleton().openResource(filename,
508                        ResourceGroupManager::getSingleton().getWorldResourceGroupName());
509
510                setWorldGeometry(stream);
511        }
512}
513//-------------------------------------------------------------------------
514void KdTerrainSceneManager::setWorldGeometry(DataStreamPtr& stream, const String& typeName)
515{
516        // Clear out any existing world resources (if not default)
517        if (ResourceGroupManager::getSingleton().getWorldResourceGroupName() !=
518                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME)
519        {
520                ResourceGroupManager::getSingleton().clearResourceGroup(
521                        ResourceGroupManager::getSingleton().getWorldResourceGroupName());
522        }
523        destroyLevelIndexes();
524        mTerrainPages.clear();
525        // Load the configuration
526        loadConfig(stream);
527        initLevelIndexes();
528
529        // Resize the octree, allow for 1 page for now
530        //float max_x = mOptions.scale.x * mOptions.pageSize;
531        //float max_y = mOptions.scale.y;
532        //float max_z = mOptions.scale.z * mOptions.pageSize;
533        //resize( AxisAlignedBox( 0, 0, 0, max_x, max_y, max_z ) );
534
535        setupTerrainMaterial();
536
537        setupTerrainPages();
538
539}
540//-------------------------------------------------------------------------
541void KdTerrainSceneManager::attachPage(ushort pageX, ushort pageZ, KdTerrainPage* page)
542{
543        assert(pageX == 0 && pageZ == 0 && "Multiple pages not yet supported");
544
545        assert(mTerrainPages[pageX][pageZ] == 0 && "Page at that index not yet expired!");
546        // Insert page into list
547        mTerrainPages[pageX][pageZ] = page;
548        // Attach page to terrain root
549        mTerrainRoot->addChild(page->pageSceneNode);
550
551}
552//-------------------------------------------------------------------------
553float KdTerrainSceneManager::getHeightAt( float x, float z )
554{
555
556
557        Vector3 pt( x, 0, z );
558
559        KdTerrainRenderable * t = getTerrainTile( pt );
560
561        if ( t == 0 )
562        {
563                //  printf( "No tile found for point\n" );
564                return -1;
565        }
566
567        float h = t -> getHeightAt( x, z );
568
569        // printf( "Height is %f\n", h );
570        return h;
571
572}
573//-------------------------------------------------------------------------
574KdTerrainPage* KdTerrainSceneManager::getTerrainPage( const Vector3 & pt )
575{
576        if (mPagingEnabled)
577        {
578                // TODO
579                return 0;
580        }
581        else
582        {
583                // Single page
584                if (mTerrainPages.empty() || mTerrainPages[0].empty())
585                        return 0;
586                return mTerrainPages[0][0];
587        }
588}
589//-------------------------------------------------------------------------
590KdTerrainRenderable * KdTerrainSceneManager::getTerrainTile( const Vector3 & pt )
591{
592        KdTerrainPage* tp = getTerrainPage(pt);
593        if (!tp)
594                return NULL;
595        else
596                return tp->getTerrainTile(pt);
597}
598//-------------------------------------------------------------------------
599bool KdTerrainSceneManager::intersectSegment( const Vector3 & start,
600                                                                                  const Vector3 & end, Vector3 * result )
601{
602        KdTerrainRenderable * t = getTerrainTile( start );
603
604        if ( t == 0 )
605        {
606                *result = Vector3( -1, -1, -1 );
607                return false;
608        }
609
610        return t -> intersectSegment( start, end, result );
611}
612//-------------------------------------------------------------------------
613void KdTerrainSceneManager::setUseTriStrips(bool useStrips)
614{
615        mOptions.useTriStrips = useStrips;
616}
617//-------------------------------------------------------------------------
618void KdTerrainSceneManager::setUseLODMorph(bool morph)
619{
620        // Set true only if vertex programs are supported
621        mOptions.lodMorph = morph &&
622                mDestRenderSystem->getCapabilities()->hasCapability(RSC_VERTEX_PROGRAM);
623}
624//-------------------------------------------------------------------------
625void KdTerrainSceneManager::setUseVertexNormals(bool useNormals)
626{
627        mOptions.lit = useNormals;
628}
629//-------------------------------------------------------------------------
630void KdTerrainSceneManager::setUseVertexColours(bool useColours)
631{
632        mOptions.coloured = useColours;
633}
634//-------------------------------------------------------------------------
635void KdTerrainSceneManager::setWorldTexture(const String& textureName)
636{
637        mWorldTextureName = textureName;
638}
639//-------------------------------------------------------------------------
640void KdTerrainSceneManager::setDetailTexture(const String& textureName)
641{
642        mDetailTextureName = textureName;
643
644}
645//-------------------------------------------------------------------------
646void KdTerrainSceneManager::setDetailTextureRepeat(int repeat)
647{
648        mOptions.detailTile = repeat;
649}
650//-------------------------------------------------------------------------
651void KdTerrainSceneManager::setTileSize(int size)
652{
653        mOptions.tileSize = size;
654}
655//-------------------------------------------------------------------------
656void KdTerrainSceneManager::setPageSize(int size)
657{
658        mOptions.pageSize = size;
659}
660//-------------------------------------------------------------------------
661void KdTerrainSceneManager::setMaxPixelError(int pixelError)
662{
663        mOptions.maxPixelError = pixelError;
664}
665//-------------------------------------------------------------------------
666void KdTerrainSceneManager::setScale(const Vector3& scale)
667{
668        mOptions.scale = scale;
669}
670//-------------------------------------------------------------------------
671void KdTerrainSceneManager::setMaxGeoMipMapLevel(int maxMip)
672{
673        mOptions.maxGeoMipMapLevel = maxMip;
674}
675//-------------------------------------------------------------------------
676void KdTerrainSceneManager::setCustomMaterial(const String& materialName)
677{
678        mCustomMaterialName = materialName;
679        if (materialName != "")
680                mUseCustomMaterial = true;
681        else
682                mUseCustomMaterial = false;
683}
684//-------------------------------------------------------------------------
685void KdTerrainSceneManager::setCustomMaterialMorphFactorParam(const String& paramName)
686{
687        mUseNamedParameterLodMorph = true;
688        mLodMorphParamName = paramName;
689
690}
691//-------------------------------------------------------------------------
692void KdTerrainSceneManager::setCustomMaterialMorphFactorParam(uint paramIndex)
693{
694        mUseNamedParameterLodMorph = false;
695        mLodMorphParamIndex = paramIndex;
696}
697//-------------------------------------------------------------------------
698void KdTerrainSceneManager::setLODMorphStart(Real morphStart)
699{
700        mOptions.lodMorphStart = morphStart;
701}
702//-------------------------------------------------------------------------
703void KdTerrainSceneManager::setPrimaryCamera(const Camera* cam)
704{
705        mOptions.primaryCamera = cam;
706}
707//-------------------------------------------------------------------------
708void KdTerrainSceneManager::registerPageSource(const String& typeName,
709                                                                                        KdTerrainPageSource* source)
710{
711        std::pair<KdPageSourceMap::iterator, bool> retPair =
712                mPageSources.insert(
713                KdPageSourceMap::value_type(typeName, source));
714        if (!retPair.second)
715        {
716                OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM,
717                        "The page source " + typeName + " is already registered",
718                        "TerrainSceneManager::registerPageSource");
719        }
720        LogManager::getSingleton().logMessage(
721                "TerrainSceneManager: Registered a new PageSource for "
722                "type " + typeName);
723}
724//-------------------------------------------------------------------------
725void KdTerrainSceneManager::selectPageSource(const String& typeName,
726                                                                                  KdTerrainPageSourceOptionList& optionList)
727{
728        KdPageSourceMap::iterator i = mPageSources.find(typeName);
729        if (i == mPageSources.end())
730        {
731                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
732                        "Cannot locate a TerrainPageSource for type " + typeName,
733                        "TerrainSceneManager::selectPageSource");
734        }
735
736        if (mActivePageSource)
737        {
738                mActivePageSource->shutdown();
739        }
740        mActivePageSource = i->second;
741        mActivePageSource->initialise(this, mOptions.tileSize, mOptions.pageSize,
742                mPagingEnabled, optionList);
743
744        LogManager::getSingleton().logMessage(
745                "TerrainSceneManager: Activated PageSource " + typeName);
746
747}
748//-------------------------------------------------------------------------
749int KdTerrainSceneManager::getDetailTextureRepeat(void)
750{
751        return (int)mOptions.detailTile;
752}
753//-------------------------------------------------------------------------
754int KdTerrainSceneManager::getTileSize(void)
755{
756        return (int)mOptions.tileSize;
757}
758//-------------------------------------------------------------------------
759int KdTerrainSceneManager::getPageSize(void)
760{
761        return (int)mOptions.pageSize;
762}
763//-------------------------------------------------------------------------
764int KdTerrainSceneManager::getMaxPixelError(void)
765{
766        return (int)mOptions.maxPixelError;
767}
768//-------------------------------------------------------------------------
769const Vector3& KdTerrainSceneManager::getScale(void)
770{
771        return mOptions.scale;
772}
773//-------------------------------------------------------------------------
774int KdTerrainSceneManager::getMaxGeoMipMapLevel(void)
775{
776        return (int)mOptions.maxGeoMipMapLevel;
777}
778//-----------------------------------------------------------------------
779void KdTerrainSceneManager::initLevelIndexes()
780{
781        if ( mLevelIndex.size() == 0 )
782        {
783                for ( int i = 0; i < 16; i++ )
784                {
785
786                        mLevelIndex.push_back( new IndexMap() );
787
788                }
789
790        }
791}
792//-----------------------------------------------------------------------
793void KdTerrainSceneManager::destroyLevelIndexes()
794{
795        for ( size_t i = 0; i < mLevelIndex.size(); i++ )
796        {
797                delete mLevelIndex[i];
798        }
799        mLevelIndex.clear();
800}
801//-------------------------------------------------------------------------
802//-------------------------------------------------------------------------
803RaySceneQuery*
804KdTerrainSceneManager::createRayQuery(const Ray& ray, unsigned long mask)
805{
806        KdTerrainRaySceneQuery *trsq = new KdTerrainRaySceneQuery(this);
807        trsq->setRay(ray);
808        trsq->setQueryMask(mask);
809        return trsq;
810}
811//-------------------------------------------------------------------------
812KdTerrainRaySceneQuery::KdTerrainRaySceneQuery(SceneManager* creator)
813:DefaultRaySceneQuery(creator)
814{
815        mSupportedWorldFragments.insert(SceneQuery::WFT_SINGLE_INTERSECTION);
816}
817//-------------------------------------------------------------------------
818KdTerrainRaySceneQuery::~KdTerrainRaySceneQuery()
819{
820}
821//-------------------------------------------------------------------------
822void KdTerrainRaySceneQuery::execute(RaySceneQueryListener* listener)
823{
824        mWorldFrag.fragmentType = SceneQuery::WFT_SINGLE_INTERSECTION;
825
826        const Vector3& dir = mRay.getDirection();
827        const Vector3& origin = mRay.getOrigin();
828        // Straight up / down?
829        if (dir == Vector3::UNIT_Y || dir == Vector3::NEGATIVE_UNIT_Y)
830        {
831                Real height = static_cast<KdTerrainSceneManager*>(mParentSceneMgr)->getHeightAt(
832                        origin.x, origin.z);
833                if (height != -1 && (height <= origin.y && dir.y < 0) || (height >= origin.y && dir.y > 0))
834                {
835                        mWorldFrag.singleIntersection.x = origin.x;
836                        mWorldFrag.singleIntersection.z = origin.z;
837                        mWorldFrag.singleIntersection.y = height;
838                        if (!listener->queryResult(&mWorldFrag,
839                                (mWorldFrag.singleIntersection - origin).length()))
840                                return;
841                }
842        }
843        else
844        {
845                // Perform arbitrary query
846                if (static_cast<KdTerrainSceneManager*>(mParentSceneMgr)->intersectSegment(
847                        origin, origin + (dir * 100000), &mWorldFrag.singleIntersection))
848                {
849                        if (!listener->queryResult(&mWorldFrag,
850                                (mWorldFrag.singleIntersection - origin).length()))
851                                return;
852                }
853        }
854        DefaultRaySceneQuery::execute(listener);
855}
856//-------------------------------------------------------------------------
857MaterialPtr& KdTerrainSceneManager::getTerrainMaterial(void)
858{
859        return mOptions.terrainMaterial;
860}
861//-------------------------------------------------------------------------
862KdTerrainSceneManager::KdPageSourceIterator KdTerrainSceneManager::getPageSourceIterator(void)
863{
864        return KdPageSourceIterator(mPageSources.begin(), mPageSources.end());
865}
866//-------------------------------------------------------------------------
867void KdTerrainSceneManager::setWorldGeometryRenderQueue(uint8 qid)
868{
869        for (KdTerrainPage2D::iterator pi = mTerrainPages.begin();
870                pi != mTerrainPages.end(); ++pi)
871        {
872                KdTerrainPageRow& row = *pi;
873                for (KdTerrainPageRow::iterator ri = row.begin(); ri != row.end(); ++ri)
874                {
875                        KdTerrainPage* page = *ri;
876                        if (page)
877                        {
878                                page->setRenderQueue(qid);
879                        }
880                }
881        }
882
883}
884/************************************************************************/
885/* Factory for KdTreeTerrainSceneManager                                */
886/************************************************************************/
887//-----------------------------------------------------------------------
888const String KdTerrainSceneManagerFactory::FACTORY_TYPE_NAME = "KdTreeTerrainSceneManager";
889//-----------------------------------------------------------------------
890void KdTerrainSceneManagerFactory::initMetaData(void) const
891{
892        mMetaData.typeName = FACTORY_TYPE_NAME;
893        mMetaData.description = "Scene manager that organises the scene based on a kd-tree and renders terrain";
894        mMetaData.sceneTypeMask = 0xFFFF; // support all types of scenes (hopefully)
895        mMetaData.worldGeometrySupported = true;
896}
897//-----------------------------------------------------------------------
898KdTerrainSceneManagerFactory::
899KdTerrainSceneManagerFactory(GtpVisibility::VisibilityManager * vm)
900{
901        visManager = vm;
902}
903//-----------------------------------------------------------------------
904KdTerrainSceneManagerFactory::~KdTerrainSceneManagerFactory()
905{
906        for (KdTerrainPageSources::iterator i = mTerrainPageSources.begin();
907                i != mTerrainPageSources.end(); ++i)
908        {
909                delete *i;
910        }
911        mTerrainPageSources.clear();
912}
913//-----------------------------------------------------------------------
914SceneManager* KdTerrainSceneManagerFactory::createInstance(
915        const String& instanceName)
916{
917        KdTerrainSceneManager * sm =
918                new KdTerrainSceneManager(instanceName, visManager);
919
920        KdHeightmapTerrainPageSource* ps = new KdHeightmapTerrainPageSource();
921        mTerrainPageSources.push_back(ps);
922        sm->registerPageSource("Heightmap", ps);
923
924        return sm;
925}
926//-----------------------------------------------------------------------
927void KdTerrainSceneManagerFactory::destroyInstance(SceneManager* instance)
928{
929        delete instance;
930}
931} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.