public void DrawHeightmapFlat(HeightmapView heightmapView, SortedList <int, Color> heightColorGradient) { int startX, endX; HeightmapDrawRangeHelper(heightmapView, out startX, out endX); if (endX <= startX) { return; // Off screen } int xFlipFactor = heightmapView.flipX ? -1 : 1; for (int z = heightmapView.heightmap.EndZ - 1; z >= heightmapView.heightmap.StartZ; z--) // From back to front of heightmap { for (int x = startX; x < endX; x++) { byte height = heightmapView.heightmap[x * xFlipFactor, z]; if (height == heightmapView.heightmap.DefaultHeight) { continue; } // Draw top surface DrawPixel(new Position(heightmapView.position.X + x, 0, heightmapView.position.Z + z), heightColorGradient.GetColorFromGradient(height + heightmapView.position.Y), 0); } } }
public static AABB AsAABB(this AnimationSet animationSet, Position position, bool facingLeft) { // TODO: Stop assuming a height, and get a real AABB from the heightmap (requires Heightmap cache its own AABB) var heightmapView = new HeightmapView(animationSet.Heightmap, position, facingLeft); var heightmapXZ = heightmapView.Bounds; const int guessHeight = 50; var aabb = new AABB(heightmapXZ.Left, heightmapXZ.Right - 1, position.Y, position.Y + guessHeight, heightmapXZ.Y, heightmapXZ.Y + heightmapXZ.Height - 1); return(aabb); }
/// <summary>Constrain rendering to the display bounds</summary> void HeightmapDrawRangeHelper(HeightmapView heightmapView, out int startX, out int endX) { if (heightmapView.flipX) { startX = Math.Max(1 - heightmapView.heightmap.EndX, displayBounds.Left - heightmapView.position.X); endX = Math.Min(1 - heightmapView.heightmap.StartX, displayBounds.Right - heightmapView.position.X); } else { startX = Math.Max(heightmapView.heightmap.StartX, displayBounds.Left - heightmapView.position.X); endX = Math.Min(heightmapView.heightmap.EndX, displayBounds.Right - heightmapView.position.X); } }
public void DrawHeightmapSolid(HeightmapView heightmapView, SortedList <int, Color> heightColorGradient) { int startX, endX; HeightmapDrawRangeHelper(heightmapView, out startX, out endX); if (endX <= startX) { return; // Off screen } int xFlipFactor = heightmapView.flipX ? -1 : 1; for (int z = heightmapView.heightmap.EndZ - 1; z >= heightmapView.heightmap.StartZ; z--) // From back to front of heightmap { for (int x = startX; x < endX; x++) { byte height = heightmapView.heightmap[x * xFlipFactor, z]; if (height == heightmapView.heightmap.DefaultHeight) { continue; } byte nextHeight = heightmapView.heightmap[x * xFlipFactor, z - 1]; if (nextHeight != heightmapView.heightmap.DefaultHeight && nextHeight > height) { continue; // Next row will cover this one entirely } // Draw top surface const int zTestOffset = 1; // <- The top surface should be "under" any other pixels DrawPixel(heightmapView.position + new Position(x, height, z), heightColorGradient.GetColorFromGradient(height + heightmapView.position.Y), zTestOffset); if (nextHeight != heightmapView.heightmap.DefaultHeight && nextHeight == height) { continue; // Next row covers this one's "solid" section } // Draw solidness for (int h = height + heightmapView.position.Y - 1; h >= heightmapView.position.Y; h--) { Color c = Color.Lerp(heightColorGradient.GetColorFromGradient(h), Color.Black, 0.6f); DrawPixel(new Position(heightmapView.position.X + x, h, heightmapView.position.Z + z), c, 0); } } } }