| 195 | } |
| 196 | |
| 197 | Tr2SkinnedModel* Tr2SkinnedObjectLod::SetLOD( const TriFrustum* frustum, float estimatedPixelDiameter ) |
| 198 | { |
| 199 | CCP_STATS_ZONE( __FUNCTION__ ); |
| 200 | |
| 201 | if( !m_allowLodSelection ) |
| 202 | { |
| 203 | return NULL; |
| 204 | } |
| 205 | |
| 206 | IBlueObjectProxyPtr proxy[3] = { m_highDetailProxy, m_mediumDetailProxy, m_lowDetailProxy }; |
| 207 | |
| 208 | // are any of the proxies in the middle of building something? In that case, wait that out so |
| 209 | // we don't bombard the resource system. |
| 210 | int stickyLod = -1; |
| 211 | for( unsigned i = 0; i != 3; ++i ) |
| 212 | { |
| 213 | if( proxy[i] && proxy[i]->IsTemporary() ) |
| 214 | { |
| 215 | CCP_STATS_INC( countUnderConstructionLOD ); |
| 216 | stickyLod = m_currentLod; |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | const int high = 0; |
| 221 | const int medium = 1; |
| 222 | const int low = 2; |
| 223 | |
| 224 | int choice[3] = { high, medium, low }; // order of preferred LOD. set up for high lod by default |
| 225 | |
| 226 | if( stickyLod == 2 || |
| 227 | // small enough for low lod? |
| 228 | ( m_currentLod >= 2 && estimatedPixelDiameter <= g_skinnedLowDetailThreshold + g_skinnedMediumLowMargin ) || // before going up, add some margin |
| 229 | ( m_currentLod < 2 && estimatedPixelDiameter <= g_skinnedLowDetailThreshold - g_skinnedMediumLowMargin ) ) |
| 230 | { |
| 231 | choice[0] = low; |
| 232 | choice[1] = medium; |
| 233 | choice[2] = high; |
| 234 | } |
| 235 | else if( stickyLod == 1 || |
| 236 | // medium lod? |
| 237 | ( m_currentLod >= 1 && estimatedPixelDiameter <= g_skinnedMediumDetailThreshold + g_skinnedHighMediumMargin ) || // before going up, add some margin |
| 238 | ( m_currentLod < 1 && estimatedPixelDiameter <= g_skinnedMediumDetailThreshold - g_skinnedHighMediumMargin ) ) |
| 239 | { |
| 240 | choice[0] = medium; |
| 241 | choice[1] = low; |
| 242 | choice[2] = high; |
| 243 | } |
| 244 | |
| 245 | // Go through our choices of LOD in order, until we find something that's not null. |
| 246 | // If we got something, but it's still loading or a temp stub, we may still want to switch |
| 247 | // to something better, _if_ the new choice is already resident (so we don't trigger loads |
| 248 | // on everything at the same time). |
| 249 | |
| 250 | int selectedLod = -1; |
| 251 | Tr2SkinnedModel* model = NULL; |
| 252 | bool modelIsTemporary = true; |
| 253 | |
| 254 | for( unsigned i = 0; i != 3; ++i ) |