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

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