void AtlasClipMapImageSource::setInterestCenter( const Point2I& origin, const U32 radius ) { // Walk the quadtree, topmost unloaded stuff has highest priority. // We also need to issue unloads for stuff around the old origin... // So let's iterate over everything within the bounds of our radius of BOTH // origins. If it's within the originRect, keep it, otherwise cancel it. RectI oldOriginTexelRect, newOriginTexelRect; RectI oldOriginTOCRect, newOriginTOCRect; RectI unionRect; for(S32 i=mTOC->getTreeDepth()-1; i>=0; i--) { const U32 shift = mTOC->getTreeDepth() - i - 1; oldOriginTexelRect.point = mCacheOrigin; oldOriginTexelRect.point.x >>= shift; oldOriginTexelRect.point.y >>= shift; oldOriginTexelRect.extent.set(0,0); S32 rad = (S32)radius; oldOriginTexelRect.inset(-rad, -rad); newOriginTexelRect.point = origin; newOriginTexelRect.point.x >>= shift; newOriginTexelRect.point.y >>= shift; newOriginTexelRect.extent.set(0,0); newOriginTexelRect.inset(-rad, -rad); convertToTOCRect(i, oldOriginTexelRect, oldOriginTOCRect); convertToTOCRect(i, newOriginTexelRect, newOriginTOCRect); unionRect = oldOriginTOCRect; unionRect.unionRects(newOriginTOCRect); // Clamp our update region so we're not walking stuff that is out of range. const S32 xStart = mClamp(unionRect.point.x, 0, BIT(i)); const S32 xEnd = mClamp(unionRect.point.x + unionRect.extent.x, 0, BIT(i)); const S32 yStart = mClamp(unionRect.point.y, 0, BIT(i)); const S32 yEnd = mClamp(unionRect.point.y + unionRect.extent.y, 0, BIT(i)); for(S32 x=xStart; x<xEnd; x++) { for(S32 y=yStart; y<yEnd; y++) { const Point2I pos(x, y); AtlasInstanceTexStub *aits = mTOC->getStub(i, pos); // Note we weight our loads by depth - the closest to the root // goes first. if(newOriginTOCRect.pointInRect(pos)) mTOC->requestLoad(aits, AtlasTOC::NormalPriority, F32(shift + 1) / F32(mTOC->getTreeDepth() + 1)); else { mTOC->cancelLoadRequest(aits, AtlasTOC::NormalPriority); } } } } // Now we can update the cache origin. mCacheOrigin = origin; }