source: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp @ 2130

Revision 2130, 41.6 KB checked in by mattausch, 17 years ago (diff)

runs also under debug mode now

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