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

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