private IPatchRenderer subTileRenderer; // renders partial tile, no extra detail. #endregion Fields #region Constructors public QuadtreeLODRenderer(ITileRenderer fullTileDistant, ITileRenderer fullTileNear, IPatchRenderer subTile, IPatchRenderer subTileDetail) : base() { this.fullTileDistantRenderer = fullTileDistant; this.fullTileNearRenderer = fullTileNear; this.subTileRenderer = subTile; this.subTileDetailRenderer = subTileDetail; this.DetailRadius = 8.0f; this.DistantTileRadius = 512.0f; }
public void Render(TerrainTile tile, TerrainGlobal terrainGlobal, Matrix4 projection, Matrix4 view, Vector3 eye, Vector3 reye, float detailRadius, IPatchRenderer tileRenderer, IPatchRenderer tileDetailRenderer) { // can we render this tile without subdividing? // we can render now once we've got to a small enough tile if (this.TileSize <= 8) //4 { tileDetailRenderer.Width = GetDetailTileSize(reye, detailRadius); tileDetailRenderer.Height = tileDetailRenderer.Width; tileDetailRenderer.DetailScale = (float)this.TileSize / (float)tileDetailRenderer.Width; tileDetailRenderer.Scale = (float)this.TileSize / (float)tile.Width; tileDetailRenderer.Offset = (this.TopLeft.Position.Xz / (float)tile.Width); tileDetailRenderer.Render(tile, terrainGlobal, projection, view, eye); return; } if (!IsViewerInDetailRange(reye, detailRadius)) { // we can if we're outside the detail radius tileRenderer.Width = this.TileSize; tileRenderer.Height = this.TileSize; tileRenderer.Scale = (float)this.TileSize / (float)tile.Width; tileRenderer.Offset = (this.TopLeft.Position.Xz / (float)tile.Width); tileRenderer.Render(tile, terrainGlobal, projection, view, eye); return; } // split into 4 - need centre pos Vector3 centre = (TopLeft.Position + BottomRight.Position) * 0.5f; // top left child new QuadTreeNode() { TopLeft = this.TopLeft, TopRight = new QuadTreeVertex() { Position = new Vector3(centre.X, 0f, this.TopLeft.Position.Z) }, BottomLeft = new QuadTreeVertex() { Position = new Vector3(this.TopLeft.Position.X, 0f, centre.Z) }, BottomRight = new QuadTreeVertex() { Position = centre }, TileSize = this.TileSize / 2 }.Render(tile, terrainGlobal, projection, view, eye, reye, detailRadius, tileRenderer, tileDetailRenderer); // top right child new QuadTreeNode() { TopLeft = new QuadTreeVertex() { Position = new Vector3(centre.X, 0f, this.TopRight.Position.Z) }, TopRight = this.TopRight, BottomLeft = new QuadTreeVertex() { Position = centre }, BottomRight = new QuadTreeVertex() { Position = new Vector3(this.TopRight.Position.X, 0f, centre.Z) }, TileSize = this.TileSize / 2 }.Render(tile, terrainGlobal, projection, view, eye, reye, detailRadius, tileRenderer, tileDetailRenderer); // bottom left child new QuadTreeNode() { TopLeft = new QuadTreeVertex() { Position = new Vector3(this.BottomLeft.Position.X, 0f, centre.Z) }, TopRight = new QuadTreeVertex() { Position = centre }, BottomLeft = this.BottomLeft, BottomRight = new QuadTreeVertex() { Position = new Vector3(centre.X, 0f, this.BottomLeft.Position.Z) }, TileSize = this.TileSize / 2 }.Render(tile, terrainGlobal, projection, view, eye, reye, detailRadius, tileRenderer, tileDetailRenderer); // bottom right child new QuadTreeNode() { TopLeft = new QuadTreeVertex() { Position = centre }, TopRight = new QuadTreeVertex() { Position = new Vector3(this.BottomRight.Position.X, 0f, centre.Z) }, BottomLeft = new QuadTreeVertex() { Position = new Vector3(centre.X, 0f, this.BottomRight.Position.Z) }, BottomRight = this.BottomRight, TileSize = this.TileSize / 2 }.Render(tile, terrainGlobal, projection, view, eye, reye, detailRadius, tileRenderer, tileDetailRenderer); }