source: OGRE/trunk/ogrenew/PlugIns/OctreeSceneManager/src/OgreTerrainSceneManager.cpp @ 692

Revision 692, 36.4 KB checked in by mattausch, 19 years ago (diff)

adding ogre 1.2 and dependencies

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