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

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