visual: top-down map renderer, demo --frames-dir mode (step frames + GIF + summary), example artifacts committed
This commit is contained in:
+54
-1
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user