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

Revision 949, 15.0 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        //register rendertechnique factories
83        OgreColorCubeMapRenderTechniqueFactory* colorcube = new OgreColorCubeMapRenderTechniqueFactory();
84                addRenderTechniqueFactory(colorcube);
85        OgreDistanceCubeMapRenderTechniqueFactory* distcube = new OgreDistanceCubeMapRenderTechniqueFactory();
86                addRenderTechniqueFactory(distcube);
87        OgreConvoledCubeMapRenderTechniqueFactory* convcube = new OgreConvoledCubeMapRenderTechniqueFactory();
88                addRenderTechniqueFactory(convcube);
89        OgreCausticCasterRenderTechniqueFactory* caucast = new OgreCausticCasterRenderTechniqueFactory();
90                addRenderTechniqueFactory(caucast);
91        OgreCausticRecieverRenderTechniqueFactory* caurec = new OgreCausticRecieverRenderTechniqueFactory();
92                addRenderTechniqueFactory(caurec);
93        OgreDepthShadowRecieverRenderTechniqueFactory* dsrec = new OgreDepthShadowRecieverRenderTechniqueFactory();
94                addRenderTechniqueFactory(dsrec);
95        OgreSBBRenderTechniqueFactory* sbb = new OgreSBBRenderTechniqueFactory();
96                addRenderTechniqueFactory(sbb);
97}
98
99OgreIlluminationManager::~OgreIlluminationManager()
100{
101       
102}
103
104OgreIlluminationManager& OgreIlluminationManager::getSingleton()
105{
106        if(instance == NULL)
107                instance= new OgreIlluminationManager();
108
109        return *instance;
110}
111
112void OgreIlluminationManager::fillVisibleList(  RenderQueue * rq )
113{
114        visibleObjects.clear();
115
116        RenderQueue::QueueGroupIterator queueIt = rq->_getQueueGroupIterator();
117   
118    while (queueIt.hasMoreElements())
119    {
120        RenderQueueGroup* pGroup = queueIt.getNext();
121               
122        RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
123
124                while (groupIt.hasMoreElements())
125                {
126                        RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
127                        const QueuedRenderableCollection& solids = pPriorityGrp->getSolidsBasic();
128                        const QueuedRenderableCollection& transparents = pPriorityGrp->getTransparents();
129                                                                       
130                        solids.acceptVisitor(visitor, QueuedRenderableCollection::OM_PASS_GROUP);
131                        transparents.acceptVisitor(visitor, QueuedRenderableCollection::OM_SORT_ASCENDING);             
132                }                       
133    }
134
135        rq->clear();   
136}
137
138BillboardSet* OgreIlluminationManager::findRenderableInParticleSystem(ParticleSystem* system)
139{
140        ParticleSystemRenderer* renderer = system->getRenderer();
141       
142        const String rendererType = renderer->getType();
143        if(rendererType == "billboard")
144        {
145                BillboardSet* bbSet = ((BillboardParticleRenderer*) renderer)->getBillboardSet();
146                return bbSet;
147        }
148
149        if(rendererType == "sprite")
150        {
151                BillboardSet* bbSet = ((SpriteParticleRenderer*) renderer)->getSpriteSet();
152                return bbSet;
153        }
154       
155        OGRE_EXCEPT(0, "Unsupported particle renderable type", "OgreIlluminationManager::findRenderableInParticleSystem");
156
157        return NULL;
158}
159
160void OgreIlluminationManager::initTechniques(Entity* e)
161{
162        OgreSharedRuns* sharedruns = 0;
163       
164        for(unsigned int s = 0; s < e->getNumSubEntities(); s++)
165        {
166                SubEntity* sube = e->getSubEntity(s);
167
168                Material* mat = sube->getMaterial().getPointer();
169               
170                OgreRenderable* rend = 0;       
171                OgreTechniqueGroup* group = 0;
172       
173                for(unsigned int t = 0 ; t < mat->getNumTechniques() ; t++)
174                {
175                        Technique* tech = mat->getTechnique(t);
176
177                        for(unsigned int p = 0; p< tech->getNumPasses(); p++)
178                        {
179                                Pass* pass = tech->getPass(p);
180
181                                std::vector<IllumTechniqueParams*>& techniques = pass->getIllumTechniques();
182                                std::vector<IllumTechniqueParams*>::iterator i = techniques.begin();
183                                std::vector<IllumTechniqueParams*>::iterator iend = techniques.end();
184                               
185                                while( i != iend)
186                                {
187                                        IllumTechniqueParams* params = *i;
188                                       
189                                        if(rend == 0)
190                                        {
191                                                rend = new OgreRenderable(e, s);
192                                                group = new OgreTechniqueGroup();
193                                                sube->setRenderTechniqueGroup(group);                                                   
194                                               
195                                                if( sharedruns == 0)
196                                                {                                                                       
197                                                        sharedruns  = new OgreSharedRuns();
198                                                        addSharedRuns(sharedruns);
199                                                }
200
201                                                group->addSharedRun(sharedruns);
202                                                sharedruns->addRenderable(rend);
203                                                sharedruns->updateBounds();
204                                        }
205                                       
206                                        createTechnique(params, pass, rend, sharedruns);
207
208                                        i++;
209                                }
210                        }
211                }
212        }
213
214               
215}
216
217void OgreIlluminationManager::initTechniques()
218{
219        {
220                //Entities
221                SceneManager::MovableObjectIterator it = Root::getSingleton()._getCurrentSceneManager()
222                                                                                                        ->getMovableObjectIterator("Entity");
223                while(it.hasMoreElements())
224                {
225                        MovableObject* o = it.getNext();
226                        Entity* e = (Entity*) o;
227
228                /*      OgreSharedRuns* sharedruns = 0;
229                       
230                        for(unsigned int s = 0; s < e->getNumSubEntities(); s++)
231                        {
232                                SubEntity* sube = e->getSubEntity(s);
233
234                                Material* mat = sube->getMaterial().getPointer();
235                               
236                                OgreRenderable* rend = 0;       
237                                OgreTechniqueGroup* group = 0;
238                       
239                                for(unsigned int t = 0 ; t < mat->getNumTechniques() ; t++)
240                                {
241                                        Technique* tech = mat->getTechnique(t);
242
243                                        for(unsigned int p = 0; p< tech->getNumPasses(); p++)
244                                        {
245                                                Pass* pass = tech->getPass(p);
246
247                                                std::vector<IllumTechniqueParams*>& techniques = pass->getIllumTechniques();
248                                                std::vector<IllumTechniqueParams*>::iterator i = techniques.begin();
249                                                std::vector<IllumTechniqueParams*>::iterator iend = techniques.end();
250                                               
251                                                while( i != iend)
252                                                {
253                                                        IllumTechniqueParams* params = *i;
254                                                       
255                                                        if(rend == 0)
256                                                        {
257                                                                rend = new OgreRenderable(e, s);
258                                                                group = new OgreTechniqueGroup();
259                                                                sube->setRenderTechniqueGroup(group);                                                   
260                                                               
261                                                                if( sharedruns == 0)
262                                                                {                                                                       
263                                                                        sharedruns  = new OgreSharedRuns();
264                                                                        addSharedRuns(sharedruns);
265                                                                }
266
267                                                                group->addSharedRun(sharedruns);
268                                                                sharedruns->addRenderable(rend);
269                                                                sharedruns->updateBounds();
270                                                        }
271                                                       
272                                                        createTechnique(params, pass, rend, sharedruns);
273
274                                                        i++;
275                                                }
276                                        }
277                                }
278                        }
279
280                */
281                        initTechniques(e);
282                }
283        }
284        {
285                //ParticleSystems
286                SceneManager::MovableObjectIterator it = Root::getSingleton()._getCurrentSceneManager()
287                                                                                                        ->getMovableObjectIterator("ParticleSystem");
288                while(it.hasMoreElements())
289                {
290                        MovableObject* o = it.getNext();
291                        ParticleSystem* psys = (ParticleSystem*) o;
292
293                        BillboardSet* bbset = findRenderableInParticleSystem(psys);
294                       
295                        OgreTechniqueGroup* group = 0;                 
296                        OgreSharedRuns* sharedruns = 0;
297                        OgreRenderable* rend = 0;       
298                                               
299                        String matName = psys->getMaterialName();
300                        Material* mat = (Material*) MaterialManager::getSingleton().getByName(matName).getPointer();
301
302                        for(unsigned int t = 0 ; t < mat->getNumTechniques() ; t++)
303                        {
304                                Technique* tech = mat->getTechnique(t);
305
306                                for(unsigned int p = 0; p< tech->getNumPasses(); p++)
307                                {
308                                        Pass* pass = tech->getPass(p);
309
310                                        std::vector<IllumTechniqueParams*>& techniques = pass->getIllumTechniques();
311                                        std::vector<IllumTechniqueParams*>::iterator i = techniques.begin();
312                                        std::vector<IllumTechniqueParams*>::iterator iend = techniques.end();
313
314                                       
315                                        while( i != iend)
316                                        {
317                                                IllumTechniqueParams* params = *i;
318                                               
319                                                if(rend == 0)
320                                                {
321                                                        rend = new OgreRenderable(bbset);
322                                                        group = new OgreTechniqueGroup();
323                                                        bbset->setRenderTechniqueGroup(group);                                                 
324                                                       
325                                                        if( sharedruns == 0)
326                                                        {                                                                       
327                                                                sharedruns  = new OgreSharedRuns();
328                                                                addSharedRuns(sharedruns);
329                                                        }
330
331                                                        group->addSharedRun(sharedruns);
332                                                        sharedruns->addRenderable(rend);
333                                                        sharedruns->updateBounds();
334                                                }
335
336                                                createTechnique(params, pass, rend, sharedruns);
337
338                                                i++;
339                                        }
340                                }
341                        }
342                       
343
344                }
345        }
346}
347
348void OgreIlluminationManager::createTechnique(IllumTechniqueParams* params, Pass* pass, OgreRenderable* rend, OgreSharedRuns* sRuns)
349{
350        std::list<RenderTechniqueFactory*>::iterator it = techniqueFactories.begin();
351        std::list<RenderTechniqueFactory*>::iterator itend = techniqueFactories.end();
352
353        OgreTechniqueGroup* group = (OgreTechniqueGroup*) rend->getRenderable()->getRenderTechniqueGroup();     
354       
355                       
356        while(it != itend)
357        {
358                RenderTechniqueFactory* factory = *it;
359               
360               
361                if(factory->isType(params->getTypeName()))
362                {
363                       
364                        RenderTechnique* newTechnique = factory->createInstance(params,
365                                                                                                                                        pass,
366                                                                                                                                        rend,
367                                                                                                                                        group );
368
369                        group->addRenderTechnique(newTechnique);
370                       
371                }
372
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                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        }
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
515RenderingRun* OgreIlluminationManager::getGlobalRun(RenderingRunType runType)
516{
517        return globalSharedRuns.getRun(runType);
518}
519
520void OgreIlluminationManager::updateGlobalRun(RenderingRunType runType, unsigned long frameNum)
521{
522        globalSharedRuns.updateRun(runType, frameNum);
523}
524
525void OgreIlluminationManager::createPerLightRun(String lightName, RenderingRunType runType)
526{
527        OgreSharedRuns* runs = 0;
528       
529        if(perLightRuns.find(lightName) == perLightRuns.end())
530        {///create sharedruns
531                OgreSharedRuns* newruns = new OgreSharedRuns();
532                perLightRuns[lightName] = newruns;
533        }
534
535        runs = perLightRuns[lightName];
536
537    switch(runType)
538        {
539                case ILLUMRUN_DEPTH_SHADOWMAP:
540                if(runs->getRun(ILLUMRUN_DEPTH_SHADOWMAP) == 0)
541                {
542                        SceneManager* sm = Root::getSingleton()._getCurrentSceneManager();
543                        OgreDepthShadowMapRenderingRun* run  = new OgreDepthShadowMapRenderingRun(
544                                runs,
545                                lightName + "DEPTH_SHADOW_MAP",
546                                sm->getLight(lightName),
547                                2048, //TODO
548                                2048, //TODO
549                                "GameTools/ShadowMapDepth" //TODO
550                                );
551                        runs->addRun(ILLUMRUN_DEPTH_SHADOWMAP, run);
552                       
553                }
554                break;
555        }       
556}
557
558RenderingRun* OgreIlluminationManager::getPerLightRun(String lightName, RenderingRunType runType)
559{
560        return perLightRuns[lightName]->getRun(runType);
561}
562
563void OgreIlluminationManager::updatePerLightRun(String lightName, RenderingRunType runType, unsigned long frameNum)
564{
565        perLightRuns[lightName]->updateRun(runType, frameNum);
566}
567
Note: See TracBrowser for help on using the repository browser.