OSGScreenLOD.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <cstdlib>
00044 #include <cstdio>
00045
00046 #include "OSGConfig.h"
00047 #include "OSGRenderAction.h"
00048
00049 #include "OSGScreenLOD.h"
00050 #include "OSGDrawableStatsAttachment.h"
00051
00052 OSG_USING_NAMESPACE
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 void ScreenLOD::initMethod(InitPhase ePhase)
00068 {
00069 Inherited::initMethod(ePhase);
00070
00071 if(ePhase == TypeObject::SystemPost)
00072 {
00073 typedef ActionBase::ResultE (ScreenLOD::*Callback)(Action *);
00074
00075 Callback enter = &ScreenLOD::renderEnter;
00076
00077 RenderAction::registerEnterDefault(
00078 getClassType(),
00079 reinterpret_cast<Action::Callback>(enter));
00080 }
00081 }
00082
00083
00084
00085
00086
00087
00088 ActionBase::ResultE ScreenLOD::renderEnter(Action *action)
00089 {
00090 RenderAction *ra = dynamic_cast<RenderAction*>(action);
00091
00092 Int32 numLevels = action->getNNodes();
00093 Int32 index = 0;
00094
00095 Int32 numCovOverrides = getMFCoverageOverride()->size();
00096 bool use_overrides(numCovOverrides > 0);
00097
00098 if(numLevels > 1)
00099 {
00100 if((ra->getScreenLODCoverageThreshold() > 0.f) || use_overrides)
00101 {
00102
00103 Matrixr worldToScreen;
00104 #if 1
00105 Camera* cam = ra->getCamera();
00106 Viewport* vp = ra->getViewport();
00107 cam->getWorldToScreen(worldToScreen, *vp);
00108 #else
00109 worldToScreen = da->getDrawEnv()->getWorldToScreen();
00110 #endif
00111
00112 const BoxVolume &volume = ra->getActNode()->getVolume();
00113 Pnt3r min,max;
00114 volume.getBounds(min, max);
00115 Pnt3r p[8];
00116 p[0].setValues(min[0],min[1],min[2]);
00117 p[1].setValues(max[0],min[1],min[2]);
00118 p[2].setValues(min[0],max[1],min[2]);
00119 p[3].setValues(min[0],min[1],max[2]);
00120 p[4].setValues(max[0],max[1],min[2]);
00121 p[5].setValues(max[0],min[1],max[2]);
00122 p[6].setValues(min[0],max[1],max[2]);
00123 p[7].setValues(max[0],max[1],max[2]);
00124
00125 for(UInt32 i = 0; i<8;i++)
00126 {
00127 ra->topMatrix().mult (p[i], p[i]);
00128 worldToScreen .multFull(p[i], p[i]);
00129 }
00130 min=p[0];
00131 max=p[0];
00132 for(UInt32 i = 0; i<8; i++)
00133 {
00134 for(UInt32 j=0; j<2; j++)
00135 {
00136 if(p[i][j] < min[j])
00137 {
00138 min[j] = p[i][j];
00139 }
00140 if(p[i][j] > max[j])
00141 {
00142 max[j] = p[i][j];
00143 }
00144 }
00145 }
00146 max[0] = osgClamp(-1.f, max[0], 1.f);
00147 max[1] = osgClamp(-1.f, max[1], 1.f);
00148 min[0] = osgClamp(-1.f, min[0], 1.f);
00149 min[1] = osgClamp(-1.f, min[1], 1.f);
00150
00151
00152 Real32 cbb = (max[0] - min[0]) * (max[1] - min[1]) / 4.f;
00153
00154
00155 if (!use_overrides)
00156 {
00157
00158 Node *pmax = action->getNode(0);
00159 DrawableStatsAttachment *st_max =
00160 DrawableStatsAttachment::get(pmax);
00161
00162 if(st_max == NULL)
00163 {
00164 DrawableStatsAttachment::addTo(pmax);
00165 st_max = DrawableStatsAttachment::get(pmax);
00166 }
00167 st_max->validate();
00168
00169
00170 Node *pmin = action->getNode(numLevels-1);
00171 DrawableStatsAttachment *st_min =
00172 DrawableStatsAttachment::get(pmin);
00173 if(st_min == NULL)
00174 {
00175 DrawableStatsAttachment::addTo(pmin);
00176 st_min = DrawableStatsAttachment::get(pmin);
00177 }
00178 st_min->validate();
00179
00180
00181 Real32 deg_percent = 1.0 - (st_min->getTriangles() / st_max->getTriangles());
00182 deg_percent = deg_percent / numLevels;
00183 if(deg_percent >= 1.0)
00184 {
00185 cbb = ra->getScreenLODCoverageThreshold();
00186 }
00187
00188 Real32 base_percent = ra->getScreenLODCoverageThreshold();
00189 Real32 user_deg_factor = ra->getScreenLODDegradationFactor();
00190
00191
00192 while(cbb < base_percent)
00193 {
00194 base_percent= base_percent * deg_percent * user_deg_factor;
00195 index++;
00196 if(index >= numLevels)
00197 break;
00198 }
00199 }
00200
00201 else
00202 {
00203 unsigned idx_limit = osgMin(numLevels, numCovOverrides);
00204
00205 if(cbb > (*(getMFCoverageOverride()))[0])
00206 {
00207 index = 0;
00208 }
00209 else if(cbb <= (*(getMFCoverageOverride()))[numCovOverrides-1])
00210 {
00211 index = (numLevels > numCovOverrides) ? numCovOverrides : (idx_limit-1);
00212 }
00213 else
00214 {
00215 Int32 i = 1;
00216
00217
00218 while( (i < numCovOverrides) &&
00219 !( (cbb <= (*(getMFCoverageOverride()))[i-1]) &&
00220 (cbb > (*(getMFCoverageOverride()))[i] ) ) )
00221 {
00222 i++;
00223 }
00224 index = i;
00225 }
00226 }
00227 }
00228 }
00229
00230 if (index >= numLevels)
00231 {
00232 index=numLevels-1;
00233 }
00234
00235
00236
00237
00238 Int32 lowestLOD = ra->getScreenLODNumLevels();
00239 if(lowestLOD != 0)
00240 {
00241 lowestLOD--;
00242 if(index > lowestLOD)
00243 index = lowestLOD;
00244 }
00245
00246
00247 ra->useNodeList();
00248 if(ra->isVisible(action->getNode(index)))
00249 {
00250 ra->addNode(action->getNode(index));
00251 }
00252
00253 return ActionBase::Continue;
00254 }
00255
00256
00257
00258
00259
00260
00261
00262 ScreenLOD::ScreenLOD(void) :
00263 Inherited()
00264 {
00265 }
00266
00267 ScreenLOD::ScreenLOD(const ScreenLOD &source) :
00268 Inherited(source)
00269 {
00270 }
00271
00272 ScreenLOD::~ScreenLOD(void)
00273 {
00274 }
00275
00276
00277
00278 void ScreenLOD::changed(ConstFieldMaskArg whichField,
00279 UInt32 origin,
00280 BitVector details)
00281 {
00282 Inherited::changed(whichField, origin, details);
00283 }
00284
00285 void ScreenLOD::dump( UInt32 ,
00286 const BitVector ) const
00287 {
00288 SLOG << "Dump ScreenLOD NI" << std::endl;
00289 }