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

RevLine 
[1163]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>
[1175]11#include <OgreSubEntity.h>
[1182]12#include <OgreMaterialManager.h>
[1258]13#include <OgreLogManager.h>
14#include <OgreStringConverter.h>
15
[1163]16#include "OgreKdTreeSceneManager.h"
17#include "OgreKdTreeSceneNode.h"
18#include "OgreKdTree.h"
[1258]19
[1296]20#include <OgreMeshInstance.h>
21#include <OgreBoundingBoxConverter.h>
22#include <OgreTypeConverter.h>
[1258]23#include <VisibilityEnvironment.h>
[1175]24#include "OgreVisibilityOptionsManager.h"
[1163]25
26namespace Ogre
27{
[1182]28
29KdTreeSceneManager::KdTreeSceneManager(const String& name, GtpVisibility::VisibilityManager *vm):
30SceneManager(name),
31mVisibilityManager(vm),
32mKdTree(0),
33mMaxDepth(KDTREE_MAX_DEPTH),
34mShowBoxes(false),
[1192]35mHiLiteLevel(0),
[1182]36mShowAllBoxes(false),
[1214]37mEnhancedVisiblity(true),
[1304]38mBuildMethod(KdTree::KDBM_RECURSIVE),
[1182]39mRenderMethod(KdTree::KDRM_INTERNAL),
40mShowVisualization(false),
41mRenderNodesForViz(false),
42mRenderNodesContentForViz(false),
43mVisualizeCulledNodes(false),
44mLeavePassesInQueue(0),
45mDelayRenderTransparents(true),
[1312]46mUseDepthPass(false),
[1182]47mIsDepthPassPhase(false),
48mUseItemBuffer(false),
49mIsItemBufferPhase(false),
50mCurrentEntityId(1),
51mEnableDepthWrite(true),
52mSkipTransparents(false),
53mRenderTransparentsForItemBuffer(true),
54mExecuteVertexProgramForAllPasses(false),
[1251]55mIsHierarchicalCulling(false),
[1296]56mDeleteQueueAfterRendering(true),
57mViewCellsLoaded(false),
58mUseViewCells(false),
59mUseVisibilityFilter(false),
60mViewCellsManager(0),
61mElementaryViewCell(0),
62mCurrentViewCell(0)
[1182]63{
[1220]64        // Replace root node with my node
65        OGRE_DELETE(mSceneRoot);
66        mSceneRoot = new KdTreeSceneNode(this, "root node");
67        mSceneRoot->_notifyRootNode();
[1163]68
[1220]69        // init heirarchy interface
70        mHierarchyInterface = new KdTreeHierarchyInterface(this, mDestRenderSystem);
[1182]71}
[1163]72
[1182]73KdTreeSceneManager::~KdTreeSceneManager(void)
74{
75        delete mHierarchyInterface;
76        delete mKdTree;
77}
78
[1285]79void KdTreeSceneManager::clearScene()
80{
81        // DEBUG
[1296]82        //if (mKdTree)
83        //      mKdTree->dump();
[1285]84
85        // must happen before actual scene is cleared
86        OGRE_DELETE(mKdTree);
87
88        SceneManager::clearScene();
89}
90
91
[1182]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")
[1165]112        {
[1182]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;
[1192]123                        if (mHiLiteLevel > mMaxDepth)
124                                mHiLiteLevel = mMaxDepth;
[1182]125                        return true;
126                }
127                return true;
[1165]128        }
[1182]129        else if (strKey == "KT")
[1165]130        {
[1182]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                }
[1165]141        }
[1182]142        else if (strKey == "KI")
[1163]143        {
[1182]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                }
[1163]154        }
[1182]155        else if (strKey == "RebuildKdTree")
[1163]156        {
[1182]157                OGRE_DELETE(mKdTree);
[1192]158                mKdTree = new KdTree(mMaxDepth, mBuildMethod, mHiLiteLevel, mShowAllBoxes, mShowNodes);
[1182]159                mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot));
[1214]160                mKdTree->setEnhancedVis(mEnhancedVisiblity);
[1182]161                return true;
[1163]162        }
[1206]163        else if (strKey == "EnhancedVisibility")
164        {
165                bool enh = *static_cast<const bool *>(pValue);
[1214]166                mEnhancedVisiblity = enh;
[1211]167                if (mKdTree)
[1214]168                        mKdTree->setEnhancedVis(mEnhancedVisiblity);
[1211]169                //setEnhancedVis(enh);
[1206]170                return true;
171        }
[1182]172        else if (strKey == "BuildMethod")
173        {
[1220]174                KdTree::BuildMethod bm = *static_cast<const KdTree::BuildMethod *>(pValue);
175                if (bm == KdTree::KDBM_RECURSIVE || bm == KdTree::KDBM_PRIORITYQUEUE)
[1163]176                {
[1220]177                        mBuildMethod = bm;
[1182]178                        return true;
[1163]179                }
[1182]180                else
[1163]181                {
[1182]182                        return false;
[1163]183                }
[1182]184        }
185        else if (strKey == "RenderMethod")
186        {
[1220]187                KdTree::RenderMethod rm = *static_cast<const KdTree::RenderMethod *>(pValue);
188                if (rm == KdTree::KDRM_INTERNAL)
[1163]189                {
[1220]190                        mRenderMethod = rm;
[1163]191                        return true;
192                }
[1220]193                else if (rm == KdTree::KDRM_GTP_VFC)
[1163]194                {
[1220]195                        mRenderMethod = rm;
[1182]196                        int cmt = GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING;
197                        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
198                                .setOption("Algorithm", &cmt);
[1163]199                }
[1220]200                else if (rm == KdTree::KDRM_GTP_SWC)
[1170]201                {
[1220]202                        mRenderMethod = rm;
[1182]203                        int cmt = GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING;
204                        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
205                                .setOption("Algorithm", &cmt);
206                }
[1220]207                else if (rm == KdTree::KDRM_GTP_CHC)
[1182]208                {
[1220]209                        mRenderMethod = rm;
[1182]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)
[1177]229                                mRenderMethod = KdTree::KDRM_GTP_VFC;
[1182]230                        else if (val == GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING)
[1177]231                                mRenderMethod = KdTree::KDRM_GTP_SWC;
[1182]232                        else if (val == GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING)
[1177]233                                mRenderMethod = KdTree::KDRM_GTP_CHC;
[1182]234                        // default, should never happen
[1170]235                        else
[1182]236                                mRenderMethod = KdTree::KDRM_INTERNAL;
[1170]237                }
[1192]238                else
239                {
240                        mRenderMethod = KdTree::KDRM_INTERNAL;
241                }
[1182]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        }
[1192]250        else if (strKey == "HiLiteLevel")
[1183]251        {
[1192]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        {
[1183]275                bool sn = *static_cast<const bool *>(pValue);
[1192]276                mShowNodes = sn;
[1183]277                if (mKdTree)
[1192]278                        mKdTree->setShowNodes(mShowNodes);
[1183]279                return true;
280        }
281        // options for CHC
[1273]282        else if (strKey == "UseDepthPass")
[1183]283        {
284                mUseDepthPass = (*static_cast<const bool *>(pValue));
285                return true;
286        }
[1273]287        else if (strKey == "PrepareVisualization")
[1183]288        {
289                mShowVisualization = (*static_cast<const bool *>(pValue));
290                return true;
291        }
[1273]292        else if (strKey == "RenderNodesForViz")
[1183]293        {
294                mRenderNodesForViz = (*static_cast<const bool *>(pValue));
295                return true;
296        }
[1273]297        else if (strKey == "RenderNodesContentForViz")
[1183]298        {
299                mRenderNodesContentForViz = (*static_cast<const bool *>(pValue));
300                return true;
301        }
[1273]302        else if (strKey == "SkyBoxEnabled")
[1183]303        {
304                mSkyBoxEnabled = (*static_cast<const bool *>(pValue));
305                return true;
306        }
[1273]307        else if (strKey == "SkyPlaneEnabled")
[1183]308        {
309                mSkyPlaneEnabled = (*static_cast<const bool *>(pValue));
310                return true;
311        }
[1273]312        else if (strKey == "SkyDomeEnabled")
[1183]313        {
314                mSkyDomeEnabled = (*static_cast<const bool *>(pValue));
315                return true;
316        }
[1273]317        else if (strKey == "VisualizeCulledNodes")
[1183]318        {
319                mVisualizeCulledNodes = (*static_cast<const bool *>(pValue));
320                return true;
321        }
[1273]322        else if (strKey == "DelayRenderTransparents")
[1183]323        {
324                mDelayRenderTransparents = (*static_cast<const bool *>(pValue));
325                return true;
326        }
[1182]327
[1273]328        else if (strKey == "DepthWrite")
[1183]329        {
330                mEnableDepthWrite = (*static_cast<const bool *>(pValue));
331                return true;
332        }
[1273]333        else if (strKey == "UseItemBuffer")
[1183]334        {
335                mUseItemBuffer = (*static_cast<const bool *>(pValue));
336                return true;
337        }
[1273]338        else if (strKey == "ExecuteVertexProgramForAllPasses")
[1183]339        {
340                mExecuteVertexProgramForAllPasses  = (*static_cast<const bool *>(pValue));
341                return true;
342        }
[1273]343        else if (strKey == "RenderTransparentsForItemBuffer")
[1183]344        {
345                mRenderTransparentsForItemBuffer  = (*static_cast<const bool *>(pValue));
346                return true;
347        }
[1296]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                }
[1183]361
[1296]362                return mViewCellsLoaded;
363        }
364        else if (strKey == "UseViewCells")
365        {
366                if (mViewCellsLoaded)
367                {
368                        mUseViewCells = *static_cast<const bool *>(pValue);
[1183]369
[1296]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
[1182]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        }
[1206]425        else if (strKey == "EnhancedVisibility")
426        {
[1211]427                if (mKdTree)
428                        *static_cast<bool *>(pDestValue) = mKdTree->getEnhancedVis();
429                else
[1214]430                        *static_cast<bool *>(pDestValue) = mEnhancedVisiblity;
[1211]431                return true;
[1206]432        }
[1182]433        else if (strKey == "BuildMethod")
434        {
[1220]435                *static_cast<KdTree::BuildMethod *>(pDestValue) = mBuildMethod;
[1182]436                return true;
[1163]437        }
[1182]438        else if (strKey == "RenderMethod")
[1163]439        {
[1220]440                *static_cast<KdTree::RenderMethod *>(pDestValue) = mRenderMethod;
[1182]441                return true;
442        }
[1183]443        else if (strKey == "ShowKdTree")
444        {
445                *static_cast<bool *>(pDestValue) = mShowBoxes;
446                return true;
[1192]447        }       
448        else if (strKey == "HiLiteLevel")
449        {
450                *static_cast<int *>(pDestValue) = mHiLiteLevel;
451                return true;
[1183]452        }
[1192]453        else if (strKey == "ShowAllBoxes")
[1183]454        {
[1192]455                *static_cast<bool *>(pDestValue) = mShowAllBoxes;
[1183]456                return true;
457        }
[1192]458        else if (strKey == "ShowNodes")
[1182]459        {
[1192]460                *static_cast<bool *>(pDestValue) = mShowNodes;
461                return true;
[1182]462        }
[1296]463        // vis options
[1312]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        }
[1296]486        else if (strKey == "NumHierarchyNodes")
487        {
488                unsigned int numnodes = 0;
489                if (mKdTree)
[1312]490                        numnodes = mKdTree->getTreeStats().mNumNodes;
[1182]491
[1296]492                * static_cast<unsigned int *>(pDestValue) = (unsigned int)numnodes;
493                return true;
494        }
[1312]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        }
[1296]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
[1182]555        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
556                .getOption(strKey, pDestValue) || SceneManager::getOption(strKey, pDestValue);
557}
558
559bool KdTreeSceneManager::getOptionKeys(StringVector &refKeys)
560{
[1296]561        refKeys.push_back("Algorithm");
[1182]562        refKeys.push_back("BuildMethod");
[1296]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");
[1182]570        refKeys.push_back("KI");
571        refKeys.push_back("KT");
572        refKeys.push_back("KdTreeMaxDepth");
[1296]573        refKeys.push_back("LoadViewCells");
574        refKeys.push_back("NumHierarchyNodes");
575        refKeys.push_back("PrepareVisualization");
[1182]576        refKeys.push_back("RebuildKdTree");
577        refKeys.push_back("RenderMethod");
[1296]578        refKeys.push_back("RenderNodesContentForViz");
579        refKeys.push_back("RenderNodesForViz");
580        refKeys.push_back("RenderTransparentsForItemBuffer");
581        refKeys.push_back("ShowAllBoxes");
[1182]582        refKeys.push_back("ShowKdTree");
[1192]583        refKeys.push_back("ShowNodes");
[1296]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");
[1182]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
[1206]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
[1182]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        {
[1192]693                mKdTree = new KdTree(mMaxDepth, mBuildMethod);
[1182]694                mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot));
[1214]695                mKdTree->setEnhancedVis(mEnhancedVisiblity);
[1182]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        {
[1495]733                getRenderQueue()->clear(mDeleteQueueAfterRendering);
[1195]734                if (mShowVisualization)
735                {
736                        PrepareVisualization(cam);
737                }
738                else
739                {
740                        mVisibleNodes.clear();
741                        if (mKdTree)
[1301]742                        {
743                                // determine visibility
[1206]744                                mKdTree->queueVisibleObjects(KDCAMPTR_CAST(cam), getRenderQueue(), onlyShadowCasters, mShowBoxes, mVisibleNodes);
[1301]745                                // apply view cell pvs
746                                updatePvs(cam);
747                        }
[1195]748                }
[1182]749        }
750        else
751        {
752                //-- show visible scene nodes and octree bounding boxes from last frame
753                if (mShowVisualization)
[1163]754                {
[1182]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)
[1163]766                        {
[1182]767                                getRenderQueue()->clear();
768                                if (mKdTree)
[1206]769                                        mKdTree->queueVisibleObjects(KDCAMPTR_CAST(cam), getRenderQueue(), onlyShadowCasters, mShowBoxes, mVisibleNodes);
[1163]770                        }
[1182]771
772                        // only shadow casters will be rendered in shadow texture pass
773                        if (0) mHierarchyInterface->SetOnlyShadowCasters(onlyShadowCasters);
774
775
[1296]776                        //-- apply view cell pvs -
777                        updatePvs(cam);
[1182]778                }
[1195]779                mVisibleNodes.clear(); 
[1182]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)
[1163]806                        {
[1182]807                                // disable illumination stage to prevent rendering shadows
808                                mIlluminationStage = IRS_NONE;
[1163]809                        }
[1182]810
811                        // standard rendering for shadow maps because of performance
812                        SceneManager::_renderVisibleObjects();
813
814                        mIlluminationStage = savedStage;
[1163]815                }
[1182]816                else //-- the hierarchical culling algorithm
[1170]817                {
[1264]818                        // this is also called in TerrainSceneManager: really necessary?
[1182]819                        //mDestRenderSystem -> setLightingEnabled(false);
820
821                        // don't render backgrounds for item buffer
822                        if (mUseItemBuffer)
[1170]823                        {
[1182]824                                clearSpecialCaseRenderQueues();
825                                getRenderQueue()->clear();
[1170]826                        }
[1182]827
828                        //-- hierarchical culling
[1264]829
[1182]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:
[1251]870                        // all which are not in mLeavePassesInQueue
[1182]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)
[1170]885                        {
[1187]886                                KdTree::NodeList::const_iterator it, end = mVisibleNodes.end();
887                                for (it = mVisibleNodes.begin(); it != end; it++)
[1185]888                                {
[1187]889                                        (*it)->queueVisibleObjects(mHierarchyInterface->GetFrameId(), mCameraInProgress,
890                                                getRenderQueue(), false, mShowBoxes);
[1185]891                                }
[1170]892                        }
[1251]893
[1182]894                        //-- now we can render all remaining queue objects
895                        //-- used for depth pass, transparents, overlay
896                        clearSpecialCaseRenderQueues();
[1163]897
[1182]898                        SceneManager::_renderVisibleObjects();
899                } // hierarchical culling
900
901
902                // reset ambient light
903                setAmbientLight(savedAmbient);
904
905
[1304]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
[1182]914                if (0) WriteLog(); // write out stats
[1163]915        }
[1182]916}
[1163]917
[1264]918
[1187]919void KdTreeSceneManager::_renderNode(KdTree::NodePtr node, Camera * cam,
920                                                                         bool onlyShadowCasters, int leavePassesInQueue)
[1182]921{
[1185]922        RenderQueueGroup *currentGroup =
923                getRenderQueue()->getQueueGroup(getRenderQueue()->getDefaultQueueGroup());
924        currentGroup->clear(leavePassesInQueue);
[1175]925
[1187]926        node->queueVisibleObjects(mHierarchyInterface->GetFrameId(), cam, getRenderQueue(),
927                onlyShadowCasters, mShowBoxes);
928        mVisibleNodes.push_back(node);
929
[1185]930        _renderQueueGroupObjects(currentGroup, QueuedRenderableCollection::OM_PASS_GROUP);
[1182]931}
[1296]932
[1182]933//-----------------------------------------------------------------------
[1296]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//-----------------------------------------------------------------------
[1182]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())
[1175]1017        {
[1182]1018                RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
[1175]1019
[1182]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)
[1175]1043        {
[1182]1044                return SceneManager::validatePassForRendering(pass);
[1175]1045        }
1046
[1182]1047        // skip all but first pass if we are doing the depth pass
1048        if ((mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() > 0))
[1175]1049        {
[1182]1050                return false;
[1175]1051        }
[1182]1052        // all but first pass
1053        /*else if ((!mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() != 0))
1054        {
1055        return false;
1056        }*/
[1175]1057
[1182]1058        return SceneManager::validatePassForRendering(pass);
1059}
1060//-----------------------------------------------------------------------
1061void KdTreeSceneManager::_renderQueueGroupObjects(RenderQueueGroup* pGroup,
1062                                                                                                  QueuedRenderableCollection::OrganisationMode om)
1063{
1064        if (mRenderMethod == KdTree::KDRM_INTERNAL || !mIsItemBufferPhase)
[1175]1065        {
[1182]1066                SceneManager::_renderQueueGroupObjects(pGroup, om);
1067                return;
[1175]1068        }
[1182]1069#ifdef  ITEM_BUFFER
1070        //-- item buffer
1071        //-- item buffer: render objects using false colors
[1175]1072
[1182]1073        // Iterate through priorities
1074        RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
1075
1076        while (groupIt.hasMoreElements())
[1175]1077        {
[1182]1078                RenderItemBuffer(groupIt.getNext());
[1175]1079        }
[1182]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;
[1175]1091
[1182]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
[1163]1112        {
[1182]1113                SceneManager::renderAdditiveStencilShadowedQueueGroupObjects(pGroup, om);
[1163]1114        }
[1182]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();
[1163]1124
[1182]1125                while (groupIt.hasMoreElements())
[1163]1126                {
[1182]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);
[1163]1134                }
[1182]1135        }
1136        else
1137        {
1138                SceneManager::renderModulativeStencilShadowedQueueGroupObjects(pGroup, om);
1139        }
1140}
1141//-----------------------------------------------------------------------
1142void KdTreeSceneManager::InitDepthPass()
1143{
1144        MaterialPtr depthMat = MaterialManager::getSingleton().getByName("Visibility/DepthPass");
[1163]1145
[1182]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);
[1163]1156        }
[1182]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");
[1163]1167
[1182]1168        if (itemBufferMat.isNull())
[1175]1169        {
[1182]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)
[1175]1194                {
[1182]1195                        getRenderQueue()->addRenderable(c);
1196                }   
1197        }
1198        catch (...)
1199        {
1200                // ignore
1201        }
[1175]1202
[1185]1203        if (mRenderNodesForViz || mRenderNodesContentForViz)
1204        {
[1195]1205                RenderQueue * queue = getRenderQueue();
1206                unsigned long frameid = 0;
[1185]1207
[1195]1208                if (mRenderMethod == KdTree::KDRM_INTERNAL)
1209                        frameid = Root::getSingleton().getCurrentFrameNumber();
1210                else
1211                        frameid = mHierarchyInterface->GetFrameId();
1212
[1187]1213                for (KdTree::NodeList::iterator it = mVisibleNodes.begin(); it != mVisibleNodes.end(); ++it)
[1182]1214                {
[1195]1215                        if (mRenderNodesForViz && (*it)->isLeaf())
[1185]1216                        {
[1190]1217                                WireBoundingBox * wirebox = (*it)->getWireBoundingBox();
[1195]1218                                wirebox->setMaterial("KdTree/BoxViz");
1219                                getRenderQueue()->addRenderable(wirebox);
[1185]1220                        }
1221                        // add renderables itself
1222                        if (mRenderNodesContentForViz)
1223                        {
[1195]1224                                (*it)->queueVisibleObjects(frameid, cam, queue, false, false);
[1185]1225                        }
1226                }
1227        }       
[1182]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));
[1175]1245        }
1246
[1182]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)
[1163]1256        {
[1182]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;
[1163]1261
[1182]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);
[1163]1270                }
1271
[1182]1272                if (mShadowTechnique == SHADOWTYPE_STENCIL_MODULATIVE)
[1163]1273                {
[1182]1274                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
1275                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
[1163]1276                }
1277
[1182]1278                // transparents should be rendered after hierarchical culling to
1279                // provide front-to-back ordering
1280                if (mDelayRenderTransparents)
1281                {
1282                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
[1163]1283                }
1284        }
1285
[1182]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}
[1296]1300
1301//-------------------------------------------------------------------------
1302void KdTreeSceneManager::SetObjectsVisible(const bool visible)
[1182]1303{
[1296]1304        GtpVisibilityPreprocessor::ObjectContainer::iterator it, it_end = mObjects.end();
[1182]1305
[1296]1306        for (it = mObjects.begin(); it != it_end; ++ it)
1307        {
1308                OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(*it);
[1593]1309                Entity *ent = omi->GetEntity();
[1182]1310
[1296]1311                ent->setVisible(visible);
1312        }
[1182]1313}
1314//-----------------------------------------------------------------------
[1296]1315bool KdTreeSceneManager::LoadViewCells(const String &filename)
[1182]1316{
[1296]1317        // objects are set to invisible initially
1318        SetObjectsVisible(false);
[1177]1319
[1296]1320        const string bboxesFilename = mVisibilityManager->GetVisibilityEnvironment()->getViewCellsFileName();
[1182]1321
[1296]1322        // converter between view cell ids and Ogre entites
1323        GtpVisibilityPreprocessor::IndexedBoundingBoxContainer iboxes;
[1595]1324        KdTreeBoundingBoxConverter bconverter(this);
[2115]1325
[1296]1326        // load the view cells assigning the found objects to the pvss
1327        mViewCellsManager =
[2114]1328                GtpVisibilityPreprocessor::ViewCellsManager::
[2115]1329                        LoadViewCells(filename, mObjects, false, &bconverter);
[1182]1330
[1296]1331        return (mViewCellsManager != NULL);
1332}
1333//-------------------------------------------------------------------------
1334void KdTreeSceneManager::applyViewCellPvs(GtpVisibilityPreprocessor::ViewCell *vc,
1335                                                                                                        const bool load)
[1816]1336{       
[1296]1337        if (!vc)
1338        {       
1339                // set everything visible for savety
[1816]1340
1341                // NOTE: should not happen, rather apply view cell
1342                // representing unbounded space then
[1296]1343                SetObjectsVisible(true);
[2115]1344
[1296]1345                return;
[1163]1346        }
1347
[1816]1348        //////////
1349        //-- set PVS of view cell visible
[2066]1350
[1816]1351        GtpVisibilityPreprocessor::ObjectPvsIterator pit = vc->GetPvs().GetIterator();
[1296]1352
[1816]1353        while (pit.HasMoreEntries())
1354        {               
[2123]1355                GtpVisibilityPreprocessor::Intersectable *entry = pit.Next();
[1182]1356
[2123]1357                if (entry)
[1816]1358                {
[2123]1359                        OgreMeshInstance *omi = static_cast<OgreMeshInstance *>(entry);
[1816]1360                        omi->GetEntity()->setVisible(load);
1361                }
[1173]1362        }
[1296]1363}
1364//-------------------------------------------------------------------------
1365void KdTreeSceneManager::updatePvs(Camera *cam)
1366{
1367        if (!(mViewCellsLoaded && mUseViewCells))
1368                return;
[1182]1369
[1296]1370        const GtpVisibilityPreprocessor::Vector3 viewPoint =
1371                OgreTypeConverter::ConvertFromOgre(cam->getDerivedPosition());
[1232]1372
[1296]1373        GtpVisibilityPreprocessor::ViewCell *newElementary =
1374                mViewCellsManager->GetViewCell(viewPoint);
[1182]1375
[1296]1376        // elementary view cell did not change => apply same pvs
1377        if (mElementaryViewCell == newElementary)
1378                return;
[1182]1379
[1296]1380        mElementaryViewCell = newElementary;
1381        //LogManager::getSingleton().logMessage("unloading");
1382        //-- unload old pvs
1383        applyViewCellPvs(mCurrentViewCell, false);
[1182]1384
1385
[1296]1386        //-- the new view cell
[1182]1387
[1296]1388        GtpVisibilityPreprocessor::ViewCell *viewCell;
1389
1390
1391        if (mUseVisibilityFilter)
[1163]1392        {
[1296]1393                //-- compute new filtered cell
1394                GtpVisibilityPreprocessor::PrVs prvs;
1395                mViewCellsManager->GetPrVS(viewPoint, prvs, 5);
1396                viewCell = prvs.mViewCell;
[1163]1397        }
[1296]1398        else
1399        {
1400                viewCell = newElementary;
1401        }
1402        //LogManager::getSingleton().logMessage("loading");
1403        //-- load new pvs
1404        applyViewCellPvs(viewCell, true);
[1163]1405
[1296]1406        // store pvs
1407        mCurrentViewCell->SetPvs(viewCell->GetPvs());
[1182]1408
[1296]1409        // delete merge tree of filtered view cell
1410        if (mUseVisibilityFilter)
1411                mViewCellsManager->DeleteLocalMergeTree(viewCell);
[1182]1412}
1413
1414//-----------------------------------------------------------------------
[1296]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() << ", "
[1312]1423                << "Hierarchy nodes: " << (mKdTree ? mKdTree->getTreeStats().mNumNodes : 0) << ", "
[1296]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/************************************************************************/
[1182]1438//-----------------------------------------------------------------------
[1296]1439//-----------------------------------------------------------------------
[1182]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
[1163]1461} // namespace Ogre
1462
Note: See TracBrowser for help on using the repository browser.