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

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