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

Revision 2280, 74.2 KB checked in by mattausch, 18 years ago (diff)

removed dependency on ogre in gtpvisibility

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