// For each Ladbm terrain tile, we set the virtual LOD offset and the // number of effective levels once per frame. // static int tilePreCull(pfTraverser *trav, void *travData) { set mpct = pointer to the pfMPClipTexture associated with this tile set ct = mpct->getClipTexture(); if (mpct != NULL) { // Work out the distance from the eye to the closest point on the tile in object space: set tileDistance = the distance from the eye to the tile center. if tileDistance is < a threshold value set tileDistance using pfuGetClosestPointOnTriangle for the 2 triangles making up the tile. // min_dst_dxyz is the Min change in s,t per change in x,y,z in object space. // min_dst_dxyz is pretty much a constant and we should probably just // calculate it once using the cliptexture extremities. // But for now, do it per tile ... // set min_dst_dxyz using the texcoords & xyz coords of the corners of the tile // min & max LOD stuff similar to pfspherepatch.C int virtSizeS, virtSizeT; ct->getVirtualSize(&virtSizeS, &virtSizeT, NULL); set nLevels = log2int(virtSizeS)+1; pfFrustum *appfrust = new pfFrustum; // XXX per-frame malloc!!! int viewportWidth, viewportHeight; pfChannel *chan = trav->getChan(); chan->getBaseFrust(appfrust); chan->getSize(&viewportWidth, &viewportHeight); /* comment from pfspherepatch.C :: wrong-- should use culling frustum! */ // The floating-point size of the biggest (finest) square mipmap level // that can be needed for rendering textured geometry given the current // frustum, viewport & min distance from the eye to the tile. // The result is clamped to the range 1..virtSizeS. float minlod_size = pfuCalcSizeFinestMipLOD(appfrust, viewportWidth, viewportHeight, tileDistance, min_dst_dxyz, virtSizeS); pfDelete(appfrust); // comment from pfspherepatch.C :: per-frame delete! get rid of this! // The highest res level needed for rendering (0 is the finest LOD). float minLODTexPix = nLevels-1 - log2(minlod_size); int invalidBorder = mpct->getInvalidBorder(); int clipSize = ct->getClipSize(); float minLODLoaded = ct->getMinDTRLOD(); float maxLODLoaded = ct->getNumAllocatedLevels()-1; // Work out the min & max distances from clip center to this tile in texture coords. // This bbox stuff is similar to what's in virtcliptex.c - it does an approximation. set centCoordS, centCoordT to be the texcoord of the clipcenter set minS, minT, maxS, maxT = appropriate texcoord values for the tile set bboxMinDist = PF_MAX4(minS - centCoordS, centCoordS - maxS, minT - centCoordT, centCoordT - maxT); set bboxMaxDist = PF_MAX4(maxS - centCoordS, centCoordS - minS, maxT - centCoordT, centCoordT - minT); // The following case only happens when the clipcentre is on this tile // if (bboxMinDist < 0.f) bboxMinDist = 0.f; // tradeoff=0.: just decrease numEffectiveLevels without changing // LODOffset (i.e. choose high res but // possibly garbage on the horizon) // tradeoff=1.: decrease numEffectiveLevels but increase LODOffset // by the same amount (i.e. get the desired // area but possibly blur out fine levels) // 0.applyVirtualParams(LODOffset, numEffectiveLevels); ct->applyMinLOD(minLOD); ct->applyMaxLOD(maxLOD); }