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

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