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

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