internal TerrainModel(int numPatchesX, int numPatchesY, Patch[,] patches, HeightMap heightMap, float tau, Effect effect) { HeightMap = heightMap; _numPatchesX = numPatchesX; _numPatchesY = numPatchesY; _patches = patches; _tau = tau; Effect = effect; }
internal TerrainModel(int numPatchesX, int numPatchesY, Patch[,] patches, HeightMap heightMap, Effect effect) { HeightMap = heightMap; _numPatchesX = numPatchesX; _numPatchesY = numPatchesY; _patches = new List<Patch>(_numPatchesX * _numPatchesY); _numLevels = 0; for (int x = 0; x < _numPatchesX; x++) for (int y = 0; y < _numPatchesY; y++) { _patches.Add(patches[x, y]); _numLevels = Math.Max(_numLevels, patches[x, y].Levels); } _visiblePatches = new List<Patch>(_patches.Count); MaxPatchesAtLevel = new int[_numLevels - 1]; MaxPatchesAtLevel[0] = 4; for (int i = 1; i < _numLevels - 1; i++) { MaxPatchesAtLevel[i] = MaxPatchesAtLevel[i - 1] * 2; } Effect = effect; }
internal void SetNeighbours(Patch pLeft, Patch pRight, Patch pTop, Patch pBottom) { _left = pLeft; _right = pRight; _top = pTop; _bottom = pBottom; }
public void Update(ICamera camera) { // TODO: Maybe don't need to update levels for invisible patches? // set preferred tesselation levels for each patch for (int y = 0; y < _numPatchesY; y++) { for (int x = 0; x < _numPatchesX; x++) { if (camera.BoundingFrustum.Contains(_patches[x, y].BoundingBox) != ContainmentType.Disjoint) { _patches[x, y].Visible = true; _patches[x, y].UpdateLevelOfDetail(camera); } else { _patches[x, y].Visible = false; } } } // now, make sure that each patch is no more than 1 level different from its neighbours // we loop through all patches, and if any are changed, set a flag. continue the outer // loop until the "changed" flag is false for all patches bool bChanged; do { bChanged = false; for (int y = 0; y < _numPatchesY; y++) { for (int x = 0; x < _numPatchesX; x++) { // get the minimum level for neighbouring patches Patch pPatch = _patches[x, y]; int nLevel = pPatch.ActiveLevel; int nLeft = pPatch.LeftActiveLevel; int nRight = pPatch.RightActiveLevel; int nTop = pPatch.TopActiveLevel; int nBottom = pPatch.BottomActiveLevel; int nMinimumNeighbouringLevel = Math.Min(Math.Min(nLeft, nRight), Math.Min(nTop, nBottom)); if (nLevel > nMinimumNeighbouringLevel + 1) { pPatch.ActiveLevel = nMinimumNeighbouringLevel + 1; bChanged = true; } } } }while (bChanged); // finally, update geometry to match LOD for (int y = 0; y < _numPatchesY; y++) { for (int x = 0; x < _numPatchesX; x++) { _patches[x, y].UpdateTessellation(); } } /*int numVisible = 0; * for (int y = 0; y < _numPatchesY; y++) * for (int x = 0; x < _numPatchesX; x++) * if (_patches[x, y].Visible) * numVisible++;*/ }