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

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