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

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