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

Revision 1273, 28.3 KB checked in by szydlowski, 18 years ago (diff)

Added the KdTerrainSceneManager?, a subclass of the KdTreeSceneManager? capable of rendering terrain like the TerrainSceneManager? from Ogre.
All the *Kd*Terrain* classes are identical to their octree counterparts, save prefixing all classes and structures with Kd to avoid namespace clashes.
This was necessary, since the TerrainSceneManager? was hard coded in these classes, and all references had to be replaced with the KdTerrainSceneManager?.
Also added a comprehensive README for the demo application.

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
306}
307//-------------------------------------------------------------------------
308void KdTerrainSceneManager::setupTerrainMaterial(void)
309{
310        if (mCustomMaterialName == "")
311        {
312                // define our own material
313                mOptions.terrainMaterial =
314                        MaterialManager::getSingleton().getByName(TERRAIN_MATERIAL_NAME);
315                if (mOptions.terrainMaterial.isNull())
316                {
317                        // Make unique terrain material name
318                        StringUtil::StrStreamType s;
319                        s << mName << "/Terrain";
320                        mOptions.terrainMaterial = MaterialManager::getSingleton().create(
321                                s.str(),
322                                ResourceGroupManager::getSingleton().getWorldResourceGroupName());
323
324                }
325                else
326                {
327                        mOptions.terrainMaterial->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
328                }
329
330                Pass* pass = mOptions.terrainMaterial->getTechnique(0)->getPass(0);
331
332                if ( mWorldTextureName != "" )
333                {
334                        pass->createTextureUnitState( mWorldTextureName, 0 );
335                }
336                if ( mDetailTextureName != "" )
337                {
338                        pass->createTextureUnitState( mDetailTextureName, 1 );
339                }
340
341                mOptions.terrainMaterial -> setLightingEnabled( mOptions.lit );
342
343                if (mOptions.lodMorph &&
344                        mDestRenderSystem->getCapabilities()->hasCapability(RSC_VERTEX_PROGRAM) &&
345                        GpuProgramManager::getSingleton().getByName("Terrain/VertexMorph").isNull())
346                {
347                        // Create & assign LOD morphing vertex program
348                        String syntax;
349                        if (GpuProgramManager::getSingleton().isSyntaxSupported("arbvp1"))
350                        {
351                                syntax = "arbvp1";
352                        }
353                        else
354                        {
355                                syntax = "vs_1_1";
356                        }
357
358                        // Get source, and take into account current fog mode
359                        FogMode fm = getFogMode();
360                        const String& source = KdTerrainVertexProgram::getProgramSource(
361                                fm, syntax);
362
363                        GpuProgramPtr prog = GpuProgramManager::getSingleton().createProgramFromString(
364                                "Terrain/VertexMorph", ResourceGroupManager::getSingleton().getWorldResourceGroupName(),
365                                source, GPT_VERTEX_PROGRAM, syntax);
366
367                        // Attach
368                        pass->setVertexProgram("Terrain/VertexMorph");
369
370                        // Get params
371                        GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters();
372
373                        // worldviewproj
374                        params->setAutoConstant(0, GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
375                        // morph factor
376                        params->setAutoConstant(4, GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);
377                        // fog exp density(if relevant)
378                        if (fm == FOG_EXP || fm == FOG_EXP2)
379                        {
380                                params->setConstant(5, Vector3(getFogDensity(), 0, 0));
381                                // Override scene fog since otherwise it's applied twice
382                                // Set to linear and we derive [0,1] fog value in the shader
383                                pass->setFog(true, FOG_LINEAR, getFogColour(), 0, 1, 0);
384                        }
385
386                        // Also set shadow receiver program
387                        const String& source2 = KdTerrainVertexProgram::getProgramSource(
388                                fm, syntax, true);
389
390                        prog = GpuProgramManager::getSingleton().createProgramFromString(
391                                "Terrain/VertexMorphShadowReceive",
392                                ResourceGroupManager::getSingleton().getWorldResourceGroupName(),
393                                source2, GPT_VERTEX_PROGRAM, syntax);
394                        pass->setShadowReceiverVertexProgram("Terrain/VertexMorphShadowReceive");
395                        params = pass->getShadowReceiverVertexProgramParameters();
396                        // worldviewproj
397                        params->setAutoConstant(0, GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
398                        // world
399                        params->setAutoConstant(4, GpuProgramParameters::ACT_WORLD_MATRIX);
400                        // texture view / proj
401                        params->setAutoConstant(8, GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX);
402                        // morph factor
403                        params->setAutoConstant(12, GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);
404
405
406                        // Set param index
407                        mLodMorphParamName = "";
408                        mLodMorphParamIndex = 4;
409                }
410
411                mOptions.terrainMaterial->load();
412
413        }
414        else
415        {
416                // Custom material
417                mOptions.terrainMaterial =
418                        MaterialManager::getSingleton().getByName(mCustomMaterialName);
419                mOptions.terrainMaterial->load();
420
421        }
422
423        // now set up the linkage between vertex program and LOD morph param
424        if (mOptions.lodMorph)
425        {
426                Technique* t = mOptions.terrainMaterial->getBestTechnique();
427                for (ushort i = 0; i < t->getNumPasses(); ++i)
428                {
429                        Pass* p = t->getPass(i);
430                        if (p->hasVertexProgram())
431                        {
432                                // we have to assume vertex program includes LOD morph capability
433                                GpuProgramParametersSharedPtr params =
434                                        p->getVertexProgramParameters();
435                                // Check to see if custom param is already there
436                                GpuProgramParameters::AutoConstantIterator aci = params->getAutoConstantIterator();
437                                bool found = false;
438                                while (aci.hasMoreElements())
439                                {
440                                        const GpuProgramParameters::AutoConstantEntry& ace = aci.getNext();
441                                        if (ace.paramType == GpuProgramParameters::ACT_CUSTOM &&
442                                                ace.data == MORPH_CUSTOM_PARAM_ID)
443                                        {
444                                                found = true;
445                                        }
446                                }
447                                if (!found)
448                                {
449                                        if(mLodMorphParamName != "")
450                                        {
451                                                params->setNamedAutoConstant(mLodMorphParamName,
452                                                        GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);
453                                        }
454                                        else
455                                        {
456                                                params->setAutoConstant(mLodMorphParamIndex,
457                                                        GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);
458                                        }
459                                }
460
461                        }
462                }
463        }
464
465}
466//-------------------------------------------------------------------------
467void KdTerrainSceneManager::setupTerrainPages(void)
468{
469
470        //create a root terrain node.
471        if (!mTerrainRoot)
472                mTerrainRoot = getRootSceneNode() -> createChildSceneNode( "Terrain" );
473
474        //setup the page array.
475        unsigned short pageSlots = 1 + (mBufferedPageMargin * 2);
476        unsigned short i, j;
477        for (i = 0; i < pageSlots; ++i)
478        {
479                mTerrainPages.push_back(KdTerrainPageRow());
480                for (j = 0; j < pageSlots; ++j)
481                {
482                        mTerrainPages[i].push_back(0);
483                }
484        }
485
486        // If we're not paging, load immediate for convenience
487        if ( mActivePageSource && !mPagingEnabled )
488                mActivePageSource->requestPage(0,0);
489
490
491}
492//-------------------------------------------------------------------------
493void KdTerrainSceneManager::setWorldGeometry( const String& filename )
494{
495        // try to open in the current folder first
496        std::ifstream fs;
497        fs.open(filename.c_str());
498        if (fs)
499        {
500                // Wrap as a stream
501                DataStreamPtr stream(
502                        new FileStreamDataStream(filename, &fs, false));
503                setWorldGeometry(stream);
504        }
505        else
506        {
507                // otherwise try resource system
508                DataStreamPtr stream =
509                        ResourceGroupManager::getSingleton().openResource(filename,
510                        ResourceGroupManager::getSingleton().getWorldResourceGroupName());
511
512                setWorldGeometry(stream);
513        }
514}
515//-------------------------------------------------------------------------
516void KdTerrainSceneManager::setWorldGeometry(DataStreamPtr& stream, const String& typeName )
517{
518        // Clear out any existing world resources (if not default)
519        if (ResourceGroupManager::getSingleton().getWorldResourceGroupName() !=
520                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME)
521        {
522                ResourceGroupManager::getSingleton().clearResourceGroup(
523                        ResourceGroupManager::getSingleton().getWorldResourceGroupName());
524        }
525        destroyLevelIndexes();
526        mTerrainPages.clear();
527        // Load the configuration
528        loadConfig(stream);
529        initLevelIndexes();
530
531        // Resize the octree, allow for 1 page for now
532        //float max_x = mOptions.scale.x * mOptions.pageSize;
533        //float max_y = mOptions.scale.y;
534        //float max_z = mOptions.scale.z * mOptions.pageSize;
535        //resize( AxisAlignedBox( 0, 0, 0, max_x, max_y, max_z ) );
536
537        setupTerrainMaterial();
538
539        setupTerrainPages();
540
541}
542//-------------------------------------------------------------------------
543void KdTerrainSceneManager::attachPage(ushort pageX, ushort pageZ, KdTerrainPage* page)
544{
545        assert(pageX == 0 && pageZ == 0 && "Multiple pages not yet supported");
546
547        assert(mTerrainPages[pageX][pageZ] == 0 && "Page at that index not yet expired!");
548        // Insert page into list
549        mTerrainPages[pageX][pageZ] = page;
550        // Attach page to terrain root
551        mTerrainRoot->addChild(page->pageSceneNode);
552
553}
554//-------------------------------------------------------------------------
555float KdTerrainSceneManager::getHeightAt( float x, float z )
556{
557
558
559        Vector3 pt( x, 0, z );
560
561        KdTerrainRenderable * t = getTerrainTile( pt );
562
563        if ( t == 0 )
564        {
565                //  printf( "No tile found for point\n" );
566                return -1;
567        }
568
569        float h = t -> getHeightAt( x, z );
570
571        // printf( "Height is %f\n", h );
572        return h;
573
574}
575//-------------------------------------------------------------------------
576KdTerrainPage* KdTerrainSceneManager::getTerrainPage( const Vector3 & pt )
577{
578        if (mPagingEnabled)
579        {
580                // TODO
581                return 0;
582        }
583        else
584        {
585                // Single page
586                if (mTerrainPages.empty() || mTerrainPages[0].empty())
587                        return 0;
588                return mTerrainPages[0][0];
589        }
590}
591//-------------------------------------------------------------------------
592KdTerrainRenderable * KdTerrainSceneManager::getTerrainTile( const Vector3 & pt )
593{
594        KdTerrainPage* tp = getTerrainPage(pt);
595        if (!tp)
596                return NULL;
597        else
598                return tp->getTerrainTile(pt);
599}
600//-------------------------------------------------------------------------
601bool KdTerrainSceneManager::intersectSegment( const Vector3 & start,
602                                                                                  const Vector3 & end, Vector3 * result )
603{
604        KdTerrainRenderable * t = getTerrainTile( start );
605
606        if ( t == 0 )
607        {
608                *result = Vector3( -1, -1, -1 );
609                return false;
610        }
611
612        return t -> intersectSegment( start, end, result );
613}
614//-------------------------------------------------------------------------
615void KdTerrainSceneManager::setUseTriStrips(bool useStrips)
616{
617        mOptions.useTriStrips = useStrips;
618}
619//-------------------------------------------------------------------------
620void KdTerrainSceneManager::setUseLODMorph(bool morph)
621{
622        // Set true only if vertex programs are supported
623        mOptions.lodMorph = morph &&
624                mDestRenderSystem->getCapabilities()->hasCapability(RSC_VERTEX_PROGRAM);
625}
626//-------------------------------------------------------------------------
627void KdTerrainSceneManager::setUseVertexNormals(bool useNormals)
628{
629        mOptions.lit = useNormals;
630}
631//-------------------------------------------------------------------------
632void KdTerrainSceneManager::setUseVertexColours(bool useColours)
633{
634        mOptions.coloured = useColours;
635}
636//-------------------------------------------------------------------------
637void KdTerrainSceneManager::setWorldTexture(const String& textureName)
638{
639        mWorldTextureName = textureName;
640}
641//-------------------------------------------------------------------------
642void KdTerrainSceneManager::setDetailTexture(const String& textureName)
643{
644        mDetailTextureName = textureName;
645
646}
647//-------------------------------------------------------------------------
648void KdTerrainSceneManager::setDetailTextureRepeat(int repeat)
649{
650        mOptions.detailTile = repeat;
651}
652//-------------------------------------------------------------------------
653void KdTerrainSceneManager::setTileSize(int size)
654{
655        mOptions.tileSize = size;
656}
657//-------------------------------------------------------------------------
658void KdTerrainSceneManager::setPageSize(int size)
659{
660        mOptions.pageSize = size;
661}
662//-------------------------------------------------------------------------
663void KdTerrainSceneManager::setMaxPixelError(int pixelError)
664{
665        mOptions.maxPixelError = pixelError;
666}
667//-------------------------------------------------------------------------
668void KdTerrainSceneManager::setScale(const Vector3& scale)
669{
670        mOptions.scale = scale;
671}
672//-------------------------------------------------------------------------
673void KdTerrainSceneManager::setMaxGeoMipMapLevel(int maxMip)
674{
675        mOptions.maxGeoMipMapLevel = maxMip;
676}
677//-------------------------------------------------------------------------
678void KdTerrainSceneManager::setCustomMaterial(const String& materialName)
679{
680        mCustomMaterialName = materialName;
681        if (materialName != "")
682                mUseCustomMaterial = true;
683        else
684                mUseCustomMaterial = false;
685}
686//-------------------------------------------------------------------------
687void KdTerrainSceneManager::setCustomMaterialMorphFactorParam(const String& paramName)
688{
689        mUseNamedParameterLodMorph = true;
690        mLodMorphParamName = paramName;
691
692}
693//-------------------------------------------------------------------------
694void KdTerrainSceneManager::setCustomMaterialMorphFactorParam(uint paramIndex)
695{
696        mUseNamedParameterLodMorph = false;
697        mLodMorphParamIndex = paramIndex;
698}
699//-------------------------------------------------------------------------
700void KdTerrainSceneManager::setLODMorphStart(Real morphStart)
701{
702        mOptions.lodMorphStart = morphStart;
703}
704//-------------------------------------------------------------------------
705void KdTerrainSceneManager::setPrimaryCamera(const Camera* cam)
706{
707        mOptions.primaryCamera = cam;
708}
709//-------------------------------------------------------------------------
710void KdTerrainSceneManager::registerPageSource(const String& typeName,
711                                                                                        KdTerrainPageSource* source)
712{
713        std::pair<KdPageSourceMap::iterator, bool> retPair =
714                mPageSources.insert(
715                KdPageSourceMap::value_type(typeName, source));
716        if (!retPair.second)
717        {
718                OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM,
719                        "The page source " + typeName + " is already registered",
720                        "TerrainSceneManager::registerPageSource");
721        }
722        LogManager::getSingleton().logMessage(
723                "TerrainSceneManager: Registered a new PageSource for "
724                "type " + typeName);
725}
726//-------------------------------------------------------------------------
727void KdTerrainSceneManager::selectPageSource(const String& typeName,
728                                                                                  KdTerrainPageSourceOptionList& optionList)
729{
730        KdPageSourceMap::iterator i = mPageSources.find(typeName);
731        if (i == mPageSources.end())
732        {
733                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
734                        "Cannot locate a TerrainPageSource for type " + typeName,
735                        "TerrainSceneManager::selectPageSource");
736        }
737
738        if (mActivePageSource)
739        {
740                mActivePageSource->shutdown();
741        }
742        mActivePageSource = i->second;
743        mActivePageSource->initialise(this, mOptions.tileSize, mOptions.pageSize,
744                mPagingEnabled, optionList);
745
746        LogManager::getSingleton().logMessage(
747                "TerrainSceneManager: Activated PageSource " + typeName);
748
749}
750//-------------------------------------------------------------------------
751int KdTerrainSceneManager::getDetailTextureRepeat(void)
752{
753        return (int)mOptions.detailTile;
754}
755//-------------------------------------------------------------------------
756int KdTerrainSceneManager::getTileSize(void)
757{
758        return (int)mOptions.tileSize;
759}
760//-------------------------------------------------------------------------
761int KdTerrainSceneManager::getPageSize(void)
762{
763        return (int)mOptions.pageSize;
764}
765//-------------------------------------------------------------------------
766int KdTerrainSceneManager::getMaxPixelError(void)
767{
768        return (int)mOptions.maxPixelError;
769}
770//-------------------------------------------------------------------------
771const Vector3& KdTerrainSceneManager::getScale(void)
772{
773        return mOptions.scale;
774}
775//-------------------------------------------------------------------------
776int KdTerrainSceneManager::getMaxGeoMipMapLevel(void)
777{
778        return (int)mOptions.maxGeoMipMapLevel;
779}
780//-----------------------------------------------------------------------
781void KdTerrainSceneManager::initLevelIndexes()
782{
783        if ( mLevelIndex.size() == 0 )
784        {
785                for ( int i = 0; i < 16; i++ )
786                {
787
788                        mLevelIndex.push_back( new IndexMap() );
789
790                }
791
792        }
793}
794//-----------------------------------------------------------------------
795void KdTerrainSceneManager::destroyLevelIndexes()
796{
797        for ( size_t i = 0; i < mLevelIndex.size(); i++ )
798        {
799                delete mLevelIndex[i];
800        }
801        mLevelIndex.clear();
802}
803//-------------------------------------------------------------------------
804//-------------------------------------------------------------------------
805RaySceneQuery*
806KdTerrainSceneManager::createRayQuery(const Ray& ray, unsigned long mask)
807{
808        KdTerrainRaySceneQuery *trsq = new KdTerrainRaySceneQuery(this);
809        trsq->setRay(ray);
810        trsq->setQueryMask(mask);
811        return trsq;
812}
813//-------------------------------------------------------------------------
814KdTerrainRaySceneQuery::KdTerrainRaySceneQuery(SceneManager* creator)
815:DefaultRaySceneQuery(creator)
816{
817        mSupportedWorldFragments.insert(SceneQuery::WFT_SINGLE_INTERSECTION);
818}
819//-------------------------------------------------------------------------
820KdTerrainRaySceneQuery::~KdTerrainRaySceneQuery()
821{
822}
823//-------------------------------------------------------------------------
824void KdTerrainRaySceneQuery::execute(RaySceneQueryListener* listener)
825{
826        mWorldFrag.fragmentType = SceneQuery::WFT_SINGLE_INTERSECTION;
827
828        const Vector3& dir = mRay.getDirection();
829        const Vector3& origin = mRay.getOrigin();
830        // Straight up / down?
831        if (dir == Vector3::UNIT_Y || dir == Vector3::NEGATIVE_UNIT_Y)
832        {
833                Real height = static_cast<KdTerrainSceneManager*>(mParentSceneMgr)->getHeightAt(
834                        origin.x, origin.z);
835                if (height != -1 && (height <= origin.y && dir.y < 0) || (height >= origin.y && dir.y > 0))
836                {
837                        mWorldFrag.singleIntersection.x = origin.x;
838                        mWorldFrag.singleIntersection.z = origin.z;
839                        mWorldFrag.singleIntersection.y = height;
840                        if (!listener->queryResult(&mWorldFrag,
841                                (mWorldFrag.singleIntersection - origin).length()))
842                                return;
843                }
844        }
845        else
846        {
847                // Perform arbitrary query
848                if (static_cast<KdTerrainSceneManager*>(mParentSceneMgr)->intersectSegment(
849                        origin, origin + (dir * 100000), &mWorldFrag.singleIntersection))
850                {
851                        if (!listener->queryResult(&mWorldFrag,
852                                (mWorldFrag.singleIntersection - origin).length()))
853                                return;
854                }
855        }
856        DefaultRaySceneQuery::execute(listener);
857}
858//-------------------------------------------------------------------------
859MaterialPtr& KdTerrainSceneManager::getTerrainMaterial(void)
860{
861        return mOptions.terrainMaterial;
862}
863//-------------------------------------------------------------------------
864KdTerrainSceneManager::KdPageSourceIterator KdTerrainSceneManager::getPageSourceIterator(void)
865{
866        return KdPageSourceIterator(mPageSources.begin(), mPageSources.end());
867}
868//-------------------------------------------------------------------------
869void KdTerrainSceneManager::setWorldGeometryRenderQueue(uint8 qid)
870{
871        for (KdTerrainPage2D::iterator pi = mTerrainPages.begin();
872                pi != mTerrainPages.end(); ++pi)
873        {
874                KdTerrainPageRow& row = *pi;
875                for (KdTerrainPageRow::iterator ri = row.begin(); ri != row.end(); ++ri)
876                {
877                        KdTerrainPage* page = *ri;
878                        if (page)
879                        {
880                                page->setRenderQueue(qid);
881                        }
882                }
883        }
884
885}
886/************************************************************************/
887/* Factory for KdTreeTerrainSceneManager                                */
888/************************************************************************/
889//-----------------------------------------------------------------------
890const String KdTerrainSceneManagerFactory::FACTORY_TYPE_NAME = "KdTreeTerrainSceneManager";
891//-----------------------------------------------------------------------
892void KdTerrainSceneManagerFactory::initMetaData(void) const
893{
894        mMetaData.typeName = FACTORY_TYPE_NAME;
895        mMetaData.description = "Scene manager that organises the scene based on a kd-tree and renders terrain";
896        mMetaData.sceneTypeMask = 0xFFFF; // support all types of scenes (hopefully)
897        mMetaData.worldGeometrySupported = true;
898}
899//-----------------------------------------------------------------------
900KdTerrainSceneManagerFactory::
901KdTerrainSceneManagerFactory(GtpVisibility::VisibilityManager * vm)
902{
903        visManager = vm;
904}
905//-----------------------------------------------------------------------
906KdTerrainSceneManagerFactory::~KdTerrainSceneManagerFactory()
907{
908        for (KdTerrainPageSources::iterator i = mTerrainPageSources.begin();
909                i != mTerrainPageSources.end(); ++i)
910        {
911                delete *i;
912        }
913        mTerrainPageSources.clear();
914}
915//-----------------------------------------------------------------------
916SceneManager* KdTerrainSceneManagerFactory::createInstance(
917        const String& instanceName)
918{
919        KdTerrainSceneManager * sm =
920                new KdTerrainSceneManager(instanceName, visManager);
921
922        KdHeightmapTerrainPageSource* ps = new KdHeightmapTerrainPageSource();
923        mTerrainPageSources.push_back(ps);
924        sm->registerPageSource("Heightmap", ps);
925
926        return sm;
927}
928//-----------------------------------------------------------------------
929void KdTerrainSceneManagerFactory::destroyInstance(SceneManager* instance)
930{
931        delete instance;
932}
933} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.