source: GTP/trunk/Lib/Illum/IllumModule/OgreIllumModule/src/OgreIlluminationManager.cpp @ 1062

Revision 1062, 15.2 KB checked in by szirmay, 18 years ago (diff)
Line 
1#include "OgreIlluminationManager.h"
2#include "OgreParticleSystemRenderer.h"
3#include "OgreBillboardParticleRenderer.h"
4#include "SpriteParticleRenderer.h"
5 
6
7OgreIlluminationManager* OgreIlluminationManager::instance = NULL;
8
9Vector3 sortfrom;
10RenderingRunType sortType;
11
12class sortFromVector
13{
14public:
15   bool operator()(OgreSharedRuns* a, OgreSharedRuns* b)
16   {
17           float dist1 = (a->getRootPosition() - sortfrom).length();
18           float dist2 = (b->getRootPosition() - sortfrom).length();
19
20           return dist1 > dist2;
21   }
22};
23
24class sortFromVectorWithRunType
25{
26public:
27   bool operator()(OgreSharedRuns* a, OgreSharedRuns* b)
28   {
29           float dist1 = (a->getRootPosition(sortType) - sortfrom).length();
30           float dist2 = (b->getRootPosition(sortType) - sortfrom).length();
31
32           return dist1 > dist2;
33   }
34};
35
36
37class VisibleFinderVisitor : public QueuedRenderableVisitor
38{
39private:
40        std::vector<const Renderable*>* visibleObjects;
41public:
42   
43        VisibleFinderVisitor(std::vector<const Renderable*>* visibleObjectsVector)
44        {
45                this->visibleObjects = visibleObjectsVector;
46        }
47
48        void visit(const Renderable* r)
49        {               
50                OgreTechniqueGroup* tg = (OgreTechniqueGroup*) r->getRenderTechniqueGroup();
51               
52                if(tg != 0)
53                {
54                        tg->validateSharedRuns();
55                        visibleObjects->push_back(r);
56                }
57        }
58        bool visit(const Pass* p)       
59        {
60                return true;
61        }
62        void visit(const RenderablePass* rp)
63        {
64                Renderable* r = rp->renderable;
65
66                OgreTechniqueGroup* tg = (OgreTechniqueGroup*) r->getRenderTechniqueGroup();
67               
68                if(tg != 0)
69                {
70                        tg->validateSharedRuns();
71                        visibleObjects->push_back(r);
72                }       
73        }
74
75};
76
77OgreIlluminationManager::OgreIlluminationManager()
78{
79        visitor = new VisibleFinderVisitor(&visibleObjects);
80        maxRad = 400;
81       
82        for(int i = 0; i < RUN_TYPE_COUNT; i++)
83        {
84                maxRads[(RenderingRunType)i] = (float) maxRad;
85        }
86
87        //register rendertechnique factories
88        OgreColorCubeMapRenderTechniqueFactory* colorcube = new OgreColorCubeMapRenderTechniqueFactory();
89                addRenderTechniqueFactory(colorcube);
90        OgreDistanceCubeMapRenderTechniqueFactory* distcube = new OgreDistanceCubeMapRenderTechniqueFactory();
91                addRenderTechniqueFactory(distcube);
92        OgreConvoledCubeMapRenderTechniqueFactory* convcube = new OgreConvoledCubeMapRenderTechniqueFactory();
93                addRenderTechniqueFactory(convcube);
94        OgreCausticCasterRenderTechniqueFactory* caucast = new OgreCausticCasterRenderTechniqueFactory();
95                addRenderTechniqueFactory(caucast);
96        OgreCausticRecieverRenderTechniqueFactory* caurec = new OgreCausticRecieverRenderTechniqueFactory();
97                addRenderTechniqueFactory(caurec);
98        OgreDepthShadowRecieverRenderTechniqueFactory* dsrec = new OgreDepthShadowRecieverRenderTechniqueFactory();
99                addRenderTechniqueFactory(dsrec);
100        OgreSBBRenderTechniqueFactory* sbb = new OgreSBBRenderTechniqueFactory();
101                addRenderTechniqueFactory(sbb);
102        OgreFireRenderTechniqueFactory* fire = new OgreFireRenderTechniqueFactory();
103                addRenderTechniqueFactory(fire);
104        OgreHierarchicalParticleSystemTechniqueFactory* HPSF = new OgreHierarchicalParticleSystemTechniqueFactory();
105                addRenderTechniqueFactory(HPSF);
106}
107
108OgreIlluminationManager::~OgreIlluminationManager()
109{
110       
111}
112
113OgreIlluminationManager& OgreIlluminationManager::getSingleton()
114{
115        if(instance == NULL)
116                instance= new OgreIlluminationManager();
117
118        return *instance;
119}
120
121void OgreIlluminationManager::fillVisibleList(  RenderQueue * rq )
122{
123        visibleObjects.clear();
124
125        RenderQueue::QueueGroupIterator queueIt = rq->_getQueueGroupIterator();
126   
127    while (queueIt.hasMoreElements())
128    {
129        RenderQueueGroup* pGroup = queueIt.getNext();
130               
131        RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
132
133                while (groupIt.hasMoreElements())
134                {
135                        RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
136                        const QueuedRenderableCollection& solids = pPriorityGrp->getSolidsBasic();
137                        const QueuedRenderableCollection& transparents = pPriorityGrp->getTransparents();
138                                                                       
139                        solids.acceptVisitor(visitor, QueuedRenderableCollection::OM_PASS_GROUP);
140                        transparents.acceptVisitor(visitor, QueuedRenderableCollection::OM_SORT_ASCENDING);             
141                }                       
142    }
143
144        rq->clear();   
145}
146
147BillboardSet* OgreIlluminationManager::findRenderableInParticleSystem(ParticleSystem* system)
148{
149        ParticleSystemRenderer* renderer = system->getRenderer();
150       
151        const String rendererType = renderer->getType();
152        if(rendererType == "billboard")
153        {
154                BillboardSet* bbSet = ((BillboardParticleRenderer*) renderer)->getBillboardSet();
155                return bbSet;
156        }
157
158        if(rendererType == "sprite")
159        {
160                BillboardSet* bbSet = ((SpriteParticleRenderer*) renderer)->getSpriteSet();
161                return bbSet;
162        }
163       
164        OGRE_EXCEPT(0, "Unsupported particle renderable type", "OgreIlluminationManager::findRenderableInParticleSystem");
165
166        return NULL;
167}
168
169void OgreIlluminationManager::initTechniques(Entity* e)
170{
171        if( e->getParentSceneNode() == 0 )//Entity not attached
172                return;
173
174        OgreSharedRuns* sharedruns = 0;
175       
176        for(unsigned int s = 0; s < e->getNumSubEntities(); s++)
177        {
178                SubEntity* sube = e->getSubEntity(s);
179
180                Material* mat = sube->getMaterial().getPointer();
181               
182                OgreRenderable* rend = 0;       
183                OgreTechniqueGroup* group = 0;
184       
185                for(unsigned int t = 0 ; t < mat->getNumTechniques() ; t++)
186                {
187                        Technique* tech = mat->getTechnique(t);
188
189                        for(unsigned int p = 0; p< tech->getNumPasses(); p++)
190                        {
191                                Pass* pass = tech->getPass(p);
192
193                                std::vector<IllumTechniqueParams*>& techniques = pass->getIllumTechniques();
194                                std::vector<IllumTechniqueParams*>::iterator i = techniques.begin();
195                                std::vector<IllumTechniqueParams*>::iterator iend = techniques.end();
196                               
197                                while( i != iend)
198                                {
199                                        IllumTechniqueParams* params = *i;
200                                       
201                                        if(rend == 0)
202                                        {
203                                                rend = new OgreRenderable(e, s);
204                                                group = new OgreTechniqueGroup();
205                                                sube->setRenderTechniqueGroup(group);                                                   
206                                               
207                                                if( sharedruns == 0)
208                                                {                                                                       
209                                                        sharedruns  = new OgreSharedRuns();
210                                                        addSharedRuns(sharedruns);
211                                                }
212
213                                                group->addSharedRun(sharedruns);
214                                                sharedruns->addRenderable(rend);
215                                                sharedruns->updateBounds();
216                                        }
217                                       
218                                        createTechnique(params, pass, rend, sharedruns);
219
220                                        i++;
221                                }
222                        }
223                }
224        }
225
226               
227}
228
229
230void OgreIlluminationManager::initTechniques(BillboardSet* bbs, ParticleSystem* sys)
231{
232        if( bbs->getParentSceneNode() == 0 )//billboardset not attached
233                return;
234
235        OgreSharedRuns* sharedruns = 0;
236
237        Material* mat = bbs->getMaterial().getPointer();
238       
239        OgreRenderable* rend = 0;       
240        OgreTechniqueGroup* group = 0;
241
242        for(unsigned int t = 0 ; t < mat->getNumTechniques() ; t++)
243        {
244                Technique* tech = mat->getTechnique(t);
245
246                for(unsigned int p = 0; p< tech->getNumPasses(); p++)
247                {
248                        Pass* pass = tech->getPass(p);
249
250                        std::vector<IllumTechniqueParams*>& techniques = pass->getIllumTechniques();
251                        std::vector<IllumTechniqueParams*>::iterator i = techniques.begin();
252                        std::vector<IllumTechniqueParams*>::iterator iend = techniques.end();
253                       
254                        while( i != iend)
255                        {
256                                IllumTechniqueParams* params = *i;
257                               
258                                if(rend == 0)
259                                {
260                                        rend = new OgreRenderable(bbs, sys);
261                                        group = new OgreTechniqueGroup();
262                                        bbs->setRenderTechniqueGroup(group);                                                   
263                                       
264                                        if( sharedruns == 0)
265                                        {                                                                       
266                                                sharedruns  = new OgreSharedRuns();
267                                                addSharedRuns(sharedruns);
268                                        }
269
270                                        group->addSharedRun(sharedruns);
271                                        sharedruns->addRenderable(rend);
272                                        sharedruns->updateBounds();
273                                }
274                               
275                                createTechnique(params, pass, rend, sharedruns);
276
277                                i++;
278                        }
279                }
280        }
281                       
282}
283
284void OgreIlluminationManager::initTechniques()
285{
286        {
287                //Entities
288                SceneManager::MovableObjectIterator it = Root::getSingleton()._getCurrentSceneManager()
289                                                                                                        ->getMovableObjectIterator("Entity");
290                while(it.hasMoreElements())
291                {
292                        MovableObject* o = it.getNext();
293                        Entity* e = (Entity*) o;
294               
295                        initTechniques(e);
296                }
297        }
298        {
299                //ParticleSystems
300                SceneManager::MovableObjectIterator it = Root::getSingleton()._getCurrentSceneManager()
301                                                                                                        ->getMovableObjectIterator("ParticleSystem");
302                while(it.hasMoreElements())
303                {
304                        MovableObject* o = it.getNext();
305                        ParticleSystem* psys = (ParticleSystem*) o;
306                       
307                        try
308                        {
309                         BillboardSet* bbset = findRenderableInParticleSystem(psys);
310                         bbset->setMaterialName(psys->getMaterialName());
311                         initTechniques(bbset, psys);
312                        }
313                        catch( ... )
314                        {
315                                //unsupported particle renderer, skip init
316                        }
317                }
318        }
319}
320
321void OgreIlluminationManager::createTechnique(IllumTechniqueParams* params, Pass* pass, OgreRenderable* rend, OgreSharedRuns* sRuns)
322{
323        std::list<RenderTechniqueFactory*>::iterator it = techniqueFactories.begin();
324        std::list<RenderTechniqueFactory*>::iterator itend = techniqueFactories.end();
325
326        OgreTechniqueGroup* group = (OgreTechniqueGroup*) rend->getRenderable()->getRenderTechniqueGroup();     
327       
328                       
329        while(it != itend)
330        {
331                RenderTechniqueFactory* factory = *it;
332               
333               
334                if(factory->isType(params->getTypeName()))
335                {
336                       
337                        RenderTechnique* newTechnique = factory->createInstance(params,
338                                                                                                                                        pass,
339                                                                                                                                        rend,
340                                                                                                                                        group );
341
342                        group->addRenderTechnique(newTechnique);
343                       
344                }
345
346                it++;
347        }
348}
349void OgreIlluminationManager::preAllUpdates()
350{
351        std::vector<UpdateListener*>::iterator it = updateListeners.begin();
352        std::vector<UpdateListener*>::iterator itend = updateListeners.end();
353
354        while(it != itend)
355        {
356                UpdateListener* l = *it;
357                l->preAllUpdates();
358                it++;
359        }
360}
361
362void OgreIlluminationManager::postAllUpdates()
363{
364        std::vector<UpdateListener*>::iterator it = updateListeners.begin();
365        std::vector<UpdateListener*>::iterator itend = updateListeners.end();
366
367        while(it != itend)
368        {
369                UpdateListener* l = *it;
370                l->postAllUpdates();
371                it++;
372        }
373}
374
375void OgreIlluminationManager::update(unsigned long frameNumber, RenderTarget* rt)
376{
377
378        RenderSystem* renderSystem = Root::getSingleton().getRenderSystem();
379        SceneManager* sceneManager = Root::getSingleton()._getCurrentSceneManager();
380       
381        for(unsigned short i = 0; i<rt->getNumViewports();i++)
382        {
383                //find visible objects from the camera
384                RenderQueue* rq = sceneManager->getRenderQueue();
385                rq->clear();
386                RenderQueue::QueueGroupIterator groupIter = rq->_getQueueGroupIterator();
387                while (groupIter.hasMoreElements())
388                {
389                        RenderQueueGroup* g = groupIter.getNext();
390                        //g->addOrganisationMode(QueuedRenderableCollection::OM_SORT_ASCENDING);
391                        g->defaultOrganisationMode();
392                }
393               
394                sceneManager->_findVisibleObjects(rt->getViewport(i)->getCamera(),false);
395                fillVisibleList(rq);   
396
397                int l = visibleObjects.size(); //debug
398               
399                joinSharedRuns();
400
401                int ll = sharedRunRoots.size(); //debug
402
403                //update precomputings                         
404                std::vector<const Renderable*>::iterator iter = visibleObjects.begin();
405                const std::vector<const Renderable*>::iterator iend = visibleObjects.end();
406
407                preAllUpdates();
408
409                while(iter != iend)
410                {
411                        const Renderable* rend = *iter;
412                        OgreTechniqueGroup* techniqueGroup = (OgreTechniqueGroup*) rend->getRenderTechniqueGroup();
413                        if(techniqueGroup != 0)
414                        {
415                                techniqueGroup->update(frameNumber);
416                        }
417                        iter++;
418                }
419
420                postAllUpdates();
421
422        }
423}
424
425void OgreIlluminationManager::sharedRunSplit(SharedRuns* old, SharedRuns* new1, SharedRuns* new2)
426{
427        sharedRunRoots.remove(old);
428        sharedRunRoots.push_back(new1);
429        sharedRunRoots.push_back(new2);
430}
431
432void OgreIlluminationManager::sharedRunJoin(SharedRuns* old1, SharedRuns* old2, SharedRuns* newsr)
433{
434        sharedRunRoots.remove(old1);
435        sharedRunRoots.remove(old2);
436        sharedRunRoots.push_back(newsr);
437}
438
439void OgreIlluminationManager::joinSharedRuns()
440{
441        std::list<SharedRuns*>::iterator it1 = sharedRunRoots.begin();
442        std::list<SharedRuns*>::iterator itend = sharedRunRoots.end();
443
444        bool again = false;
445
446        while(it1 != itend)
447        {
448                std::list<SharedRuns*>::iterator it2 = sharedRunRoots.begin();         
449               
450                while(it2 != itend)
451                {
452                        if( it1 != it2 && OgreSharedRuns::canJoin(*it1, *it2))
453                        {
454                                SharedRuns* newruns = (*it1)->joinRuns(*it2);
455                                sharedRunJoin(*it1, *it2, newruns);
456                                again = true;
457                                break;
458                        }
459                        it2++;
460                }
461
462                if(again)
463                        break;         
464
465                it1++;
466        }
467        if(again)
468        joinSharedRuns();
469
470}
471
472void OgreIlluminationManager::addSharedRuns(SharedRuns* runs)
473{
474        sharedRunRoots.push_back(runs);
475}
476
477void OgreIlluminationManager::getNearestCausticCasters(Vector3 position, std::vector<OgreSharedRuns*>* nearestcasters, unsigned int maxCount)
478{
479        sortfrom = position;
480        std::vector<OgreSharedRuns*> allcasters;
481        //fill casters
482        std::list<SharedRuns*>::iterator it = sharedRunRoots.begin();
483        std::list<SharedRuns*>::iterator itend = sharedRunRoots.end();
484        while(it != itend)
485        {
486                OgreSharedRuns* sr = (OgreSharedRuns*) (*it);
487               
488                sr->findSharedRootsForType(ILLUMRUN_CAUSTIC_CUBEMAP, allcasters);
489               
490                it++;
491        }
492
493        //sort
494        std::stable_sort(allcasters.begin(), allcasters.end(), sortFromVector());
495
496        for(unsigned int i = 0; i < maxCount && i < allcasters.size(); i++)
497        {
498                nearestcasters->push_back(allcasters.at(i));
499        }
500}
501
502void OgreIlluminationManager::createGlobalRun(RenderingRunType runType)
503{
504        switch(runType)
505        {
506                case ILLUMRUN_SCENE_CAMERA_DEPTH:
507                if(globalSharedRuns.getRun(ILLUMRUN_SCENE_CAMERA_DEPTH) == 0)
508                {
509                        OgreSceneCameraDepthRenderingRun* run = new OgreSceneCameraDepthRenderingRun
510                                (&globalSharedRuns, "ILLUMMODULE_SCENE_CAMERA_DEPTH", mainViewport);
511                        globalSharedRuns.addRun(ILLUMRUN_SCENE_CAMERA_DEPTH, run);
512                }
513                break;
514        }
515}
516
517
518
519RenderingRun* OgreIlluminationManager::getGlobalRun(RenderingRunType runType)
520{
521        return globalSharedRuns.getRun(runType);
522}
523
524GlobalUseRenderTarget* OgreIlluminationManager::getGlobalTarget(GlobalTargetType type)
525{
526        std::map<GlobalTargetType, GlobalUseRenderTarget*>::iterator it = globalTargets.find(type);
527       
528        if( it != globalTargets.end())
529                return (*it).second;
530
531        return 0;
532}
533
534void OgreIlluminationManager::addGlobalTarget(GlobalTargetType type, GlobalUseRenderTarget* target)
535{
536        globalTargets[type] = target; 
537}
538
539void OgreIlluminationManager::updateGlobalRun(RenderingRunType runType, unsigned long frameNum)
540{
541        globalSharedRuns.updateRun(runType, frameNum);
542}
543
544void OgreIlluminationManager::createPerLightRun(String lightName, RenderingRunType runType)
545{
546        OgreSharedRuns* runs = 0;
547       
548        if(perLightRuns.find(lightName) == perLightRuns.end())
549        {///create sharedruns
550                OgreSharedRuns* newruns = new OgreSharedRuns();
551                perLightRuns[lightName] = newruns;
552        }
553
554        runs = perLightRuns[lightName];
555
556    switch(runType)
557        {
558                case ILLUMRUN_DEPTH_SHADOWMAP:
559                if(runs->getRun(ILLUMRUN_DEPTH_SHADOWMAP) == 0)
560                {
561                        SceneManager* sm = Root::getSingleton()._getCurrentSceneManager();
562                        OgreDepthShadowMapRenderingRun* run  = new OgreDepthShadowMapRenderingRun(
563                                runs,
564                                lightName + "DEPTH_SHADOW_MAP",
565                                sm->getLight(lightName),
566                                512, //TODO
567                                512, //TODO
568                                "GameTools/ShadowMapDepth" //TODO
569                                );
570                        runs->addRun(ILLUMRUN_DEPTH_SHADOWMAP, run);
571                       
572                }
573                break;
574        }       
575}
576
577RenderingRun* OgreIlluminationManager::getPerLightRun(String lightName, RenderingRunType runType)
578{
579        return perLightRuns[lightName]->getRun(runType);
580}
581
582void OgreIlluminationManager::updatePerLightRun(String lightName, RenderingRunType runType, unsigned long frameNum)
583{
584        perLightRuns[lightName]->updateRun(runType, frameNum);
585}
586
Note: See TracBrowser for help on using the repository browser.