source: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreBvHierarchySceneManager.cpp @ 2067

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