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

Revision 2555, 74.4 KB checked in by mattausch, 17 years ago (diff)

added partial implementation of chc++. problem: bounding box rendering in Ogre is VERY slow

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