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

Revision 2176, 66.9 KB checked in by mattausch, 17 years ago (diff)

removed using namespace std from .h

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