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

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