RenderSet::references_t RenderSet:: computeChildrenRenderSet( Reference ref ) { references_t R; RenderInfo::LevelOfDetal lod = render_info->testLod (ref ); switch(lod) { case RenderInfo::Lod_NeedBetterF: R |= computeChildrenRenderSet( ref.bottom() ); R |= computeChildrenRenderSet( ref.top() ); break; case RenderInfo::Lod_NeedBetterT: R |= computeChildrenRenderSet( ref.left() ); if ( render_info->region(ref.right ()).a.time < L) { R |= computeChildrenRenderSet( ref.right() ); } break; case RenderInfo::Lod_Ok: R |= ref; break; case RenderInfo::Lod_Invalid: // ref is not within the current view frustum break; } return R; }
RenderInfo::LevelOfDetal RenderInfo:: testLod( Reference ref ) const { float timePixels, scalePixels; Region r = RegionFactory ( bl )(ref); if (!computePixelsPerUnit( r, timePixels, scalePixels )) return Lod_Invalid; if(0) if (-10==ref.log2_samples_size[0] && -8==ref.log2_samples_size[1]) { fprintf(stdout, "Ref (%d,%d)\t%g\t%g\n", ref.block_index[0], ref.block_index[1], timePixels,scalePixels); fflush(stdout); } GLdouble needBetterF, needBetterT; if (0==scalePixels) needBetterF = 1.01; else needBetterF = scalePixels / (redundancy*bl.texels_per_column ()); if (0==timePixels) needBetterT = 1.01; else needBetterT = timePixels / (redundancy*bl.texels_per_row ()); if (!ReferenceInfo(ref.top(), bl, vp).boundsCheck(ReferenceInfo::BoundsCheck_HighS) && !ReferenceInfo(ref.bottom(), bl, vp).boundsCheck(ReferenceInfo::BoundsCheck_HighS)) needBetterF = 0; if (!ReferenceInfo(ref.left(), bl, vp).boundsCheck(ReferenceInfo::BoundsCheck_HighT)) needBetterT = 0; if ( needBetterF > needBetterT && needBetterF > 1 ) return Lod_NeedBetterF; else if ( needBetterT > 1 ) return Lod_NeedBetterT; else return Lod_Ok; }
Reference RenderSet:: computeRefAt( Heightmap::Position p, Reference entireHeightmap ) const { Reference ref = entireHeightmap; // The first 'ref' will be a super-ref containing all other refs, thus // containing 'p' too. This while-loop zooms in on a ref containing // 'p' with enough details. // If 'p' is not within entireHeightmap this algorithm will choose some ref // along the border closest to the point 'p'. while (true) { RenderInfoI::LevelOfDetal lod = render_info->testLod(ref); Region r = render_info->region(ref); switch(lod) { case RenderInfoI::Lod_NeedBetterF: if ((r.a.scale+r.b.scale)/2 > p.scale) ref = ref.bottom(); else ref = ref.top(); break; case RenderInfoI::Lod_NeedBetterT: if ((r.a.time+r.b.time)/2 > p.time) ref = ref.left(); else ref = ref.right(); break; default: return ref; } } }