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

Revision 2130, 53.4 KB checked in by mattausch, 17 years ago (diff)

runs also under debug mode now

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>
[828]14#include "VspBspTree.h"
[863]15#include "Containers.h"
16#include "ViewCellsManager.h"
[903]17#include <OgreConfigFile.h>
18#include "OgreTypeConverter.h"
19#include "OgreMeshInstance.h"
20#include "common.h"
[931]21#include "OgreBoundingBoxConverter.h"
[1593]22#include <OgreManualObject.h>
[1616]23#include "IntersectableWrapper.h"
[1816]24#include "IVReader.h"
[2119]25#include "ObjReader.h"
[675]26
[1816]27
[2119]28
[675]29namespace Ogre {
30
31//-----------------------------------------------------------------------
[2066]32OcclusionCullingSceneManager::OcclusionCullingSceneManager(
33                                                                const String& name,
34                                                                GtpVisibility::VisibilityManager *visManager):
[897]35TerrainSceneManager(name),
[675]36mVisibilityManager(visManager),
37mShowVisualization(false),
38mRenderNodesForViz(false),
39mRenderNodesContentForViz(false),
40mVisualizeCulledNodes(false),
41mLeavePassesInQueue(0),
42mDelayRenderTransparents(true),
43mUseDepthPass(false),
44mIsDepthPassPhase(false),
45mUseItemBuffer(false),
46mIsItemBufferPhase(false),
47mCurrentEntityId(1),
48mEnableDepthWrite(true),
49mSkipTransparents(false),
50mRenderTransparentsForItemBuffer(true),
[925]51mExecuteVertexProgramForAllPasses(false),
[903]52mIsHierarchicalCulling(false),
53mViewCellsLoaded(false),
54mUseViewCells(false),
55mUseVisibilityFilter(false),
56mCurrentViewCell(NULL),
[1251]57mElementaryViewCell(NULL),
[1276]58mDeleteQueueAfterRendering(true),
[1606]59mNormalExecution(false),
[1616]60mShowViewCells(false),
[1816]61mViewCellsGeometryLoaded(false),
[1823]62mShowTerrain(false),
63mViewCellsFilename(""),
64mFilename("terrain")
[675]65{
[1816]66        Ogre::LogManager::getSingleton().
67                logMessage("creating occlusion culling scene manager");
[1264]68
[675]69        mHierarchyInterface = new OctreeHierarchyInterface(this, mDestRenderSystem);
70       
[868]71        if (0)
72        {
[925]73                mDisplayNodes = true;
74                mShowBoundingBoxes = true;
75                mShowBoxes = true;
[868]76        }
77
[675]78        // TODO: set maxdepth to reasonable value
79        mMaxDepth = 50;
[2123]80
81        mObjReader = new ObjReader(this);
[675]82}
83//-----------------------------------------------------------------------
[720]84void OcclusionCullingSceneManager::InitDepthPass()
[675]85{
[1610]86        MaterialPtr depthMat =
87                MaterialManager::getSingleton().getByName("Visibility/DepthPass");
[675]88
89        if (depthMat.isNull())
90    {
91                depthMat = MaterialManager::getSingleton().create(
92                "Visibility/DepthPass",
93                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
94
95        mDepthPass = depthMat->getTechnique(0)->getPass(0);
96                mDepthPass->setColourWriteEnabled(false);
97                mDepthPass->setDepthWriteEnabled(true);
98                mDepthPass->setLightingEnabled(false);
99        }
100        else
101        {
102                mDepthPass = depthMat->getTechnique(0)->getPass(0);
103        }
104}
105//-----------------------------------------------------------------------
[720]106OcclusionCullingSceneManager::~OcclusionCullingSceneManager()
[675]107{
108        OGRE_DELETE(mHierarchyInterface);
[903]109        CLEAR_CONTAINER(mObjects);
110        OGRE_DELETE(mCurrentViewCell);
[2123]111
112        OGRE_DELETE(mObjReader);
[675]113}
114//-----------------------------------------------------------------------
[720]115void OcclusionCullingSceneManager::InitItemBufferPass()
[675]116{
117        MaterialPtr itemBufferMat = MaterialManager::getSingleton().
118                getByName("Visibility/ItemBufferPass");
119
120        if (itemBufferMat.isNull())
121    {
122                // Init
[1610]123                itemBufferMat =
124                        MaterialManager::getSingleton().create("Visibility/ItemBufferPass",
[675]125                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
126
127                mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0);
128                mItemBufferPass->setColourWriteEnabled(true);
129                mItemBufferPass->setDepthWriteEnabled(true);
130                mItemBufferPass->setLightingEnabled(true);
131                //mItemBufferPass->setLightingEnabled(false);
132        }
133        else
134        {
135                mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0);
136        }
137        //mItemBufferPass->setAmbient(1, 1, 0);
138}
[897]139//-------------------------------------------------------------------------
[925]140#if 1
[1816]141void OcclusionCullingSceneManager::setWorldGeometry(DataStreamPtr& stream,
142                                                                                                        const String& typeName)
[897]143{
[2097]144        // Clear out any existing world resources (if not default)
[897]145    if (ResourceGroupManager::getSingleton().getWorldResourceGroupName() !=
146        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME)
147    {
148        ResourceGroupManager::getSingleton().clearResourceGroup(
149            ResourceGroupManager::getSingleton().getWorldResourceGroupName());
150    }
[1610]151       
[897]152        destroyLevelIndexes();
153    mTerrainPages.clear();
[1610]154
[897]155    // Load the configuration
[938]156    loadConfig(stream);
[897]157
[2097]158        //////////////
159        // file loading
[1823]160
[2097]161        // load the scene
[2119]162        LoadScene(mFilename, mViewCellsFilename);
[2097]163       
[2119]164        // load view cells: load later ...
165        if (0) mViewCellsLoaded = LoadViewCells(mViewCellsFilename);
[1823]166
[1816]167        if (mShowTerrain)
[1823]168        {       
[1816]169                initLevelIndexes();
[897]170
[1816]171                // Resize the octree, allow for 1 page for now
172                float max_x = mOptions.scale.x * mOptions.pageSize;
[1823]173                float max_y = mOptions.scale.y;// * mOptions.pageSize;
[1816]174                float max_z = mOptions.scale.z * mOptions.pageSize;
175
176                float maxAxis = std::max(max_x, max_y);
177                maxAxis = std::max(maxAxis, max_z);
[2130]178                resize(AxisAlignedBox( 0, 0, 0, maxAxis, maxAxis, maxAxis));
179                //resize(AxisAlignedBox( 0, 0, 0, max_x, max_y, max_z ));
[1823]180
[1816]181                setupTerrainMaterial();
182                setupTerrainPages();
[1823]183        }       
[897]184 }
[925]185#endif
[2097]186
[1816]187//-------------------------------------------------------------------------
188void OcclusionCullingSceneManager::loadConfig(DataStreamPtr& stream)
189{
[1823]190        // Set up the options
[1816]191        ConfigFile config;
192        String val;
193
194        config.load(stream);
195
196        std::stringstream d;
[1823]197               
198        val = config.getSetting("DepthPass");
[1816]199
200    if (!val.empty())
201        {
[1823]202                mUseDepthPass = atoi(val.c_str());
[1816]203        }
204
[1823]205        val = config.getSetting("FlushQueue");
206       
[1816]207        if (!val.empty())
208        {
[1823]209                mDeleteQueueAfterRendering = atoi(val.c_str());
210        }
[1816]211
[1823]212        val = config.getSetting("Scene");
213
214    if (!val.empty())
215        {
216                mFilename = val.c_str();
217               
[2102]218                // load terrain instead of scene
[1823]219                if (mFilename == "terrain")
220                {
221                        mShowTerrain = true;
[2097]222                        LogManager::getSingleton().logMessage("loading terrain");
[1823]223                }
[2108]224                else
225                {
226                        mShowTerrain = false;
227                        LogManager::getSingleton().logMessage("loading geometry");
228                }
[1816]229        }
[1823]230
231        if (!mShowTerrain)
232        {
233                val = config.getSetting("ViewCells");
234
235                if (!val.empty())
236                {
[2097]237                        mViewCellsFilename = val;
[1823]238                }
239        }
[2097]240
[1816]241        val = config.getSetting("OnlineCullingAlgorithm");
242               
243        if (!val.empty())
244        {
245                GtpVisibility::VisibilityEnvironment::CullingManagerType algorithm;
246
247                if (val == "CHC")
248                {
249                        algorithm =
250                                GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING;
251                }
252                else if (val == "SWC")
253                {
254                         algorithm =
255                                 GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING;
256                 }
257                 else if (val == "VFC")
258                 {
259                         algorithm =
260                                 GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING;
261                 }
262                 else // default rendering
263                 {
264                         algorithm =
265                                 GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS;
[1823]266
267                         mNormalExecution = true;
[1816]268                 }
269
270                 mVisibilityManager->SetCullingManager(algorithm);
[1823]271
272                 d << "setting algorithm to: " << algorithm;
273                 LogManager::getSingleton().logMessage(d.str());
[1816]274        }
275
[2097]276        /////////////
[1823]277        // terrain options
278
279        if (!mShowTerrain)
280                return;
281
[2097]282        val = config.getSetting("DetailTile");
283        if (!val.empty())
[1823]284                setDetailTextureRepeat(atoi(val.c_str()));
285
[2097]286        val = config.getSetting("MaxMipMapLevel");
287        if (!val.empty())
288                setMaxGeoMipMapLevel(atoi(val.c_str()));
[1823]289
290
[2097]291        val = config.getSetting("PageSize");
292        if (!val.empty())
293                setPageSize(atoi(val.c_str()));
[1823]294        else
295                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing option 'PageSize'",
296                "TerrainSceneManager::loadConfig");
297
298
[2097]299        val = config.getSetting("TileSize");
300        if (!val.empty())
301                setTileSize(atoi(val.c_str()));
[1823]302        else
303                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing option 'TileSize'",
304                "TerrainSceneManager::loadConfig");
305
306        Vector3 v = Vector3::UNIT_SCALE;
307
308        val = config.getSetting( "PageWorldX" );
309        if ( !val.empty() )
310                v.x = atof( val.c_str() );
311
312        val = config.getSetting( "MaxHeight" );
313        if ( !val.empty() )
314                v.y = atof( val.c_str() );
315
316        val = config.getSetting( "PageWorldZ" );
317        if ( !val.empty() )
318                v.z = atof( val.c_str() );
319
320        // Scale x/z relative to pagesize
321        v.x /= mOptions.pageSize;
322        v.z /= mOptions.pageSize;
323        setScale(v);
324
325        val = config.getSetting( "MaxPixelError" );
326        if ( !val.empty() )
327                setMaxPixelError(atoi( val.c_str() ));
328
329        mDetailTextureName = config.getSetting( "DetailTexture" );
330
331        mWorldTextureName = config.getSetting( "WorldTexture" );
332
333        if ( config.getSetting( "VertexColours" ) == "yes" )
334                mOptions.coloured = true;
335
336        if ( config.getSetting( "VertexNormals" ) == "yes" )
337                mOptions.lit = true;
338
339        if ( config.getSetting( "UseTriStrips" ) == "yes" )
340                setUseTriStrips(true);
341
342        if ( config.getSetting( "VertexProgramMorph" ) == "yes" )
343                setUseLODMorph(true);
344
345        val = config.getSetting( "LODMorphStart");
346        if ( !val.empty() )
347                setLODMorphStart(atof(val.c_str()));
348
349        val = config.getSetting( "CustomMaterialName" );
350        if ( !val.empty() )
351                setCustomMaterial(val);
352
353        val = config.getSetting( "MorphLODFactorParamName" );
354        if ( !val.empty() )
355                setCustomMaterialMorphFactorParam(val);
356
357        val = config.getSetting( "MorphLODFactorParamIndex" );
358        if ( !val.empty() )
359                setCustomMaterialMorphFactorParam(atoi(val.c_str()));
360
361        // Now scan through the remaining settings, looking for any PageSource
362        // prefixed items
363        String pageSourceName = config.getSetting("PageSource");
364        if (pageSourceName == "")
[1816]365        {
[1823]366                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Missing option 'PageSource'",
367                        "TerrainSceneManager::loadConfig");
[1816]368        }
[2108]369
[1823]370        TerrainPageSourceOptionList optlist;
371        ConfigFile::SettingsIterator setIt = config.getSettingsIterator();
372        while (setIt.hasMoreElements())
373        {
374                String name = setIt.peekNextKey();
375                String value = setIt.getNext();
376                if (StringUtil::startsWith(name, pageSourceName, false))
377                {
378                        optlist.push_back(TerrainPageSourceOption(name, value));
379                }
380        }
[2108]381
[1823]382        // set the page source
383        selectPageSource(pageSourceName, optlist);
[1816]384}
[2123]385
386
387void OcclusionCullingSceneManager::MailPvsObjects()
388{
389        GtpVisibilityPreprocessor::ObjectPvsIterator pit =
390                        mCurrentViewCell->GetPvs().GetIterator();
391
392        while (pit.HasMoreEntries())
393        {               
394                GtpVisibilityPreprocessor::Intersectable *obj = pit.Next();
395
396                if (obj->Type() !=
397                        GtpVisibilityPreprocessor::Intersectable::ENGINE_INTERSECTABLE)
398                        continue;
399                       
400                EngineIntersectable *oi = static_cast<EngineIntersectable *>(obj);
401
402                EntityContainer *entries = oi->GetItem();
403                EntityContainer::const_iterator eit, eit_end = entries->end();
404
405                for (eit = entries->begin(); eit != eit_end; ++ eit)
406                {
407                        (*eit)->setUserAny(Any((int)0));
408                }
409        }
410}
[675]411//-----------------------------------------------------------------------
[2123]412void OcclusionCullingSceneManager::ShowViewCellsGeometry()
413{/*
414        // show only current view cell
415        if (!mShowViewCells)
416        {
417                const int id = mCurrentViewCell->GetId();
418
419                MovableMap::iterator fit = mViewCellsGeometry.find(id);
420
421                if ((fit != mViewCellsGeometry.end()) && (*fit).second)
422                        (*fit).second->_updateRenderQueue(getRenderQueue());
423        }
424        else
425        {
426                MovableMap::const_iterator mit, mit_end = mViewCellsGeometry.end();
427
428                for (mit = mViewCellsGeometry.begin(); mit != mit_end; ++ mit)
429                {
430                        if ((*mit).second)
431                                (*mit).second->_updateRenderQueue(getRenderQueue());
432                }       
433        }*/
434}
435
436
437void OcclusionCullingSceneManager::RenderPvsEntry(GtpVisibilityPreprocessor::Intersectable *obj)
438{
439        switch (obj->Type())
440        {       
441                case GtpVisibilityPreprocessor::Intersectable::OGRE_MESH_INSTANCE:
442                        {
443                                OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(obj);
444                                omi->GetEntity()->_updateRenderQueue(getRenderQueue());
445                        }
446                        break;
447
448                case GtpVisibilityPreprocessor::Intersectable::ENGINE_INTERSECTABLE:
449                        {
450                                EngineIntersectable *oi = static_cast<EngineIntersectable *>(obj);
451
452                                EntityContainer *entries = oi->GetItem();
453                                EntityContainer::const_iterator eit, eit_end = entries->end();
454
455                                for (eit = entries->begin(); eit != eit_end; ++ eit)
456                                {
457                                        Entity *ent = *eit;
458                                        // mailing hack
459                                        Any newAny = ent->getUserAny();
460                                        int flt = any_cast<int>(newAny);
461
462                                        if (any_cast<int>(newAny) == 0)
463                                        {
464                                                ent->setUserAny(Any((int)1));
465                                                ent->_updateRenderQueue(getRenderQueue());
466                                        }
467                                }
468                        }
469                        break;
470                default:
471                        break;
472        }       
473}
474//-----------------------------------------------------------------------
475void OcclusionCullingSceneManager::SetObjectVisible(GtpVisibilityPreprocessor::Intersectable *entry,
476                                                                                                        const bool visible)
477{
478        switch (entry->Type())
479        {
480        case GtpVisibilityPreprocessor::Intersectable::OGRE_MESH_INSTANCE:
481                {
482                        OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(entry);
483                        omi->GetEntity()->setVisible(visible);
484                        //GtpVisibilityPreprocessor::Debug << "assigned id " << omi->GetId() << endl;
485                }
486                break;
487        case GtpVisibilityPreprocessor::Intersectable::ENGINE_INTERSECTABLE:
488                {
489                        EngineIntersectable *oi = static_cast<EngineIntersectable *>(entry);
490
491                        EntityContainer *entries = oi->GetItem();
492                        EntityContainer::const_iterator eit, eit_end = entries->end();
493                        for (eit = entries->begin(); eit != eit_end; ++ eit)
494                        {
495                                Entity *ent = *eit;
496                                ent->setVisible(visible);
497                        }
498                }
499                break;
500        default:
501                break;
502        }
503}
504//-----------------------------------------------------------------------
[720]505void OcclusionCullingSceneManager::PrepareVisualization(Camera *cam)
[1620]506{
[675]507        // add player camera for visualization purpose
508        try
509        {
510                Camera *c;
511                if ((c = getCamera("PlayerCam")) != NULL)
512                {
513                        getRenderQueue()->addRenderable(c);
514                }   
515    }
516    catch (...)
517    {
518        // ignore
519    }
[1597]520
[868]521        // add bounding boxes of rendered objects
[944]522        if (0)
[675]523        for (BoxList::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it)
524        {
525                getRenderQueue()->addRenderable(*it);
526        }
[1618]527
[2108]528        // show current view cell geometry
[2123]529    if (mCurrentViewCell)// && mCurrentViewCell->GetMesh())
530        {
[1606]531                //const bool showSingleViewCell = true;
[1616]532                if (mViewCellsGeometryLoaded)
[1602]533                {
[2123]534                        ShowViewCellsGeometry();
[1602]535                }
[2123]536               
[1816]537                //////////
538                //-- set PVS of view cell visible
539
[2123]540                GtpVisibilityPreprocessor::ObjectPvsIterator pit =
541                        mCurrentViewCell->GetPvs().GetIterator();
[1816]542
[2123]543                MailPvsObjects();
544
[1816]545                while (pit.HasMoreEntries())
[2123]546                {
547                        RenderPvsEntry(pit.Next());
548                }       
[1593]549        }
[2123]550#if 0
[1618]551   if (mRenderNodesForViz || mRenderNodesContentForViz)
[675]552        {
553                // HACK: change node material so it is better suited for visualization
554                MaterialPtr nodeMat = MaterialManager::getSingleton().getByName("Core/NodeMaterial");
555                nodeMat->setAmbient(1, 1, 0);
556                nodeMat->setLightingEnabled(true);
557                nodeMat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
558
559                for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++it)
560                {
561                        if (mRenderNodesForViz)
562                        {
[1597]563                                // render the visible leaf nodes
[925]564                                if ((*it)->numAttachedObjects() &&
565                                        !(*it)->numChildren() &&
566                                        ((*it)->getAttachedObject(0)->getMovableType() == "Entity") &&
567                                        (*it)->getAttachedObject(0)->isVisible())
[675]568                                {
[1597]569                                        //getRenderQueue()->addRenderable((*it));
570                                        (*it)->_addToRenderQueue(cam, getRenderQueue(), false);
[675]571                                }
572
[1597]573                                // add bounding boxes instead of node itself
[1602]574                                if (0)
575                                        (*it)->_addBoundingBoxToQueue(getRenderQueue());
[675]576                        }
[1593]577
[903]578                        // add renderables itself
[1602]579                        if (mRenderNodesContentForViz)
[675]580                        {
581                                (*it)->_addToRenderQueue(cam, getRenderQueue(), false);
582                        }
583                }
[2123]584        }
585#endif
[675]586}
587//-----------------------------------------------------------------------
[1232]588const Pass *OcclusionCullingSceneManager::_setPass(const Pass* pass, bool evenIfSuppressed)
[675]589{
[1276]590        if (mNormalExecution)
[868]591        {
[897]592                return SceneManager::_setPass(pass);
[868]593        }
594
[675]595        // TODO: setting vertex program is not efficient
596        //Pass *usedPass = ((mIsDepthPassPhase && !pass->hasVertexProgram()) ? mDepthPass : pass);
597       
598        // set depth fill pass if we currently do not make an aabb occlusion query
[868]599        const bool useDepthPass =
600                (mIsDepthPassPhase && !mHierarchyInterface->IsBoundingBoxQuery());
601
[925]602        const IlluminationRenderStage savedStage = mIlluminationStage;
[675]603       
604        // set illumination stage to NONE so no shadow material is used
605        // for depth pass or for occlusion query
606        if (mIsDepthPassPhase || mHierarchyInterface->IsBoundingBoxQuery())
607        {
608                mIlluminationStage = IRS_NONE;
609        }
610       
611        // --- set vertex program of current pass in order to set correct depth
[868]612        if (mExecuteVertexProgramForAllPasses &&
613                mIsDepthPassPhase &&
614                pass->hasVertexProgram())
[675]615        {
616                // add vertex program of current pass to depth pass
617                mDepthPass->setVertexProgram(pass->getVertexProgramName());
618
619                if (mDepthPass->hasVertexProgram())
620                {
621                        const GpuProgramPtr& prg = mDepthPass->getVertexProgram();
622                        // Load this program if not done already
623                        if (!prg->isLoaded())
624                                prg->load();
625                        // Copy params
626                        mDepthPass->setVertexProgramParameters(pass->getVertexProgramParameters());
627                }
628        }
[868]629        else if (mDepthPass->hasVertexProgram()) // reset vertex program
[675]630        {
631                mDepthPass->setVertexProgram("");
632        }
633       
[1232]634        const Pass *usedPass = useDepthPass ? mDepthPass : pass;
635
[868]636        // save old depth write: needed for item buffer
637        const bool IsDepthWrite = usedPass->getDepthWriteEnabled();
[675]638
639        // global option which enables / disables depth writes
640        if (!mEnableDepthWrite)
641        {
[1232]642                //usedPass->setDepthWriteEnabled(false);
[675]643        }
644        //else if (mIsItemBufferPass) {usedPass = mItemBufferPass;}
[868]645
646        //-- set actual pass here
[897]647        const Pass *result = SceneManager::_setPass(usedPass);
[675]648
[868]649
[675]650        // reset depth write
651        if (!mEnableDepthWrite)
652        {
[1232]653                //usedPass->setDepthWriteEnabled(IsDepthWrite);
[675]654        }
655
656        // reset illumination stage
657        mIlluminationStage = savedStage;
658
659        return result;
660}
661//-----------------------------------------------------------------------
[897]662void OcclusionCullingSceneManager::_findVisibleObjects(Camera* cam,
663                                                                                                                bool onlyShadowCasters)
[675]664{
665        if (mShowVisualization)
666    {
[1593]667                //////////////
668                //-- show visible scene nodes and octree bounding boxes from last frame
[675]669                PrepareVisualization(cam);
670        }
671        else
672        {       
[1597]673                // hierarchical culling interleaves identification
[675]674                // and rendering of objects in _renderVisibibleObjects
675
676                // for the shadow pass we use only standard rendering
[1597]677                // because shadows have low occlusion snyway
[675]678                if (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE &&
679                        mIlluminationStage == IRS_RENDER_TO_TEXTURE)
680                {
[868]681                        OctreeSceneManager::_findVisibleObjects(cam, onlyShadowCasters);
[675]682                }
[903]683
[675]684                // only shadow casters will be rendered in shadow texture pass
[868]685                if (0) mHierarchyInterface->SetOnlyShadowCasters(onlyShadowCasters);
[1602]686
687                ///////////
688                //-- set visibility according to pvs of current view cell
689
690                UpdatePvs(cam);
691
692                if (mNormalExecution)
693                {
694                        OctreeSceneManager::_findVisibleObjects(cam, onlyShadowCasters);
695                        //return;
696                }
[675]697        }
[1593]698               
[1264]699        // lists only used for visualization
[675]700        mVisible.clear();
701        mBoxes.clear();
702}
703//-----------------------------------------------------------------------
[720]704void OcclusionCullingSceneManager::_renderVisibleObjects()
[675]705{
[2122]706        // $$matt temp: Remove this!!
[2123]707        if (0)
[2122]708        {
709                getDestinationRenderSystem()->_setCullingMode(CULL_NONE);
[2123]710                //LogManager::getSingleton().logMessage("warning: culling mode");
[2122]711        }
712
[1276]713        if (mNormalExecution)
[868]714        {
[1593]715                // the standard octree rendering mode
[1602]716                TerrainSceneManager::_renderVisibleObjects();
[1610]717                getRenderQueue()->clear(mDeleteQueueAfterRendering);
[868]718                return;
719        }
720
[675]721        InitDepthPass();          // create material for depth pass
722        InitItemBufferPass(); // create material for item buffer pass
723
724        // save ambient light to reset later
725        ColourValue savedAmbient = mAmbientLight;
726
[1593]727        ////////////////////
728        //-- apply standard rendering for some modes
729        //-- (e.g., the visualization mode, the shadow pass)
[675]730
[1823]731        if (mShowVisualization ||
732            (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE &&
733             mIlluminationStage == IRS_RENDER_TO_TEXTURE))
[675]734        {       
735                IlluminationRenderStage savedStage = mIlluminationStage;
736       
737                if (mShowVisualization)
[868]738                {
[675]739                        // disable illumination stage to prevent rendering shadows
740                        mIlluminationStage = IRS_NONE;
[868]741                }
[675]742
743                // standard rendering for shadow maps because of performance
744                TerrainSceneManager::_renderVisibleObjects();
745
746                mIlluminationStage = savedStage;
747        }
748        else //-- the hierarchical culling algorithm
749        {
[1251]750                // note matt: this is also called in TerrainSceneManager: really necessary?
[868]751                mDestRenderSystem -> setLightingEnabled(false);
752
[675]753                if (mUseItemBuffer)
754                {
[1593]755                        // don't render backgrounds for item buffer
[675]756                        clearSpecialCaseRenderQueues();
757                        getRenderQueue()->clear();
758                }
759
[1593]760                ////////////////////
[675]761                //-- hierarchical culling
[1593]762
[675]763                // the objects of different layers (e.g., background, scene,
764                // overlay) must be identified and rendered one after another
765
[1593]766                // first render all early skies
[675]767                clearSpecialCaseRenderQueues();
768                addSpecialCaseRenderQueue(RENDER_QUEUE_BACKGROUND);
769                addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_EARLY);
770                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE);
771
772                TerrainSceneManager::_renderVisibleObjects();
773
774#ifdef GTP_VISIBILITY_MODIFIED_OGRE
775                // delete previously rendered content
776                _deleteRenderedQueueGroups();
777#endif
778
[1593]779                ///////////////////
[675]780                //-- prepare queue for visible objects (i.e., all but overlay and skies late)
[1593]781
[675]782                clearSpecialCaseRenderQueues();
783                addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_LATE);
784                addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY);
[897]785       
[675]786                // exclude this queues from hierarchical rendering
787                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE);
788
789                // set all necessary parameters for
790                // hierarchical visibility culling and rendering
791                InitVisibilityCulling(mCameraInProgress);
792
[897]793
[675]794                /**
795                * the hierarchical culling algorithm
796                * for depth pass: we just find objects and update depth buffer
797                * for "delayed" rendering: we render some passes afterwards
798                * e.g., transparents, because they need front-to-back sorting
799                **/
800               
801                mVisibilityManager->ApplyVisibilityCulling();
802
[868]803                // delete remaining renderables from queue:
804                // all which are not in mLeavePassesInQueue)
[675]805#ifdef GTP_VISIBILITY_MODIFIED_OGRE
806                _deleteRenderedQueueGroups(mLeavePassesInQueue);
807#endif
808
[1593]809                /////////////
[1251]810                //-- reset parameters needed for special rendering
811               
[675]812                mIsDepthPassPhase = false;
813                mIsItemBufferPhase = false;
814                mSkipTransparents = false;
[868]815                mIsHierarchicalCulling = false;
816               
[675]817                mLeavePassesInQueue = 0;
[897]818               
[1823]819                 // the shaded geometry is rendered in a second pass
820                if (mUseDepthPass)
[675]821                {
[1593]822                        // add visible nodes found by the visibility culling algorithm
[868]823                        NodeList::const_iterator it, it_end = mVisible.end();
824
825                        //getRenderQueue()->clear();
826                        for (it = mVisible.begin(); it != it_end; ++ it)
[675]827                        {
828                                (*it)->_addToRenderQueue(mCameraInProgress, getRenderQueue(), false);
829                        }
830                }
[1602]831               
[1593]832                /////////////
[675]833                //-- now we can render all remaining queue objects
[868]834                //-- used for depth pass, transparents, overlay
[675]835
[1597]836        clearSpecialCaseRenderQueues();
837
[675]838                TerrainSceneManager::_renderVisibleObjects();
[1251]839        } // end hierarchical culling
[675]840               
841        // HACK: set the new render level index, important to avoid cracks
842        // in terrain caused by LOD
843        TerrainRenderable::NextRenderLevelIndex();
844       
845        // reset ambient light
846        setAmbientLight(savedAmbient);
847
[1304]848        // almost same effect as below
849        getRenderQueue()->clear(mDeleteQueueAfterRendering);
[1251]850
[1267]851        if (0) WriteLog(); // write out stats
[675]852}
853
854//-----------------------------------------------------------------------
[720]855void OcclusionCullingSceneManager::_updateSceneGraph(Camera* cam)
[675]856{
[1276]857        if (mNormalExecution)
[868]858        {
859                OctreeSceneManager::_updateSceneGraph(cam);
860                return;
861        }
862
[675]863        mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface);
864        mHierarchyInterface->SetRenderSystem(mDestRenderSystem);
865
866        TerrainSceneManager::_updateSceneGraph(cam);
867}
868//-----------------------------------------------------------------------
[720]869bool OcclusionCullingSceneManager::setOption(const String & key, const void * val)
[675]870{
871        if (key == "UseDepthPass")
872        {
873                mUseDepthPass = (*static_cast<const bool *>(val));
874                return true;
875        }
876        if (key == "PrepareVisualization")
877        {
878                mShowVisualization = (*static_cast<const bool *>(val));
879                return true;
880        }
881        if (key == "RenderNodesForViz")
882        {
883                mRenderNodesForViz = (*static_cast<const bool *>(val));
884                return true;
885        }
886        if (key == "RenderNodesContentForViz")
887        {
888                mRenderNodesContentForViz = (*static_cast<const bool *>(val));
889                return true;
890        }
891        if (key == "SkyBoxEnabled")
892        {
893                mSkyBoxEnabled = (*static_cast<const bool *>(val));
894                return true;
895        }
896        if (key == "SkyPlaneEnabled")
897        {
898                mSkyPlaneEnabled = (*static_cast<const bool *>(val));
899                return true;
900        }
901        if (key == "SkyDomeEnabled")
902        {
903                mSkyDomeEnabled = (*static_cast<const bool *>(val));
904                return true;
905        }
906        if (key == "VisualizeCulledNodes")
907        {
908                mVisualizeCulledNodes = (*static_cast<const bool *>(val));
909                return true;
910        }
911        if (key == "DelayRenderTransparents")
912        {
[2122]913                //LoadScene(mFilename, mViewCellsFilename);
[675]914                mDelayRenderTransparents = (*static_cast<const bool *>(val));
915                return true;
916        }
917        if (key == "DepthWrite")
918        {
919                mEnableDepthWrite = (*static_cast<const bool *>(val));
920                return true;
921        }
922        if (key == "UseItemBuffer")
923        {
924                mUseItemBuffer = (*static_cast<const bool *>(val));
925                return true;
926        }
927        if (key == "ExecuteVertexProgramForAllPasses")
928        {
929                mExecuteVertexProgramForAllPasses  = (*static_cast<const bool *>(val));
930                return true;
931        }
932        if (key == "RenderTransparentsForItemBuffer")
933        {
934                mRenderTransparentsForItemBuffer  = (*static_cast<const bool *>(val));
935                return true;
936        }
[1296]937        else if (key == "DeleteRenderQueue")
938        {
939                mDeleteQueueAfterRendering = (*static_cast<const bool *>(val));
940                return true;
941        }
[675]942        if (key == "NodeVizScale")
943        {
944                OctreeNode::setVizScale(*static_cast<const float *>(val));
945                return true;
946        }
[903]947        if (key == "UseViewCells")
[2097]948        {       
949                if (!mViewCellsLoaded)
[938]950                {
[2102]951                        // try to load view cells
[2097]952                        mViewCellsLoaded = LoadViewCells(mViewCellsFilename);   
953                }
[903]954
[2097]955                if (!mViewCellsLoaded)
956                        return false;
957               
958                // only use this option if view cells are available
959                mUseViewCells = *static_cast<const bool *>(val);
960
961                // reset view cell
962                OGRE_DELETE(mCurrentViewCell);
[1595]963                       
[2097]964                if (mUseViewCells)
965                {
966                        mCurrentViewCell = mViewCellsManager->GenerateViewCell();
967                }
968               
969                // view cell corresponding to leaf in the view cell hierarchy
970                mElementaryViewCell = NULL;
[938]971
[2108]972                // all objects are set to invisible per default
[2097]973                SetObjectsVisible(!mUseViewCells);
[1616]974
[2097]975                MovableObjectIterator movit = getMovableObjectIterator("Entity");
976                while (movit.hasMoreElements())
977                {
978                        Entity *ent = static_cast<Entity *>(movit.getNext());
979                        ent->setVisible(!mUseViewCells);
[938]980                }
[2097]981               
[903]982                return true;
983        }
[1602]984        if (key == "ShowViewCells")
985        {
986                // only use this option if view cells are available
987                if (mViewCellsLoaded)
988                {
[1606]989                        mShowViewCells = *static_cast<const bool *>(val);
[1602]990                        // if we decide use view cells
991                        // all objects are set to invisible per default
[1606]992                        VisualizeViewCells(mShowViewCells);
[1602]993                }
994
995                return true;
996        }
[1276]997        if (key == "NormalExecution")
998        {
999                mNormalExecution = *static_cast<const bool *>(val);
1000                return true;
1001        }
[2108]1002        if (key == "ShowTerrain")
1003        {
1004                mShowTerrain = *static_cast<const bool *>(val);
1005                return true;
1006        }
[903]1007        if (key == "UseVisibilityFilter")
[675]1008        {
[903]1009                mUseVisibilityFilter = *static_cast<const bool *>(val);
[1823]1010
1011                // set null => recomputation of the pvs
[903]1012        mElementaryViewCell = NULL;
[2108]1013
[903]1014                return true;
1015        }
[1823]1016        if (key == "ViewCellsLoaded")
1017        {
1018                return mViewCellsLoaded;
1019        }
[675]1020
1021        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
1022                setOption(key, val) || TerrainSceneManager::setOption(key, val);
1023}
1024//-----------------------------------------------------------------------
[1816]1025bool OcclusionCullingSceneManager::getOption(const String &key, void *val)
[675]1026{
1027        if (key == "NumHierarchyNodes")
1028        {
1029                * static_cast<unsigned int *>(val) = (unsigned int)mNumOctants;
1030                return true;
1031        }
[925]1032        if (key == "VisibilityManager")
1033        {
1034                * static_cast<GtpVisibility::VisibilityManager **>(val) =
1035                        (GtpVisibility::VisibilityManager *)mVisibilityManager;
1036                return true;
1037        }
1038        if (key == "HierarchInterface")
1039        {
1040                * static_cast<GtpVisibility::HierarchyInterface **>(val) =
1041                        (GtpVisibility::HierarchyInterface *)mHierarchyInterface;
1042                return true;
1043        }
[1816]1044        if (key == "ShowTerrain")
1045        {
1046                * static_cast<bool *>(val) = (bool *)mShowTerrain;
1047                return true;
1048        }
[1823]1049        if (key == "UseDepthPass")
1050        {
1051                * static_cast<bool *>(val) = (bool *)mUseDepthPass;
1052                return true;
1053        }
[2108]1054        if (key == "NormalExecution")
[1823]1055        {
[2108]1056                * static_cast<bool *>(val) = (bool *)mNormalExecution;
1057                return true;
1058        }
1059        if (key == "Algorithm")
1060        {
[1823]1061                GtpVisibility::VisibilityEnvironment::CullingManagerType algorithm =
1062                        mVisibilityManager->GetCullingManagerType();
[925]1063
[1823]1064                * static_cast<unsigned int *>(val) =
1065                        (unsigned int)algorithm;
1066                return true;
1067        }
1068
[675]1069        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
1070                getOption(key, val) && TerrainSceneManager::getOption(key, val);
1071}
1072//-----------------------------------------------------------------------
[720]1073bool OcclusionCullingSceneManager::getOptionValues(const String & key,
[675]1074                                                                                                        StringVector &refValueList)
1075{
1076        return TerrainSceneManager::getOptionValues( key, refValueList);
1077}
1078//-----------------------------------------------------------------------
[720]1079bool OcclusionCullingSceneManager::getOptionKeys(StringVector & refKeys)
[675]1080{
1081        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
1082                getOptionKeys(refKeys) || TerrainSceneManager::getOptionKeys(refKeys);
1083}
1084//-----------------------------------------------------------------------
[720]1085void OcclusionCullingSceneManager::setVisibilityManager(GtpVisibility::
[675]1086                                                                                                                 VisibilityManager *visManager)
1087{
1088        mVisibilityManager = visManager;
1089}
1090//-----------------------------------------------------------------------
[720]1091GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::getVisibilityManager( void )
[675]1092{
1093        return mVisibilityManager;
1094}
1095//-----------------------------------------------------------------------
[720]1096void OcclusionCullingSceneManager::WriteLog()
[675]1097{
1098        std::stringstream d;
1099
1100        d << "Depth pass: " << StringConverter::toString(mUseDepthPass) << ", "
1101          << "Delay transparents: " << StringConverter::toString(mDelayRenderTransparents) << ", "
1102          << "Use optimization: " << StringConverter::toString(mHierarchyInterface->GetTestGeometryForVisibleLeaves()) << ", "
1103          << "Algorithm type: " << mVisibilityManager->GetCullingManagerType() << ", "
1104          << "Hierarchy nodes: " << mNumOctants << ", "
1105          << "Traversed nodes: " << mHierarchyInterface->GetNumTraversedNodes() << ", "
1106          << "Rendered nodes: " << mHierarchyInterface->GetNumRenderedNodes() << ", "
1107          << "Query culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumQueryCulledNodes() << ", "
1108          << "Frustum culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumFrustumCulledNodes() << ", "
[868]1109      << "Queries issued: " << mVisibilityManager->GetCullingManager()->GetNumQueriesIssued() << ", "
1110          << "Found objects: " << (int)mVisible.size() << "\n";
[675]1111
1112        LogManager::getSingleton().logMessage(d.str());
1113}
1114//-----------------------------------------------------------------------
[925]1115void OcclusionCullingSceneManager::renderBasicQueueGroupObjects(RenderQueueGroup* pGroup,
1116                                                                                                                                QueuedRenderableCollection::OrganisationMode om)
[675]1117{
[925]1118    // Basic render loop
1119    // Iterate through priorities
1120    RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
1121
1122    while (groupIt.hasMoreElements())
1123    {
1124        RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
1125
1126        // Sort the queue first
1127        pPriorityGrp->sort(mCameraInProgress);
1128
1129        // Do solids
1130        renderObjects(pPriorityGrp->getSolidsBasic(), om, true);
1131
[1593]1132                // for correct rendering, transparents must be rendered
1133                // after hierarchical culling => don't render them now
[925]1134
[1593]1135        if (mNormalExecution || !mSkipTransparents)
[925]1136                {
[1593]1137                        // Do transparents (always descending)
[925]1138                        renderObjects(pPriorityGrp->getTransparents(),
[1597]1139                                QueuedRenderableCollection::OM_SORT_DESCENDING, true);
[925]1140                }
1141
1142
[1593]1143    } // for each priority
[675]1144}
[925]1145
[675]1146//-----------------------------------------------------------------------
[720]1147bool OcclusionCullingSceneManager::validatePassForRendering(Pass* pass)
[675]1148{
[1276]1149        if (mNormalExecution)
[868]1150        {
1151                return SceneManager::validatePassForRendering(pass);
1152        }
1153
[675]1154        // skip all but first pass if we are doing the depth pass
[868]1155        if ((mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() > 0))
[675]1156        {
1157                return false;
1158        }
[868]1159        // all but first pass
1160        /*else if ((!mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() != 0))
1161        {
1162                return false;
1163        }*/
[675]1164
1165        return SceneManager::validatePassForRendering(pass);
1166}
1167//-----------------------------------------------------------------------
[897]1168void OcclusionCullingSceneManager::_renderQueueGroupObjects(RenderQueueGroup* pGroup,
1169                                                                                                                        QueuedRenderableCollection::OrganisationMode om)
[675]1170{
[1276]1171        if (mNormalExecution || !mIsItemBufferPhase)
[675]1172        {
[897]1173                TerrainSceneManager::_renderQueueGroupObjects(pGroup, om);
[675]1174                return;
1175        }
[897]1176#ifdef  ITEM_BUFFER
1177        //-- item buffer
[1622]1178        //-- render objects using false colors
[675]1179
1180    // Iterate through priorities
1181    RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
1182
1183        while (groupIt.hasMoreElements())
1184    {
1185                RenderItemBuffer(groupIt.getNext());
1186        }
[897]1187#endif // ITEM_BUFFER
[675]1188}
[897]1189#ifdef ITEM_BUFFER
[675]1190//-----------------------------------------------------------------------
[720]1191void OcclusionCullingSceneManager::RenderItemBuffer(RenderPriorityGroup* pGroup)
[675]1192{
1193        // Do solids
[897]1194        QueuedRenderableCollection solidObjs = pGroup->getSolidsBasic();//msz
[675]1195
1196        // ----- SOLIDS LOOP -----
1197        RenderPriorityGroup::SolidRenderablePassMap::const_iterator ipass, ipassend;
1198        ipassend = solidObjs.end();
1199
1200        for (ipass = solidObjs.begin(); ipass != ipassend; ++ipass)
1201        {
1202                // Fast bypass if this group is now empty
1203                if (ipass->second->empty())
1204                        continue;
1205
[868]1206                // Render only first pass of renderable as false color
[675]1207                if (ipass->first->getIndex() > 0)
1208                        continue;
1209
1210                RenderPriorityGroup::RenderableList* rendList = ipass->second;
1211               
1212                RenderPriorityGroup::RenderableList::const_iterator irend, irendend;
1213                irendend = rendList->end();
1214                       
1215                for (irend = rendList->begin(); irend != irendend; ++irend)
1216                {
[868]1217                        if (0)
1218                        {
[1593]1219                                std::stringstream d; d << "itembuffer, pass name: " <<
1220                                        ipass->first->getParent()->getParent()->getName();
1221
1222                                LogManager::getSingleton().logMessage(d.str());
[868]1223                        }
[675]1224                       
1225                        RenderSingleObjectForItemBuffer(*irend, ipass->first);
1226                }
1227        }
1228
[1816]1229        ///////////
[868]1230        //-- TRANSPARENT LOOP: must be handled differently from solids
[675]1231
1232        // transparents are treated either as solids or completely discarded
1233        if (mRenderTransparentsForItemBuffer)
1234        {
[897]1235                QueuedRenderableCollection transpObjs = pGroup->getTransparents(); //msz
[675]1236                RenderPriorityGroup::TransparentRenderablePassList::const_iterator
1237                        itrans, itransend;
1238
1239                itransend = transpObjs.end();
1240                for (itrans = transpObjs.begin(); itrans != itransend; ++itrans)
1241                {
1242                        // like for solids, render only first pass
1243                        if (itrans->pass->getIndex() == 0)
1244                        {       
1245                                RenderSingleObjectForItemBuffer(itrans->renderable, itrans->pass);
1246                        }
1247                }
1248        }
1249}
1250//-----------------------------------------------------------------------
[720]1251void OcclusionCullingSceneManager::RenderSingleObjectForItemBuffer(Renderable *rend, Pass *pass)
[675]1252{
1253        static LightList nullLightList;
1254       
1255        int col[4];
1256       
1257        // -- create color code out of object id
1258        col[0] = (rend->getId() >> 16) & 255;
1259        col[1] = (rend->getId() >> 8) & 255;
1260        col[2] = rend->getId() & 255;
1261//      col[3] = 255;
1262
1263        //mDestRenderSystem->setColour(col[0], col[1], col[2], col[3]);
1264   
1265        mItemBufferPass->setAmbient(ColourValue(col[0] / 255.0f,
1266                                                                                    col[1] / 255.0f,
1267                                                                                        col[2] / 255.0f, 1));
1268
1269        // set vertex program of current pass
1270        if (mExecuteVertexProgramForAllPasses && pass->hasVertexProgram())
1271        {
1272                mItemBufferPass->setVertexProgram(pass->getVertexProgramName());
1273
1274                if (mItemBufferPass->hasVertexProgram())
1275                {
1276                        const GpuProgramPtr& prg = mItemBufferPass->getVertexProgram();
1277                        // Load this program if not done already
1278                        if (!prg->isLoaded())
1279                                prg->load();
1280                        // Copy params
1281                        mItemBufferPass->setVertexProgramParameters(pass->getVertexProgramParameters());
1282                }
1283        }
1284        else if (mItemBufferPass->hasVertexProgram())
1285        {
1286                mItemBufferPass->setVertexProgram("");
1287        }
1288
[897]1289        const Pass *usedPass = _setPass(mItemBufferPass);
[675]1290
1291
[903]1292        // render a single object, this will set up auto params if required
[675]1293        renderSingleObject(rend, usedPass, false, &nullLightList);
1294}
[897]1295#endif // ITEM_BUFFER
[675]1296//-----------------------------------------------------------------------
[720]1297GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::GetVisibilityManager()
[675]1298{
1299        return mVisibilityManager;
1300}
1301//-----------------------------------------------------------------------
[720]1302void OcclusionCullingSceneManager::InitVisibilityCulling(Camera *cam)
[675]1303{
1304        // reset culling manager stats
1305        mVisibilityManager->GetCullingManager()->InitFrame(mVisualizeCulledNodes);
1306
1307        // set depth pass flag before rendering
1308        mIsDepthPassPhase = mUseDepthPass;
1309
[868]1310        mIsHierarchicalCulling = true; // during hierarchical culling
1311
[675]1312        // item buffer needs full ambient lighting to use item colors as unique id
1313        if (mUseItemBuffer)
1314        {
1315                mIsItemBufferPhase = true;
1316                setAmbientLight(ColourValue(1,1,1,1));
1317        }
1318
1319
1320        // set passes which are stored in render queue
1321        // for rendering AFTER hierarchical culling, i.e., passes which need
1322        // a special rendering order
[868]1323       
[675]1324        mLeavePassesInQueue = 0;
1325
[897]1326        // if we have the depth pass or use an item buffer, no passes are left in the queue
1327        if (1 && !mUseDepthPass && !mUseItemBuffer)
[675]1328        {
1329                if (mShadowTechnique == SHADOWTYPE_STENCIL_ADDITIVE)
1330                {
1331                        // TODO: remove this pass because it should be processed during hierarchical culling
1332                        //mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
1333
1334                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DECAL;
1335                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DIFFUSE_SPECULAR;
1336                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
1337
[903]1338                        // just render ambient passes
[897]1339                        /*** msz: no more IRS_AMBIENT, see OgreSceneManager.h ***/
1340                        // mIlluminationStage = IRS_AMBIENT;
[925]1341                        //getRenderQueue()->setSplitPassesByLightingType(true);
[675]1342                }
1343       
1344                if (mShadowTechnique == SHADOWTYPE_STENCIL_MODULATIVE)
1345                {
1346                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
1347                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
1348                }
1349       
1350                // transparents should be rendered after hierarchical culling to
1351                // provide front-to-back ordering
1352                if (mDelayRenderTransparents)
1353                {
1354                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
1355                }
1356        }
1357
[868]1358        // skip rendering transparents during the hierarchical culling
[675]1359        // (because they will be rendered afterwards)
[868]1360        mSkipTransparents =
1361                (mIsDepthPassPhase || (mLeavePassesInQueue & RenderPriorityGroup::TRANSPARENT_PASSES));
[675]1362
1363        // -- initialise interface for rendering traversal of the hierarchy
1364        mHierarchyInterface->SetHierarchyRoot(mOctree);
1365       
1366        // possible two cameras (one for culling, one for rendering)
1367        mHierarchyInterface->InitTraversal(mCameraInProgress,
1368                                                                           mCullCamera ? getCamera("CullCamera") : NULL,
1369                                                                           mLeavePassesInQueue);
1370               
1371}
1372//-----------------------------------------------------------------------
[720]1373OctreeHierarchyInterface *OcclusionCullingSceneManager::GetHierarchyInterface()
[675]1374{
1375        return mHierarchyInterface;
1376}
1377//-----------------------------------------------------------------------
[720]1378void OcclusionCullingSceneManager::endFrame()
[675]1379{
1380        TerrainRenderable::ResetRenderLevelIndex();
1381}
1382//-----------------------------------------------------------------------
[720]1383Entity* OcclusionCullingSceneManager::createEntity(const String& entityName,
[675]1384                                                                                                        const String& meshName)
1385{
1386        Entity *ent = SceneManager::createEntity(entityName, meshName);
1387
1388        for (int i = 0; i < (int)ent->getNumSubEntities(); ++i)
1389        {
1390                ent->getSubEntity(i)->setId(mCurrentEntityId);
1391        }
1392
1393        // increase counter of entity id values
1394        ++ mCurrentEntityId;
1395
1396        return ent;
1397}
1398//-----------------------------------------------------------------------
[897]1399void OcclusionCullingSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(
1400        RenderQueueGroup* pGroup, QueuedRenderableCollection::OrganisationMode om)
[675]1401{
1402        // only render solid passes during hierarchical culling
1403        if (mIsHierarchicalCulling)
1404        {
1405                RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
1406            LightList lightList;
1407
1408                while (groupIt.hasMoreElements())
1409                {
1410                        RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
1411
1412                        // Sort the queue first
1413                        pPriorityGrp->sort(mCameraInProgress);
1414
1415                        // Clear light list
1416                        lightList.clear();
1417
1418                        // Render all the ambient passes first, no light iteration, no lights
[897]1419                        /*** msz: no more IRS_AMBIENT, see OgreSceneManager.h ***/
1420                        // mIlluminationStage = IRS_AMBIENT;
[675]1421
[897]1422                        OctreeSceneManager::renderObjects(pPriorityGrp->getSolidsBasic(), om, false, &lightList);
[675]1423                        // Also render any objects which have receive shadows disabled
[897]1424                        OctreeSceneManager::renderObjects(pPriorityGrp->getSolidsNoShadowReceive(), om, true);
[903]1425#if 0           
1426                        std::stringstream d;
1427                        d << " solid size: " << (int)pPriorityGrp->_getSolidPasses().size()
1428                                << " solid no shadow size: " << (int)pPriorityGrp->_getSolidPassesNoShadow().size()
1429                                << "difspec size: " << (int)pPriorityGrp->_getSolidPassesDiffuseSpecular().size()
1430                                << " decal size: " << (int)pPriorityGrp->_getSolidPassesDecal().size();
1431                        LogManager::getSingleton().logMessage(d.str());
1432#endif
[675]1433                }
1434        }
[903]1435        else // render the rest of the passes
[675]1436        {
[897]1437                OctreeSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(pGroup, om);
[675]1438        }
1439}
1440//-----------------------------------------------------------------------
[897]1441void OcclusionCullingSceneManager::renderModulativeStencilShadowedQueueGroupObjects(
1442        RenderQueueGroup* pGroup, QueuedRenderableCollection::OrganisationMode om)
[675]1443{
1444   if (mIsHierarchicalCulling)
1445   {
1446           // Iterate through priorities
1447           RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
1448
1449           while (groupIt.hasMoreElements())
1450           {
1451                   RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
1452
1453                   // Sort the queue first
1454                   pPriorityGrp->sort(mCameraInProgress);
1455                   // Do (shadowable) solids
[897]1456                   OctreeSceneManager::renderObjects(pPriorityGrp->getSolidsBasic(), om, true);
[675]1457           }
1458   }
1459   else
1460   {
[931]1461           OctreeSceneManager::renderModulativeStencilShadowedQueueGroupObjects(pGroup, om);
[675]1462   }
1463}
[903]1464//-------------------------------------------------------------------------
1465void OcclusionCullingSceneManager::SetObjectsVisible(const bool visible)
1466{
1467        GtpVisibilityPreprocessor::ObjectContainer::iterator it, it_end = mObjects.end();
[828]1468
[903]1469        for (it = mObjects.begin(); it != it_end; ++ it)
1470        {
[1616]1471                GtpVisibilityPreprocessor::Intersectable *entry = *it;
1472
[2123]1473                SetObjectVisible(entry, visible);
[903]1474        }
1475}
1476//-----------------------------------------------------------------------
[938]1477bool OcclusionCullingSceneManager::LoadViewCells(const String &filename)
[863]1478{
[2097]1479        // no filename specified
[1823]1480        if (filename == "")
1481                return false;
1482
[2097]1483        // view cells already loaded
[1676]1484        if (mViewCellsLoaded)
1485                return true;
1486
[938]1487        // converter between view cell ids and Ogre entites
[1595]1488        OctreeBoundingBoxConverter bconverter(this);
[931]1489
[863]1490        // load the view cells assigning the found objects to the pvss
[2097]1491        const bool finalizeViewCells = false;
[903]1492
[2114]1493        // load the view cells assigning the found objects to the pvss
1494        mViewCellsManager =
1495                GtpVisibilityPreprocessor::ViewCellsManager::
[2115]1496                        LoadViewCells(filename, mObjects, false, &bconverter);
[2097]1497       
[2098]1498        Ogre::LogManager::getSingleton().logMessage("******** view cells loaded *********");
[1823]1499
[1620]1500        // objects are set to invisible initially
1501        SetObjectsVisible(false);
[1616]1502
[1593]1503        if (finalizeViewCells)
1504        {
1505                CreateViewCellsGeometry();
1506        }
1507
[938]1508        return (mViewCellsManager != NULL);
[863]1509}
[903]1510//-------------------------------------------------------------------------
[1593]1511void OcclusionCullingSceneManager::ApplyViewCellPvs(GtpVisibilityPreprocessor::ViewCell *vc,
[903]1512                                                                                                        const bool load)
[2097]1513{       
1514        // NOTE: should not encounter NULL view cell,
[1593]1515        // rather apply view cell representing unbounded space then
[903]1516        if (!vc)
1517        {       
[2097]1518                LogManager::getSingleton().logMessage("error: should not come here");
1519                // question: if no view cell, set everything visible?
[1616]1520                //SetObjectsVisible(true);
[1622]1521                SetObjectsVisible(false);
[903]1522                return;
1523        }
[944]1524               
[1593]1525        ////////////
1526        //-- set PVS of view cell to visible
1527
[2098]1528        //std::stringstream d; d << "appying new view cell pvs: " << vc->GetPvs().GetSize();
1529        //LogManager::getSingleton().logMessage(d.str());
[2097]1530
[2123]1531        GtpVisibilityPreprocessor::ObjectPvsIterator pit = vc->GetPvs().GetIterator();
1532
[1816]1533        while (pit.HasMoreEntries())
1534        {               
[2123]1535                GtpVisibilityPreprocessor::Intersectable *obj = pit.Next();
[1816]1536
[1610]1537                // no associated geometry found
[1816]1538                if (!obj) continue;
[1616]1539       
[2123]1540                SetObjectVisible(obj, load);
[863]1541        }
1542}
[903]1543//-------------------------------------------------------------------------
[1593]1544void OcclusionCullingSceneManager::UpdatePvs(Camera *cam)
[903]1545{
[938]1546        if (!(mViewCellsLoaded && mUseViewCells))
1547                return;
[863]1548
[938]1549        const GtpVisibilityPreprocessor::Vector3 viewPoint =
1550                OgreTypeConverter::ConvertFromOgre(cam->getDerivedPosition());
[903]1551
[2097]1552        //std::stringstream d; d << "vp: " << viewPoint;
1553        //LogManager::getSingleton().logMessage(d.str());
1554
[938]1555        GtpVisibilityPreprocessor::ViewCell *newElementary =
1556                mViewCellsManager->GetViewCell(viewPoint);
[903]1557
[2097]1558        // elementary view cell did not change => don't change pvs
[938]1559        if (mElementaryViewCell == newElementary)
1560                return;
[903]1561
[938]1562        mElementaryViewCell = newElementary;
[1593]1563       
1564
1565        //////////////
[938]1566        //-- unload old pvs
[903]1567
[1593]1568        ApplyViewCellPvs(mCurrentViewCell, false);
[903]1569
[1593]1570        // the new view cell
[938]1571        GtpVisibilityPreprocessor::ViewCell *viewCell;
[903]1572               
[938]1573        if (mUseVisibilityFilter)
[1593]1574        {       
1575                ////////////
[938]1576                //-- compute new filtered cell
[1593]1577
[938]1578                GtpVisibilityPreprocessor::PrVs prvs;
1579                mViewCellsManager->GetPrVS(viewPoint, prvs, 5);
1580                viewCell = prvs.mViewCell;
1581        }
1582        else
1583        {
[1597]1584                viewCell = newElementary;
[938]1585        }
[1593]1586
1587        ///////////////
[938]1588        //-- load new pvs
[903]1589
[1593]1590        ApplyViewCellPvs(viewCell, true);
1591
1592        if (viewCell)
1593        {
[2097]1594                // store current view cell
[1593]1595                mCurrentViewCell->SetPvs(viewCell->GetPvs());
1596                mCurrentViewCell->SetMesh(viewCell->GetMesh());
1597                mCurrentViewCell->SetId(viewCell->GetId());
[903]1598
[1593]1599                // delete merge tree of filtered view cell
1600                if (mUseVisibilityFilter)
1601                        mViewCellsManager->DeleteLocalMergeTree(viewCell);
1602        }
[903]1603}
[1593]1604//-------------------------------------------------------------------------
1605void OcclusionCullingSceneManager::CreateViewCellsGeometry()
1606{
[1616]1607        //LogManager::getSingleton().logMessage("creating view cells geometry");
[1622]1608        if (mViewCellsGeometryLoaded) return;
[1593]1609
[2067]1610        GtpVisibilityPreprocessor::ViewCellContainer viewCells =
1611                mViewCellsManager->GetViewCells();
[1593]1612
1613        GtpVisibilityPreprocessor::ViewCellContainer::const_iterator it, it_end = viewCells.end();
1614        for (it = viewCells.begin(); it != it_end; ++ it)
1615        {
1616                GtpVisibilityPreprocessor::ViewCell *viewCell = *it;
1617
[2067]1618                ManualObject *manual =
1619                        OgreTypeConverter::ConvertToOgre(viewCell->GetMesh(), this);
[1616]1620               
1621                if (manual)
1622                {
1623                        mViewCellsGeometry[viewCell->GetId()] = manual;
[1593]1624
[1616]1625                        // attach to scene node
1626                        getRootSceneNode()->createChildSceneNode()->attachObject(manual);
1627                        manual->setQueryFlags(0); // returned by no query
[1602]1628       
[1616]1629                        // initialy set to invisible
1630                        manual->setVisible(false);
1631                }
[1593]1632        }
[1616]1633       
1634        mViewCellsGeometryLoaded = true;
[1593]1635}
[1602]1636//-------------------------------------------------------------------------
1637void OcclusionCullingSceneManager::VisualizeViewCells(const bool visualize)
1638{
[1616]1639        MovableMap::const_iterator mit, mit_end = mViewCellsGeometry.end();
[1602]1640                       
1641        for (mit = mViewCellsGeometry.begin(); mit != mit_end; ++ mit)
1642        {
[1616]1643                if ((*mit).second)
1644                        (*mit).second->setVisible(visualize);
[1602]1645        }       
1646}
[955]1647#if 0
[951]1648//-------------------------------------------------------------------------
1649void OcclusionCullingSceneManager::TestVisible(SceneNode *node)
1650{
1651        // first test for scene node, then for octant (part of the hierarchy)
1652        if (!node->mVisibleChildren)
[1602]1653        {
[951]1654                node->setVisible(false);
[1602]1655        }
[903]1656
[951]1657        node->getOctant()->mVisibleChildren --;
1658}
1659//-------------------------------------------------------------------------
1660void OcclusionCullingSceneManager::TestVisible(Octree *octant)
1661{
1662        // first test for scene node, then for octant (part of the hierarchy)
1663        if (!octant->mVisibleChildren)
[1593]1664        {
[951]1665                octant->setVisible(false);
[1593]1666        }
[951]1667}
[903]1668
[951]1669//-------------------------------------------------------------------------
1670void OcclusionCullingSceneManager::UpdateVisibility(Entity *ent)
1671{
1672        if (!ent->isVisible())
1673        {
1674                bool visible = TestVisible(ent->getParentNode());
1675               
1676                if (!visible)
1677                        visible = TestVisible(octant->getParentNode());
[903]1678
[951]1679                if (!visible)
1680                        mHierarchyInterface->pullupVisibility();
1681        }
1682}
[955]1683#endif
[1816]1684// splits strings containing multiple file names
[1823]1685static int SplitFilenames(const std::string str,
1686                                                  std::vector<std::string> &filenames)
[1816]1687{
1688        int pos = 0;
1689
1690        while(1)
1691        {
1692                int npos = (int)str.find(';', pos);
1693               
1694                if (npos < 0 || npos - pos < 1)
1695                        break;
1696                filenames.push_back(std::string(str, pos, npos - pos));
1697                pos = npos + 1;
1698        }
1699       
1700        filenames.push_back(std::string(str, pos, str.size() - pos));
1701        return (int)filenames.size();
1702}
[903]1703//-----------------------------------------------------------------------
[2119]1704bool OcclusionCullingSceneManager::LoadScene(const String &filename,
1705                                                                                         const String &viewCellsFilename)
[1816]1706{
1707        using namespace std;
[2108]1708
[1816]1709        // use leaf nodes of the original spatial hierarchy as occludees
1710        vector<string> filenames;
1711        const int files = SplitFilenames(filename, filenames);
1712       
[2108]1713        stringstream d;
[1816]1714        d << "number of input files: " << files << "\n";
1715        LogManager::getSingleton().logMessage(d.str());
1716
1717        bool result = false;
1718        vector<string>::const_iterator fit, fit_end = filenames.end();
1719        int i = 0;
1720
1721        if (filename == "terrain")
1722        {
[1823]1723                LogManager::getSingleton().logMessage("loading terrain");
1724
[1816]1725                // terrain hack
[1823]1726                return false;
[1816]1727        }
[2108]1728
[1816]1729        for (fit = filenames.begin(); fit != fit_end; ++ fit, ++ i)
1730        {
1731                const string fn = *fit;
1732
[2119]1733                if (strstr(fn.c_str(), ".obj"))
[1816]1734                {
1735                        // load iv files
[2119]1736                        if (!LoadSceneObj(filename, viewCellsFilename, getRootSceneNode()))
1737                        {
1738                                LogManager::getSingleton().logMessage("error loading file");
1739                                return false;
1740            }
1741                }
1742                else if (strstr(fn.c_str(), ".iv") || strstr(fn.c_str(), ".wrl"))
1743                {
1744                        // load iv files
[1816]1745                        if (!LoadSceneIV(fn, getRootSceneNode(), i))
1746                        {
1747                                // terrain hack
1748                                LogManager::getSingleton().logMessage("error loading file");
1749                        }
1750                }
1751                       
1752                // at least one piece of geometry loaded
1753                result = true;
1754        }
[2108]1755
[1816]1756        return result;
1757}
1758//-----------------------------------------------------------------------
1759bool OcclusionCullingSceneManager::LoadSceneIV(const String &filename,
1760                                                                                           SceneNode *root,
1761                                                                                           const int index)
1762{
1763        IVReader ivReader;
1764
1765        Timer *timer = PlatformManager::getSingleton().createTimer();
1766        timer->reset();
1767
1768        if (1)
1769        {
1770                std::string logFilename = "IVLog" + Ogre::StringConverter().toString(index) + ".log";
1771               
1772                Log *log = LogManager::getSingleton().createLog(logFilename);
1773                ivReader.setLog(log);
1774        }
1775       
1776        //viennaNode->translate(Vector3(-300, -300, 0));
1777
1778        if (ivReader.loadFile(filename.c_str()))
1779        {
1780                SceneNode *node = root->createChildSceneNode("IVSceneNode" + index);
1781
1782                ivReader.buildTree(this, node);
1783               
1784                ivReader.collapse();
1785
1786                std::stringstream d;
1787                d << "loaded " << filename << " in " << timer->getMilliseconds() * 1e-3 << " secs";
1788                LogManager::getSingleton().logMessage(d.str());
1789               
1790                PlatformManager::getSingleton().destroyTimer(timer);
1791
1792                //-- bake into static geometry
1793                /*if (USE_STATIC_GEOMETRY)
1794                {
1795                        BakeSceneIntoStaticGeometry("staticVienna", "Vienna");
1796                }*/
1797       
1798                return true;
1799        }
1800
1801        return false;
1802}
1803//-----------------------------------------------------------------------
[2119]1804bool OcclusionCullingSceneManager::LoadSceneObj(const String &filename,
1805                                                                                                const String &viewCellsFile,
1806                                                                                                SceneNode *root)
1807{
1808        Timer *timer = PlatformManager::getSingleton().createTimer();
1809        timer->reset();
1810
[2123]1811        if (!mObjReader->LoadFile(filename.c_str(), viewCellsFile, root))
[2119]1812        {
1813                PlatformManager::getSingleton().destroyTimer(timer);
1814                return false;
1815        }
1816
1817        std::stringstream d;
1818        d << "loaded " << filename << " in " << timer->getMilliseconds() * 1e-3 << " secs";
1819        LogManager::getSingleton().logMessage(d.str());
1820               
1821        PlatformManager::getSingleton().destroyTimer(timer);
1822
1823        return true;
1824}
1825//-----------------------------------------------------------------------
[903]1826const String OcclusionCullingSceneManagerFactory::FACTORY_TYPE_NAME = "OcclusionCullingSceneManager";
1827//-----------------------------------------------------------------------
1828void OcclusionCullingSceneManagerFactory::initMetaData(void) const
1829{
1830        mMetaData.typeName = FACTORY_TYPE_NAME;
1831        mMetaData.description = "Scene manager organising the scene on the basis of an octree with advanced occlusion culling (TM).";
1832        mMetaData.sceneTypeMask = 0xFFFF; // support all types
1833        mMetaData.worldGeometrySupported = false;
1834}
1835//-----------------------------------------------------------------------
[925]1836SceneManager *OcclusionCullingSceneManagerFactory::createInstance(
1837                const String& instanceName)
[903]1838{
[2097]1839        OcclusionCullingSceneManager* tsm =
1840                new OcclusionCullingSceneManager(instanceName, visManager);
[925]1841       
1842        // Create & register default sources (one per manager)
1843        HeightmapTerrainPageSource* ps = new HeightmapTerrainPageSource();
1844        mTerrainPageSources.push_back(ps);
1845        tsm->registerPageSource("Heightmap", ps);
[2130]1846LogManager::getSingleton().logMessage("here4");
[925]1847        return tsm;
[903]1848}
1849//-----------------------------------------------------------------------
1850void OcclusionCullingSceneManagerFactory::destroyInstance(SceneManager* instance)
1851{
1852        delete instance;
1853}
1854
[675]1855} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.