source: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreOcclusionCullingSceneManager.cpp @ 2255

Revision 2255, 74.6 KB checked in by mattausch, 18 years ago (diff)

improved scenemanager config

Line 
1#include "OgreOcclusionCullingSceneManager.h"
2#include "OgreVisibilityOptionsManager.h"
3#include <OgreMath.h>
4#include <OgreIteratorWrappers.h>
5#include <OgreRenderSystem.h>
6#include <OgreCamera.h>
7#include <OgreLogManager.h>
8#include <OgreStringConverter.h>
9#include <OgreEntity.h>
10#include <OgreSubEntity.h>
11#include <OgreMaterialManager.h>
12#include <OgreIteratorWrappers.h>
13#include <OgreHeightmapTerrainPageSource.h>
14#include "VspBspTree.h"
15#include "Containers.h"
16#include "ViewCellsManager.h"
17#include <OgreConfigFile.h>
18#include "OgreTypeConverter.h"
19#include "OgreMeshInstance.h"
20#include "common.h"
21#include "OgreBoundingBoxConverter.h"
22#include <OgreManualObject.h>
23#include "IntersectableWrapper.h"
24#include "IVReader.h"
25#include "ObjReader.h"
26#include "OgreOcclusionQueriesQueryManager.h"
27#include "VisibilityInfo.h"
28#include "Preprocessor.h"
29
30
31namespace Ogre {
32
33//-----------------------------------------------------------------------
34OcclusionCullingSceneManager::OcclusionCullingSceneManager(
35                                                                const String& name,
36                                                                GtpVisibility::VisibilityManager *visManager):
37TerrainSceneManager(name),
38mVisibilityManager(visManager),
39mShowVisualization(false),
40mRenderNodesForViz(false),
41mRenderNodesContentForViz(false),
42mVisualizeCulledNodes(false),
43mLeavePassesInQueue(0),
44mDelayRenderTransparents(true),
45mUseDepthPass(false),
46mIsDepthPassPhase(false),
47mUseItemBuffer(false),
48mIsItemBufferPhase(false),
49mCurrentEntityId(1),
50mEnableDepthWrite(true),
51mSkipTransparents(false),
52mRenderTransparentsForItemBuffer(true),
53mExecuteVertexProgramForAllPasses(false),
54mIsHierarchicalCulling(false),
55mViewCellsLoaded(false),
56mUseViewCells(false),
57mUseVisibilityFilter(false),
58mCurrentViewCell(NULL),
59mElementaryViewCell(NULL),
60mDeleteQueueAfterRendering(true),
61mNormalExecution(false),
62mShowViewCells(false),
63mViewCellsGeometryLoaded(false),
64mShowTerrain(false),
65mViewCellsFilename(""),
66mFilename("terrain"),
67mFlushRate(10),
68mCurrentFrame(0),
69mUseVisibilityQueries(true),
70mUseFromPointQueries(false),
71mQueryMode(NODE_QUERIES),
72mResetMaterialForQueries(false)
73{
74        Ogre::LogManager::getSingleton().
75                logMessage("creating occlusion culling scene manager");
76
77        mHierarchyInterface = new OctreeHierarchyInterface(this, mDestRenderSystem);
78       
79        if (0)
80        {
81                mDisplayNodes = true;
82                mShowBoundingBoxes = true;
83                mShowBoxes = true;
84        }
85
86        // set maxdepth to reasonable value
87        mMaxDepth = 50;
88
89        mObjReader = new ObjReader(this);
90}
91//-----------------------------------------------------------------------
92void OcclusionCullingSceneManager::InitDepthPass()
93{
94        MaterialPtr depthMat =
95                MaterialManager::getSingleton().getByName("Visibility/DepthPass");
96
97        if (depthMat.isNull())
98    {
99                depthMat = MaterialManager::getSingleton().create(
100                "Visibility/DepthPass",
101                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
102
103        mDepthPass = depthMat->getTechnique(0)->getPass(0);
104                mDepthPass->setColourWriteEnabled(false);
105                mDepthPass->setDepthWriteEnabled(true);
106                mDepthPass->setLightingEnabled(false);
107        }
108        else
109        {
110                mDepthPass = depthMat->getTechnique(0)->getPass(0);
111        }
112}
113//-----------------------------------------------------------------------
114OcclusionCullingSceneManager::~OcclusionCullingSceneManager()
115{
116        CLEAR_CONTAINER(mObjects);
117
118        OGRE_DELETE(mHierarchyInterface);
119        OGRE_DELETE(mCurrentViewCell);
120
121        OGRE_DELETE(mObjReader);
122}
123//-----------------------------------------------------------------------
124void OcclusionCullingSceneManager::InitItemBufferPass()
125{
126        MaterialPtr itemBufferMat = MaterialManager::getSingleton().
127                getByName("Visibility/ItemBufferPass");
128
129        if (itemBufferMat.isNull())
130    {
131                // Init
132                itemBufferMat =
133                        MaterialManager::getSingleton().create("Visibility/ItemBufferPass",
134                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
135
136                mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0);
137                mItemBufferPass->setColourWriteEnabled(true);
138                mItemBufferPass->setDepthWriteEnabled(true);
139                mItemBufferPass->setLightingEnabled(true);
140                //mItemBufferPass->setLightingEnabled(false);
141        }
142        else
143        {
144                mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0);
145        }
146        //mItemBufferPass->setAmbient(1, 1, 0);
147}
148//-------------------------------------------------------------------------
149#if 1
150void OcclusionCullingSceneManager::setWorldGeometry(DataStreamPtr& stream,
151                                                                                                        const String& typeName)
152{
153        // Clear out any existing world resources (if not default)
154    if (ResourceGroupManager::getSingleton().getWorldResourceGroupName() !=
155        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME)
156    {
157        ResourceGroupManager::getSingleton().clearResourceGroup(
158            ResourceGroupManager::getSingleton().getWorldResourceGroupName());
159    }
160       
161        destroyLevelIndexes();
162    mTerrainPages.clear();
163
164    // Load the configuration
165    loadConfig(stream);
166
167        //////////////
168        // file loading
169
170        // load the scene
171        LoadScene(mFilename, mViewCellsFilename);
172       
173        // load view cells: load later ...
174        if (0) mViewCellsLoaded = LoadViewCells(mViewCellsFilename);
175
176        if (mShowTerrain)
177        {       
178                initLevelIndexes();
179
180                // Resize the octree, allow for 1 page for now
181                float max_x = mOptions.scale.x * mOptions.pageSize;
182                float max_y = mOptions.scale.y;// * mOptions.pageSize;
183                float max_z = mOptions.scale.z * mOptions.pageSize;
184
185                float maxAxis = std::max(max_x, max_y);
186                maxAxis = std::max(maxAxis, max_z);
187                resize(AxisAlignedBox( 0, 0, 0, maxAxis, maxAxis, maxAxis));
188                //resize(AxisAlignedBox( 0, 0, 0, max_x, max_y, max_z ));
189
190                setupTerrainMaterial();
191                setupTerrainPages();
192        }       
193 }
194#endif
195
196//-------------------------------------------------------------------------
197void OcclusionCullingSceneManager::loadConfig(DataStreamPtr& stream)
198{
199        // Set up the options
200        ConfigFile config;
201        String val;
202       
203        config.load(stream);
204       
205        LogManager::getSingleton().logMessage("****** OcclusionCullingSceneManager Options ********");
206
207        val = config.getSetting("DepthPass");
208
209    if (!val.empty())
210        {
211                if ( val == "yes" )
212                        mUseDepthPass = true;
213                else
214                        mUseDepthPass = false;
215        }
216
217        val = config.getSetting("ExecuteVertexProgramForDepth");
218
219        if (!val.empty())
220        {
221                if ( val == "yes" )
222                        mExecuteVertexProgramForAllPasses = true;
223                else
224                        mExecuteVertexProgramForAllPasses = false;
225        }
226
227        val = config.getSetting("UseVisibilityQueries");
228
229        if (!val.empty())
230        {
231                if ( val == "yes" )
232                        mUseVisibilityQueries = true;
233                else
234                        mUseVisibilityQueries = false;
235        }
236
237        val = config.getSetting("UseFromPointQueries");
238       
239        if (!val.empty())
240        {
241                if (val == "yes")
242                        mUseFromPointQueries = true;
243                else
244                        mUseFromPointQueries = false;
245        }
246
247        val = config.getSetting("QueryObjectsMode");
248
249        if (!val.empty())
250        {
251                if (val == "EXACT")
252                        mQueryMode = EXACT_QUERIES;
253                else if (val == "NODE")
254                        mQueryMode = NODE_QUERIES;
255                else
256                        mQueryMode = APPROXIMATE_QUERIES;
257        }
258
259        val = config.getSetting("ResetMaterialForQueries");
260
261        if (!val.empty())
262        {
263                if (val == "yes")
264                        mResetMaterialForQueries = true;
265                else
266                        mResetMaterialForQueries = false;
267        }
268
269        val = config.getSetting("FlushQueue");
270       
271        if (!val.empty())
272        {
273                if ( val == "yes" )
274                        mDeleteQueueAfterRendering = true;
275                else
276                        mDeleteQueueAfterRendering = false;
277        }
278
279        val = config.getSetting("Scene");
280
281    if (!val.empty())
282        {
283                mFilename = val.c_str();
284               
285                // load terrain instead of scene
286                if (mFilename == "terrain")
287                {
288                        mShowTerrain = true;
289                        LogManager::getSingleton().logMessage("loading terrain");
290                }
291                else
292                {
293                        mShowTerrain = false;
294                        LogManager::getSingleton().logMessage("loading geometry");
295                }
296        }
297
298        if (!mShowTerrain)
299        {
300                val = config.getSetting("ViewCells");
301
302                if (!val.empty())
303                {
304                        mViewCellsFilename = val;
305                }
306        }
307
308        val = config.getSetting("OnlineCullingAlgorithm");
309               
310        if (!val.empty())
311        {
312                GtpVisibility::VisibilityEnvironment::CullingManagerType algorithm;
313
314                if (val == "CHC")
315                {
316                        algorithm =
317                                GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING;
318                        LogManager::getSingleton().logMessage("Using chc algorithm");
319                }
320                else if (val == "SWC")
321                {
322                         algorithm =
323                                 GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING;
324
325                         LogManager::getSingleton().logMessage("Using stop and wait algorithm");
326                 }
327                 else if (val == "VFC")
328                 {
329                         algorithm =
330                                 GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING;
331
332                         LogManager::getSingleton().logMessage("Using frustum culling algorithm");
333                 }
334                 else // default rendering
335                 {
336                         algorithm =
337                                 GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS;
338
339                         mNormalExecution = true;
340                         LogManager::getSingleton().logMessage("Using default octree scene manager rendering");
341                 }
342
343                 mVisibilityManager->SetCullingManager(algorithm);
344        }
345
346        /////////////
347        // terrain options
348
349        if (mUseDepthPass)
350                LogManager::getSingleton().logMessage("using depth pass");
351        else
352                LogManager::getSingleton().logMessage("not using depth pass");
353       
354        if (mExecuteVertexProgramForAllPasses)
355                LogManager::getSingleton().logMessage("executing vertex program for passes");
356        else
357                LogManager::getSingleton().logMessage("not executing vertex program for passes");
358
359        if (mUseVisibilityQueries)
360                LogManager::getSingleton().logMessage("using visibility queries");
361        else
362                LogManager::getSingleton().logMessage("not using visibility queries");
363
364        if (mUseFromPointQueries)
365                LogManager::getSingleton().logMessage("using from point queries");
366        else
367                LogManager::getSingleton().logMessage("not using from point queries");
368
369        if (mQueryMode == EXACT_QUERIES)
370                LogManager::getSingleton().logMessage("using exact queries");
371        else if (mQueryMode == NODE_QUERIES)
372                LogManager::getSingleton().logMessage("using node queries");
373        else if (mQueryMode == APPROXIMATE_QUERIES)
374                LogManager::getSingleton().logMessage("using approximate queries");
375
376        if (mResetMaterialForQueries)
377                LogManager::getSingleton().logMessage("resetting material for queries");
378        else
379                LogManager::getSingleton().logMessage("resetting material for queries");
380
381        if (mDeleteQueueAfterRendering)
382                LogManager::getSingleton().logMessage("flushing queue after some frames");
383        else
384                LogManager::getSingleton().logMessage("not flushing queue after some frames");
385
386        if (!mShowTerrain)
387                return;
388
389        val = config.getSetting("DetailTile");
390        if (!val.empty())
391                setDetailTextureRepeat(atoi(val.c_str()));
392
393        val = config.getSetting("MaxMipMapLevel");
394        if (!val.empty())
395                setMaxGeoMipMapLevel(atoi(val.c_str()));
396
397
398        val = config.getSetting("PageSize");
399        if (!val.empty())
400                setPageSize(atoi(val.c_str()));
401        else
402                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing option 'PageSize'",
403                "TerrainSceneManager::loadConfig");
404
405
406        val = config.getSetting("TileSize");
407        if (!val.empty())
408                setTileSize(atoi(val.c_str()));
409        else
410                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing option 'TileSize'",
411                "TerrainSceneManager::loadConfig");
412
413        Vector3 v = Vector3::UNIT_SCALE;
414
415        val = config.getSetting( "PageWorldX" );
416        if ( !val.empty() )
417                v.x = atof( val.c_str() );
418
419        val = config.getSetting( "MaxHeight" );
420        if ( !val.empty() )
421                v.y = atof( val.c_str() );
422
423        val = config.getSetting( "PageWorldZ" );
424        if ( !val.empty() )
425                v.z = atof( val.c_str() );
426
427        // Scale x/z relative to pagesize
428        v.x /= mOptions.pageSize;
429        v.z /= mOptions.pageSize;
430        setScale(v);
431
432        val = config.getSetting( "MaxPixelError" );
433        if ( !val.empty() )
434                setMaxPixelError(atoi( val.c_str() ));
435
436        mDetailTextureName = config.getSetting( "DetailTexture" );
437
438        mWorldTextureName = config.getSetting( "WorldTexture" );
439
440        if ( config.getSetting( "VertexColours" ) == "yes" )
441                mOptions.coloured = true;
442
443        if ( config.getSetting( "VertexNormals" ) == "yes" )
444                mOptions.lit = true;
445
446        if ( config.getSetting( "UseTriStrips" ) == "yes" )
447                setUseTriStrips(true);
448
449        if ( config.getSetting( "VertexProgramMorph" ) == "yes" )
450                setUseLODMorph(true);
451
452        val = config.getSetting( "LODMorphStart");
453        if ( !val.empty() )
454                setLODMorphStart(atof(val.c_str()));
455
456        val = config.getSetting( "CustomMaterialName" );
457        if ( !val.empty() )
458                setCustomMaterial(val);
459
460        val = config.getSetting( "MorphLODFactorParamName" );
461        if ( !val.empty() )
462                setCustomMaterialMorphFactorParam(val);
463
464        val = config.getSetting( "MorphLODFactorParamIndex" );
465        if ( !val.empty() )
466                setCustomMaterialMorphFactorParam(atoi(val.c_str()));
467
468        // Now scan through the remaining settings, looking for any PageSource
469        // prefixed items
470        String pageSourceName = config.getSetting("PageSource");
471        if (pageSourceName == "")
472        {
473                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing option 'PageSource'",
474                        "TerrainSceneManager::loadConfig");
475        }
476
477        TerrainPageSourceOptionList optlist;
478        ConfigFile::SettingsIterator setIt = config.getSettingsIterator();
479        while (setIt.hasMoreElements())
480        {
481                String name = setIt.peekNextKey();
482                String value = setIt.getNext();
483                if (StringUtil::startsWith(name, pageSourceName, false))
484                {
485                        optlist.push_back(TerrainPageSourceOption(name, value));
486                }
487        }
488
489        // set the page source
490        selectPageSource(pageSourceName, optlist);
491
492       
493        LogManager::getSingleton().logMessage("****** OcclusionCullingSceneManager Options Finished ********");
494}
495//-----------------------------------------------------------------------
496void OcclusionCullingSceneManager::MailPvsObjects()
497{
498        GtpVisibilityPreprocessor::ObjectPvsIterator pit =
499                        mCurrentViewCell->GetPvs().GetIterator();
500
501        while (pit.HasMoreEntries())
502        {               
503                GtpVisibilityPreprocessor::Intersectable *obj = pit.Next();
504
505                if (obj->Type() !=
506                        GtpVisibilityPreprocessor::Intersectable::ENGINE_INTERSECTABLE)
507                        continue;
508                       
509                EngineIntersectable *oi = static_cast<EngineIntersectable *>(obj);
510
511                EntityContainer *entries = oi->GetItem();
512                EntityContainer::const_iterator eit, eit_end = entries->end();
513
514                for (eit = entries->begin(); eit != eit_end; ++ eit)
515                {
516                        (*eit)->setUserAny(Any((int)0));
517                }
518        }
519}
520//-----------------------------------------------------------------------
521void OcclusionCullingSceneManager::ShowViewCellsGeometry()
522{/*
523        // show only current view cell
524        if (!mShowViewCells)
525        {
526                const int id = mCurrentViewCell->GetId();
527
528                MovableMap::iterator fit = mViewCellsGeometry.find(id);
529
530                if ((fit != mViewCellsGeometry.end()) && (*fit).second)
531                        (*fit).second->_updateRenderQueue(getRenderQueue());
532        }
533        else
534        {
535                MovableMap::const_iterator mit, mit_end = mViewCellsGeometry.end();
536
537                for (mit = mViewCellsGeometry.begin(); mit != mit_end; ++ mit)
538                {
539                        if ((*mit).second)
540                                (*mit).second->_updateRenderQueue(getRenderQueue());
541                }       
542        }*/
543}
544//-----------------------------------------------------------------------
545void OcclusionCullingSceneManager::RenderPvsEntry(GtpVisibilityPreprocessor::Intersectable *obj)
546{
547        switch (obj->Type())
548        {       
549                case GtpVisibilityPreprocessor::Intersectable::OGRE_MESH_INSTANCE:
550                        {
551                                OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(obj);
552                                omi->GetEntity()->_updateRenderQueue(getRenderQueue());
553                        }
554                        break;
555
556                case GtpVisibilityPreprocessor::Intersectable::ENGINE_INTERSECTABLE:
557                        {
558                                EngineIntersectable *oi = static_cast<EngineIntersectable *>(obj);
559
560                                EntityContainer *entries = oi->GetItem();
561                                EntityContainer::const_iterator eit, eit_end = entries->end();
562
563                                for (eit = entries->begin(); eit != eit_end; ++ eit)
564                                {
565                                        Entity *ent = *eit;
566                                        // mailing hack
567                                        Any newAny = ent->getUserAny();
568                                        int flt = any_cast<int>(newAny);
569
570                                        if (any_cast<int>(newAny) == 0)
571                                        {
572                                                ent->setUserAny(Any((int)1));
573                                                ent->_updateRenderQueue(getRenderQueue());
574                                        }
575                                }
576                        }
577                        break;
578                default:
579                        break;
580        }       
581}
582//-----------------------------------------------------------------------
583void OcclusionCullingSceneManager::SetObjectVisible(GtpVisibilityPreprocessor::Intersectable *entry,
584                                                                                                        const bool visible)
585{
586        switch (entry->Type())
587        {
588        case GtpVisibilityPreprocessor::Intersectable::OGRE_MESH_INSTANCE:
589                {
590                        OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(entry);
591                        omi->GetEntity()->setVisible(visible);
592                        //GtpVisibilityPreprocessor::Debug << "assigned id " << omi->GetId() << endl;
593                }
594                break;
595        case GtpVisibilityPreprocessor::Intersectable::ENGINE_INTERSECTABLE:
596                {
597                        EngineIntersectable *oi = static_cast<EngineIntersectable *>(entry);
598
599                        EntityContainer *entries = oi->GetItem();
600                        EntityContainer::const_iterator eit, eit_end = entries->end();
601                        for (eit = entries->begin(); eit != eit_end; ++ eit)
602                        {
603                                Entity *ent = *eit;
604                                ent->setVisible(visible);
605                        }
606                }
607                break;
608        default:
609                break;
610        }
611}
612//-----------------------------------------------------------------------
613void OcclusionCullingSceneManager::PrepareVisualization(Camera *cam)
614{
615        // add player camera for visualization purpose
616        try
617        {
618                Camera *c;
619                if ((c = getCamera("PlayerCam")) != NULL)
620                {
621                        getRenderQueue()->addRenderable(c);
622                }   
623    }
624    catch (...)
625    {
626        // ignore
627    }
628
629        // add bounding boxes of rendered objects
630        if (0)
631        for (BoxList::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it)
632        {
633                getRenderQueue()->addRenderable(*it);
634        }
635
636        // show current view cell geometry
637    if (mCurrentViewCell)// && mCurrentViewCell->GetMesh())
638        {
639                //const bool showSingleViewCell = true;
640                if (mViewCellsGeometryLoaded)
641                {
642                        ShowViewCellsGeometry();
643                }
644               
645                //////////
646                //-- set PVS of view cell visible
647
648                GtpVisibilityPreprocessor::ObjectPvsIterator pit =
649                        mCurrentViewCell->GetPvs().GetIterator();
650
651                MailPvsObjects();
652
653                while (pit.HasMoreEntries())
654                {
655                        RenderPvsEntry(pit.Next());
656                }       
657        }
658#if 0
659   if (mRenderNodesForViz || mRenderNodesContentForViz)
660        {
661                // HACK: change node material so it is better suited for visualization
662                MaterialPtr nodeMat = MaterialManager::getSingleton().getByName("Core/NodeMaterial");
663                nodeMat->setAmbient(1, 1, 0);
664                nodeMat->setLightingEnabled(true);
665                nodeMat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
666
667                for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++it)
668                {
669                        if (mRenderNodesForViz)
670                        {
671                                // render the visible leaf nodes
672                                if ((*it)->numAttachedObjects() &&
673                                        !(*it)->numChildren() &&
674                                        ((*it)->getAttachedObject(0)->getMovableType() == "Entity") &&
675                                        (*it)->getAttachedObject(0)->isVisible())
676                                {
677                                        //getRenderQueue()->addRenderable((*it));
678                                        (*it)->_addToRenderQueue(cam, getRenderQueue(), false);
679                                }
680
681                                // add bounding boxes instead of node itself
682                                if (0) (*it)->_addBoundingBoxToQueue(getRenderQueue());
683                        }
684
685                        // add renderables itself
686                        if (mRenderNodesContentForViz)
687                        {
688                                (*it)->_addToRenderQueue(cam, getRenderQueue(), false);
689                        }
690                }
691        }
692#endif
693}
694//-----------------------------------------------------------------------
695const Pass *OcclusionCullingSceneManager::_setPass(const Pass* pass, bool evenIfSuppressed)
696{
697        if (mNormalExecution)
698        {
699                return TerrainSceneManager::_setPass(pass, evenIfSuppressed);
700        }
701
702        // problem: setting vertex program is not efficient
703        //Pass *usedPass = ((mIsDepthPassPhase && !pass->hasVertexProgram()) ? mDepthPass : pass);
704       
705        // set depth fill pass if we currently do not make an aabb occlusion query
706        const bool useDepthPass =
707                mUseDepthPass && mIsDepthPassPhase && !mHierarchyInterface->IsBoundingBoxQuery();
708
709        const IlluminationRenderStage savedStage = mIlluminationStage;
710       
711        if (useDepthPass)
712        {
713                // set illumination stage to NONE so no shadow material is used
714                // for depth pass or for occlusion query
715                if (mIsDepthPassPhase || mHierarchyInterface->IsBoundingBoxQuery())
716                {
717                        mIlluminationStage = IRS_NONE;
718                }
719       
720                //////////////////
721                //-- set vertex program of current pass in order to set correct depth
722                if (mExecuteVertexProgramForAllPasses &&
723                        mIsDepthPassPhase &&
724                        pass->hasVertexProgram())
725                {
726                        // add vertex program of current pass to depth pass
727                        mDepthPass->setVertexProgram(pass->getVertexProgramName());
728
729                        if (mDepthPass->hasVertexProgram())
730                        {
731                                const GpuProgramPtr& prg = mDepthPass->getVertexProgram();
732                                // Load this program if not done already
733                                if (!prg->isLoaded())
734                                        prg->load();
735                                // Copy params
736                                mDepthPass->setVertexProgramParameters(pass->getVertexProgramParameters());
737                        }
738                }
739                else if (mDepthPass->hasVertexProgram())
740                {       // reset vertex program
741                        mDepthPass->setVertexProgram("");
742                }
743        }
744
745        // using depth pass instead
746        const Pass *usedPass = useDepthPass ? mDepthPass : pass;
747
748#if 0 // tmp matt: pass is now const
749        // save old depth write: needed for item buffer
750        const bool isDepthWrite = usedPass->getDepthWriteEnabled();
751
752        // global option which enables / disables depth writes
753        if (!mEnableDepthWrite)
754                usedPass->setDepthWriteEnabled(false);
755#endif
756
757        ///////////////
758        //-- set actual pass here
759
760        const Pass *result = SceneManager::_setPass(usedPass, evenIfSuppressed);
761
762
763        // reset depth write
764#if 0 // tmp matt: this is now a const function
765        if (!mEnableDepthWrite)
766                usedPass->setDepthWriteEnabled(isDepthWrite);
767#endif
768        // reset illumination stage
769        mIlluminationStage = savedStage;
770
771        return result;
772}
773//-----------------------------------------------------------------------
774void OcclusionCullingSceneManager::myFindVisibleObjects(Camera* cam,
775                                                                                                                bool onlyShadowCasters)
776{
777        // clear render queue
778        // fully reset it after some frames
779        const bool flushQueue =
780                mDeleteQueueAfterRendering && ((mCurrentFrame % mFlushRate) == 0);
781        getRenderQueue()->clear(flushQueue);
782
783        ++ mCurrentFrame;
784
785        if (mShowVisualization)
786    {
787                //////////////
788                //-- show visible scene nodes and octree bounding boxes from last frame
789
790                PrepareVisualization(cam);
791               
792                        // lists only used for visualization
793                mVisible.clear();
794                mBoxes.clear();
795
796                return;
797        }
798       
799
800        mVisible.clear();
801        mBoxes.clear();
802
803        ///////////
804        //-- set visibility according to pvs of current view cell
805
806        UpdatePvs(cam);
807
808        // standard rendering in first pass
809        // hierarchical culling interleaves identification
810        // and rendering of objects in _renderVisibibleObjects
811
812        // for the shadow pass we use only standard rendering
813        // because shadows have low occlusion anyway
814        if ((mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE &&
815                 mIlluminationStage == IRS_RENDER_TO_TEXTURE) ||
816                mNormalExecution)
817        {
818                TerrainSceneManager::_findVisibleObjects(cam, onlyShadowCasters);
819        }
820        else if (mUseDepthPass)
821        {
822                // render scene once in order to fill depth buffer
823                RenderHierarchicalCulling();
824        }
825       
826        // only shadow casters will be rendered in shadow texture pass
827        //if (0) mHierarchyInterface->SetOnlyShadowCasters(onlyShadowCasters);
828}
829//-----------------------------------------------------------------------
830void OcclusionCullingSceneManager::_renderVisibleObjects()
831{
832        if (mNormalExecution)
833        {
834                // the standard octree rendering mode
835                TerrainSceneManager::_renderVisibleObjects();
836                //getRenderQueue()->clear(flushQueue);
837                return;
838        }
839
840        //const bool flushQueue = mDeleteQueueAfterRendering && ((mCurrentFrame % mFlushRate) == 0);
841        //++ mCurrentFrame;
842
843        // create material for item buffer pass
844        InitItemBufferPass();
845
846        // save ambient light to reset later
847        ColourValue savedAmbient = mAmbientLight;
848
849        ////////////////////
850        //-- apply standard rendering for some modes
851        //-- (e.g., the visualization mode, the shadow pass)
852
853        // also go here if find visible object is disabled
854        // (then the render queue is already filled)
855        if (!mFindVisibleObjects ||
856                mUseDepthPass || mShowVisualization ||
857            (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE &&
858             mIlluminationStage == IRS_RENDER_TO_TEXTURE))
859        {       
860                IlluminationRenderStage savedStage = mIlluminationStage;
861       
862                if (mShowVisualization)
863                        // disable illumination stage to prevent rendering shadows
864                        mIlluminationStage = IRS_NONE;
865               
866                // standard rendering for shadow maps because of performance
867                TerrainSceneManager::_renderVisibleObjects();
868
869                mIlluminationStage = savedStage;
870        }
871        else //-- the hierarchical culling algorithm
872        {
873                // note matt: this is also called in TerrainSceneManager: really necessary?
874                mDestRenderSystem->setLightingEnabled(false);
875
876                if (mUseItemBuffer)
877                {
878                        // don't render backgrounds for item buffer
879                        clearSpecialCaseRenderQueues();
880                        getRenderQueue()->clear();
881                }
882
883                ////////////////////
884                //-- hierarchical culling
885
886                // the objects of different layers (e.g., background, scene,
887                // overlay) must be identified and rendered one after another
888
889                // first render all early skies
890                clearSpecialCaseRenderQueues();
891                addSpecialCaseRenderQueue(RENDER_QUEUE_BACKGROUND);
892                addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_EARLY);
893                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE);
894
895                TerrainSceneManager::_renderVisibleObjects();
896
897#ifdef GTP_VISIBILITY_MODIFIED_OGRE
898                // delete previously rendered content
899                _deleteRenderedQueueGroups();
900#endif
901
902                ///////////////////
903                //-- prepare queue for visible objects (i.e., all but overlay and skies late)
904
905                clearSpecialCaseRenderQueues();
906                addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_LATE);
907                addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY);
908       
909                // exclude these queues from hierarchical rendering
910                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE);
911
912                // set all necessary parameters for
913                // hierarchical visibility culling and rendering
914                InitVisibilityCulling(mCameraInProgress);
915
916
917                /**
918                * the hierarchical culling algorithm
919                * for depth pass: we just find objects and update depth buffer
920                * for "delayed" rendering: we render some passes afterwards
921                * e.g., transparents, because they need front-to-back sorting
922                **/
923               
924                mVisibilityManager->ApplyVisibilityCulling();
925
926                // delete remaining renderables from queue:
927                // all which are not in mLeavePassesInQueue)
928#ifdef GTP_VISIBILITY_MODIFIED_OGRE
929                _deleteRenderedQueueGroups(mLeavePassesInQueue);
930#endif
931
932                /////////////
933                //-- reset parameters needed during hierarchical rendering
934               
935                mIsItemBufferPhase = false;
936                mSkipTransparents = false;
937                mIsHierarchicalCulling = false;
938               
939                mLeavePassesInQueue = 0;
940                       
941                /////////////
942                //-- now we can render all remaining queue objects
943                //-- used for depth pass, transparents, overlay
944
945        clearSpecialCaseRenderQueues();
946
947                TerrainSceneManager::_renderVisibleObjects();
948        } // end hierarchical culling
949               
950        // HACK: set the new render level index, important to avoid cracks
951        // in terrain caused by LOD
952        TerrainRenderable::NextRenderLevelIndex();
953       
954        // reset ambient light
955        setAmbientLight(savedAmbient);
956
957        // remove rest from queue
958#if 0
959        getRenderQueue()->clear(flushQueue);
960#endif
961       
962        if (0) WriteLog(); // write out stats
963}
964//-----------------------------------------------------------------------
965void OcclusionCullingSceneManager::_updateSceneGraph(Camera* cam)
966{
967        if (!mNormalExecution)
968        {
969                mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface);
970                mHierarchyInterface->SetRenderSystem(mDestRenderSystem);
971        }
972
973        TerrainSceneManager::_updateSceneGraph(cam);
974}
975//-----------------------------------------------------------------------
976bool OcclusionCullingSceneManager::setOption(const String & key, const void * val)
977{
978        if (key == "UseDepthPass")
979        {
980                mUseDepthPass = (*static_cast<const bool *>(val));
981                return true;
982        }
983        if (key == "PrepareVisualization")
984        {
985                mShowVisualization = (*static_cast<const bool *>(val));
986                return true;
987        }
988        if (key == "RenderNodesForViz")
989        {
990                mRenderNodesForViz = (*static_cast<const bool *>(val));
991                return true;
992        }
993        if (key == "RenderNodesContentForViz")
994        {
995                mRenderNodesContentForViz = (*static_cast<const bool *>(val));
996                return true;
997        }
998        if (key == "SkyBoxEnabled")
999        {
1000                mSkyBoxEnabled = (*static_cast<const bool *>(val));
1001                return true;
1002        }
1003        if (key == "SkyPlaneEnabled")
1004        {
1005                mSkyPlaneEnabled = (*static_cast<const bool *>(val));
1006                return true;
1007        }
1008        if (key == "SkyDomeEnabled")
1009        {
1010                mSkyDomeEnabled = (*static_cast<const bool *>(val));
1011                return true;
1012        }
1013        if (key == "VisualizeCulledNodes")
1014        {
1015                mVisualizeCulledNodes = (*static_cast<const bool *>(val));
1016                return true;
1017        }
1018        if (key == "DelayRenderTransparents")
1019        {
1020                //LoadScene(mFilename, mViewCellsFilename);
1021                mDelayRenderTransparents = (*static_cast<const bool *>(val));
1022                return true;
1023        }
1024        if (key == "DepthWrite")
1025        {
1026                mEnableDepthWrite = (*static_cast<const bool *>(val));
1027                return true;
1028        }
1029        if (key == "UseItemBuffer")
1030        {
1031                mUseItemBuffer = (*static_cast<const bool *>(val));
1032                return true;
1033        }
1034        if (key == "ExecuteVertexProgramForAllPasses")
1035        {
1036                mExecuteVertexProgramForAllPasses  = (*static_cast<const bool *>(val));
1037                return true;
1038        }
1039        if (key == "RenderTransparentsForItemBuffer")
1040        {
1041                mRenderTransparentsForItemBuffer  = (*static_cast<const bool *>(val));
1042                return true;
1043        }
1044        else if (key == "FlushQueue")
1045        {
1046                mDeleteQueueAfterRendering = (*static_cast<const bool *>(val));
1047                return true;
1048        }
1049        if (key == "NodeVizScale")
1050        {
1051                OctreeNode::setVizScale(*static_cast<const float *>(val));
1052                return true;
1053        }
1054        if (key == "UseViewCells")
1055        {       
1056                if (!mViewCellsLoaded)
1057                {
1058                        // try to load view cells
1059                        mViewCellsLoaded = LoadViewCells(mViewCellsFilename);   
1060                }
1061
1062                if (!mViewCellsLoaded)
1063                        return false;
1064               
1065                // only use this option if view cells are available
1066                mUseViewCells = *static_cast<const bool *>(val);
1067
1068                // reset view cell
1069                OGRE_DELETE(mCurrentViewCell);
1070                       
1071                if (mUseViewCells)
1072                {
1073                        mCurrentViewCell = mViewCellsManager->GenerateViewCell();
1074                }
1075               
1076                // view cell corresponding to leaf in the view cell hierarchy
1077                mElementaryViewCell = NULL;
1078
1079                // all objects are set to invisible per default
1080                SetObjectsVisible(!mUseViewCells);
1081
1082                MovableObjectIterator movit = getMovableObjectIterator("Entity");
1083                while (movit.hasMoreElements())
1084                {
1085                        Entity *ent = static_cast<Entity *>(movit.getNext());
1086                        ent->setVisible(!mUseViewCells);
1087                }
1088               
1089                return true;
1090        }
1091        if (key == "ShowViewCells")
1092        {
1093                // only use this option if view cells are available
1094                if (mViewCellsLoaded)
1095                {
1096                        mShowViewCells = *static_cast<const bool *>(val);
1097                        // if we decide use view cells
1098                        // all objects are set to invisible per default
1099                        VisualizeViewCells(mShowViewCells);
1100                }
1101
1102                return true;
1103        }
1104        if (key == "NormalExecution")
1105        {
1106                mNormalExecution = *static_cast<const bool *>(val);
1107                return true;
1108        }
1109        if (key == "ShowTerrain")
1110        {
1111                mShowTerrain = *static_cast<const bool *>(val);
1112                return true;
1113        }
1114        if (key == "UseVisibilityFilter")
1115        {
1116                mUseVisibilityFilter = *static_cast<const bool *>(val);
1117
1118                // set null => recomputation of the pvs
1119        mElementaryViewCell = NULL;
1120
1121                return true;
1122        }
1123        if (key == "UseVisibilityQueries")
1124        {
1125                mUseVisibilityQueries = *static_cast<const bool *>(val);
1126
1127                return true;
1128        }
1129        if (key == "UseFromPointQueries")
1130        {
1131                mUseFromPointQueries = *static_cast<const bool *>(val);
1132
1133                return true;
1134        }
1135        if (key == "QueryMode")
1136        {
1137                mQueryMode = *static_cast<const int *>(val);
1138
1139                return true;
1140        }
1141        if (key == "ResetMaterialForQueries")
1142        {
1143                mResetMaterialForQueries = *static_cast<const bool *>(val);
1144        }
1145        if (key == "UseFromPointQueries")
1146        {
1147                mUseFromPointQueries = *static_cast<const bool *>(val);
1148                return true;
1149        }
1150
1151        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
1152                setOption(key, val) || TerrainSceneManager::setOption(key, val);
1153}
1154//-----------------------------------------------------------------------
1155bool OcclusionCullingSceneManager::getOption(const String &key, void *val)
1156{
1157        if (key == "NumHierarchyNodes")
1158        {
1159                * static_cast<unsigned int *>(val) = (unsigned int)mNumOctants;
1160                return true;
1161        }
1162        if (key == "VisibilityManager")
1163        {
1164                * static_cast<GtpVisibility::VisibilityManager **>(val) = mVisibilityManager;
1165                return true;
1166        }
1167        if (key == "HierarchyInterface")
1168        {
1169                * static_cast<GtpVisibility::HierarchyInterface **>(val) = mHierarchyInterface;
1170                return true;
1171        }
1172        if (key == "ShowTerrain")
1173        {
1174                * static_cast<bool *>(val) = mShowTerrain;
1175                return true;
1176        }
1177        if (key == "UseDepthPass")
1178        {
1179                * static_cast<bool *>(val) = mUseDepthPass;
1180                return true;
1181        }
1182        if (key == "FlushQueue")
1183        {
1184                * static_cast<bool *>(val) = mDeleteQueueAfterRendering;
1185                return true;
1186        }
1187        if (key == "NormalExecution")
1188        {
1189                * static_cast<bool *>(val) = mNormalExecution;
1190                return true;
1191        }
1192        if (key == "Algorithm")
1193        {
1194                GtpVisibility::VisibilityEnvironment::CullingManagerType algorithm =
1195                        mVisibilityManager->GetCullingManagerType();
1196
1197                * static_cast<unsigned int *>(val) = (unsigned int)algorithm;
1198
1199                return true;
1200        }
1201
1202        if (key == "VisibleObjects")
1203        {
1204                if (mNormalExecution)
1205                        return false;
1206
1207                const bool fromPoint = false;
1208                const bool nodeVisibility = true;
1209               
1210                * static_cast<unsigned int *>(val) =
1211                        (unsigned int)QueryVisibleObjectsExact(mCameraInProgress,
1212                                                                                                   mCurrentViewport,
1213                                                                                                   fromPoint,
1214                                                                                                   nodeVisibility);
1215                return true;
1216        }
1217
1218        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
1219                getOption(key, val) && TerrainSceneManager::getOption(key, val);
1220}
1221//-----------------------------------------------------------------------
1222bool OcclusionCullingSceneManager::getOptionValues(const String & key,
1223                                                                                                        StringVector &refValueList)
1224{
1225        return TerrainSceneManager::getOptionValues( key, refValueList);
1226}
1227//-----------------------------------------------------------------------
1228bool OcclusionCullingSceneManager::getOptionKeys(StringVector & refKeys)
1229{
1230        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
1231                getOptionKeys(refKeys) || TerrainSceneManager::getOptionKeys(refKeys);
1232}
1233//-----------------------------------------------------------------------
1234void OcclusionCullingSceneManager::setVisibilityManager(GtpVisibility::
1235                                                                                                                 VisibilityManager *visManager)
1236{
1237        mVisibilityManager = visManager;
1238}
1239//-----------------------------------------------------------------------
1240GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::getVisibilityManager( void )
1241{
1242        return mVisibilityManager;
1243}
1244//-----------------------------------------------------------------------
1245void OcclusionCullingSceneManager::WriteLog()
1246{
1247        std::stringstream d;
1248
1249        d << "Depth pass: " << StringConverter::toString(mUseDepthPass) << ", "
1250          << "Delay transparents: " << StringConverter::toString(mDelayRenderTransparents) << ", "
1251          << "Use optimization: " << StringConverter::toString(mHierarchyInterface->GetTestGeometryForVisibleLeaves()) << ", "
1252          << "Algorithm type: " << mVisibilityManager->GetCullingManagerType() << ", "
1253          << "Hierarchy nodes: " << mNumOctants << ", "
1254          << "Traversed nodes: " << mHierarchyInterface->GetNumTraversedNodes() << ", "
1255          << "Rendered nodes: " << mHierarchyInterface->GetNumRenderedNodes() << ", "
1256          << "Query culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumQueryCulledNodes() << ", "
1257          << "Frustum culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumFrustumCulledNodes() << ", "
1258      << "Queries issued: " << mVisibilityManager->GetCullingManager()->GetNumQueriesIssued() << ", "
1259          << "Found objects: " << (int)mVisible.size() << "\n";
1260
1261        LogManager::getSingleton().logMessage(d.str());
1262}
1263//-----------------------------------------------------------------------
1264void OcclusionCullingSceneManager::renderBasicQueueGroupObjects(RenderQueueGroup* pGroup,
1265                                                                                                                                QueuedRenderableCollection::OrganisationMode om)
1266{
1267        if (mNormalExecution)
1268        {
1269                return TerrainSceneManager::renderBasicQueueGroupObjects(pGroup, om);
1270        }
1271
1272    // Basic render loop
1273    // Iterate through priorities
1274    RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
1275
1276    while (groupIt.hasMoreElements())
1277    {
1278        RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
1279
1280        // Sort the queue first
1281        pPriorityGrp->sort(mCameraInProgress);
1282
1283        // Do solids
1284        renderObjects(pPriorityGrp->getSolidsBasic(), om, true);
1285
1286                // for correct rendering, transparents must be rendered
1287                // after hierarchical culling => don't render them now
1288
1289        if (!mSkipTransparents)
1290                {
1291                        // Do transparents (always descending)
1292                        renderObjects(pPriorityGrp->getTransparents(),
1293                                QueuedRenderableCollection::OM_SORT_DESCENDING, true);
1294                }
1295    } // for each priority
1296}
1297//-----------------------------------------------------------------------
1298bool OcclusionCullingSceneManager::validatePassForRendering(Pass* pass)
1299{
1300        if (mNormalExecution)
1301        {
1302                return TerrainSceneManager::validatePassForRendering(pass);
1303        }
1304
1305        // skip all but first pass if we are doing the depth pass
1306        if ((mIsDepthPassPhase || mIsItemBufferPhase) &&
1307                (pass->getIndex() > 0))
1308        {
1309                return false;
1310        }
1311        // all but first pass
1312        /*else if ((!mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() != 0))
1313        {
1314                return false;
1315        }*/
1316
1317        return SceneManager::validatePassForRendering(pass);
1318}
1319//-----------------------------------------------------------------------
1320void OcclusionCullingSceneManager::_renderQueueGroupObjects(RenderQueueGroup* pGroup,
1321                                                                                                                        QueuedRenderableCollection::OrganisationMode om)
1322{
1323        if (mNormalExecution || !mIsItemBufferPhase)
1324        {
1325                TerrainSceneManager::_renderQueueGroupObjects(pGroup, om);
1326                return;
1327        }
1328
1329#ifdef  ITEM_BUFFER
1330
1331        ///////////////////
1332        //-- item buffer: render objects using false colors
1333
1334    // Iterate through priorities
1335    RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
1336
1337        while (groupIt.hasMoreElements())
1338    {
1339                RenderItemBuffer(groupIt.getNext());
1340        }
1341#endif // ITEM_BUFFER
1342}
1343#ifdef ITEM_BUFFER
1344//-----------------------------------------------------------------------
1345void OcclusionCullingSceneManager::RenderItemBuffer(RenderPriorityGroup* pGroup)
1346{
1347        // Do solids
1348        QueuedRenderableCollection solidObjs = pGroup->getSolidsBasic();//msz
1349
1350        // ----- SOLIDS LOOP -----
1351        RenderPriorityGroup::SolidRenderablePassMap::const_iterator ipass, ipassend;
1352        ipassend = solidObjs.end();
1353
1354        for (ipass = solidObjs.begin(); ipass != ipassend; ++ipass)
1355        {
1356                // Fast bypass if this group is now empty
1357                if (ipass->second->empty())
1358                        continue;
1359
1360                // Render only first pass of renderable as false color
1361                if (ipass->first->getIndex() > 0)
1362                        continue;
1363
1364                RenderPriorityGroup::RenderableList* rendList = ipass->second;
1365               
1366                RenderPriorityGroup::RenderableList::const_iterator irend, irendend;
1367                irendend = rendList->end();
1368                       
1369                for (irend = rendList->begin(); irend != irendend; ++irend)
1370                {
1371                        if (0)
1372                        {
1373                                std::stringstream d; d << "itembuffer, pass name: " <<
1374                                        ipass->first->getParent()->getParent()->getName();
1375
1376                                LogManager::getSingleton().logMessage(d.str());
1377                        }
1378                       
1379                        RenderSingleObjectForItemBuffer(*irend, ipass->first);
1380                }
1381        }
1382
1383        ///////////
1384        //-- TRANSPARENT LOOP: must be handled differently from solids
1385
1386        // transparents are treated either as solids or completely discarded
1387        if (mRenderTransparentsForItemBuffer)
1388        {
1389                QueuedRenderableCollection transpObjs = pGroup->getTransparents(); //msz
1390                RenderPriorityGroup::TransparentRenderablePassList::const_iterator
1391                        itrans, itransend;
1392
1393                itransend = transpObjs.end();
1394                for (itrans = transpObjs.begin(); itrans != itransend; ++itrans)
1395                {
1396                        // like for solids, render only first pass
1397                        if (itrans->pass->getIndex() == 0)
1398                        {       
1399                                RenderSingleObjectForItemBuffer(itrans->renderable, itrans->pass);
1400                        }
1401                }
1402        }
1403}
1404//-----------------------------------------------------------------------
1405void OcclusionCullingSceneManager::RenderSingleObjectForItemBuffer(Renderable *rend, Pass *pass)
1406{
1407        static LightList nullLightList;
1408       
1409        int col[4];
1410       
1411        // -- create color code out of object id
1412        col[0] = (rend->getId() >> 16) & 255;
1413        col[1] = (rend->getId() >> 8) & 255;
1414        col[2] = rend->getId() & 255;
1415//      col[3] = 255;
1416
1417        //mDestRenderSystem->setColour(col[0], col[1], col[2], col[3]);
1418   
1419        mItemBufferPass->setAmbient(ColourValue(col[0] / 255.0f,
1420                                                                                    col[1] / 255.0f,
1421                                                                                        col[2] / 255.0f, 1));
1422
1423        // set vertex program of current pass
1424        if (mExecuteVertexProgramForAllPasses && pass->hasVertexProgram())
1425        {
1426                mItemBufferPass->setVertexProgram(pass->getVertexProgramName());
1427
1428                if (mItemBufferPass->hasVertexProgram())
1429                {
1430                        const GpuProgramPtr& prg = mItemBufferPass->getVertexProgram();
1431                        // Load this program if not done already
1432                        if (!prg->isLoaded())
1433                                prg->load();
1434                        // Copy params
1435                        mItemBufferPass->setVertexProgramParameters(pass->getVertexProgramParameters());
1436                }
1437        }
1438        else if (mItemBufferPass->hasVertexProgram())
1439        {
1440                mItemBufferPass->setVertexProgram("");
1441        }
1442
1443        const Pass *usedPass = _setPass(mItemBufferPass);
1444
1445
1446        // render a single object, this will set up auto params if required
1447        renderSingleObject(rend, usedPass, false, &nullLightList);
1448}
1449#endif // ITEM_BUFFER
1450//-----------------------------------------------------------------------
1451GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::GetVisibilityManager()
1452{
1453        return mVisibilityManager;
1454}
1455//-----------------------------------------------------------------------
1456void OcclusionCullingSceneManager::InitVisibilityCulling(Camera *cam)
1457{
1458        // reset culling manager stats
1459        mVisibilityManager->GetCullingManager()->InitFrame(mVisualizeCulledNodes);
1460
1461        // set depth pass flag before rendering
1462        mIsDepthPassPhase = mUseDepthPass;
1463
1464        // indicates that we use hierarchical culling from now on
1465        mIsHierarchicalCulling = true;
1466
1467        // item buffer needs full ambient lighting to use item colors as unique id
1468        if (mUseItemBuffer)
1469        {
1470                mIsItemBufferPhase = true;
1471                setAmbientLight(ColourValue(1,1,1,1));
1472        }
1473
1474
1475        // set passes which are stored in render queue
1476        // for rendering AFTER hierarchical culling, i.e., passes which need
1477        // a special rendering order
1478       
1479        mLeavePassesInQueue = 0;
1480
1481        // if we have the depth pass or use an item buffer, we leave no passes in the queue
1482        if (!mUseDepthPass && !mUseItemBuffer)
1483        {
1484                if (mShadowTechnique == SHADOWTYPE_STENCIL_ADDITIVE)
1485                {
1486                        // TODO: remove this pass because it should be processed during hierarchical culling
1487                        //mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
1488
1489                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DECAL;
1490                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DIFFUSE_SPECULAR;
1491                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
1492
1493                        // just render ambient passes
1494                        /*** msz: no more IRS_AMBIENT, see OgreSceneManager.h ***/
1495                        // mIlluminationStage = IRS_AMBIENT;
1496                        //getRenderQueue()->setSplitPassesByLightingType(true);
1497                }
1498       
1499                if (mShadowTechnique == SHADOWTYPE_STENCIL_MODULATIVE)
1500                {
1501                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
1502                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
1503                }
1504       
1505                // transparents should be rendered after hierarchical culling to
1506                // provide front-to-back ordering
1507                if (mDelayRenderTransparents)
1508                {
1509                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
1510                }
1511        }
1512
1513        // skip rendering transparents during the hierarchical culling
1514        // (because they will be rendered afterwards)
1515        mSkipTransparents =
1516                (mIsDepthPassPhase || (mLeavePassesInQueue & RenderPriorityGroup::TRANSPARENT_PASSES));
1517
1518        // -- initialise interface for rendering traversal of the hierarchy
1519        mHierarchyInterface->SetHierarchyRoot(mOctree);
1520       
1521        // possible two cameras (one for culling, one for rendering)
1522        mHierarchyInterface->InitTraversal(cam,
1523                                                                           mCullCamera ? getCamera("CullCamera") : NULL,
1524                                                                           mLeavePassesInQueue);
1525               
1526}
1527//-----------------------------------------------------------------------
1528OctreeHierarchyInterface *OcclusionCullingSceneManager::GetHierarchyInterface()
1529{
1530        return mHierarchyInterface;
1531}
1532//-----------------------------------------------------------------------
1533void OcclusionCullingSceneManager::endFrame()
1534{
1535        TerrainRenderable::ResetRenderLevelIndex();
1536}
1537//-----------------------------------------------------------------------
1538Entity* OcclusionCullingSceneManager::createEntity(const String& entityName,
1539                                                                                                        const String& meshName)
1540{
1541        Entity *ent = SceneManager::createEntity(entityName, meshName);
1542
1543        for (int i = 0; i < (int)ent->getNumSubEntities(); ++i)
1544        {
1545                ent->getSubEntity(i)->setId(mCurrentEntityId);
1546        }
1547
1548        // increase counter of entity id values
1549        ++ mCurrentEntityId;
1550
1551        return ent;
1552}
1553//-----------------------------------------------------------------------
1554void OcclusionCullingSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(
1555        RenderQueueGroup* pGroup, QueuedRenderableCollection::OrganisationMode om)
1556{
1557        if (mNormalExecution || !mIsHierarchicalCulling)
1558        {
1559                // render the rest of the passes
1560                TerrainSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(pGroup, om);
1561                return;
1562        }
1563       
1564        // only render solid passes during hierarchical culling
1565        RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
1566        LightList lightList;
1567
1568        while (groupIt.hasMoreElements())
1569        {
1570                RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
1571
1572                // Sort the queue first
1573                pPriorityGrp->sort(mCameraInProgress);
1574
1575                // Clear light list
1576                lightList.clear();
1577
1578                // Render all the ambient passes first, no light iteration, no lights
1579                /*** msz: no more IRS_AMBIENT, see OgreSceneManager.h ***/
1580                // mIlluminationStage = IRS_AMBIENT;
1581
1582                OctreeSceneManager::renderObjects(pPriorityGrp->getSolidsBasic(), om, false, &lightList);
1583                // Also render any objects which have receive shadows disabled
1584                OctreeSceneManager::renderObjects(pPriorityGrp->getSolidsNoShadowReceive(), om, true);
1585#if 0           
1586                std::stringstream d;
1587                d << " solid size: " << (int)pPriorityGrp->_getSolidPasses().size()
1588                        << " solid no shadow size: " << (int)pPriorityGrp->_getSolidPassesNoShadow().size()
1589                        << "difspec size: " << (int)pPriorityGrp->_getSolidPassesDiffuseSpecular().size()
1590                        << " decal size: " << (int)pPriorityGrp->_getSolidPassesDecal().size();
1591                LogManager::getSingleton().logMessage(d.str());
1592#endif
1593        }
1594}
1595//-----------------------------------------------------------------------
1596void OcclusionCullingSceneManager::renderModulativeStencilShadowedQueueGroupObjects(
1597        RenderQueueGroup* pGroup, QueuedRenderableCollection::OrganisationMode om)
1598{
1599   if (mNormalExecution || !mIsHierarchicalCulling)
1600   {
1601           TerrainSceneManager::renderModulativeStencilShadowedQueueGroupObjects(pGroup, om);
1602           return;
1603   }
1604
1605   // Iterate through priorities
1606   RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
1607
1608   while (groupIt.hasMoreElements())
1609   {
1610           RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
1611
1612           // Sort the queue first
1613           pPriorityGrp->sort(mCameraInProgress);
1614           // Do (shadowable) solids
1615           OctreeSceneManager::renderObjects(pPriorityGrp->getSolidsBasic(), om, true);
1616   }
1617}
1618//-------------------------------------------------------------------------
1619void OcclusionCullingSceneManager::SetObjectsVisible(const bool visible)
1620{
1621        GtpVisibilityPreprocessor::ObjectContainer::iterator it, it_end = mObjects.end();
1622
1623        for (it = mObjects.begin(); it != it_end; ++ it)
1624        {
1625                GtpVisibilityPreprocessor::Intersectable *entry = *it;
1626
1627                SetObjectVisible(entry, visible);
1628        }
1629}
1630//-----------------------------------------------------------------------
1631bool OcclusionCullingSceneManager::LoadViewCells(const String &filename)
1632{
1633        // no filename specified
1634        if (filename == "")
1635                return false;
1636
1637        // view cells already loaded
1638        if (mViewCellsLoaded)
1639                return true;
1640
1641        // converter between view cell ids and Ogre entites
1642        OctreeBoundingBoxConverter bconverter(this);
1643
1644        // load the view cells assigning the found objects to the pvss
1645        const bool finalizeViewCells = false;
1646
1647        // load the view cells assigning the found objects to the pvss
1648        mViewCellsManager =
1649                GtpVisibilityPreprocessor::ViewCellsManager::
1650                        LoadViewCells(filename, mObjects, false, &bconverter);
1651       
1652        Ogre::LogManager::getSingleton().logMessage("******** view cells loaded *********");
1653
1654        // objects are set to invisible initially
1655        SetObjectsVisible(false);
1656
1657        if (finalizeViewCells)
1658        {
1659                CreateViewCellsGeometry();
1660        }
1661
1662        return (mViewCellsManager != NULL);
1663}
1664//-------------------------------------------------------------------------
1665void OcclusionCullingSceneManager::ApplyViewCellPvs(GtpVisibilityPreprocessor::ViewCell *vc,
1666                                                                                                        const bool load)
1667{       
1668        // NOTE: should not encounter NULL view cell,
1669        // rather apply view cell representing unbounded space then
1670        if (!vc)
1671        {       
1672                LogManager::getSingleton().logMessage("error: should not come here");
1673                // question: if no view cell, set everything visible?
1674                //SetObjectsVisible(true);
1675                SetObjectsVisible(false);
1676                return;
1677        }
1678               
1679        ////////////
1680        //-- set PVS of view cell to visible
1681
1682        //std::stringstream d; d << "appying new view cell pvs: " << vc->GetPvs().GetSize();
1683        //LogManager::getSingleton().logMessage(d.str());
1684
1685        GtpVisibilityPreprocessor::ObjectPvsIterator pit = vc->GetPvs().GetIterator();
1686
1687        while (pit.HasMoreEntries())
1688        {               
1689                GtpVisibilityPreprocessor::Intersectable *obj = pit.Next();
1690
1691                // no associated geometry found
1692                if (!obj) continue;
1693       
1694                SetObjectVisible(obj, load);
1695        }
1696}
1697//-------------------------------------------------------------------------
1698void OcclusionCullingSceneManager::UpdatePvs(Camera *cam)
1699{
1700        if (!(mViewCellsLoaded && mUseViewCells))
1701                return;
1702
1703        const GtpVisibilityPreprocessor::Vector3 viewPoint =
1704                OgreTypeConverter::ConvertFromOgre(cam->getDerivedPosition());
1705
1706        //std::stringstream d; d << "vp: " << viewPoint;
1707        //LogManager::getSingleton().logMessage(d.str());
1708
1709        GtpVisibilityPreprocessor::ViewCell *newElementary =
1710                mViewCellsManager->GetViewCell(viewPoint);
1711
1712        // elementary view cell did not change => don't change pvs
1713        if (mElementaryViewCell == newElementary)
1714                return;
1715
1716        mElementaryViewCell = newElementary;
1717       
1718
1719        //////////////
1720        //-- unload old pvs
1721
1722        ApplyViewCellPvs(mCurrentViewCell, false);
1723
1724        // the new view cell
1725        GtpVisibilityPreprocessor::ViewCell *viewCell;
1726               
1727        if (mUseVisibilityFilter)
1728        {       
1729                ////////////
1730                //-- compute new filtered cell
1731
1732                GtpVisibilityPreprocessor::PrVs prvs;
1733                mViewCellsManager->GetPrVS(viewPoint, prvs, 5);
1734                viewCell = prvs.mViewCell;
1735        }
1736        else
1737        {
1738                viewCell = newElementary;
1739        }
1740
1741        ///////////////
1742        //-- load new pvs
1743
1744        ApplyViewCellPvs(viewCell, true);
1745
1746        if (viewCell)
1747        {
1748                // store current view cell
1749                mCurrentViewCell->SetPvs(viewCell->GetPvs());
1750                mCurrentViewCell->SetMesh(viewCell->GetMesh());
1751                mCurrentViewCell->SetId(viewCell->GetId());
1752
1753                // delete merge tree of filtered view cell
1754                if (mUseVisibilityFilter)
1755                        mViewCellsManager->DeleteLocalMergeTree(viewCell);
1756        }
1757}
1758//-------------------------------------------------------------------------
1759void OcclusionCullingSceneManager::CreateViewCellsGeometry()
1760{
1761        //LogManager::getSingleton().logMessage("creating view cells geometry");
1762        if (mViewCellsGeometryLoaded) return;
1763
1764        GtpVisibilityPreprocessor::ViewCellContainer viewCells =
1765                mViewCellsManager->GetViewCells();
1766
1767        GtpVisibilityPreprocessor::ViewCellContainer::const_iterator it, it_end = viewCells.end();
1768        for (it = viewCells.begin(); it != it_end; ++ it)
1769        {
1770                GtpVisibilityPreprocessor::ViewCell *viewCell = *it;
1771
1772                ManualObject *manual =
1773                        OgreTypeConverter::ConvertToOgre(viewCell->GetMesh(), this);
1774               
1775                if (manual)
1776                {
1777                        mViewCellsGeometry[viewCell->GetId()] = manual;
1778
1779                        // attach to scene node
1780                        getRootSceneNode()->createChildSceneNode()->attachObject(manual);
1781                        manual->setQueryFlags(0); // returned by no query
1782       
1783                        // initialy set to invisible
1784                        manual->setVisible(false);
1785                }
1786        }
1787       
1788        mViewCellsGeometryLoaded = true;
1789}
1790//-------------------------------------------------------------------------
1791void OcclusionCullingSceneManager::VisualizeViewCells(const bool visualize)
1792{
1793        MovableMap::const_iterator mit, mit_end = mViewCellsGeometry.end();
1794                       
1795        for (mit = mViewCellsGeometry.begin(); mit != mit_end; ++ mit)
1796        {
1797                if ((*mit).second)
1798                        (*mit).second->setVisible(visualize);
1799        }       
1800}
1801#if 0
1802//-------------------------------------------------------------------------
1803void OcclusionCullingSceneManager::TestVisible(SceneNode *node)
1804{
1805        // first test for scene node, then for octant (part of the hierarchy)
1806        if (!node->mVisibleChildren)
1807        {
1808                node->setVisible(false);
1809        }
1810
1811        node->getOctant()->mVisibleChildren --;
1812}
1813//-------------------------------------------------------------------------
1814void OcclusionCullingSceneManager::TestVisible(Octree *octant)
1815{
1816        // first test for scene node, then for octant (part of the hierarchy)
1817        if (!octant->mVisibleChildren)
1818        {
1819                octant->setVisible(false);
1820        }
1821}
1822
1823//-------------------------------------------------------------------------
1824void OcclusionCullingSceneManager::UpdateVisibility(Entity *ent)
1825{
1826        if (!ent->isVisible())
1827        {
1828                bool visible = TestVisible(ent->getParentNode());
1829               
1830                if (!visible)
1831                        visible = TestVisible(octant->getParentNode());
1832
1833                if (!visible)
1834                        mHierarchyInterface->pullupVisibility();
1835        }
1836}
1837#endif
1838// splits strings containing multiple file names
1839static int SplitFilenames(const std::string str,
1840                                                  std::vector<std::string> &filenames)
1841{
1842        int pos = 0;
1843
1844        while(1)
1845        {
1846                int npos = (int)str.find(';', pos);
1847               
1848                if (npos < 0 || npos - pos < 1)
1849                        break;
1850                filenames.push_back(std::string(str, pos, npos - pos));
1851                pos = npos + 1;
1852        }
1853       
1854        filenames.push_back(std::string(str, pos, str.size() - pos));
1855        return (int)filenames.size();
1856}
1857//-----------------------------------------------------------------------
1858bool OcclusionCullingSceneManager::LoadScene(const String &filename,
1859                                                                                         const String &viewCellsFilename)
1860{
1861        using namespace std;
1862
1863        // use leaf nodes of the original spatial hierarchy as occludees
1864        vector<string> filenames;
1865        const int files = SplitFilenames(filename, filenames);
1866       
1867        stringstream d;
1868        d << "number of input files: " << files << "\n";
1869        LogManager::getSingleton().logMessage(d.str());
1870
1871        bool result = false;
1872        vector<string>::const_iterator fit, fit_end = filenames.end();
1873        int i = 0;
1874
1875        if (filename == "terrain" || filename == "")
1876        {
1877                LogManager::getSingleton().logMessage("not loading scene");
1878
1879                // terrain hack
1880                return false;
1881        }
1882
1883        for (fit = filenames.begin(); fit != fit_end; ++ fit, ++ i)
1884        {
1885                const string fn = *fit;
1886
1887                if (strstr(fn.c_str(), ".obj"))
1888                {
1889                        // load iv files
1890                        if (!LoadSceneObj(filename, viewCellsFilename, getRootSceneNode()))
1891                        {
1892                                LogManager::getSingleton().logMessage("error loading file");
1893                                return false;
1894            }
1895                }
1896                else if (strstr(fn.c_str(), ".iv") || strstr(fn.c_str(), ".wrl"))
1897                {
1898                        // load iv files
1899                        if (!LoadSceneIV(fn, getRootSceneNode(), i))
1900                        {
1901                                // terrain hack
1902                                LogManager::getSingleton().logMessage("error loading file");
1903                        }
1904                }
1905                       
1906                // at least one piece of geometry loaded
1907                result = true;
1908        }
1909
1910        return result;
1911}
1912//-----------------------------------------------------------------------
1913bool OcclusionCullingSceneManager::LoadSceneIV(const String &filename,
1914                                                                                           SceneNode *root,
1915                                                                                           const int index)
1916{
1917        IVReader ivReader;
1918
1919        Timer *timer = PlatformManager::getSingleton().createTimer();
1920        timer->reset();
1921
1922        if (1)
1923        {
1924                std::string logFilename = "IVLog" + Ogre::StringConverter().toString(index) + ".log";
1925               
1926                Log *log = LogManager::getSingleton().createLog(logFilename);
1927                ivReader.setLog(log);
1928        }
1929       
1930        //viennaNode->translate(Vector3(-300, -300, 0));
1931
1932        if (ivReader.loadFile(filename.c_str()))
1933        {
1934                SceneNode *node = root->createChildSceneNode("IVSceneNode" + index);
1935
1936                ivReader.buildTree(this, node);
1937               
1938                ivReader.collapse();
1939
1940                std::stringstream d;
1941                d << "loaded " << filename << " in " << timer->getMilliseconds() * 1e-3 << " secs";
1942                LogManager::getSingleton().logMessage(d.str());
1943               
1944                PlatformManager::getSingleton().destroyTimer(timer);
1945
1946                //-- bake into static geometry
1947                /*if (USE_STATIC_GEOMETRY)
1948                {
1949                        BakeSceneIntoStaticGeometry("staticVienna", "Vienna");
1950                }*/
1951       
1952                return true;
1953        }
1954
1955        return false;
1956}
1957//-----------------------------------------------------------------------
1958void OcclusionCullingSceneManager::RenderHierarchicalCulling(const bool fillRenderQueue)
1959{
1960        // create material for depth pass
1961        InitDepthPass();
1962
1963        ////////////////////
1964        //-- hierarchical culling
1965
1966        // set all necessary parameters for
1967        // hierarchical visibility culling and rendering
1968        InitVisibilityCulling(mCameraInProgress);
1969
1970
1971        /**
1972        * the hierarchical culling algorithm
1973        * for depth pass: we just find objects and update depth buffer
1974        * for "delayed" rendering: we render some passes afterwards
1975        * e.g., transparents, because they need front-to-back sorting
1976        **/
1977               
1978        mVisibilityManager->ApplyVisibilityCulling();
1979
1980        // delete remaining renderables from queue:
1981        // all which are not in mLeavePassesInQueue)
1982        _deleteRenderedQueueGroups(mLeavePassesInQueue);
1983
1984        /////////////
1985        //-- reset parameters needed for special rendering
1986               
1987        mIsDepthPassPhase = false;
1988        mIsItemBufferPhase = false;
1989        mSkipTransparents = false;
1990        mIsHierarchicalCulling = false;
1991        mLeavePassesInQueue = 0;
1992               
1993        if (fillRenderQueue)
1994        {
1995                // the shaded geometry is rendered in a second pass
1996                // add visible nodes found by the visibility culling algorithm
1997                NodeList::const_iterator it, it_end = mVisible.end();
1998        for (it = mVisible.begin(); it != it_end; ++ it)
1999                {
2000                        (*it)->_addToRenderQueue(mCameraInProgress, getRenderQueue(), false);
2001                }
2002        }
2003}
2004//-----------------------------------------------------------------------
2005bool OcclusionCullingSceneManager::LoadSceneObj(const String &filename,
2006                                                                                                const String &viewCellsFile,
2007                                                                                                SceneNode *root)
2008{
2009        Timer *timer = PlatformManager::getSingleton().createTimer();
2010        timer->reset();
2011
2012        if (!mObjReader->LoadFile(filename.c_str(), viewCellsFile, root))
2013        {
2014                PlatformManager::getSingleton().destroyTimer(timer);
2015                return false;
2016        }
2017
2018        std::stringstream d;
2019        d << "loaded " << filename << " in " << timer->getMilliseconds() * 1e-3 << " secs";
2020        LogManager::getSingleton().logMessage(d.str());
2021               
2022        PlatformManager::getSingleton().destroyTimer(timer);
2023
2024        return true;
2025}
2026
2027//-----------------------------------------------------------------------
2028void OcclusionCullingSceneManager::_renderScene(Camera* camera,
2029                                                                                                Viewport* vp,
2030                                                                                                bool includeOverlays)
2031{
2032        if (mNormalExecution)
2033        {
2034                TerrainSceneManager::_renderScene(camera, vp, includeOverlays);
2035                return;
2036        }
2037
2038    Root::getSingleton()._setCurrentSceneManager(this);
2039        mActiveQueuedRenderableVisitor->targetSceneMgr = this;
2040
2041    if (isShadowTechniqueInUse())
2042    {
2043        // Prepare shadow materials
2044        initShadowVolumeMaterials();
2045    }
2046
2047    // Perform a quick pre-check to see whether we should override far distance
2048    // When using stencil volumes we have to use infinite far distance
2049    // to prevent dark caps getting clipped
2050    if (isShadowTechniqueStencilBased() &&
2051        camera->getProjectionType() == PT_PERSPECTIVE &&
2052        camera->getFarClipDistance() != 0 &&
2053        mDestRenderSystem->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE) &&
2054        mShadowUseInfiniteFarPlane)
2055    {
2056        // infinite far distance
2057        camera->setFarClipDistance(0);
2058    }
2059
2060    mCameraInProgress = camera;
2061
2062
2063    // Update controllers
2064    ControllerManager::getSingleton().updateAllControllers();
2065
2066    // Update the scene, only do this once per frame
2067    unsigned long thisFrameNumber = Root::getSingleton().getCurrentFrameNumber();
2068    if (thisFrameNumber != mLastFrameNumber)
2069    {
2070        // Update animations
2071        _applySceneAnimations();
2072        mLastFrameNumber = thisFrameNumber;
2073    }
2074
2075    // Update scene graph for this camera (can happen multiple times per frame)
2076    _updateSceneGraph(camera);
2077
2078    // Auto-track nodes
2079    AutoTrackingSceneNodes::iterator atsni, atsniend;
2080    atsniend = mAutoTrackingSceneNodes.end();
2081    for (atsni = mAutoTrackingSceneNodes.begin(); atsni != atsniend; ++atsni)
2082    {
2083        (*atsni)->_autoTrack();
2084    }
2085    // Auto-track camera if required
2086    camera->_autoTrack();
2087
2088
2089    // Are we using any shadows at all?
2090    if (isShadowTechniqueInUse() &&
2091        mIlluminationStage != IRS_RENDER_TO_TEXTURE &&
2092                vp->getShadowsEnabled() &&
2093                mFindVisibleObjects)
2094    {
2095        // Locate any lights which could be affecting the frustum
2096        findLightsAffectingFrustum(camera);
2097        if (isShadowTechniqueTextureBased())
2098        {
2099            // *******
2100            // WARNING
2101            // *******
2102            // This call will result in re-entrant calls to this method
2103            // therefore anything which comes before this is NOT
2104            // guaranteed persistent. Make sure that anything which
2105            // MUST be specific to this camera / target is done
2106            // AFTER THIS POINT
2107            prepareShadowTextures(camera, vp);
2108            // reset the cameras because of the re-entrant call
2109            mCameraInProgress = camera;
2110        }
2111    }
2112
2113    // Invert vertex winding?
2114    if (camera->isReflected())
2115    {
2116        mDestRenderSystem->setInvertVertexWinding(true);
2117    }
2118    else
2119    {
2120        mDestRenderSystem->setInvertVertexWinding(false);
2121    }
2122
2123    // Tell params about viewport
2124    mAutoParamDataSource.setCurrentViewport(vp);
2125    // Set the viewport
2126    setViewport(vp);
2127
2128    // Tell params about camera
2129    mAutoParamDataSource.setCurrentCamera(camera);
2130    // Set autoparams for finite dir light extrusion
2131    mAutoParamDataSource.setShadowDirLightExtrusionDistance(mShadowDirLightExtrudeDist);
2132
2133    // Tell params about current ambient light
2134    mAutoParamDataSource.setAmbientLightColour(mAmbientLight);
2135        // Tell rendersystem
2136        mDestRenderSystem->setAmbientLight(mAmbientLight.r, mAmbientLight.g, mAmbientLight.b);
2137
2138    // Tell params about render target
2139    mAutoParamDataSource.setCurrentRenderTarget(vp->getTarget());
2140
2141
2142    // Set camera window clipping planes (if any)
2143    if (mDestRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES))
2144    {
2145        if (camera->isWindowSet()) 
2146        {
2147            const std::vector<Plane>& planeList =
2148                camera->getWindowPlanes();
2149            for (ushort i = 0; i < 4; ++i)
2150            {
2151                mDestRenderSystem->enableClipPlane(i, true);
2152                mDestRenderSystem->setClipPlane(i, planeList[i]);
2153            }
2154        }
2155        else
2156        {
2157            for (ushort i = 0; i < 4; ++i)
2158            {
2159                mDestRenderSystem->enableClipPlane(i, false);
2160            }
2161        }
2162    }
2163
2164        // Prepare render queue for receiving new objects
2165        //prepareRenderQueue();
2166
2167        mDestRenderSystem->_beginGeometryCount();
2168    // Begin the frame
2169    mDestRenderSystem->_beginFrame();
2170
2171    // Set rasterisation mode
2172    mDestRenderSystem->_setPolygonMode(camera->getPolygonMode());
2173
2174        // Set initial camera state
2175        mDestRenderSystem->_setProjectionMatrix(mCameraInProgress->getProjectionMatrixRS());
2176        mDestRenderSystem->_setViewMatrix(mCameraInProgress->getViewMatrix(true));
2177
2178        // Prepare render queue for receiving new objects
2179#ifdef GAMETOOLS_ILLUMINATION_MODULE
2180        if (mFindVisibleObjects)
2181                prepareRenderQueue();
2182#else
2183                prepareRenderQueue();
2184#endif
2185
2186    if (mFindVisibleObjects)
2187    {
2188        // Parse the scene and tag visibles
2189        myFindVisibleObjects(camera,
2190            mIlluminationStage == IRS_RENDER_TO_TEXTURE? true : false);
2191    }
2192    // Add overlays, if viewport deems it
2193    if (vp->getOverlaysEnabled() && mIlluminationStage != IRS_RENDER_TO_TEXTURE)
2194    {
2195        OverlayManager::getSingleton()._queueOverlaysForRendering(camera, getRenderQueue(), vp);
2196    }
2197    // Queue skies, if viewport seems it
2198    if (vp->getSkiesEnabled() && mFindVisibleObjects && mIlluminationStage != IRS_RENDER_TO_TEXTURE)
2199    {
2200        _queueSkiesForRendering(camera);
2201    }
2202
2203    // Render scene content
2204    _renderVisibleObjects();
2205
2206    // End frame
2207    mDestRenderSystem->_endFrame();
2208
2209    // Notify camera or vis faces
2210    camera->_notifyRenderedFaces(mDestRenderSystem->_getFaceCount());
2211}
2212//-----------------------------------------------------------------------
2213int OcclusionCullingSceneManager::QueryVisibleObjectsExact(Camera *camera,
2214                                                                                                                   Viewport* vp,
2215                                                                                                                   const bool fromPoint,
2216                                                                                                                   const bool nodeVisibility)
2217{
2218        const int itemBufferMode = 0;
2219        const bool relativeVisibility = false;
2220        const bool approximateVisibility = false;
2221
2222        int queryModes = 0;
2223
2224        if (nodeVisibility)
2225                queryModes |= GtpVisibility::QueryManager::NODE_VISIBILITY;
2226        else
2227                queryModes |= GtpVisibility::QueryManager::GEOMETRY_VISIBILITY;
2228
2229        OcclusionQueriesQueryManager *queryManager =
2230                new OcclusionQueriesQueryManager(mHierarchyInterface,
2231                                                                                 vp,
2232                                                                                 queryModes,
2233                                                                                 itemBufferMode);
2234
2235        mVisibilityManager->SetQueryManager(queryManager);
2236
2237        GtpVisibility::NodeInfoContainer visibleNodes;
2238        GtpVisibility::MeshInfoContainer visibleGeometry;
2239        GtpVisibility::PatchInfoContainer visiblePatches;
2240
2241        if (fromPoint)
2242        {
2243                queryManager->ComputeFromPointVisibility(camera->getDerivedPosition(),
2244                                                                                                 &visibleNodes,
2245                                                                                                 &visibleGeometry,
2246                                                                                                 &visiblePatches,
2247                                                                                                 relativeVisibility,
2248                                                                                                 approximateVisibility);
2249        }
2250        else
2251        {
2252                queryManager->ComputeCameraVisibility(*camera,
2253                                                                                          &visibleNodes,
2254                                                                                          &visibleGeometry,
2255                                                                                          &visiblePatches,
2256                                                                                          relativeVisibility,
2257                                                                                          approximateVisibility);
2258        }
2259               
2260        if (0)
2261        {
2262                std::stringstream d;
2263                d << "Query mode: " << queryModes
2264                  << " visible nodes: " << (int)visibleNodes.size()
2265                  << " visible geometry: " << (int)visibleGeometry.size();
2266
2267                LogManager::getSingleton().logMessage(d.str());
2268        }
2269
2270        ///////////////////////
2271        //-- put items in render queue
2272        //////////
2273
2274        getRenderQueue()->clear();
2275
2276        //////////////////////
2277        //-- apply queries on geometry level
2278
2279        if (!nodeVisibility)
2280        {
2281                GtpVisibility::MeshInfoContainer::iterator geomIt, geomIt_end = visibleGeometry.end();
2282
2283                for (geomIt = visibleGeometry.begin(); geomIt != geomIt_end; ++geomIt)
2284                {
2285                        MovableObject *mo = (*geomIt).GetSource();
2286
2287                        // add if not 0
2288                        if (!(*geomIt).GetVisiblePixels())
2289                                continue;
2290
2291                        mo->_notifyCurrentCamera(camera);
2292
2293                        if (mo->isVisible())
2294                        {
2295                                mo->_updateRenderQueue(getRenderQueue());
2296                        }
2297                }
2298        }
2299        else
2300        {
2301                ////////////////
2302                //-- apply queries on node level
2303
2304                GtpVisibility::NodeInfoContainer::iterator nodesIt, nodesIt_end = visibleNodes.end();
2305
2306                for (nodesIt = visibleNodes.begin(); nodesIt != nodesIt_end; ++ nodesIt)
2307                {
2308                        if (!(*nodesIt).GetVisiblePixels())
2309                                continue;
2310
2311                        Octree *octree = static_cast<Octree *>((*nodesIt).GetSource());
2312
2313                        NodeList::iterator nIt, nIt_end = octree->mNodes.end();
2314
2315                        for (nIt = octree->mNodes.begin(); nIt != nIt_end; ++ nIt)
2316                        {
2317                                (*nIt)->_addToRenderQueue(camera, getRenderQueue(), false);
2318                        }
2319                }
2320        }
2321
2322    delete queryManager;
2323
2324        if (nodeVisibility)
2325                return (int)visibleNodes.size();
2326        else
2327                return (int)visibleGeometry.size();
2328}
2329//-----------------------------------------------------------------------
2330void OcclusionCullingSceneManager::RenderDepthForQuery(Camera* camera,
2331                                                                                                           Viewport* vp)
2332{
2333    Root::getSingleton()._setCurrentSceneManager(this);
2334        mActiveQueuedRenderableVisitor->targetSceneMgr = this;
2335
2336    mCameraInProgress = camera;
2337
2338    // Update scene graph for this camera (can happen multiple times per frame)
2339    _updateSceneGraph(camera);
2340
2341    // Invert vertex winding?
2342    if (camera->isReflected())
2343    {
2344        mDestRenderSystem->setInvertVertexWinding(true);
2345    }
2346    else
2347    {
2348        mDestRenderSystem->setInvertVertexWinding(false);
2349    }
2350
2351    // Tell params about viewport
2352    mAutoParamDataSource.setCurrentViewport(vp);
2353    // Set the viewport
2354    setViewport(vp);
2355
2356    // Tell params about camera
2357    mAutoParamDataSource.setCurrentCamera(camera);
2358    // Set autoparams for finite dir light extrusion
2359    mAutoParamDataSource.setShadowDirLightExtrusionDistance(mShadowDirLightExtrudeDist);
2360
2361    // Tell params about current ambient light
2362    mAutoParamDataSource.setAmbientLightColour(mAmbientLight);
2363        // Tell rendersystem
2364        mDestRenderSystem->setAmbientLight(mAmbientLight.r, mAmbientLight.g, mAmbientLight.b);
2365
2366    // Tell params about render target
2367    mAutoParamDataSource.setCurrentRenderTarget(vp->getTarget());
2368
2369
2370    // Set camera window clipping planes (if any)
2371    if (mDestRenderSystem->getCapabilities()->hasCapability(RSC_USER_CLIP_PLANES))
2372    {
2373        if (camera->isWindowSet()) 
2374        {
2375            const std::vector<Plane>& planeList =
2376                camera->getWindowPlanes();
2377            for (ushort i = 0; i < 4; ++i)
2378            {
2379                mDestRenderSystem->enableClipPlane(i, true);
2380                mDestRenderSystem->setClipPlane(i, planeList[i]);
2381            }
2382        }
2383        else
2384        {
2385            for (ushort i = 0; i < 4; ++i)
2386            {
2387                mDestRenderSystem->enableClipPlane(i, false);
2388            }
2389        }
2390    }
2391
2392        // Prepare render queue for receiving new objects
2393        prepareRenderQueue();
2394
2395        // Begin the frame
2396    mDestRenderSystem->_beginFrame();
2397
2398    // Set rasterisation mode
2399    mDestRenderSystem->_setPolygonMode(camera->getPolygonMode());
2400
2401        // Set initial camera state
2402        mDestRenderSystem->_setProjectionMatrix(mCameraInProgress->getProjectionMatrixRS());
2403        mDestRenderSystem->_setViewMatrix(mCameraInProgress->getViewMatrix(true));
2404
2405        //////////////
2406        //-- Render scene in order fill depth buffer
2407
2408        // don't have to fill queue, just render depth
2409        const bool fillQueue = false;
2410
2411        RenderHierarchicalCulling(fillQueue);
2412        // _renderVisibleObjects();
2413   
2414    // End frame
2415    mDestRenderSystem->_endFrame();
2416}
2417//-----------------------------------------------------------------------
2418const String OcclusionCullingSceneManagerFactory::FACTORY_TYPE_NAME = "OcclusionCullingSceneManager";
2419//-----------------------------------------------------------------------
2420void OcclusionCullingSceneManagerFactory::initMetaData(void) const
2421{
2422        mMetaData.typeName = FACTORY_TYPE_NAME;
2423        mMetaData.description = "Scene manager organising the scene on the basis of an octree with advanced occlusion culling (TM).";
2424        mMetaData.sceneTypeMask = 0xFFFF; // support all types
2425        mMetaData.worldGeometrySupported = false;
2426}
2427//-----------------------------------------------------------------------
2428SceneManager *OcclusionCullingSceneManagerFactory::createInstance(
2429                const String& instanceName)
2430{
2431        OcclusionCullingSceneManager* tsm =
2432                new OcclusionCullingSceneManager(instanceName, visManager);
2433       
2434        // Create & register default sources (one per manager)
2435        HeightmapTerrainPageSource* ps = new HeightmapTerrainPageSource();
2436        mTerrainPageSources.push_back(ps);
2437        tsm->registerPageSource("Heightmap", ps);
2438
2439        return tsm;
2440}
2441//-----------------------------------------------------------------------
2442void OcclusionCullingSceneManager::AddVisibleMeshGeometryToQueue(
2443                                                const GtpVisibility::MeshInfoContainer &visibleGeometry,
2444                                                Camera *cam)
2445{
2446        GtpVisibility::MeshInfoContainer::const_iterator geomIt, geomIt_end = visibleGeometry.end();
2447
2448        for (geomIt = visibleGeometry.begin(); geomIt != geomIt_end; ++geomIt)
2449        {
2450                MovableObject *mo = (*geomIt).GetSource();
2451
2452                // add if not 0
2453                if (!(*geomIt).GetVisiblePixels())
2454                        continue;
2455
2456                mo->_notifyCurrentCamera(cam);
2457
2458                if (mo->isVisible())
2459                {
2460                        mo->_updateRenderQueue(getRenderQueue());
2461                }
2462        }
2463}
2464//-----------------------------------------------------------------------
2465void OcclusionCullingSceneManager::AddVisibleNodeGeometryToQueue(
2466                                                const GtpVisibility::NodeInfoContainer &visibleNodes,
2467                                                Camera *cam)
2468{
2469        ////////////////
2470        //-- apply queries on node level
2471
2472        GtpVisibility::NodeInfoContainer::const_iterator nodesIt, nodesIt_end = visibleNodes.end();
2473
2474        for (nodesIt = visibleNodes.begin(); nodesIt != nodesIt_end; ++ nodesIt)
2475        {
2476                if (!(*nodesIt).GetVisiblePixels())
2477                        continue;
2478
2479                Octree *octree = static_cast<Octree *>((*nodesIt).GetSource());
2480
2481                NodeList::iterator nIt, nIt_end = octree->mNodes.end();
2482
2483                for (nIt = octree->mNodes.begin(); nIt != nIt_end; ++ nIt)
2484                {
2485                        (*nIt)->_addToRenderQueue(cam, getRenderQueue(), false);
2486                }
2487        }
2488}
2489//-----------------------------------------------------------------------
2490void OcclusionCullingSceneManager::_findVisibleObjects(Camera* cam,
2491                                                                                                           bool onlyShadowCasters)                                                                               
2492{
2493        if (mNormalExecution || (!mUseVisibilityQueries == 0))
2494        {
2495                TerrainSceneManager::_findVisibleObjects(cam, onlyShadowCasters);
2496                return;
2497        }
2498
2499        // don't need shading, render only depth
2500        // note:have to disable deph write for nodes!
2501    bool savedUseDepthPass = mUseDepthPass;
2502        if (mResetMaterialForQueries) mUseDepthPass = true;
2503
2504        // lists only used for visualization
2505        getRenderQueue()->clear();
2506        mVisible.clear();
2507        mBoxes.clear();
2508
2509        const int itemBufferMode = 0;
2510        const bool relativeVisibility = false;
2511        bool approximateVisibility = false;
2512
2513        int queryModes = 0;
2514
2515        if (mQueryMode != 0)
2516        {
2517                queryModes |= GtpVisibility::QueryManager::NODE_VISIBILITY;
2518
2519                if (mQueryMode == 2)
2520                {
2521                        approximateVisibility = true;
2522                }
2523        }
2524        else
2525        {
2526                queryModes |= GtpVisibility::QueryManager::GEOMETRY_VISIBILITY;
2527        }       
2528                       
2529
2530        OcclusionQueriesQueryManager *queryManager =
2531                new OcclusionQueriesQueryManager(mHierarchyInterface,
2532                                                                                 cam->getViewport(),
2533                                                                                 //mCurrentViewport,
2534                                                                                 queryModes,
2535                                                                                 itemBufferMode);
2536
2537        mVisibilityManager->SetQueryManager(queryManager);
2538
2539        GtpVisibility::NodeInfoContainer visibleNodes;
2540        GtpVisibility::MeshInfoContainer visibleGeometry;
2541        GtpVisibility::PatchInfoContainer visiblePatches;
2542
2543        if (mUseFromPointQueries)
2544        {
2545                queryManager->ComputeFromPointVisibility(cam->getDerivedPosition(),
2546                                                                                                 &visibleNodes,
2547                                                                                                 &visibleGeometry,
2548                                                                                                 &visiblePatches,
2549                                                                                                 relativeVisibility,
2550                                                                                                 approximateVisibility);
2551        }
2552        else
2553        {
2554                queryManager->ComputeCameraVisibility(*cam,
2555                                                                                          &visibleNodes,
2556                                                                                          &visibleGeometry,
2557                                                                                          &visiblePatches,
2558                                                                                          relativeVisibility,
2559                                                                                          approximateVisibility);
2560        }
2561               
2562        if (0)
2563        {
2564                std::stringstream d;
2565                d << "Query mode: " << queryModes
2566                  << " visible nodes: " << (int)visibleNodes.size()
2567                  << " visible geometry: " << (int)visibleGeometry.size();
2568
2569                LogManager::getSingleton().logMessage(d.str());
2570        }
2571
2572        ///////////////////////
2573        //-- put items in render queue
2574       
2575        if (mQueryMode != EXACT_QUERIES)
2576        {
2577                ////////////
2578                //-- apply queries on geometry level
2579
2580                AddVisibleNodeGeometryToQueue(visibleNodes, cam);
2581        }
2582        else
2583        {
2584                AddVisibleMeshGeometryToQueue(visibleGeometry, cam);
2585        }
2586
2587        // reset depth pass
2588        mUseDepthPass = savedUseDepthPass;
2589
2590        delete queryManager;
2591}
2592
2593//-----------------------------------------------------------------------
2594void OcclusionCullingSceneManagerFactory::destroyInstance(SceneManager* instance)
2595{
2596        delete instance;
2597}
2598
2599} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.