source: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreOcclusionCullingSceneManager.cpp @ 868

Revision 868, 30.3 KB checked in by mattausch, 18 years ago (diff)

fitting objects to bb, debug

Line 
1#include "OgreOcclusionCullingSceneManager.h"
2#include "OgreVisibilityOptionsManager.h"
3#include "OgreTypeConverter.h"
4#include <OgreMath.h>
5#include <OgreIteratorWrappers.h>
6#include <OgreRenderSystem.h>
7#include <OgreCamera.h>
8#include <OgreLogManager.h>
9#include <OgreStringConverter.h>
10#include <OgreEntity.h>
11#include <OgreSubEntity.h>
12#include <OgreIteratorWrappers.h>
13#include "VspBspTree.h"
14#include "Containers.h"
15#include "ViewCellsManager.h"
16
17
18// normal terrain rendering
19const static NORMAL_RENDER_HACK = false;
20
21namespace Ogre {
22
23//-----------------------------------------------------------------------
24OcclusionCullingSceneManager::OcclusionCullingSceneManager(
25                                                        GtpVisibility::VisibilityManager *visManager):
26TerrainSceneManager(),
27mVisibilityManager(visManager),
28mShowVisualization(false),
29mRenderNodesForViz(false),
30mRenderNodesContentForViz(false),
31mVisualizeCulledNodes(false),
32mLeavePassesInQueue(0),
33mDelayRenderTransparents(true),
34mUseDepthPass(false),
35mIsDepthPassPhase(false),
36mUseItemBuffer(false),
37mIsItemBufferPhase(false),
38mCurrentEntityId(1),
39mEnableDepthWrite(true),
40mSkipTransparents(false),
41mRenderTransparentsForItemBuffer(true),
42mExecuteVertexProgramForAllPasses(true),
43mIsHierarchicalCulling(false)
44{
45        mHierarchyInterface = new OctreeHierarchyInterface(this, mDestRenderSystem);
46       
47        if (0)
48        {
49        mDisplayNodes = true;
50        mShowBoundingBoxes = true;
51        mShowBoxes = true;
52        }
53
54        // TODO: set maxdepth to reasonable value
55        mMaxDepth = 50;
56}
57//-----------------------------------------------------------------------
58void OcclusionCullingSceneManager::InitDepthPass()
59{
60        MaterialPtr depthMat = MaterialManager::getSingleton().getByName("Visibility/DepthPass");
61
62        if (depthMat.isNull())
63    {
64                depthMat = MaterialManager::getSingleton().create(
65                "Visibility/DepthPass",
66                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
67
68        mDepthPass = depthMat->getTechnique(0)->getPass(0);
69                mDepthPass->setColourWriteEnabled(false);
70                mDepthPass->setDepthWriteEnabled(true);
71                mDepthPass->setLightingEnabled(false);
72        }
73        else
74        {
75                mDepthPass = depthMat->getTechnique(0)->getPass(0);
76        }
77}
78//-----------------------------------------------------------------------
79OcclusionCullingSceneManager::~OcclusionCullingSceneManager()
80{
81        OGRE_DELETE(mHierarchyInterface);
82}
83//-----------------------------------------------------------------------
84void OcclusionCullingSceneManager::InitItemBufferPass()
85{
86        MaterialPtr itemBufferMat = MaterialManager::getSingleton().
87                getByName("Visibility/ItemBufferPass");
88
89        if (itemBufferMat.isNull())
90    {
91                // Init
92                itemBufferMat = MaterialManager::getSingleton().create("Visibility/ItemBufferPass",
93                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
94
95                mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0);
96                mItemBufferPass->setColourWriteEnabled(true);
97                mItemBufferPass->setDepthWriteEnabled(true);
98                mItemBufferPass->setLightingEnabled(true);
99                //mItemBufferPass->setLightingEnabled(false);
100        }
101        else
102        {
103                mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0);
104        }
105        //mItemBufferPass->setAmbient(1, 1, 0);
106}
107//-----------------------------------------------------------------------
108void OcclusionCullingSceneManager::PrepareVisualization(Camera *cam)
109{
110        // add player camera for visualization purpose
111        try
112        {
113                Camera *c;
114                if ((c = getCamera("PlayerCam")) != NULL)
115                {
116                        getRenderQueue()->addRenderable(c);
117                }   
118    }
119    catch (...)
120    {
121        // ignore
122    }
123        // add bounding boxes of rendered objects
124        for (BoxList::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it)
125        {
126                getRenderQueue()->addRenderable(*it);
127        }
128       
129        if (mRenderNodesForViz || mRenderNodesContentForViz)
130        {
131                // HACK: change node material so it is better suited for visualization
132                MaterialPtr nodeMat = MaterialManager::getSingleton().getByName("Core/NodeMaterial");
133                nodeMat->setAmbient(1, 1, 0);
134                nodeMat->setLightingEnabled(true);
135                nodeMat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
136
137                for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++it)
138                {
139                        if (mRenderNodesForViz)
140                        {
141                                // render the leaf nodes
142                                if (((*it)->numAttachedObjects() > 0) && ((*it)->numChildren() == 0) &&
143                                         (*it)->getAttachedObject(0)->getMovableType() == "Entity")
144                                {
145                                        getRenderQueue()->addRenderable((*it));
146                                }
147
148                                // addbounding boxes instead of node itself
149                                //(*it)->_addBoundingBoxToQueue(getRenderQueue());
150                        }
151                        if (mRenderNodesContentForViz)
152                        {
153                                (*it)->_addToRenderQueue(cam, getRenderQueue(), false);
154                        }
155                }
156        }       
157}
158//-----------------------------------------------------------------------
159Pass *OcclusionCullingSceneManager::setPass(Pass* pass)
160{
161        if (NORMAL_RENDER_HACK)
162        {
163                return SceneManager::setPass(pass);
164        }
165
166        // TODO: setting vertex program is not efficient
167        //Pass *usedPass = ((mIsDepthPassPhase && !pass->hasVertexProgram()) ? mDepthPass : pass);
168       
169        // set depth fill pass if we currently do not make an aabb occlusion query
170        const bool useDepthPass =
171                (mIsDepthPassPhase && !mHierarchyInterface->IsBoundingBoxQuery());
172
173        Pass *usedPass = useDepthPass ? mDepthPass : pass;
174               
175        IlluminationRenderStage savedStage = mIlluminationStage;
176       
177        // set illumination stage to NONE so no shadow material is used
178        // for depth pass or for occlusion query
179        if (mIsDepthPassPhase || mHierarchyInterface->IsBoundingBoxQuery())
180        {
181                mIlluminationStage = IRS_NONE;
182        }
183       
184        // --- set vertex program of current pass in order to set correct depth
185        if (mExecuteVertexProgramForAllPasses &&
186                mIsDepthPassPhase &&
187                pass->hasVertexProgram())
188        {
189                // add vertex program of current pass to depth pass
190                mDepthPass->setVertexProgram(pass->getVertexProgramName());
191
192                if (mDepthPass->hasVertexProgram())
193                {
194                        const GpuProgramPtr& prg = mDepthPass->getVertexProgram();
195                        // Load this program if not done already
196                        if (!prg->isLoaded())
197                                prg->load();
198                        // Copy params
199                        mDepthPass->setVertexProgramParameters(pass->getVertexProgramParameters());
200                }
201        }
202        else if (mDepthPass->hasVertexProgram()) // reset vertex program
203        {
204                mDepthPass->setVertexProgram("");
205        }
206       
207        // save old depth write: needed for item buffer
208        const bool IsDepthWrite = usedPass->getDepthWriteEnabled();
209
210        // global option which enables / disables depth writes
211        if (!mEnableDepthWrite)
212        {
213                usedPass->setDepthWriteEnabled(false);
214        }
215        //else if (mIsItemBufferPass) {usedPass = mItemBufferPass;}
216       
217
218        //-- set actual pass here
219        Pass *result = SceneManager::setPass(usedPass);
220
221
222        // reset depth write
223        if (!mEnableDepthWrite)
224        {
225                usedPass->setDepthWriteEnabled(IsDepthWrite);
226        }
227
228        // reset illumination stage
229        mIlluminationStage = savedStage;
230
231        return result;
232}
233//-----------------------------------------------------------------------
234void OcclusionCullingSceneManager::_findVisibleObjects(Camera* cam, bool onlyShadowCasters)
235{
236        if (NORMAL_RENDER_HACK)
237        {
238                OctreeSceneManager::_findVisibleObjects(cam, onlyShadowCasters);
239                return;
240        }
241
242        //-- show visible scene nodes and octree bounding boxes from last frame
243        if (mShowVisualization)
244    {
245                PrepareVisualization(cam);
246        }
247        else
248        {       
249                // for hierarchical culling, we interleave identification
250                // and rendering of objects in _renderVisibibleObjects
251
252                // for the shadow pass we use only standard rendering
253                // because of low occlusion
254                if (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE &&
255                        mIlluminationStage == IRS_RENDER_TO_TEXTURE)
256                {
257                        OctreeSceneManager::_findVisibleObjects(cam, onlyShadowCasters);
258                }
259                // only shadow casters will be rendered in shadow texture pass
260                if (0) mHierarchyInterface->SetOnlyShadowCasters(onlyShadowCasters);
261        }
262       
263       
264        // -- delete lists stored for visualization
265        mVisible.clear();
266        mBoxes.clear();
267}
268//-----------------------------------------------------------------------
269void OcclusionCullingSceneManager::_renderVisibleObjects()
270{
271        if (NORMAL_RENDER_HACK)
272        {
273                OctreeSceneManager::_renderVisibleObjects();
274
275                return;
276        }
277
278        InitDepthPass();          // create material for depth pass
279        InitItemBufferPass(); // create material for item buffer pass
280
281        // save ambient light to reset later
282        ColourValue savedAmbient = mAmbientLight;
283
284        //-- apply standard rendering for some modes (e.g., visualization, shadow pass)
285
286        if (mShowVisualization ||
287           (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE &&
288            mIlluminationStage == IRS_RENDER_TO_TEXTURE))
289        {       
290                IlluminationRenderStage savedStage = mIlluminationStage;
291       
292                if (mShowVisualization)
293                {
294                        // disable illumination stage to prevent rendering shadows
295                        mIlluminationStage = IRS_NONE;
296                }
297
298                // standard rendering for shadow maps because of performance
299                TerrainSceneManager::_renderVisibleObjects();
300
301                mIlluminationStage = savedStage;
302        }
303        else //-- the hierarchical culling algorithm
304        {
305                // this is also called in TerrainSceneManager: really
306                // nexessary?
307                mDestRenderSystem -> setLightingEnabled(false);
308
309                // don't render backgrounds for item buffer
310                if (mUseItemBuffer)
311                {
312                        clearSpecialCaseRenderQueues();
313                        getRenderQueue()->clear();
314                }
315
316                //-- hierarchical culling
317                // the objects of different layers (e.g., background, scene,
318                // overlay) must be identified and rendered one after another
319
320                //-- render all early skies
321                clearSpecialCaseRenderQueues();
322                addSpecialCaseRenderQueue(RENDER_QUEUE_BACKGROUND);
323                addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_EARLY);
324                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE);
325
326                TerrainSceneManager::_renderVisibleObjects();
327
328#ifdef GTP_VISIBILITY_MODIFIED_OGRE
329                // delete previously rendered content
330                _deleteRenderedQueueGroups();
331#endif
332
333                //-- prepare queue for visible objects (i.e., all but overlay and skies late)
334                clearSpecialCaseRenderQueues();
335                addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_LATE);
336                addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY);
337                       
338                // exclude this queues from hierarchical rendering
339                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE);
340
341                // set all necessary parameters for
342                // hierarchical visibility culling and rendering
343                InitVisibilityCulling(mCameraInProgress);
344
345       
346                /**
347                * the hierarchical culling algorithm
348                * for depth pass: we just find objects and update depth buffer
349                * for "delayed" rendering: we render some passes afterwards
350                * e.g., transparents, because they need front-to-back sorting
351                **/
352               
353                mVisibilityManager->ApplyVisibilityCulling();
354
355                // delete remaining renderables from queue:
356                // all which are not in mLeavePassesInQueue)
357#ifdef GTP_VISIBILITY_MODIFIED_OGRE
358                _deleteRenderedQueueGroups(mLeavePassesInQueue);
359#endif
360
361                //-- reset parameters
362                mIsDepthPassPhase = false;
363                mIsItemBufferPhase = false;
364                mSkipTransparents = false;
365                mIsHierarchicalCulling = false;
366               
367                mLeavePassesInQueue = 0;
368
369#if 1   
370                // add visible nodes found by the visibility culling algorithm
371                if (mUseDepthPass)
372                {
373                        NodeList::const_iterator it, it_end = mVisible.end();
374
375                        //getRenderQueue()->clear();
376                        for (it = mVisible.begin(); it != it_end; ++ it)
377                        {
378                                (*it)->_addToRenderQueue(mCameraInProgress, getRenderQueue(), false);
379                        }
380                }
381#endif 
382                //-- now we can render all remaining queue objects
383                //-- used for depth pass, transparents, overlay
384                clearSpecialCaseRenderQueues();
385
386                TerrainSceneManager::_renderVisibleObjects();
387        } // hierarchical culling
388               
389        // HACK: set the new render level index, important to avoid cracks
390        // in terrain caused by LOD
391        TerrainRenderable::NextRenderLevelIndex();
392       
393        // reset ambient light
394        setAmbientLight(savedAmbient);
395
396        getRenderQueue()->clear(); // finally clear render queue
397        if (0) OGRE_DELETE(mRenderQueue); // HACK: should rather only be cleared ...
398
399        if (0) WriteLog(); // write out stats
400}
401
402//-----------------------------------------------------------------------
403void OcclusionCullingSceneManager::_updateSceneGraph(Camera* cam)
404{
405        if (NORMAL_RENDER_HACK)
406        {
407                OctreeSceneManager::_updateSceneGraph(cam);
408                return;
409        }
410
411        mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface);
412        mHierarchyInterface->SetRenderSystem(mDestRenderSystem);
413
414        TerrainSceneManager::_updateSceneGraph(cam);
415}
416//-----------------------------------------------------------------------
417bool OcclusionCullingSceneManager::setOption(const String & key, const void * val)
418{
419        if (key == "UseDepthPass")
420        {
421                mUseDepthPass = (*static_cast<const bool *>(val));
422                return true;
423        }
424        if (key == "PrepareVisualization")
425        {
426                mShowVisualization = (*static_cast<const bool *>(val));
427                return true;
428        }
429        if (key == "RenderNodesForViz")
430        {
431                mRenderNodesForViz = (*static_cast<const bool *>(val));
432                return true;
433        }
434        if (key == "RenderNodesContentForViz")
435        {
436                mRenderNodesContentForViz = (*static_cast<const bool *>(val));
437                return true;
438        }
439        if (key == "SkyBoxEnabled")
440        {
441                mSkyBoxEnabled = (*static_cast<const bool *>(val));
442                return true;
443        }
444        if (key == "SkyPlaneEnabled")
445        {
446                mSkyPlaneEnabled = (*static_cast<const bool *>(val));
447                return true;
448        }
449        if (key == "SkyDomeEnabled")
450        {
451                mSkyDomeEnabled = (*static_cast<const bool *>(val));
452                return true;
453        }
454        if (key == "VisualizeCulledNodes")
455        {
456                mVisualizeCulledNodes = (*static_cast<const bool *>(val));
457                return true;
458        }
459        if (key == "DelayRenderTransparents")
460        {
461                mDelayRenderTransparents = (*static_cast<const bool *>(val));
462                return true;
463        }
464
465        if (key == "DepthWrite")
466        {
467                mEnableDepthWrite = (*static_cast<const bool *>(val));
468                return true;
469        }
470        if (key == "UseItemBuffer")
471        {
472                mUseItemBuffer = (*static_cast<const bool *>(val));
473                return true;
474        }
475        if (key == "ExecuteVertexProgramForAllPasses")
476        {
477                mExecuteVertexProgramForAllPasses  = (*static_cast<const bool *>(val));
478                return true;
479        }
480        if (key == "RenderTransparentsForItemBuffer")
481        {
482                mRenderTransparentsForItemBuffer  = (*static_cast<const bool *>(val));
483                return true;
484        }
485        if (key == "NodeVizScale")
486        {
487                OctreeNode::setVizScale(*static_cast<const float *>(val));
488                return true;
489        }
490
491        if (key == "UseArbQueries")
492        {
493                bool useArbQueries = (*static_cast<const bool *>(val));
494
495                if (useArbQueries)
496                {
497                        mHierarchyInterface->DeleteQueries();
498                        mDestRenderSystem->setConfigOption("ArbQueries", "Yes");
499                }
500                else
501                {
502                        mHierarchyInterface->DeleteQueries();
503                        mDestRenderSystem->setConfigOption("ArbQueries", "No");
504                }
505        }
506
507        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
508                setOption(key, val) || TerrainSceneManager::setOption(key, val);
509}
510//-----------------------------------------------------------------------
511bool OcclusionCullingSceneManager::getOption(const String & key, void *val)
512{
513        if (key == "NumHierarchyNodes")
514        {
515                * static_cast<unsigned int *>(val) = (unsigned int)mNumOctants;
516                return true;
517        }
518       
519        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
520                getOption(key, val) && TerrainSceneManager::getOption(key, val);
521}
522//-----------------------------------------------------------------------
523bool OcclusionCullingSceneManager::getOptionValues(const String & key,
524                                                                                                        StringVector &refValueList)
525{
526        return TerrainSceneManager::getOptionValues( key, refValueList);
527}
528//-----------------------------------------------------------------------
529bool OcclusionCullingSceneManager::getOptionKeys(StringVector & refKeys)
530{
531        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
532                getOptionKeys(refKeys) || TerrainSceneManager::getOptionKeys(refKeys);
533}
534//-----------------------------------------------------------------------
535void OcclusionCullingSceneManager::setVisibilityManager(GtpVisibility::
536                                                                                                                 VisibilityManager *visManager)
537{
538        mVisibilityManager = visManager;
539}
540//-----------------------------------------------------------------------
541GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::getVisibilityManager( void )
542{
543        return mVisibilityManager;
544}
545//-----------------------------------------------------------------------
546void OcclusionCullingSceneManager::WriteLog()
547{
548        std::stringstream d;
549
550        d << "Depth pass: " << StringConverter::toString(mUseDepthPass) << ", "
551          << "Delay transparents: " << StringConverter::toString(mDelayRenderTransparents) << ", "
552          << "Use optimization: " << StringConverter::toString(mHierarchyInterface->GetTestGeometryForVisibleLeaves()) << ", "
553          << "Algorithm type: " << mVisibilityManager->GetCullingManagerType() << ", "
554          << "Hierarchy nodes: " << mNumOctants << ", "
555          << "Traversed nodes: " << mHierarchyInterface->GetNumTraversedNodes() << ", "
556          << "Rendered nodes: " << mHierarchyInterface->GetNumRenderedNodes() << ", "
557          << "Query culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumQueryCulledNodes() << ", "
558          << "Frustum culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumFrustumCulledNodes() << ", "
559      << "Queries issued: " << mVisibilityManager->GetCullingManager()->GetNumQueriesIssued() << ", "
560          << "Found objects: " << (int)mVisible.size() << "\n";
561
562        LogManager::getSingleton().logMessage(d.str());
563}
564//-----------------------------------------------------------------------
565void OcclusionCullingSceneManager::renderObjects(
566        const RenderPriorityGroup::TransparentRenderablePassList& objs,
567    bool doLightIteration, const LightList* manualLightList)
568{
569        // for correct rendering, transparents must be rendered after hierarchical culling
570        // => do nothing
571        if (NORMAL_RENDER_HACK || !mSkipTransparents)
572        {
573                OctreeSceneManager::renderObjects(objs, doLightIteration, manualLightList);
574        }
575}
576//-----------------------------------------------------------------------
577bool OcclusionCullingSceneManager::validatePassForRendering(Pass* pass)
578{
579        if (NORMAL_RENDER_HACK)
580        {
581                return SceneManager::validatePassForRendering(pass);
582        }
583
584        // skip all but first pass if we are doing the depth pass
585        if ((mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() > 0))
586        {
587                return false;
588        }
589        // all but first pass
590        /*else if ((!mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() != 0))
591        {
592                return false;
593        }*/
594
595        return SceneManager::validatePassForRendering(pass);
596}
597//-----------------------------------------------------------------------
598void OcclusionCullingSceneManager::renderQueueGroupObjects(RenderQueueGroup* pGroup)
599{
600        if (NORMAL_RENDER_HACK || !mIsItemBufferPhase)
601        {
602                TerrainSceneManager::renderQueueGroupObjects(pGroup);
603                return;
604        }
605
606        //-- item buffer: render objects using false colors
607
608    // Iterate through priorities
609    RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
610
611        while (groupIt.hasMoreElements())
612    {
613                RenderItemBuffer(groupIt.getNext());
614        }
615}
616//-----------------------------------------------------------------------
617void OcclusionCullingSceneManager::RenderItemBuffer(RenderPriorityGroup* pGroup)
618{
619        // Do solids
620        RenderPriorityGroup::SolidRenderablePassMap solidObjs = pGroup->_getSolidPasses();
621
622        // ----- SOLIDS LOOP -----
623        RenderPriorityGroup::SolidRenderablePassMap::const_iterator ipass, ipassend;
624        ipassend = solidObjs.end();
625
626        for (ipass = solidObjs.begin(); ipass != ipassend; ++ipass)
627        {
628                // Fast bypass if this group is now empty
629                if (ipass->second->empty())
630                        continue;
631
632                // Render only first pass of renderable as false color
633                if (ipass->first->getIndex() > 0)
634                        continue;
635
636                RenderPriorityGroup::RenderableList* rendList = ipass->second;
637               
638                RenderPriorityGroup::RenderableList::const_iterator irend, irendend;
639                irendend = rendList->end();
640                       
641                for (irend = rendList->begin(); irend != irendend; ++irend)
642                {
643                        if (0)
644                        {
645                        std::stringstream d; d << "itembuffer, pass name: " <<
646                                ipass->first->getParent()->getParent()->getName();
647                               
648                        LogManager::getSingleton().logMessage(d.str());
649                        }
650                       
651                        RenderSingleObjectForItemBuffer(*irend, ipass->first);
652                }
653        }
654
655        //-- TRANSPARENT LOOP: must be handled differently from solids
656
657        // transparents are treated either as solids or completely discarded
658        if (mRenderTransparentsForItemBuffer)
659        {
660                RenderPriorityGroup::TransparentRenderablePassList transpObjs =
661                        pGroup->_getTransparentPasses();
662                RenderPriorityGroup::TransparentRenderablePassList::const_iterator
663                        itrans, itransend;
664
665                itransend = transpObjs.end();
666                for (itrans = transpObjs.begin(); itrans != itransend; ++itrans)
667                {
668                        // like for solids, render only first pass
669                        if (itrans->pass->getIndex() == 0)
670                        {       
671                                RenderSingleObjectForItemBuffer(itrans->renderable, itrans->pass);
672                        }
673                }
674        }
675}
676//-----------------------------------------------------------------------
677void OcclusionCullingSceneManager::RenderSingleObjectForItemBuffer(Renderable *rend, Pass *pass)
678{
679        static LightList nullLightList;
680       
681        int col[4];
682       
683        // -- create color code out of object id
684        col[0] = (rend->getId() >> 16) & 255;
685        col[1] = (rend->getId() >> 8) & 255;
686        col[2] = rend->getId() & 255;
687//      col[3] = 255;
688
689        //mDestRenderSystem->setColour(col[0], col[1], col[2], col[3]);
690   
691        mItemBufferPass->setAmbient(ColourValue(col[0] / 255.0f,
692                                                                                    col[1] / 255.0f,
693                                                                                        col[2] / 255.0f, 1));
694
695        // set vertex program of current pass
696        if (mExecuteVertexProgramForAllPasses && pass->hasVertexProgram())
697        {
698                mItemBufferPass->setVertexProgram(pass->getVertexProgramName());
699
700                if (mItemBufferPass->hasVertexProgram())
701                {
702                        const GpuProgramPtr& prg = mItemBufferPass->getVertexProgram();
703                        // Load this program if not done already
704                        if (!prg->isLoaded())
705                                prg->load();
706                        // Copy params
707                        mItemBufferPass->setVertexProgramParameters(pass->getVertexProgramParameters());
708                }
709        }
710        else if (mItemBufferPass->hasVertexProgram())
711        {
712                mItemBufferPass->setVertexProgram("");
713        }
714
715        Pass *usedPass = setPass(mItemBufferPass);
716
717
718        // Render a single object, this will set up auto params if required
719        renderSingleObject(rend, usedPass, false, &nullLightList);
720}
721//-----------------------------------------------------------------------
722GtpVisibility::VisibilityManager *OcclusionCullingSceneManager::GetVisibilityManager()
723{
724        return mVisibilityManager;
725}
726//-----------------------------------------------------------------------
727void OcclusionCullingSceneManager::InitVisibilityCulling(Camera *cam)
728{
729        // reset culling manager stats
730        mVisibilityManager->GetCullingManager()->InitFrame(mVisualizeCulledNodes);
731
732        // set depth pass flag before rendering
733        mIsDepthPassPhase = mUseDepthPass;
734
735        mIsHierarchicalCulling = true; // during hierarchical culling
736
737        // item buffer needs full ambient lighting to use item colors as unique id
738        if (mUseItemBuffer)
739        {
740                mIsItemBufferPhase = true;
741                setAmbientLight(ColourValue(1,1,1,1));
742        }
743
744
745        // set passes which are stored in render queue
746        // for rendering AFTER hierarchical culling, i.e., passes which need
747        // a special rendering order
748       
749        mLeavePassesInQueue = 0;
750
751        if (!mUseDepthPass && !mUseItemBuffer)
752        {
753                if (mShadowTechnique == SHADOWTYPE_STENCIL_ADDITIVE)
754                {
755                        // TODO: remove this pass because it should be processed during hierarchical culling
756                        //mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
757
758                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DECAL;
759                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DIFFUSE_SPECULAR;
760                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
761
762                        // just render ambient stuff
763                        mIlluminationStage = IRS_AMBIENT;
764                        getRenderQueue()->setSplitPassesByLightingType(true);
765                }
766       
767                if (mShadowTechnique == SHADOWTYPE_STENCIL_MODULATIVE)
768                {
769                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
770                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
771                }
772       
773                // transparents should be rendered after hierarchical culling to
774                // provide front-to-back ordering
775                if (mDelayRenderTransparents)
776                {
777                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
778                }
779        }
780
781        // skip rendering transparents during the hierarchical culling
782        // (because they will be rendered afterwards)
783        mSkipTransparents =
784                (mIsDepthPassPhase || (mLeavePassesInQueue & RenderPriorityGroup::TRANSPARENT_PASSES));
785
786        // -- initialise interface for rendering traversal of the hierarchy
787        mHierarchyInterface->SetHierarchyRoot(mOctree);
788       
789        // possible two cameras (one for culling, one for rendering)
790        mHierarchyInterface->InitTraversal(mCameraInProgress,
791                                                                           mCullCamera ? getCamera("CullCamera") : NULL,
792                                                                           mLeavePassesInQueue);
793               
794}
795//-----------------------------------------------------------------------
796OctreeHierarchyInterface *OcclusionCullingSceneManager::GetHierarchyInterface()
797{
798        return mHierarchyInterface;
799}
800//-----------------------------------------------------------------------
801void OcclusionCullingSceneManager::endFrame()
802{
803        TerrainRenderable::ResetRenderLevelIndex();
804}
805//-----------------------------------------------------------------------
806Entity* OcclusionCullingSceneManager::createEntity(const String& entityName,
807                                                                                                        const String& meshName)
808{
809        Entity *ent = SceneManager::createEntity(entityName, meshName);
810
811        for (int i = 0; i < (int)ent->getNumSubEntities(); ++i)
812        {
813                ent->getSubEntity(i)->setId(mCurrentEntityId);
814        }
815
816        // increase counter of entity id values
817        ++ mCurrentEntityId;
818
819        return ent;
820}
821//-----------------------------------------------------------------------
822void OcclusionCullingSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup)
823{
824        // only render solid passes during hierarchical culling
825        if (mIsHierarchicalCulling)
826        {
827                RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
828            LightList lightList;
829
830                while (groupIt.hasMoreElements())
831                {
832                        RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
833
834                        // Sort the queue first
835                        pPriorityGrp->sort(mCameraInProgress);
836
837                        // Clear light list
838                        lightList.clear();
839
840                        // Render all the ambient passes first, no light iteration, no lights
841                        mIlluminationStage = IRS_AMBIENT;
842
843                        OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPasses(), false, &lightList);
844                        // Also render any objects which have receive shadows disabled
845                        OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPassesNoShadow(), true);
846                }
847        }
848        else
849        {
850                OctreeSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(pGroup);
851        }
852}
853//-----------------------------------------------------------------------
854void OcclusionCullingSceneManager::renderModulativeStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup)
855{
856   if (mIsHierarchicalCulling)
857   {
858           // Iterate through priorities
859           RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
860
861           while (groupIt.hasMoreElements())
862           {
863                   RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
864
865                   // Sort the queue first
866                   pPriorityGrp->sort(mCameraInProgress);
867
868                   // Do (shadowable) solids
869                   OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPasses(), true);
870           }
871   }
872   else
873   {
874           SceneManager::renderModulativeStencilShadowedQueueGroupObjects(pGroup);
875   }
876}
877//-------------------------------------------------------------------------
878void OcclusionCullingSceneManager::setWorldGeometry( const String& filename )
879{
880    // Clear out any existing world resources (if not default)
881    if (ResourceGroupManager::getSingleton().getWorldResourceGroupName() !=
882        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME)
883    {
884        ResourceGroupManager::getSingleton().clearResourceGroup(
885            ResourceGroupManager::getSingleton().getWorldResourceGroupName());
886    }
887    mTerrainPages.clear();
888    // Load the configuration
889    loadConfig(filename);
890
891    // Resize the octree, allow for 1 page for now
892    float max_x = mOptions.scale.x * mOptions.pageSize;
893    float max_y = mOptions.scale.y;
894    float max_z = mOptions.scale.z * mOptions.pageSize;
895
896        float maxAxis = std::max(max_x, max_y);
897        maxAxis = std::max(maxAxis, max_z);
898        resize( AxisAlignedBox( 0, 0, 0, maxAxis, maxAxis, maxAxis ) );
899   
900    setupTerrainMaterial();
901    setupTerrainPages();
902}
903
904//-------------------------------------------------------------------------
905MovableObject *OcclusionCullingSceneManager::FindCorrespondingObject(const AxisAlignedBox &box)
906{
907        list<SceneNode *> sceneNodeList;
908
909        findNodesIn(box, sceneNodeList, NULL);
910
911        list<SceneNode *>::const_iterator sit, sit_end = sceneNodeList.end();
912
913        bool overlap = false;
914
915        MovableObject *bestFittingObj = NULL;
916        float bestFit = 0.0;
917       
918        // find the bbox which is closest to the current bbox
919        for (sit = sceneNodeList.begin(); sit != sceneNodeList.end(), !overlap; ++ sit)
920        {
921                SceneNode *sn = *sit;
922                SceneNode::ObjectIterator oit = sn->getAttachedObjectIterator();
923
924        while (oit.hasMoreElements())
925                {
926                         MovableObject *mo = oit.getNext();
927                         const AxisAlignedBox bbox = mo->getWorldBoundingBox();
928                         
929                         const float overlap = GtpVisibilityPreprocessor::RatioOfOverlap(
930                                 OgreTypeConverter::ConvertFromOgre(bbox),
931                                 OgreTypeConverter::ConvertFromOgre(box));
932
933                         if (overlap > bestFit)
934                         {
935                                 bestFit = overlap;
936                                 bestFittingObj = mo;
937                                       
938                                 // perfect fit => object found
939                                 if (overlap > (1.0 - GtpVisibilityPreprocessor::Limits::Small))
940                                        break;
941                         }
942                }
943        }
944
945        return bestFittingObj;
946}
947
948
949void OcclusionCullingSceneManager::LoadViewCells(string filename)
950{
951        GtpVisibilityPreprocessor::ObjectContainer objects;
952        // identify the corresponding Ogre meshes using the bounding boxes
953        IdentifyObjects(objects);
954       
955        // load the view cells assigning the found objects to the pvss
956        mViewCellsManager->LoadViewCells(filename, &objects);
957}
958
959
960void OcclusionCullingSceneManager::IdentifyObjects(GtpVisibilityPreprocessor::ObjectContainer &objects)
961{
962        const string bboxesFilename = "boxes.out";
963
964        GtpVisibilityPreprocessor::IndexedBoundingBoxContainer iboxes;
965        mViewCellsManager->LoadBoundingBoxes(bboxesFilename, iboxes);
966
967        GtpVisibilityPreprocessor::IndexedBoundingBoxContainer::
968                const_iterator iit, iit_end = iboxes.end();
969
970        for (iit = iboxes.begin(); iit != iit_end; ++ iit)
971        {
972                  const GtpVisibilityPreprocessor::AxisAlignedBox3 box = (*iit).second;
973                  const AxisAlignedBox currentBox = OgreTypeConverter::ConvertToOgre(box);
974                 
975                  MovableObject *mo = FindCorrespondingObject(currentBox);
976                  //objects.push_back(mi);
977        }
978}
979
980} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.