File size: 2,592 Bytes
d42e2ad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
"""Renders 8 distinct sample races, one for each track archetype."""

import sys
from pathlib import Path
from raceforge.audio.mix import AudioSynthesizer
from raceforge.director.base import TrackDirective
from raceforge.encode.ffmpeg_pipe import encode_full_mp4
from raceforge.render.frames import CairoFrameRenderer
from raceforge.schemas.spec import ArchetypeKind, AudioScale
from raceforge.sim.engine import SimulationEngine
from raceforge.track.builder import build_track
from raceforge.track.clearance import compute_walkable_manifold
from raceforge.track.grid import GridCell
from raceforge.track.solver import GeodesicSolver

ARCHETYPES = [
    (ArchetypeKind.SERPENTINE, 201, "olive", AudioScale.C_MAJOR_PENTATONIC),
    (ArchetypeKind.COMB_CHAMBER, 202, "slate", AudioScale.A_MINOR_PENTATONIC),
    (ArchetypeKind.SPIRAL, 203, "mint", AudioScale.LYDIAN),
    (ArchetypeKind.NESTED_RINGS, 204, "beige", AudioScale.C_MAJOR_PENTATONIC),
    (ArchetypeKind.ROOM_BRAID, 205, "olive", AudioScale.A_MINOR_PENTATONIC),
    (ArchetypeKind.CHEVRON, 206, "slate", AudioScale.LYDIAN),
    (ArchetypeKind.HUB_SPOKE, 207, "mint", AudioScale.C_MAJOR_PENTATONIC),
    (ArchetypeKind.PIPE_NETWORK, 208, "beige", AudioScale.A_MINOR_PENTATONIC),
]

out_dir = Path("out/samples")
out_dir.mkdir(parents=True, exist_ok=True)

for kind, seed, theme, scale in ARCHETYPES:
    name = kind.value
    mp4_path = out_dir / f"sample_{name}.mp4"
    wav_path = out_dir / f"sample_{name}.wav"

    print(f"--> Generating archetype '{name}' (seed {seed}, theme {theme})...")
    directive = TrackDirective(
        archetypes=[kind],
        theme=theme,
        base_speed=350.0,
        audio_scale=scale,
        bpm=128.0,
    )
    spec, grid = build_track(seed, directive)
    gcell = grid.world_to_cell(
        (spec.track.goal_tile[0] + spec.track.goal_tile[2]) / 2.0,
        (spec.track.goal_tile[1] + spec.track.goal_tile[3]) / 2.0,
    ) or GridCell(1, 1)

    w = compute_walkable_manifold(grid, spec.physics.racer_size)
    solver = GeodesicSolver(grid, w, gcell)

    engine = SimulationEngine(spec, grid, solver, fps=60, max_duration_s=8.0)
    timeline = engine.run()

    # Synthesize audio
    synth = AudioSynthesizer(spec, timeline)
    synth.synthesize(wav_path)

    # Render video
    renderer = CairoFrameRenderer(spec, grid, timeline)
    encode_full_mp4(renderer.iter_raw_bgra_frames(), wav_path, mp4_path, width=1080, height=1920, fps=60)
    print(f"✓ Saved {mp4_path} ({mp4_path.stat().st_size / 1024 / 1024:.2f} MB)")

print("All 8 archetype sample MP4s generated successfully!")