source: GTP/trunk/Lib/Illum/IllumModule/OgreIllumModule/src/OgreSharedRuns.cpp @ 2379

Revision 2379, 8.9 KB checked in by szirmay, 18 years ago (diff)
Line 
1#include "..\include\OgreSharedRuns.h"
2#include "OgreIlluminationManager.h"
3#include "OgreRenderingRun.h"
4
5void OgreSharedRuns::freeAllResources()
6{
7        if(child1 != 0)//node
8        {
9                child1->freeAllResources();
10                child2->freeAllResources();
11        }       
12        else //leaf
13        {
14                std::map<RenderingRunType, RenderingRun*>::iterator it = sharedRuns.begin();
15                std::map<RenderingRunType, RenderingRun*>::iterator itend = sharedRuns.end();
16                while(it != itend)
17                {
18                        RenderingRun* rr = (*it).second;
19                        rr->freeAllResources();
20        //              sharedRuns.erase(it);
21                        delete rr->asOgreRenderingRun();
22                        ++it;
23                }
24                sharedRuns.clear();
25        }
26}
27
28void OgreSharedRuns::runChanged(RenderingRunType runType, RenderingRun* run)
29{
30        if(child1 != 0) child1->runChanged(runType, run);
31        if(child2 != 0) child2->runChanged(runType, run);
32       
33        std::vector<TechniqueGroup*>::iterator it = childTechniqueGroups.begin();
34        std::vector<TechniqueGroup*>::iterator itend = childTechniqueGroups.end();
35
36        while(it != itend)
37        {
38                (*it)->runChanged(runType, run);
39                it++;
40        }
41}
42
43void OgreSharedRuns::runUpdated(RenderingRunType runType, RenderingRun* run)
44{
45        if(child1 != 0) child1->runUpdated(runType, run);
46        if(child2 != 0) child2->runUpdated(runType, run);
47       
48
49        std::vector<TechniqueGroup*>::iterator it = childTechniqueGroups.begin();
50        std::vector<TechniqueGroup*>::iterator itend = childTechniqueGroups.end();
51
52        while(it != itend)
53        {
54                (*it)->runUpdated(runType, run);
55                it++;
56        }
57}
58
59RenderingRun* OgreSharedRuns::getRun(RenderingRunType runType)
60{
61/*      if(parent != 0)
62                return parent->getRun(runType);*/
63       
64        if( hasOwnRun(runType) )
65                return sharedRuns[runType];
66
67        if(child1 != 0)
68        {
69                RenderingRun* run = child1->getRun(runType);
70                if( run != 0)
71                        return run;
72        }
73       
74        if(child2 != 0)
75                return child2->getRun(runType);
76
77        return 0;
78}
79
80void OgreSharedRuns::addRun(RenderingRunType runType, RenderingRun* run)
81{
82        sharedRuns[runType] = run;
83}
84
85void OgreSharedRuns::updateRun(RenderingRunType runType, unsigned long frameNum)
86{
87        /*
88        if(parent != 0)
89                parent->updateRun(runType, frameNum);
90        else
91                sharedRuns[runType]->update(frameNum);
92        */
93        RenderingRun* run = getRoot(runType)->getRun(runType);
94       
95        if(run->update(frameNum))
96                runUpdated(runType, run);
97}
98
99bool OgreSharedRuns::hasOwnRun(RenderingRunType runType)
100{
101        if(sharedRuns.find(runType) == sharedRuns.end())
102                return false;
103
104        return true;
105}
106
107void OgreSharedRuns::gatherRuns()
108{
109        OgreSharedRuns* child1 = (OgreSharedRuns*) this->child1;
110        OgreSharedRuns* child2 = (OgreSharedRuns*) this->child2;
111
112        std::map<RenderingRunType, RenderingRun*>::iterator it = child1->sharedRuns.begin();
113        std::map<RenderingRunType, RenderingRun*>::iterator itend = child1->sharedRuns.end();
114       
115        while(it != itend)
116        {
117                if( child2->hasOwnRun((*it).first) )
118                        sharedRuns[(*it).first] = (*it).second;
119
120                it++;
121        }
122       
123}
124
125void OgreSharedRuns::updateBounds()
126{
127        if(child1)
128        {
129                OgreSharedRuns* child1 = (OgreSharedRuns*) this->child1;
130                OgreSharedRuns* child2 = (OgreSharedRuns*) this->child2;
131
132                boundingBox = child1->boundingBox;
133                boundingBox.merge(child2->boundingBox);
134
135                boundingSphere.setCenter((child1->boundingSphere.getCenter()
136                                                                                + child2->boundingSphere.getCenter())/2.0);
137                float dist = (child1->boundingSphere.getCenter()
138                                                - child2->boundingSphere.getCenter()).length();
139                float radius1 = child1->boundingSphere.getRadius();
140                float radius2 = child2->boundingSphere.getRadius();
141                float maxrad = std::max(radius1, radius2);
142               
143                if(radius1 + dist <= radius2)boundingSphere.setRadius(radius2);
144                else if(radius2 + dist <= radius1)boundingSphere.setRadius(radius1);
145                else boundingSphere.setRadius(dist + maxrad);
146        }
147        else
148        {
149                std::map<OgreRenderable*, bool>::iterator it = renderables.begin();
150                OgreRenderable* rend = (*it).first;
151                rend->updateBounds();
152                boundingBox = rend->getBoundingBox();
153                boundingSphere = rend->getBoundingSphere();             
154        }
155}
156
157void OgreSharedRuns::fireRunChanges()
158{
159        std::map<RenderingRunType, RenderingRun*>::iterator it = sharedRuns.begin();
160        std::map<RenderingRunType, RenderingRun*>::iterator itend = sharedRuns.end();
161
162        while(it != itend)
163        {
164                runChanged( (*it).first, (*it).second );
165                it++;
166        }
167}
168
169SharedRuns* OgreSharedRuns::createInstance()
170{
171        return new OgreSharedRuns();
172}
173
174void OgreSharedRuns::validate()
175{
176        updateBounds();
177        if(child1 == 0)
178        {
179                if(parent != 0)
180                        parent->validate();
181                return;
182        }
183        if( canJoin(child1, child2))
184        {
185                if(parent != 0) parent->validate();
186        }
187        else    //destroy this shared object with parents
188                destroy();     
189}
190
191bool OgreSharedRuns::haveCommonRuns(SharedRuns* r1, SharedRuns* r2, std::vector<RenderingRunType>& commonruns)
192{
193        OgreSharedRuns* run1 = (OgreSharedRuns*) r1;
194        OgreSharedRuns* run2 = (OgreSharedRuns*) r2;
195
196        std::map<RenderingRunType, RenderingRun*>::iterator it = run1->sharedRuns.begin();
197        std::map<RenderingRunType, RenderingRun*>::iterator itend = run1->sharedRuns.end();
198
199        bool returnvalue = false;
200        while(it != itend)
201        {
202                if( run2->hasOwnRun((*it).first))
203                {
204                        if(                      run1->getRun((*it).first)->asOgreRenderingRun()->
205                                canJoin( run2->getRun((*it).first)->asOgreRenderingRun() )
206                           )
207                        {
208                                returnvalue = true;
209                                commonruns.push_back((*it).first);
210                        }
211                }
212                it++;
213        }
214
215        return returnvalue;
216}
217
218bool OgreSharedRuns::canJoin(SharedRuns* r1, SharedRuns* r2)
219{
220        std::vector<RenderingRunType> commonruns;
221        //check if they have common resources
222        if(!haveCommonRuns(r1, r2, commonruns))
223                return false;
224       
225        float MAXRAD = 0xffffffff;
226        //check bounds
227        for(unsigned int i = 0; i < commonruns.size(); i++)
228        {
229         
230         RenderingRunType type = commonruns.at(i);
231         float marad = OgreIlluminationManager::getSingleton().getMaxJoinRadius(type);
232         
233         MAXRAD = std::min(MAXRAD, marad);
234        }
235
236        Sphere bSphere1 = ((OgreSharedRuns*) r1)->getBoundingSphere();
237        Sphere bSphere2 = ((OgreSharedRuns*) r2)->getBoundingSphere();
238
239        float radius1 = bSphere1.getRadius();
240        float radius2 = bSphere2.getRadius();
241        float dist = (bSphere1.getCenter() - bSphere2.getCenter()).length();
242        float maxrad = std::max(radius1,radius2);
243
244        if(dist + radius1 <= radius2 && radius2 < MAXRAD) return true;
245        else if(dist + radius2 <= radius1 && radius1 < MAXRAD) return true;
246        else if(        maxrad + dist < MAXRAD) return true;
247
248        return false;
249}
250
251void OgreSharedRuns::destroy()
252{
253        if(parent != 0)
254                parent->destroy();
255
256        OgreIlluminationManager::getSingleton().sharedRunSplit(this, child1, child2);
257
258        ((OgreSharedRuns*)child1)->fireRunChanges();
259        ((OgreSharedRuns*)child2)->fireRunChanges();
260        child1->unbindParent();
261        child2->unbindAndKillParent();
262}
263
264void OgreSharedRuns::addRenderablesToQueue(RenderQueue* rq, bool checkVisible)
265{
266        if(child1 != 0) //node
267        {
268                ((OgreSharedRuns*)child1)->addRenderablesToQueue(rq);
269                ((OgreSharedRuns*)child2)->addRenderablesToQueue(rq);
270        }
271        else //leaf
272        {
273                std::map<OgreRenderable*, bool>::iterator it = renderables.begin();
274                std::map<OgreRenderable*, bool>::iterator itend = renderables.end();
275                while(it != itend)
276                {               
277                        if(!checkVisible || (*it).first->isVisible())
278                        {
279                                //rq->addRenderable(((*it).first)->getRenderable());
280                                ((*it).first)->updateRenderQueue(rq);
281                        }
282                        it++;
283                }
284        }
285}
286
287void OgreSharedRuns::notifyCamera(Camera* cam)
288{
289        if(child1 != 0) //node
290        {
291                ((OgreSharedRuns*)child1)->notifyCamera(cam);
292                ((OgreSharedRuns*)child2)->notifyCamera(cam);           
293        }
294        else
295        {
296                std::map<OgreRenderable*, bool>::iterator it = renderables.begin();
297                std::map<OgreRenderable*, bool>::iterator itend = renderables.end();
298                while(it != itend)
299                {       
300                        OgreRenderable* rend = (*it).first;
301                        if((*it).first->isVisible())
302                                rend->notifyCamera(cam);
303                        it++;
304                }
305        }
306}
307
308void OgreSharedRuns::findSharedRootsForType(RenderingRunType runType, std::vector<OgreSharedRuns*>& roots)
309{
310        if(hasOwnRun(runType))
311        {
312                roots.push_back(this);
313        }
314
315        if(child1 != 0)
316                ((OgreSharedRuns*)child1)->findSharedRootsForType(runType, roots);
317        if(child2 != 0)
318                ((OgreSharedRuns*)child2)->findSharedRootsForType(runType, roots);
319}
320
321void OgreSharedRuns::setMaterial(String materialName)
322{
323        renderableMaterials.clear();
324        std::map<OgreRenderable*, bool>::iterator it = renderables.begin();
325        std::map<OgreRenderable*, bool>::iterator itend = renderables.end();
326        while(it != itend)
327        {               
328                renderableMaterials[(*it).first] = (*it).first->getMaterialName();
329                (*it).first->setMaterialName(materialName);
330                it++;
331        }
332
333        if(child1 != 0)
334                ((OgreSharedRuns*)child1)->setMaterial(materialName);
335        if(child2 != 0)
336                ((OgreSharedRuns*)child2)->setMaterial(materialName);
337}
338
339void OgreSharedRuns::restoreMaterial()
340{
341        std::map<OgreRenderable*, String>::iterator it = renderableMaterials.begin();
342        std::map<OgreRenderable*, String>::iterator itend = renderableMaterials.end();
343        while(it != itend)
344        {               
345                (*it).first->setMaterialName((*it).second);
346                it++;
347        }
348
349        if(child1 != 0)
350                ((OgreSharedRuns*)child1)->restoreMaterial();
351        if(child2 != 0)
352                ((OgreSharedRuns*)child2)->restoreMaterial();
353}
Note: See TracBrowser for help on using the repository browser.