source: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreBiHierarchySceneManager.cpp @ 2455

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