Add NPC theater poses: sit, photo, film, perform
Once an NPC reaches its intent waypoint it now does something instead of standing in an idle T-pose: - sit: the rig settles 0.34 m into a seat and the legs swing forward on the steps - photo/film: influencers and tourists raise their camera prop briefly (a sine pulse, so it reads as taking a shot rather than a permanently raised arm) - perform: performers sway the sign board they carry Pose selection lives in NpcAvatar.theater_pose() (intent + arrived); the math is in pure helpers (crouch_for_pose, prop_lift_for_pose, sway_for_pose) so it is headless-testable. Prop/leg nodes are captured at build time and animated from their rest offsets. Performers also get a hand-held board and post. Tests/docs - Headless suite 120 -> 127 (test_npc_theater.gd). - Verified visually with a staged sit/photo/perform lineup in front of the entrance. - README, TODO section moved to DONE, MEMORY. Version 0.2.7.
This commit is contained in:
1 parent
1b976bf351
commit
e2c2a0bf4c
9 files changed
+225
-35
No files matched your search
+20
-11
@@ -112,10 +112,10 @@ SCREENS = [
|
||||
"the ring, and the HUD shows a target line with the "
|
||||
"interaction hint.",
|
||||
"prompt": (
|
||||
"Realistic 3D first-person game scene: a pedestrian NPC walking "
|
||||
"toward the camera on a city sidewalk, a thin pale-gold ring floating "
|
||||
"around the NPC's head as a selection marker, a small name label "
|
||||
"under the ring, minimal HUD target text at the bottom, daytime"),
|
||||
"Realistic 3D first-person game scene: a friendly pedestrian "
|
||||
"standing on a city sidewalk, a thin pale-gold ring floating around "
|
||||
"their head as a game selection marker, a small name label under the "
|
||||
"ring, minimal HUD target text at the bottom, daytime"),
|
||||
"regions": [
|
||||
(0.35, 0.15, 0.65, 0.60, "NPC in focus"),
|
||||
(0.44, 0.10, 0.56, 0.16, "head ring"),
|
||||
@@ -156,9 +156,9 @@ SCREENS = [
|
||||
"whether anyone is in immediate danger, plus a send action.",
|
||||
"prompt": (
|
||||
"Realistic 3D game screenshot with an in-game radio dispatch panel "
|
||||
"overlaid: form fields for location, description, behaviour, weapons "
|
||||
"seen and immediate danger, and a Send button, dark translucent panel "
|
||||
"over a softly blurred city street background"),
|
||||
"overlaid: form fields for location, description, behaviour, a threat "
|
||||
"assessment and whether anyone is in danger, and a Send button, dark "
|
||||
"translucent panel over a softly blurred city street background"),
|
||||
"regions": [
|
||||
(0.30, 0.08, 0.70, 0.92, "radio panel"),
|
||||
(0.34, 0.16, 0.66, 0.30, "location / description"),
|
||||
@@ -407,13 +407,22 @@ def _generate_ai(screen, model, request_size):
|
||||
|
||||
def generate(args):
|
||||
DESIGNS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
failed = []
|
||||
for screen in SCREENS:
|
||||
print(f"generating {screen['name']} ...")
|
||||
if args.draft:
|
||||
_draw_wireframe(screen, _design_path(screen["name"]))
|
||||
else:
|
||||
_generate_ai(screen, args.model, args.request_size)
|
||||
try:
|
||||
if args.draft:
|
||||
_draw_wireframe(screen, _design_path(screen["name"]))
|
||||
else:
|
||||
_generate_ai(screen, args.model, args.request_size)
|
||||
except SystemExit as exc:
|
||||
failed.append(screen["name"])
|
||||
print(f" FAILED {screen['name']}: {exc}", file=sys.stderr)
|
||||
print("done")
|
||||
if failed:
|
||||
print(f"failed: {', '.join(failed)}", file=sys.stderr)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in new issue
Block a user