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

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