visual: top-down map renderer, demo --frames-dir mode (step frames + GIF + summary), example artifacts committed

This commit is contained in:
opencode
2026-08-08 12:03:35 +03:00
parent c224595f49
commit 1ebccb660b
6 changed files with 236 additions and 5 deletions
+54 -1
View File
@@ -11,7 +11,7 @@ from __future__ import annotations
import math
from PIL import Image
from PIL import Image, ImageDraw
from testbed.room.world import ROOM_HEIGHT, ROOM_SIZE, Room
@@ -355,6 +355,59 @@ class Raycaster:
return grid
def render_topdown(room: Room, size: int = 400) -> Image.Image:
"""Bird's-eye view of the whole room (debug helper; uses world state).
Floor grid, crates, beacon (cyan / warm yellow when active) and the
capsule as a circle with a heading arrow.
"""
scale = size / ROOM_SIZE
img = Image.new("RGB", (size, size), (52, 52, 58))
draw = ImageDraw.Draw(img)
def xy(x: float, z: float) -> tuple[float, float]:
return (x * scale, size - z * scale)
for i in range(int(ROOM_SIZE) + 1):
c = 60 if i % 2 == 0 else 54
draw.line([xy(i, 0), xy(i, ROOM_SIZE)], fill=(c, c, c + 6), width=1)
draw.line([xy(0, i), xy(ROOM_SIZE, i)], fill=(c, c, c + 6), width=1)
for box in room.boxes:
xa, za = xy(box.x_min(), box.z_min())
xb, zb = xy(box.x_max(), box.z_max())
draw.rectangle(
[min(xa, xb), min(za, zb), max(xa, xb), max(za, zb)],
fill=box.color,
outline=(20, 20, 26),
width=2,
)
b = room.beacon
bx, bz = xy(b.x, b.z)
color = (255, 200, 90) if b.active else (120, 210, 235)
glow = (255, 240, 180) if b.active else (160, 235, 250)
r = b.radius * scale * 2.2
draw.ellipse([bx - r * 2.4, bz - r * 2.4, bx + r * 2.4, bz + r * 2.4], fill=glow)
draw.ellipse(
[bx - r, bz - r, bx + r, bz + r], fill=color, outline=(20, 20, 26), width=2
)
c = room.capsule
cx, cz = xy(c.x, c.z)
rad = c.radius * scale
draw.ellipse(
[cx - rad, cz - rad, cx + rad, cz + rad],
fill=(240, 240, 250),
outline=(20, 20, 26),
width=2,
)
fx, fz = c.forward()
tip = xy(c.x + fx * 0.7, c.z + fz * 0.7)
draw.line([(cx, cz), tip], fill=(30, 30, 40), width=3)
return img
def _ray_aabb(
ox: float,
oz: float,