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

Revision 1622, 45.0 KB checked in by mattausch, 18 years ago (diff)
Line 
1#include "OgreOcclusionCullingSceneManager.h"
2#include "OgreVisibilityOptionsManager.h"
3#include <OgreMath.h>
4#include <OgreIteratorWrappers.h>
5#include <OgreRenderSystem.h>
6#include <OgreCamera.h>
7#include <OgreLogManager.h>
8#include <OgreStringConverter.h>
9#include <OgreEntity.h>
10#include <OgreSubEntity.h>
11#include <OgreMaterialManager.h>
12#include <OgreIteratorWrappers.h>
13#include <OgreHeightmapTerrainPageSource.h>
14#include "VspBspTree.h"
15#include "Containers.h"
16#include "ViewCellsManager.h"
17#include <OgreConfigFile.h>
18#include "OgreTypeConverter.h"
19#include "OgreMeshInstance.h"
20#include "common.h"
21#include "OgreBoundingBoxConverter.h"
22#include <OgreManualObject.h>
23#include "IntersectableWrapper.h"
24
25namespace Ogre {
26
27//-----------------------------------------------------------------------
28OcclusionCullingSceneManager::OcclusionCullingSceneManager(const String& name,
29                                                        GtpVisibility::VisibilityManager *visManager):
30TerrainSceneManager(name),
31mVisibilityManager(visManager),
32mShowVisualization(false),
33mRenderNodesForViz(false),
34mRenderNodesContentForViz(false),
35mVisualizeCulledNodes(false),
36mLeavePassesInQueue(0),
37mDelayRenderTransparents(true),
38mUseDepthPass(false),
39mIsDepthPassPhase(false),
40mUseItemBuffer(false),
41mIsItemBufferPhase(false),
42mCurrentEntityId(1),
43mEnableDepthWrite(true),
44mSkipTransparents(false),
45mRenderTransparentsForItemBuffer(true),
46mExecuteVertexProgramForAllPasses(false),
47mIsHierarchicalCulling(false),
48mViewCellsLoaded(false),
49mUseViewCells(false),
50mUseVisibilityFilter(false),
51mCurrentViewCell(NULL),
52mElementaryViewCell(NULL),
53mDeleteQueueAfterRendering(true),
54mNormalExecution(false),
55mShowViewCells(false),
56mViewCellsGeometryLoaded(false)
57{
58        Ogre::LogManager::getSingleton().logMessage("creating occlusion culling scene manager");
59
60        mHierarchyInterface = new OctreeHierarchyInterface(this, mDestRenderSystem);
61       
62        if (0)
63        {
64                mDisplayNodes = true;
65                mShowBoundingBoxes = true;
66                mShowBoxes = true;
67        }
68
69        // TODO: set maxdepth to reasonable value
70        mMaxDepth = 50;
71}
72//-----------------------------------------------------------------------
73void OcclusionCullingSceneManager::InitDepthPass()
74{
75        MaterialPtr depthMat =
76                MaterialManager::getSingleton().getByName("Visibility/DepthPass");
77
78        if (depthMat.isNull())
79    {
80                depthMat = MaterialManager::getSingleton().create(
81                "Visibility/DepthPass",
82                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
83
84        mDepthPass = depthMat->getTechnique(0)->getPass(0);
85                mDepthPass->setColourWriteEnabled(false);
86                mDepthPass->setDepthWriteEnabled(true);
87                mDepthPass->setLightingEnabled(false);
88        }
89        else
90        {
91                mDepthPass = depthMat->getTechnique(0)->getPass(0);
92        }
93}
94//-----------------------------------------------------------------------
95OcclusionCullingSceneManager::~OcclusionCullingSceneManager()
96{
97        OGRE_DELETE(mHierarchyInterface);
98        CLEAR_CONTAINER(mObjects);
99        OGRE_DELETE(mCurrentViewCell);
100}
101//-----------------------------------------------------------------------
102void OcclusionCullingSceneManager::InitItemBufferPass()
103{
104        MaterialPtr itemBufferMat = MaterialManager::getSingleton().
105                getByName("Visibility/ItemBufferPass");
106
107        if (itemBufferMat.isNull())
108    {
109                // Init
110                itemBufferMat =
111                        MaterialManager::getSingleton().create("Visibility/ItemBufferPass",
112                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
113
114                mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0);
115                mItemBufferPass->setColourWriteEnabled(true);
116                mItemBufferPass->setDepthWriteEnabled(true);
117                mItemBufferPass->setLightingEnabled(true);
118                //mItemBufferPass->setLightingEnabled(false);
119        }
120        else
121        {
122                mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0);
123        }
124        //mItemBufferPass->setAmbient(1, 1, 0);
125}
126//-------------------------------------------------------------------------
127#if 1
128void OcclusionCullingSceneManager::setWorldGeometry( DataStreamPtr& stream, const String& typeName )
129{
130    // Clear out any existing world resources (if not default)
131    if (ResourceGroupManager::getSingleton().getWorldResourceGroupName() !=
132        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME)
133    {
134        ResourceGroupManager::getSingleton().clearResourceGroup(
135            ResourceGroupManager::getSingleton().getWorldResourceGroupName());
136    }
137       
138        destroyLevelIndexes();
139    mTerrainPages.clear();
140
141    // Load the configuration
142    loadConfig(stream);
143        initLevelIndexes();
144
145    // Resize the octree, allow for 1 page for now
146    float max_x = mOptions.scale.x * mOptions.pageSize;
147    float max_y = mOptions.scale.y;
148    float max_z = mOptions.scale.z * mOptions.pageSize;
149
150        float maxAxis = std::max(max_x, max_y);
151        maxAxis = std::max(maxAxis, max_z);
152        resize( AxisAlignedBox( 0, 0, 0, maxAxis, maxAxis, maxAxis ) );
153   
154    setupTerrainMaterial();
155    setupTerrainPages();
156
157 }
158#endif
159//-----------------------------------------------------------------------
160void OcclusionCullingSceneManager::PrepareVisualization(Camera *cam)
161{
162        //Ogre::LogManager::getSingleton().logMessage("here4");
163        // add player camera for visualization purpose
164        try
165        {
166                Camera *c;
167                if ((c = getCamera("PlayerCam")) != NULL)
168                {
169                        getRenderQueue()->addRenderable(c);
170                }   
171    }
172    catch (...)
173    {
174        // ignore
175    }
176
177        // add bounding boxes of rendered objects
178        if (0)
179        for (BoxList::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it)
180        {
181                getRenderQueue()->addRenderable(*it);
182        }
183
184        // set old view cell geometry to invisible
185    if (mCurrentViewCell && mCurrentViewCell->GetMesh())
186        {
187                //const bool showSingleViewCell = true;
188                if (mViewCellsGeometryLoaded)
189                {
190                        if (!mShowViewCells)
191                        {
192                                const int id = mCurrentViewCell->GetId();
193
194                                MovableMap::iterator fit = mViewCellsGeometry.find(id);
195                                if ((fit != mViewCellsGeometry.end()) && (*fit).second)
196                                        (*fit).second->_updateRenderQueue(getRenderQueue());
197                        }
198                        else
199                        {
200                                MovableMap::const_iterator mit, mit_end = mViewCellsGeometry.end();
201
202                                for (mit = mViewCellsGeometry.begin(); mit != mit_end; ++ mit)
203                                {
204                                        if ((*mit).second)
205                                                (*mit).second->_updateRenderQueue(getRenderQueue());
206                                }       
207                        }
208                }
209               
210                GtpVisibilityPreprocessor::ObjectPvsMap::const_iterator
211                        oit, oit_end = mCurrentViewCell->GetPvs().mEntries.end();
212                       
213                for (oit = mCurrentViewCell->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
214                {
215                        GtpVisibilityPreprocessor::Intersectable *entry = (*oit).first;
216
217                        if (entry->Type() == GtpVisibilityPreprocessor::Intersectable::OBJECTS_INTERSECTABLE)
218                        {
219                                ObjectsIntersectable *oi = dynamic_cast<ObjectsIntersectable *>(entry);
220                               
221                                EntityContainer *entries = oi->GetItem();
222                               
223                                EntityContainer::const_iterator eit, eit_end = entries->end();
224                                               
225                                for (eit = entries->begin(); eit != eit_end; ++ eit)
226                                {
227                                        (*eit)->setUserAny(Any((int)0));
228                                }
229                        }
230                }
231
232                for (oit = mCurrentViewCell->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
233                {
234                        GtpVisibilityPreprocessor::Intersectable *entry = (*oit).first;
235               
236                        switch (entry->Type())
237                        {       
238                                case GtpVisibilityPreprocessor::Intersectable::OGRE_MESH_INSTANCE:
239                                        {
240                                                OgreMeshInstance *omi = dynamic_cast<OgreMeshInstance *>(entry);
241                                                omi->GetEntity()->_updateRenderQueue(getRenderQueue());
242                                        }
243                                        break;
244                                case GtpVisibilityPreprocessor::Intersectable::OBJECTS_INTERSECTABLE:
245                                        {
246                                                ObjectsIntersectable *oi = dynamic_cast<ObjectsIntersectable *>(entry);
247                                       
248                                                EntityContainer *entries = oi->GetItem();
249                                                EntityContainer::const_iterator eit, eit_end = entries->end();
250                                               
251                                                for (eit = entries->begin(); eit != eit_end; ++ eit)
252                                                {
253                                                        //OgreMeshInstance *omi = dynamic_cast<OgreMeshInstance *>(*eit);
254                                                        Entity *ent = *eit;
255                                                        Any newAny = ent->getUserAny();
256
257                                                        int flt = any_cast<int>(newAny);
258                                                        //std::stringstream d; d << "any: " << flt << " ";
259                                                        //Ogre::LogManager::getSingleton().logMessage(d.str());
260                                                        if (any_cast<int>(newAny) == 0)
261                                                        {
262                                                                ent->setUserAny(Any((int)1));
263                                                                ent->_updateRenderQueue(getRenderQueue());
264                                                        }
265
266                                                        //GtpVisibilityPreprocessor::Debug << "assigned id " << omi->GetId() << endl;
267                                                }
268                                        }
269                                        break;
270                                default:
271                                        break;
272                        }
273                }       
274        }
275
276/*
277   if (mRenderNodesForViz || mRenderNodesContentForViz)
278        {
279                // HACK: change node material so it is better suited for visualization
280                MaterialPtr nodeMat = MaterialManager::getSingleton().getByName("Core/NodeMaterial");
281                nodeMat->setAmbient(1, 1, 0);
282                nodeMat->setLightingEnabled(true);
283                nodeMat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
284
285                for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++it)
286                {
287                        if (mRenderNodesForViz)
288                        {
289                                // render the visible leaf nodes
290                                if ((*it)->numAttachedObjects() &&
291                                        !(*it)->numChildren() &&
292                                        ((*it)->getAttachedObject(0)->getMovableType() == "Entity") &&
293                                        (*it)->getAttachedObject(0)->isVisible())
294                                {
295                                        //getRenderQueue()->addRenderable((*it));
296                                        (*it)->_addToRenderQueue(cam, getRenderQueue(), false);
297                                }
298
299                                // add bounding boxes instead of node itself
300                                if (0)
301                                        (*it)->_addBoundingBoxToQueue(getRenderQueue());
302                        }
303
304                        // add renderables itself
305                        if (mRenderNodesContentForViz)
306                        {
307                                (*it)->_addToRenderQueue(cam, getRenderQueue(), false);
308                        }
309                }
310        }*/
311}
312//-----------------------------------------------------------------------
313const Pass *OcclusionCullingSceneManager::_setPass(const Pass* pass, bool evenIfSuppressed)
314{
315        if (mNormalExecution)
316        {
317                return SceneManager::_setPass(pass);
318        }
319
320        // TODO: setting vertex program is not efficient
321        //Pass *usedPass = ((mIsDepthPassPhase && !pass->hasVertexProgram()) ? mDepthPass : pass);
322       
323        // set depth fill pass if we currently do not make an aabb occlusion query
324        const bool useDepthPass =
325                (mIsDepthPassPhase && !mHierarchyInterface->IsBoundingBoxQuery());
326
327        const IlluminationRenderStage savedStage = mIlluminationStage;
328       
329        // set illumination stage to NONE so no shadow material is used
330        // for depth pass or for occlusion query
331        if (mIsDepthPassPhase || mHierarchyInterface->IsBoundingBoxQuery())
332        {
333                mIlluminationStage = IRS_NONE;
334        }
335       
336        // --- set vertex program of current pass in order to set correct depth
337        if (mExecuteVertexProgramForAllPasses &&
338                mIsDepthPassPhase &&
339                pass->hasVertexProgram())
340        {
341                // add vertex program of current pass to depth pass
342                mDepthPass->setVertexProgram(pass->getVertexProgramName());
343
344                if (mDepthPass->hasVertexProgram())
345                {
346                        const GpuProgramPtr& prg = mDepthPass->getVertexProgram();
347                        // Load this program if not done already
348                        if (!prg->isLoaded())
349                                prg->load();
350                        // Copy params
351                        mDepthPass->setVertexProgramParameters(pass->getVertexProgramParameters());
352                }
353        }
354        else if (mDepthPass->hasVertexProgram()) // reset vertex program
355        {
356                mDepthPass->setVertexProgram("");
357        }
358       
359        const Pass *usedPass = useDepthPass ? mDepthPass : pass;
360
361        // save old depth write: needed for item buffer
362        const bool IsDepthWrite = usedPass->getDepthWriteEnabled();
363
364        // global option which enables / disables depth writes
365        if (!mEnableDepthWrite)
366        {
367                //usedPass->setDepthWriteEnabled(false);
368        }
369        //else if (mIsItemBufferPass) {usedPass = mItemBufferPass;}
370       
371
372        //-- set actual pass here
373
374        const Pass *result = SceneManager::_setPass(usedPass);
375
376
377        // reset depth write
378        if (!mEnableDepthWrite)
379        {
380                //usedPass->setDepthWriteEnabled(IsDepthWrite);
381        }
382
383        // reset illumination stage
384        mIlluminationStage = savedStage;
385
386        return result;
387}
388//-----------------------------------------------------------------------
389void OcclusionCullingSceneManager::_findVisibleObjects(Camera* cam,
390                                                                                                                bool onlyShadowCasters)
391{
392        if (mShowVisualization)
393    {
394                //////////////
395                //-- show visible scene nodes and octree bounding boxes from last frame
396                PrepareVisualization(cam);
397        }
398        else
399        {       
400                // hierarchical culling interleaves identification
401                // and rendering of objects in _renderVisibibleObjects
402
403                // for the shadow pass we use only standard rendering
404                // because shadows have low occlusion snyway
405                if (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE &&
406                        mIlluminationStage == IRS_RENDER_TO_TEXTURE)
407                {
408                        OctreeSceneManager::_findVisibleObjects(cam, onlyShadowCasters);
409                }
410
411                // only shadow casters will be rendered in shadow texture pass
412                if (0) mHierarchyInterface->SetOnlyShadowCasters(onlyShadowCasters);
413
414                ///////////
415                //-- set visibility according to pvs of current view cell
416
417                UpdatePvs(cam);
418
419                if (mNormalExecution)
420                {
421                        OctreeSceneManager::_findVisibleObjects(cam, onlyShadowCasters);
422                        //return;
423                }
424        }
425               
426        // lists only used for visualization
427        mVisible.clear();
428        mBoxes.clear();
429}
430//-----------------------------------------------------------------------
431void OcclusionCullingSceneManager::_renderVisibleObjects()
432{
433        if (mNormalExecution)
434        {
435                // the standard octree rendering mode
436                TerrainSceneManager::_renderVisibleObjects();
437                getRenderQueue()->clear(mDeleteQueueAfterRendering);
438                return;
439        }
440
441        InitDepthPass();          // create material for depth pass
442        InitItemBufferPass(); // create material for item buffer pass
443
444        // save ambient light to reset later
445        ColourValue savedAmbient = mAmbientLight;
446
447        ////////////////////
448        //-- apply standard rendering for some modes
449        //-- (e.g., the visualization mode, the shadow pass)
450
451        if (
452                mShowVisualization ||
453           (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE &&
454            mIlluminationStage == IRS_RENDER_TO_TEXTURE))
455        {       
456                IlluminationRenderStage savedStage = mIlluminationStage;
457       
458                if (mShowVisualization)
459                {
460                        // disable illumination stage to prevent rendering shadows
461                        mIlluminationStage = IRS_NONE;
462                }
463
464                // standard rendering for shadow maps because of performance
465                TerrainSceneManager::_renderVisibleObjects();
466
467                mIlluminationStage = savedStage;
468        }
469        else //-- the hierarchical culling algorithm
470        {
471                // note matt: this is also called in TerrainSceneManager: really necessary?
472                mDestRenderSystem -> setLightingEnabled(false);
473
474                if (mUseItemBuffer)
475                {
476                        // don't render backgrounds for item buffer
477                        clearSpecialCaseRenderQueues();
478                        getRenderQueue()->clear();
479                }
480
481                ////////////////////
482                //-- hierarchical culling
483
484                // the objects of different layers (e.g., background, scene,
485                // overlay) must be identified and rendered one after another
486
487                // first render all early skies
488                clearSpecialCaseRenderQueues();
489                addSpecialCaseRenderQueue(RENDER_QUEUE_BACKGROUND);
490                addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_EARLY);
491                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE);
492
493                TerrainSceneManager::_renderVisibleObjects();
494
495#ifdef GTP_VISIBILITY_MODIFIED_OGRE
496                // delete previously rendered content
497                _deleteRenderedQueueGroups();
498#endif
499
500                ///////////////////
501                //-- prepare queue for visible objects (i.e., all but overlay and skies late)
502
503                clearSpecialCaseRenderQueues();
504                addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_LATE);
505                addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY);
506       
507                // exclude this queues from hierarchical rendering
508                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE);
509
510                // set all necessary parameters for
511                // hierarchical visibility culling and rendering
512                InitVisibilityCulling(mCameraInProgress);
513
514
515                /**
516                * the hierarchical culling algorithm
517                * for depth pass: we just find objects and update depth buffer
518                * for "delayed" rendering: we render some passes afterwards
519                * e.g., transparents, because they need front-to-back sorting
520                **/
521               
522                mVisibilityManager->ApplyVisibilityCulling();
523
524                // delete remaining renderables from queue:
525                // all which are not in mLeavePassesInQueue)
526#ifdef GTP_VISIBILITY_MODIFIED_OGRE
527                _deleteRenderedQueueGroups(mLeavePassesInQueue);
528#endif
529
530                /////////////
531                //-- reset parameters needed for special rendering
532               
533                mIsDepthPassPhase = false;
534                mIsItemBufferPhase = false;
535                mSkipTransparents = false;
536                mIsHierarchicalCulling = false;
537               
538                mLeavePassesInQueue = 0;
539               
540                if (mUseDepthPass) // the shaded geometry is rendered in a second pass
541                {
542                        // add visible nodes found by the visibility culling algorithm
543                        NodeList::const_iterator it, it_end = mVisible.end();
544
545                        //getRenderQueue()->clear();
546                        for (it = mVisible.begin(); it != it_end; ++ it)
547                        {
548                                (*it)->_addToRenderQueue(mCameraInProgress, getRenderQueue(), false);
549                        }
550                }
551               
552                /////////////
553                //-- now we can render all remaining queue objects
554                //-- used for depth pass, transparents, overlay
555
556        clearSpecialCaseRenderQueues();
557
558                TerrainSceneManager::_renderVisibleObjects();
559        } // end hierarchical culling
560               
561        // HACK: set the new render level index, important to avoid cracks
562        // in terrain caused by LOD
563        TerrainRenderable::NextRenderLevelIndex();
564       
565        // reset ambient light
566        setAmbientLight(savedAmbient);
567
568        // almost same effect as below
569        getRenderQueue()->clear(mDeleteQueueAfterRendering);
570
571        if (0)
572        {
573                if (!mDeleteQueueAfterRendering)
574                        getRenderQueue()->clear(true); // finally clear render queue
575                else
576                        OGRE_DELETE(mRenderQueue); // HACK: should rather only be cleared ...
577        }
578
579        if (0) WriteLog(); // write out stats
580}
581
582//-----------------------------------------------------------------------
583void OcclusionCullingSceneManager::_updateSceneGraph(Camera* cam)
584{
585        if (mNormalExecution)
586        {
587                OctreeSceneManager::_updateSceneGraph(cam);
588                return;
589        }
590
591        mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface);
592        mHierarchyInterface->SetRenderSystem(mDestRenderSystem);
593
594        TerrainSceneManager::_updateSceneGraph(cam);
595}
596//-----------------------------------------------------------------------
597bool OcclusionCullingSceneManager::setOption(const String & key, const void * val)
598{
599        if (key == "UseDepthPass")
600        {
601                mUseDepthPass = (*static_cast<const bool *>(val));
602                return true;
603        }
604        if (key == "PrepareVisualization")
605        {
606                mShowVisualization = (*static_cast<const bool *>(val));
607                return true;
608        }
609        if (key == "RenderNodesForViz")
610        {
611                mRenderNodesForViz = (*static_cast<const bool *>(val));
612                return true;
613        }
614        if (key == "RenderNodesContentForViz")
615        {
616                mRenderNodesContentForViz = (*static_cast<const bool *>(val));
617                return true;
618        }
619        if (key == "SkyBoxEnabled")
620        {
621                mSkyBoxEnabled = (*static_cast<const bool *>(val));
622                return true;
623        }
624        if (key == "SkyPlaneEnabled")
625        {
626                mSkyPlaneEnabled = (*static_cast<const bool *>(val));
627                return true;
628        }
629        if (key == "SkyDomeEnabled")
630        {
631                mSkyDomeEnabled = (*static_cast<const bool *>(val));
632                return true;
633        }
634        if (key == "VisualizeCulledNodes")
635        {
636                mVisualizeCulledNodes = (*static_cast<const bool *>(val));
637                return true;
638        }
639        if (key == "DelayRenderTransparents")
640        {
641                mDelayRenderTransparents = (*static_cast<const bool *>(val));
642                return true;
643        }
644        if (key == "DepthWrite")
645        {
646                mEnableDepthWrite = (*static_cast<const bool *>(val));
647                return true;
648        }
649        if (key == "UseItemBuffer")
650        {
651                mUseItemBuffer = (*static_cast<const bool *>(val));
652                return true;
653        }
654        if (key == "ExecuteVertexProgramForAllPasses")
655        {
656                mExecuteVertexProgramForAllPasses  = (*static_cast<const bool *>(val));
657                return true;
658        }
659        if (key == "RenderTransparentsForItemBuffer")
660        {
661                mRenderTransparentsForItemBuffer  = (*static_cast<const bool *>(val));
662                return true;
663        }
664        else if (key == "DeleteRenderQueue")
665        {
666                mDeleteQueueAfterRendering = (*static_cast<const bool *>(val));
667                return true;
668        }
669        if (key == "NodeVizScale")
670        {
671                OctreeNode::setVizScale(*static_cast<const float *>(val));
672                return true;
673        }
674        if (key == "LoadViewCells")
675        {
676                if (!mViewCellsLoaded)
677                {
678                        String filename(static_cast<const char *>(val));
679                        mViewCellsLoaded = LoadViewCells(filename);     
680                }
681
682                return mViewCellsLoaded;
683        }
684        if (key == "UseViewCells")
685        {
686                // only use this option if view cells are available
687                if (mViewCellsLoaded)
688                {
689                        mUseViewCells = *static_cast<const bool *>(val);
690
691                        // reset view cell
692                        OGRE_DELETE(mCurrentViewCell);
693                       
694                        if (mUseViewCells)
695                        {
696                                mCurrentViewCell = mViewCellsManager->GenerateViewCell();
697                        }
698                        // view cell corresponding to leaf in the view cell hierarchy
699                        mElementaryViewCell = NULL;
700
701                        // if we decide use view cells
702                        // all objects are set to invisible per default
703                        SetObjectsVisible(!mUseViewCells);
704
705                        /*MovableObjectIterator movit = getMovableObjectIterator("Entity");
706                        while (movit.hasMoreElements())
707                        {
708                                Entity *ent = static_cast<Entity *>(movit.getNext());
709                                ent->setVisible(!mUseViewCells);
710                        }*/
711                }
712
713                return true;
714        }
715        if (key == "ShowViewCells")
716        {
717                // only use this option if view cells are available
718                if (mViewCellsLoaded)
719                {
720                        mShowViewCells = *static_cast<const bool *>(val);
721                        // if we decide use view cells
722                        // all objects are set to invisible per default
723                        VisualizeViewCells(mShowViewCells);
724                }
725
726                return true;
727        }
728        if (key == "NormalExecution")
729        {
730                mNormalExecution = *static_cast<const bool *>(val);
731                return true;
732        }
733        if (key == "UseVisibilityFilter")
734        {
735                mUseVisibilityFilter = *static_cast<const bool *>(val);
736                // set null =>recomputation of the pvs
737        mElementaryViewCell = NULL;
738                return true;
739        }
740
741        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
742                setOption(key, val) || TerrainSceneManager::setOption(key, val);
743}
744//-----------------------------------------------------------------------
745bool OcclusionCullingSceneManager::getOption(const String & key, void *val)
746{
747        if (key == "NumHierarchyNodes")
748        {
749                * static_cast<unsigned int *>(val) = (unsigned int)mNumOctants;
750                return true;
751        }
752        if (key == "VisibilityManager")
753        {
754                * static_cast<GtpVisibility::VisibilityManager **>(val) =
755                        (GtpVisibility::VisibilityManager *)mVisibilityManager;
756                return true;
757        }
758        if (key == "HierarchInterface")
759        {
760                * static_cast<GtpVisibility::HierarchyInterface **>(val) =
761                        (GtpVisibility::HierarchyInterface *)mHierarchyInterface;
762                return true;
763        }
764
765        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
766                getOption(key, val) && TerrainSceneManager::getOption(key, val);
767}
768//-----------------------------------------------------------------------
769bool OcclusionCullingSceneManager::getOptionValues(const String & key,
770                                                                                                        StringVector &refValueList)
771{
772        return TerrainSceneManager::getOptionValues( key, refValueList);
773}
774//-----------------------------------------------------------------------
775bool OcclusionCullingSceneManager::getOptionKeys(StringVector & refKeys)
776{
777        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
778                getOptionKeys(refKeys) || TerrainSceneManager::getOptionKeys(refKeys);
779}
780//-----------------------------------------------------------------------
781void OcclusionCullingSceneManager::setVisibilityManager(GtpVisibility::
782                                                                                                                 VisibilityManager *visManager)
783{
784        mVisibilityManager = visManager;
785}
786//-----------------------------------------------------------------------
787GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::getVisibilityManager( void )
788{
789        return mVisibilityManager;
790}
791//-----------------------------------------------------------------------
792void OcclusionCullingSceneManager::WriteLog()
793{
794        std::stringstream d;
795
796        d << "Depth pass: " << StringConverter::toString(mUseDepthPass) << ", "
797          << "Delay transparents: " << StringConverter::toString(mDelayRenderTransparents) << ", "
798          << "Use optimization: " << StringConverter::toString(mHierarchyInterface->GetTestGeometryForVisibleLeaves()) << ", "
799          << "Algorithm type: " << mVisibilityManager->GetCullingManagerType() << ", "
800          << "Hierarchy nodes: " << mNumOctants << ", "
801          << "Traversed nodes: " << mHierarchyInterface->GetNumTraversedNodes() << ", "
802          << "Rendered nodes: " << mHierarchyInterface->GetNumRenderedNodes() << ", "
803          << "Query culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumQueryCulledNodes() << ", "
804          << "Frustum culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumFrustumCulledNodes() << ", "
805      << "Queries issued: " << mVisibilityManager->GetCullingManager()->GetNumQueriesIssued() << ", "
806          << "Found objects: " << (int)mVisible.size() << "\n";
807
808        LogManager::getSingleton().logMessage(d.str());
809}
810//-----------------------------------------------------------------------
811void OcclusionCullingSceneManager::renderBasicQueueGroupObjects(RenderQueueGroup* pGroup,
812                                                                                                                                QueuedRenderableCollection::OrganisationMode om)
813{
814    // Basic render loop
815    // Iterate through priorities
816    RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
817
818    while (groupIt.hasMoreElements())
819    {
820        RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
821
822        // Sort the queue first
823        pPriorityGrp->sort(mCameraInProgress);
824
825        // Do solids
826        renderObjects(pPriorityGrp->getSolidsBasic(), om, true);
827
828                // for correct rendering, transparents must be rendered
829                // after hierarchical culling => don't render them now
830
831        if (mNormalExecution || !mSkipTransparents)
832                {
833                        // Do transparents (always descending)
834                        renderObjects(pPriorityGrp->getTransparents(),
835                                QueuedRenderableCollection::OM_SORT_DESCENDING, true);
836                }
837
838
839    } // for each priority
840}
841
842//-----------------------------------------------------------------------
843bool OcclusionCullingSceneManager::validatePassForRendering(Pass* pass)
844{
845        if (mNormalExecution)
846        {
847                return SceneManager::validatePassForRendering(pass);
848        }
849
850        // skip all but first pass if we are doing the depth pass
851        if ((mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() > 0))
852        {
853                return false;
854        }
855        // all but first pass
856        /*else if ((!mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() != 0))
857        {
858                return false;
859        }*/
860
861        return SceneManager::validatePassForRendering(pass);
862}
863//-----------------------------------------------------------------------
864void OcclusionCullingSceneManager::_renderQueueGroupObjects(RenderQueueGroup* pGroup,
865                                                                                                                        QueuedRenderableCollection::OrganisationMode om)
866{
867        if (mNormalExecution || !mIsItemBufferPhase)
868        {
869                TerrainSceneManager::_renderQueueGroupObjects(pGroup, om);
870                return;
871        }
872#ifdef  ITEM_BUFFER
873        //-- item buffer
874        //-- render objects using false colors
875
876    // Iterate through priorities
877    RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
878
879        while (groupIt.hasMoreElements())
880    {
881                RenderItemBuffer(groupIt.getNext());
882        }
883#endif // ITEM_BUFFER
884}
885#ifdef ITEM_BUFFER
886//-----------------------------------------------------------------------
887void OcclusionCullingSceneManager::RenderItemBuffer(RenderPriorityGroup* pGroup)
888{
889        // Do solids
890        QueuedRenderableCollection solidObjs = pGroup->getSolidsBasic();//msz
891
892        // ----- SOLIDS LOOP -----
893        RenderPriorityGroup::SolidRenderablePassMap::const_iterator ipass, ipassend;
894        ipassend = solidObjs.end();
895
896        for (ipass = solidObjs.begin(); ipass != ipassend; ++ipass)
897        {
898                // Fast bypass if this group is now empty
899                if (ipass->second->empty())
900                        continue;
901
902                // Render only first pass of renderable as false color
903                if (ipass->first->getIndex() > 0)
904                        continue;
905
906                RenderPriorityGroup::RenderableList* rendList = ipass->second;
907               
908                RenderPriorityGroup::RenderableList::const_iterator irend, irendend;
909                irendend = rendList->end();
910                       
911                for (irend = rendList->begin(); irend != irendend; ++irend)
912                {
913                        if (0)
914                        {
915                                std::stringstream d; d << "itembuffer, pass name: " <<
916                                        ipass->first->getParent()->getParent()->getName();
917
918                                LogManager::getSingleton().logMessage(d.str());
919                        }
920                       
921                        RenderSingleObjectForItemBuffer(*irend, ipass->first);
922                }
923        }
924
925        //-- TRANSPARENT LOOP: must be handled differently from solids
926
927        // transparents are treated either as solids or completely discarded
928        if (mRenderTransparentsForItemBuffer)
929        {
930                QueuedRenderableCollection transpObjs = pGroup->getTransparents(); //msz
931                RenderPriorityGroup::TransparentRenderablePassList::const_iterator
932                        itrans, itransend;
933
934                itransend = transpObjs.end();
935                for (itrans = transpObjs.begin(); itrans != itransend; ++itrans)
936                {
937                        // like for solids, render only first pass
938                        if (itrans->pass->getIndex() == 0)
939                        {       
940                                RenderSingleObjectForItemBuffer(itrans->renderable, itrans->pass);
941                        }
942                }
943        }
944}
945//-----------------------------------------------------------------------
946void OcclusionCullingSceneManager::RenderSingleObjectForItemBuffer(Renderable *rend, Pass *pass)
947{
948        static LightList nullLightList;
949       
950        int col[4];
951       
952        // -- create color code out of object id
953        col[0] = (rend->getId() >> 16) & 255;
954        col[1] = (rend->getId() >> 8) & 255;
955        col[2] = rend->getId() & 255;
956//      col[3] = 255;
957
958        //mDestRenderSystem->setColour(col[0], col[1], col[2], col[3]);
959   
960        mItemBufferPass->setAmbient(ColourValue(col[0] / 255.0f,
961                                                                                    col[1] / 255.0f,
962                                                                                        col[2] / 255.0f, 1));
963
964        // set vertex program of current pass
965        if (mExecuteVertexProgramForAllPasses && pass->hasVertexProgram())
966        {
967                mItemBufferPass->setVertexProgram(pass->getVertexProgramName());
968
969                if (mItemBufferPass->hasVertexProgram())
970                {
971                        const GpuProgramPtr& prg = mItemBufferPass->getVertexProgram();
972                        // Load this program if not done already
973                        if (!prg->isLoaded())
974                                prg->load();
975                        // Copy params
976                        mItemBufferPass->setVertexProgramParameters(pass->getVertexProgramParameters());
977                }
978        }
979        else if (mItemBufferPass->hasVertexProgram())
980        {
981                mItemBufferPass->setVertexProgram("");
982        }
983
984        const Pass *usedPass = _setPass(mItemBufferPass);
985
986
987        // render a single object, this will set up auto params if required
988        renderSingleObject(rend, usedPass, false, &nullLightList);
989}
990#endif // ITEM_BUFFER
991//-----------------------------------------------------------------------
992GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::GetVisibilityManager()
993{
994        return mVisibilityManager;
995}
996//-----------------------------------------------------------------------
997void OcclusionCullingSceneManager::InitVisibilityCulling(Camera *cam)
998{
999        // reset culling manager stats
1000        mVisibilityManager->GetCullingManager()->InitFrame(mVisualizeCulledNodes);
1001
1002        // set depth pass flag before rendering
1003        mIsDepthPassPhase = mUseDepthPass;
1004
1005        mIsHierarchicalCulling = true; // during hierarchical culling
1006
1007        // item buffer needs full ambient lighting to use item colors as unique id
1008        if (mUseItemBuffer)
1009        {
1010                mIsItemBufferPhase = true;
1011                setAmbientLight(ColourValue(1,1,1,1));
1012        }
1013
1014
1015        // set passes which are stored in render queue
1016        // for rendering AFTER hierarchical culling, i.e., passes which need
1017        // a special rendering order
1018       
1019        mLeavePassesInQueue = 0;
1020
1021        // if we have the depth pass or use an item buffer, no passes are left in the queue
1022        if (1 && !mUseDepthPass && !mUseItemBuffer)
1023        {
1024                if (mShadowTechnique == SHADOWTYPE_STENCIL_ADDITIVE)
1025                {
1026                        // TODO: remove this pass because it should be processed during hierarchical culling
1027                        //mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
1028
1029                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DECAL;
1030                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DIFFUSE_SPECULAR;
1031                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
1032
1033                        // just render ambient passes
1034                        /*** msz: no more IRS_AMBIENT, see OgreSceneManager.h ***/
1035                        // mIlluminationStage = IRS_AMBIENT;
1036                        //getRenderQueue()->setSplitPassesByLightingType(true);
1037                }
1038       
1039                if (mShadowTechnique == SHADOWTYPE_STENCIL_MODULATIVE)
1040                {
1041                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
1042                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
1043                }
1044       
1045                // transparents should be rendered after hierarchical culling to
1046                // provide front-to-back ordering
1047                if (mDelayRenderTransparents)
1048                {
1049                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
1050                }
1051        }
1052
1053        // skip rendering transparents during the hierarchical culling
1054        // (because they will be rendered afterwards)
1055        mSkipTransparents =
1056                (mIsDepthPassPhase || (mLeavePassesInQueue & RenderPriorityGroup::TRANSPARENT_PASSES));
1057
1058        // -- initialise interface for rendering traversal of the hierarchy
1059        mHierarchyInterface->SetHierarchyRoot(mOctree);
1060       
1061        // possible two cameras (one for culling, one for rendering)
1062        mHierarchyInterface->InitTraversal(mCameraInProgress,
1063                                                                           mCullCamera ? getCamera("CullCamera") : NULL,
1064                                                                           mLeavePassesInQueue);
1065               
1066}
1067//-----------------------------------------------------------------------
1068OctreeHierarchyInterface *OcclusionCullingSceneManager::GetHierarchyInterface()
1069{
1070        return mHierarchyInterface;
1071}
1072//-----------------------------------------------------------------------
1073void OcclusionCullingSceneManager::endFrame()
1074{
1075        TerrainRenderable::ResetRenderLevelIndex();
1076}
1077//-----------------------------------------------------------------------
1078Entity* OcclusionCullingSceneManager::createEntity(const String& entityName,
1079                                                                                                        const String& meshName)
1080{
1081        Entity *ent = SceneManager::createEntity(entityName, meshName);
1082
1083        for (int i = 0; i < (int)ent->getNumSubEntities(); ++i)
1084        {
1085                ent->getSubEntity(i)->setId(mCurrentEntityId);
1086        }
1087
1088        // increase counter of entity id values
1089        ++ mCurrentEntityId;
1090
1091        return ent;
1092}
1093//-----------------------------------------------------------------------
1094void OcclusionCullingSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(
1095        RenderQueueGroup* pGroup, QueuedRenderableCollection::OrganisationMode om)
1096{
1097        // only render solid passes during hierarchical culling
1098        if (mIsHierarchicalCulling)
1099        {
1100                RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
1101            LightList lightList;
1102
1103                while (groupIt.hasMoreElements())
1104                {
1105                        RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
1106
1107                        // Sort the queue first
1108                        pPriorityGrp->sort(mCameraInProgress);
1109
1110                        // Clear light list
1111                        lightList.clear();
1112
1113                        // Render all the ambient passes first, no light iteration, no lights
1114                        /*** msz: no more IRS_AMBIENT, see OgreSceneManager.h ***/
1115                        // mIlluminationStage = IRS_AMBIENT;
1116
1117                        OctreeSceneManager::renderObjects(pPriorityGrp->getSolidsBasic(), om, false, &lightList);
1118                        // Also render any objects which have receive shadows disabled
1119                        OctreeSceneManager::renderObjects(pPriorityGrp->getSolidsNoShadowReceive(), om, true);
1120#if 0           
1121                        std::stringstream d;
1122                        d << " solid size: " << (int)pPriorityGrp->_getSolidPasses().size()
1123                                << " solid no shadow size: " << (int)pPriorityGrp->_getSolidPassesNoShadow().size()
1124                                << "difspec size: " << (int)pPriorityGrp->_getSolidPassesDiffuseSpecular().size()
1125                                << " decal size: " << (int)pPriorityGrp->_getSolidPassesDecal().size();
1126                        LogManager::getSingleton().logMessage(d.str());
1127#endif
1128                }
1129        }
1130        else // render the rest of the passes
1131        {
1132                OctreeSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(pGroup, om);
1133        }
1134}
1135//-----------------------------------------------------------------------
1136void OcclusionCullingSceneManager::renderModulativeStencilShadowedQueueGroupObjects(
1137        RenderQueueGroup* pGroup, QueuedRenderableCollection::OrganisationMode om)
1138{
1139   if (mIsHierarchicalCulling)
1140   {
1141           // Iterate through priorities
1142           RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
1143
1144           while (groupIt.hasMoreElements())
1145           {
1146                   RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
1147
1148                   // Sort the queue first
1149                   pPriorityGrp->sort(mCameraInProgress);
1150                   // Do (shadowable) solids
1151                   OctreeSceneManager::renderObjects(pPriorityGrp->getSolidsBasic(), om, true);
1152           }
1153   }
1154   else
1155   {
1156           OctreeSceneManager::renderModulativeStencilShadowedQueueGroupObjects(pGroup, om);
1157   }
1158}
1159//-------------------------------------------------------------------------
1160void OcclusionCullingSceneManager::SetObjectsVisible(const bool visible)
1161{
1162        GtpVisibilityPreprocessor::ObjectContainer::iterator it, it_end = mObjects.end();
1163
1164        for (it = mObjects.begin(); it != it_end; ++ it)
1165        {
1166                GtpVisibilityPreprocessor::Intersectable *entry = *it;
1167
1168                switch (entry->Type())
1169                {
1170                        case GtpVisibilityPreprocessor::Intersectable::OGRE_MESH_INSTANCE:
1171                                {
1172                                        OgreMeshInstance *omi = dynamic_cast<OgreMeshInstance *>(entry);
1173                                        omi->GetEntity()->setVisible(visible);
1174                                        //GtpVisibilityPreprocessor::Debug << "assigned id " << omi->GetId() << endl;
1175                                }
1176                                break;
1177                        case GtpVisibilityPreprocessor::Intersectable::OBJECTS_INTERSECTABLE:
1178                                {
1179                                        //GtpVisibilityPreprocessor::ObjectsIntersectable *oi =
1180                                        //      dynamic_cast<GtpVisibilityPreprocessor::ObjectsIntersectable *>(entry);
1181                                        ObjectsIntersectable *oi = dynamic_cast<ObjectsIntersectable *>(entry);
1182
1183                                        //GtpVisibilityPreprocessor::ObjectContainer *entries = oi->GetItem();
1184                                        EntityContainer *entries = oi->GetItem();
1185                                        EntityContainer::const_iterator eit,
1186                                                eit_end = entries->end();
1187                                        for (eit = entries->begin(); eit != eit_end; ++ eit)
1188                                        {
1189                                                //OgreMeshInstance *omi = dynamic_cast<OgreMeshInstance *>(*eit);
1190                                                Entity *ent = *eit;
1191                                                ent->setVisible(visible);
1192                                                //GtpVisibilityPreprocessor::Debug << "assigned id " << omi->GetId() << endl;
1193                                        }
1194                                }
1195                                break;
1196                        default:
1197                                break;
1198                }
1199        }
1200}
1201//-----------------------------------------------------------------------
1202bool OcclusionCullingSceneManager::LoadViewCells(const String &filename)
1203{
1204        if (mViewCellsLoaded) return true;
1205        // converter between view cell ids and Ogre entites
1206        GtpVisibilityPreprocessor::IndexedBoundingBoxContainer iboxes;
1207        OctreeBoundingBoxConverter bconverter(this);
1208
1209        // load the view cells assigning the found objects to the pvss
1210        const bool finalizeViewCells = true;
1211        mViewCellsManager =
1212                GtpVisibilityPreprocessor::ViewCellsManager::LoadViewCells(filename, &mObjects, true, &bconverter);
1213
1214        //Ogre::LogManager().getSingleton().logMessage("view cells loaded");
1215        //Ogre::LogManager().getSingleton().flush();
1216        // objects are set to invisible initially
1217        SetObjectsVisible(false);
1218
1219        if (finalizeViewCells)
1220        {
1221                CreateViewCellsGeometry();
1222        }
1223
1224        return (mViewCellsManager != NULL);
1225}
1226//-------------------------------------------------------------------------
1227void OcclusionCullingSceneManager::ApplyViewCellPvs(GtpVisibilityPreprocessor::ViewCell *vc,
1228                                                                                                        const bool load)
1229{       // NOTE: should not encounter NULL view cell,
1230        // rather apply view cell representing unbounded space then
1231        if (!vc)
1232        {       
1233                // if no there is no view cell, set everything visible
1234                //SetObjectsVisible(true);
1235                SetObjectsVisible(false);
1236                return;
1237        }
1238               
1239        GtpVisibilityPreprocessor::ObjectPvsMap::const_iterator oit,
1240                        oit_end = vc->GetPvs().mEntries.end();
1241
1242        ////////////
1243        //-- set PVS of view cell to visible
1244
1245        for (oit = vc->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
1246        {
1247                GtpVisibilityPreprocessor::Intersectable *entry = (*oit).first;
1248                // no associated geometry found
1249                if (!entry) continue;
1250       
1251                switch (entry->Type())
1252                {
1253                        case GtpVisibilityPreprocessor::Intersectable::OGRE_MESH_INSTANCE:
1254                                {
1255                                        OgreMeshInstance *omi = dynamic_cast<OgreMeshInstance *>(entry);
1256                                        omi->GetEntity()->setVisible(load);
1257                                        //GtpVisibilityPreprocessor::Debug << "assigned id " << omi->GetId() << endl;
1258                                }
1259                                break;
1260                        case GtpVisibilityPreprocessor::Intersectable::OBJECTS_INTERSECTABLE:
1261                                {
1262                                        //GtpVisibilityPreprocessor::ObjectsIntersectable *oi =
1263                                        //      dynamic_cast<GtpVisibilityPreprocessor::ObjectsIntersectable *>(entry);
1264                                        ObjectsIntersectable *oi = dynamic_cast<ObjectsIntersectable *>(entry);
1265
1266                                        //GtpVisibilityPreprocessor::ObjectContainer *entries = oi->GetItem();
1267                                        EntityContainer *entries = oi->GetItem();
1268
1269                                        EntityContainer::const_iterator eit,
1270                                                eit_end = entries->end();
1271                                        for (eit = entries->begin(); eit != eit_end; ++ eit)
1272                                        {
1273                                                //OgreMeshInstance *omi = dynamic_cast<OgreMeshInstance *>(*eit);
1274                                                //omi->GetEntity()->setVisible(load);
1275                                                Entity *ent = *eit;
1276                                                ent->setVisible(load);                                 
1277                                                //GtpVisibilityPreprocessor::Debug << "assigned id " << omi->GetId() << endl;
1278                                        }
1279                                }
1280                                break;
1281                        default:
1282                                break;
1283                }
1284        }
1285}
1286//-------------------------------------------------------------------------
1287void OcclusionCullingSceneManager::UpdatePvs(Camera *cam)
1288{
1289        if (!(mViewCellsLoaded && mUseViewCells))
1290                return;
1291
1292        const GtpVisibilityPreprocessor::Vector3 viewPoint =
1293                OgreTypeConverter::ConvertFromOgre(cam->getDerivedPosition());
1294
1295        GtpVisibilityPreprocessor::ViewCell *newElementary =
1296                mViewCellsManager->GetViewCell(viewPoint);
1297
1298        // elementary view cell did not change => apply same pvs
1299        if (mElementaryViewCell == newElementary)
1300                return;
1301
1302        mElementaryViewCell = newElementary;
1303       
1304
1305        //////////////
1306        //-- unload old pvs
1307
1308        ApplyViewCellPvs(mCurrentViewCell, false);
1309
1310        // the new view cell
1311        GtpVisibilityPreprocessor::ViewCell *viewCell;
1312               
1313        if (mUseVisibilityFilter)
1314        {       
1315                ////////////
1316                //-- compute new filtered cell
1317
1318                GtpVisibilityPreprocessor::PrVs prvs;
1319                mViewCellsManager->GetPrVS(viewPoint, prvs, 5);
1320                viewCell = prvs.mViewCell;
1321        }
1322        else
1323        {
1324                viewCell = newElementary;
1325        }
1326
1327        ///////////////
1328        //-- load new pvs
1329
1330        ApplyViewCellPvs(viewCell, true);
1331
1332        // store pvs
1333        if (viewCell)
1334        {
1335                mCurrentViewCell->SetPvs(viewCell->GetPvs());
1336                mCurrentViewCell->SetMesh(viewCell->GetMesh());
1337                mCurrentViewCell->SetId(viewCell->GetId());
1338
1339                // delete merge tree of filtered view cell
1340                if (mUseVisibilityFilter)
1341                        mViewCellsManager->DeleteLocalMergeTree(viewCell);
1342        }
1343}
1344//-------------------------------------------------------------------------
1345void OcclusionCullingSceneManager::CreateViewCellsGeometry()
1346{
1347        //LogManager::getSingleton().logMessage("creating view cells geometry");
1348        if (mViewCellsGeometryLoaded) return;
1349
1350        GtpVisibilityPreprocessor::ViewCellContainer viewCells = mViewCellsManager->GetViewCells();
1351
1352        GtpVisibilityPreprocessor::ViewCellContainer::const_iterator it, it_end = viewCells.end();
1353        for (it = viewCells.begin(); it != it_end; ++ it)
1354        {
1355                GtpVisibilityPreprocessor::ViewCell *viewCell = *it;
1356
1357                //std::stringstream str;
1358                //str << "processing view cell with id : " << viewCell->GetId();
1359                //LogManager::getSingleton().logMessage(str.str());
1360                ManualObject *manual = OgreTypeConverter::ConvertToOgre(viewCell->GetMesh(), this);
1361               
1362                if (manual)
1363                {
1364                        mViewCellsGeometry[viewCell->GetId()] = manual;
1365
1366                        // attach to scene node
1367                        getRootSceneNode()->createChildSceneNode()->attachObject(manual);
1368                        manual->setQueryFlags(0); // returned by no query
1369       
1370                        // initialy set to invisible
1371                        manual->setVisible(false);
1372                }
1373        }
1374       
1375        mViewCellsGeometryLoaded = true;
1376}
1377//-------------------------------------------------------------------------
1378void OcclusionCullingSceneManager::VisualizeViewCells(const bool visualize)
1379{
1380        MovableMap::const_iterator mit, mit_end = mViewCellsGeometry.end();
1381                       
1382        for (mit = mViewCellsGeometry.begin(); mit != mit_end; ++ mit)
1383        {
1384                if ((*mit).second)
1385                        (*mit).second->setVisible(visualize);
1386        }       
1387}
1388#if 0
1389//-------------------------------------------------------------------------
1390void OcclusionCullingSceneManager::TestVisible(SceneNode *node)
1391{
1392        // first test for scene node, then for octant (part of the hierarchy)
1393        if (!node->mVisibleChildren)
1394        {
1395                node->setVisible(false);
1396        }
1397
1398        node->getOctant()->mVisibleChildren --;
1399}
1400//-------------------------------------------------------------------------
1401void OcclusionCullingSceneManager::TestVisible(Octree *octant)
1402{
1403        // first test for scene node, then for octant (part of the hierarchy)
1404        if (!octant->mVisibleChildren)
1405        {
1406                octant->setVisible(false);
1407        }
1408}
1409
1410//-------------------------------------------------------------------------
1411void OcclusionCullingSceneManager::UpdateVisibility(Entity *ent)
1412{
1413        if (!ent->isVisible())
1414        {
1415                bool visible = TestVisible(ent->getParentNode());
1416               
1417                if (!visible)
1418                        visible = TestVisible(octant->getParentNode());
1419
1420                if (!visible)
1421                        mHierarchyInterface->pullupVisibility();
1422        }
1423}
1424#endif
1425//-----------------------------------------------------------------------
1426const String OcclusionCullingSceneManagerFactory::FACTORY_TYPE_NAME = "OcclusionCullingSceneManager";
1427//-----------------------------------------------------------------------
1428void OcclusionCullingSceneManagerFactory::initMetaData(void) const
1429{
1430        mMetaData.typeName = FACTORY_TYPE_NAME;
1431        mMetaData.description = "Scene manager organising the scene on the basis of an octree with advanced occlusion culling (TM).";
1432        mMetaData.sceneTypeMask = 0xFFFF; // support all types
1433        mMetaData.worldGeometrySupported = false;
1434}
1435//-----------------------------------------------------------------------
1436SceneManager *OcclusionCullingSceneManagerFactory::createInstance(
1437                const String& instanceName)
1438{
1439        OcclusionCullingSceneManager* tsm = new OcclusionCullingSceneManager(instanceName, visManager);
1440       
1441        // Create & register default sources (one per manager)
1442        HeightmapTerrainPageSource* ps = new HeightmapTerrainPageSource();
1443        mTerrainPageSources.push_back(ps);
1444        tsm->registerPageSource("Heightmap", ps);
1445
1446        return tsm;
1447}
1448//-----------------------------------------------------------------------
1449void OcclusionCullingSceneManagerFactory::destroyInstance(SceneManager* instance)
1450{
1451        delete instance;
1452}
1453
1454} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.