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

Revision 2115, 41.7 KB checked in by mattausch, 17 years ago (diff)

changed pvs loading: loading objects in a first pass

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