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

Revision 2555, 42.8 KB checked in by mattausch, 17 years ago (diff)

added partial implementation of chc++. problem: bounding box rendering in Ogre is VERY slow

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