1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/3d/load_balancing_trav.h"
20 #include "nel/3d/hrc_trav.h"
21 #include "nel/3d/clip_trav.h"
22 #include "nel/misc/common.h"
23 #include "nel/misc/hierarchical_timer.h"
24 #include "nel/3d/transform.h"
28 using namespace NLMISC
;
31 // ***************************************************************************
32 #define NL3D_DEFAULT_LOADBALANCING_VALUE_SMOOTHER 50
33 #define NL3D_LOADBALANCING_SMOOTHER_MAX_RATIO 1.1f
42 // ***************************************************************************
43 // ***************************************************************************
44 // ***************************************************************************
45 // ***************************************************************************
48 // ***************************************************************************
49 CLoadBalancingGroup::CLoadBalancingGroup()
51 _PrecPolygonBalancingMode
= CLoadBalancingGroup::PolygonBalancingOff
;
53 _ValueSmoother
.init(NL3D_DEFAULT_LOADBALANCING_VALUE_SMOOTHER
);
61 // ***************************************************************************
62 void CLoadBalancingGroup::computeRatioAndSmooth(TPolygonBalancingMode polMode
)
64 // If Default group, disable load balancing
66 polMode
= PolygonBalancingOff
;
71 case PolygonBalancingOff
:
74 case PolygonBalancingOn
:
76 _FaceRatio
= (float)_NbFaceWanted
/ _NbFacePass0
;
80 case PolygonBalancingClamp
:
82 _FaceRatio
= (float)_NbFaceWanted
/ _NbFacePass0
;
85 clamp(_FaceRatio
, 0, 1);
91 // if change of PolygonBalancingMode, reset the _ValueSmoother.
92 if(polMode
!=_PrecPolygonBalancingMode
)
94 _ValueSmoother
.init(NL3D_DEFAULT_LOADBALANCING_VALUE_SMOOTHER
);
95 _PrecPolygonBalancingMode
= polMode
;
97 // if not PolygonBalancingOff, smooth the ratio.
98 if(polMode
!=PolygonBalancingOff
)
100 // FIX: If the _FaceRatio is not a float (NaN or +-oo), don't add it!!
101 if(isValidDouble(_FaceRatio
))
102 _ValueSmoother
.addValue(_FaceRatio
);
103 float fSmooth
= _ValueSmoother
.getSmoothValue();
105 // If after smoothing, the number of faces is still too big, reduce smooth effect! (frustrum clip effect)
106 if(fSmooth
*_NbFacePass0
> _NbFaceWanted
*NL3D_LOADBALANCING_SMOOTHER_MAX_RATIO
)
108 // reset the smoother
109 _ValueSmoother
.reset();
110 // reduce smooth effect
111 fSmooth
= _FaceRatio
*NL3D_LOADBALANCING_SMOOTHER_MAX_RATIO
;
112 _ValueSmoother
.addValue(fSmooth
);
115 // take the smoothed value.
124 // ***************************************************************************
125 // ***************************************************************************
126 // ***************************************************************************
127 // ***************************************************************************
130 // ***************************************************************************
131 CLoadBalancingTrav::CLoadBalancingTrav()
133 PolygonBalancingMode
= CLoadBalancingGroup::PolygonBalancingOff
;
135 // Add the default group and make it default
136 _GroupMap
["Default"].Name
= "Default";
137 _GroupMap
["Default"]._DefaultGroup
= true;
139 // set the DefaultGroup ptr.
140 _DefaultGroup
= &_GroupMap
["Default"];
142 // prepare some space
143 _VisibleList
.resize(1024);
144 _CurrentNumVisibleModels
= 0;
148 // ***************************************************************************
149 void CLoadBalancingTrav::clearVisibleList()
151 _CurrentNumVisibleModels
= 0;
155 // ***************************************************************************
156 void CLoadBalancingTrav::traverse()
158 H_AUTO( NL3D_TravLoadBalancing
);
160 CTravCameraScene::update();
164 ItGroupMap it
= _GroupMap
.begin();
165 for(;it
!=_GroupMap
.end();it
++)
167 // reset _NbFacePass0.
168 it
->second
._NbFacePass0
= 0;
172 // Traverse the graph 2 times.
174 // 1st pass, count NBFaces drawed.
177 // count _NbFacePass0.
178 traverseVisibilityList();
181 // Reset _SumNbFacePass0
184 it
= _GroupMap
.begin();
185 for(;it
!=_GroupMap
.end();it
++)
187 // compute ratio and smooth
188 it
->second
.computeRatioAndSmooth(PolygonBalancingMode
);
189 // update _SumNbFacePass0
190 _SumNbFacePass0
+= it
->second
.getNbFaceAsked();
194 // 2nd pass, compute Faces that will be drawed.
197 traverseVisibilityList();
202 // ***************************************************************************
203 void CLoadBalancingTrav::traverseVisibilityList()
205 // Traverse all nodes of the visibility list.
206 for(uint i
=0; i
<_CurrentNumVisibleModels
; i
++)
208 CTransform
*model
= _VisibleList
[i
];
209 model
->traverseLoadBalancing();
214 // ***************************************************************************
215 float CLoadBalancingTrav::getNbFaceAsked () const
217 return _SumNbFacePass0
;
221 // ***************************************************************************
222 CLoadBalancingGroup
*CLoadBalancingTrav::getOrCreateGroup(const std::string
&group
)
226 it
= _GroupMap
.find(group
);
227 // if not exist, create.
228 if(it
==_GroupMap
.end())
230 // create and set name.
231 it
= _GroupMap
.insert(make_pair(group
, CLoadBalancingGroup())).first
;
232 it
->second
.Name
= group
;
235 return &(it
->second
);
238 // ***************************************************************************
239 void CLoadBalancingTrav::setGroupNbFaceWanted(const std::string
&group
, uint nFaces
)
241 // get/create if needed, and assign.
242 getOrCreateGroup(group
)->setNbFaceWanted(nFaces
);
245 // ***************************************************************************
246 uint
CLoadBalancingTrav::getGroupNbFaceWanted(const std::string
&group
)
248 // get/create if needed, and get.
249 return getOrCreateGroup(group
)->getNbFaceWanted();
252 // ***************************************************************************
253 float CLoadBalancingTrav::getGroupNbFaceAsked (const std::string
&group
) const
255 TGroupMap::const_iterator it
;
256 it
= _GroupMap
.find(group
);
257 if(it
==_GroupMap
.end())
260 return it
->second
.getNbFaceAsked();
264 // ***************************************************************************
265 void CLoadBalancingTrav::reserveVisibleList(uint numModels
)
268 if(numModels
>_VisibleList
.size())
269 _VisibleList
.resize(numModels
);