Commit Graph
22 Commits
Author SHA1 Message Date
zwitschi de83f990ac fix(review): mannequin down 2 cm; 8 and 9 approved
Owner review: rows 1, 2 and 3 show the mannequin about 2 cm too high; rows 8 and 9 show nothing wrong.

The staging height moves from 8 cm to 6 cm above the floor plane (floor_z on the mannequin's
sit_on_floor call, which now logs +6.0), and rows 8 and 9 are approved. Rows 1, 2 and 3 go back to
pending with the change noted in the table, since the image is what changed.

Captures regenerated.
2026-11-09 21:30:09 +01:00
zwitschi 4498274328 test(vehicle): park the Chaos pawn and give the physics its own task
The pawn was found again after a cleanup removed its staging, and the diagnostic answers the
zero-wheel question with a bigger one: with the pawn present the actor is launched to Z 1993 cm - 18 m
above the ground it stands at 150 - and still reports 0 wheels.

  GigLine vehicle diag: mesh=1 simulating=1 physasset=yes setups=4 wheels=0
  GigLine vehicle: settled at Z 1993 cm, simulating=1

Wheels are only created inside CreateVehicle() when the physics state produced a vehicle, so the
chassis body is the suspect rather than the wheel setup: PA_Vehicle_Sedan has one box on the root bone,
and a body that starts intersecting geometry is the usual reason a vehicle pawn launches itself.

Parked rather than shipped: the pawn is not staged, the visible car stays as panels, and the physics is
'Vehicle physics - Chaos rig' in TODO.md with the evidence and three concrete steps. The demo no longer
carries an 18 m flying car in its captures.
2026-11-09 20:50:52 +01:00
zwitschi 4db33489e1 fix(review): raise the mannequin 8 cm, lower the player 2 cm, per the owner's notes
Owner review of the last set:

  1, 2, 8, 9  rejected - 'mannequin still too low'
  14          approved, but 'floating, only maybe 2 cm too high'

The mannequin correction had been a no-op: actor bounds on a freshly assigned skeletal mesh read as
zero, so sit_on_floor returned +2 cm while the soles sat level with the floor plane. It is now raised
8 cm, which puts them clearly above it, and the four rows are back to pending for re-review with that
noted.

The player start drops 2 cm (258 -> 256) for row 14.

Also repaired the four table rows: a cell-index mistake in the previous edit had emptied their item
links.
2026-11-09 19:57:20 +01:00
zwitschi fb5488c1df fix(review): stage objects by their measured bounds, and aim the vehicle cameras at the car
The review notes named the same class of problem in six rows: things sitting a little too low or too
high in the floor. They were all hand-typed staging heights, and every one was wrong by a different
amount - the mannequin's root is not at its soles, the resting cube's origin is not at its base, the
vehicle's wheels are 2 cm below its panel origin.

sit_on_floor() measures the actor's bounds and shifts it so the mesh's lowest point lands 2 cm above
the floor plane, and reports the correction it applied:

  MPFB character    +2.0 cm
  ScaleTest_A      -48.0 cm   (it was floating)
  vehicle wheels    +2.0 cm

The DemoMap vehicle shot was rejected as 'no vehicle in the scene': both vehicle cameras were still
aimed at the car's old position, so re-aiming them at Y -1450 brings it back into frame.

Status table notes record each fix; the hero-facade rework and the shadow-compare expectation are
left for the owner's next review.
2026-11-09 19:39:04 +01:00
zwitschi 1b4b46e957 fix(site): slice the road too - the 2 m lid was a convex hull, not geometry
The road was never mis-modelled: a 279 m strip imports with ONE auto-generated convex hull, and a
convex hull's top is the strip's maximum height. A downward trace therefore landed at 366 cm - a flat
lid about 2 m above the visible road, which sits at roughly 152 cm there. That single fact explains
every failed sidewalk fix, the 'road above its own sidewalk' reading, and why the player always ended
up on Road_Hollywood.

Slicing the road the way the sidewalks already were fixes it, and the cross-section is now continuous:

  Terrain_DEM       154
  Sidewalk_North_07 158
  Road_Hollywood_07 158   (was 366)

Two changes had to land together: the road exported in slices, and the map stopped staging the single
Road_Hollywood asset - which still sat on top of the slices and won every trace until removed.

All 23 captures regenerated; the player and the car both stand on a continuous ground plane.
2026-11-09 19:15:10 +01:00
zwitschi 4f9e92d975 fix(placement): both objects stand on the pavement, and the sun no longer separates them from their shadows
Three changes close the float:

- The sun went from pitch -74 to -82, so shadows fall under the objects instead of a metre away.
  That is what made grounded objects read as hovering, and the judge reacted to it in every run.
- The car is parked on the same sidewalk surface the player stands on (158 cm at this X) rather
  than on the carriageway, which the shipped site geometry places ~2 m ABOVE its own pavement - a
  data defect still open, but no longer visible in the review shots.
- The player already stands on the sidewalk since Y was moved to -1450.

The wheel and feet captures show the contact: feet and tyres on the pavement with their shadows at
the contact point. judge_screenshot still returns 'floating' for all three, which is advisory only -
AGENTS.md is explicit that it never replaces the human verdict - so it is recorded in the status
table as a disagreement rather than iterated against any further.

All 23 captures are regenerated and awaiting approval.
2026-11-09 19:05:41 +01:00
zwitschi b9919b8d1e fix(placement): the player stands on the sidewalk, at last - 32 cm was the whole float
The player start was at Y -1150, and the north sidewalk slice at that X spans Y -1734..-1182. He was
standing 32 cm south of it, on the roadway - which is why every trace named Road_Hollywood and every
sidewalk fix changed nothing. Moved to Y -1450 and the capsule now rests on the sidewalk:

  top surface under player: Z=158 mesh=Sidewalk_North_07 (actor Z 248)
  body: mesh bottom 161, capsule bottom 161

The cameras that frame the pawn moved with him, and the car now sits on the measured carriageway at
366 rather than the 342 it had.

The captures still read as floating in the vision judge's opinion, and the table says why honestly:
the placements measure correct, but at this sun angle the shadows fall well away from the objects,
which is what the judge is reacting to.

All 23 captures are regenerated and await a fresh approval.
2026-11-09 18:55:43 +01:00
zwitschi f8b9f070d9 fix(placement): give the sidewalk collision, and the player stands on it
The staged sidewalk mesh does not block a downward trace: the capsule fell straight through to
Road_Hollywood at 366 whatever height it started at, which is why three spawn values produced
identical captures. The mesh exists, carries QueryAndPhysics collision and its bounding box tops
out at Z 380, but a trace from above it - and a capsule landing on it - both pass through.

Until the kit mesh's own collision is fixed, an invisible 279 x 8.6 x 0.08 m cube supplies the
surface: top at Z 380, hidden in game, BlockAll. Verified in the same run that used to report the
road:

  top surface under player: Z=380 actor=StaticMeshActor_52 mesh=Cube
  foot Visibility: actor Z 470, feet 382, hit Z 380

So the capsule now rests on the pavement 2 cm above its surface.

The captures still read as floating in the ground-level shots, and the table records that: the
stopgap fixes what the character stands on, not what the camera sees, and those two disagree
until the sidewalk mesh's rendered top matches its collision.
2026-11-09 17:47:10 +01:00
zwitschi 72d5bab427 docs(review): split into ReviewMap and DemoMap, with one status table
The review file now separates the two questions it was mixing:

  ReviewMap - assets staged on their own: individual objects, the Blender import, camera angles
  and the lighting comparison. Nothing from the game map is involved.
  DemoMap   - the actual game map in development: street, buildings, player, vehicle in place.

One status table at the top covers both parts, with a Part column, and remains the only place
approval and issue notes are recorded. Between them sits the Blender-vs-UE comparison, which now
pairs ReviewMap captures as well as DemoMap ones, followed by the ReviewMap image grid and the
existing in-game shot sections.

Tools/ue_build_review_map.py also stages the LATEST vehicle assets (five systems plus the hatch
paint) and two new cameras - a three-quarter view of the car and a ground-level look at the
character's feet - so the staging map never drifts from what the Blender tools last produced.
Tools/render_screenshots.sh gained a second capture pass that renders ReviewMap into
Screenshots/review/, after the demo collection because that pass clears the engine's screenshot
folder.
2026-11-09 17:34:12 +01:00
zwitschi c94ec7bbb9 test(placement): the player stands on Road_Hollywood, not on the sidewalk
Three spawn heights - 455, 395, 469 - produced identical captures, and the in-game probe names
the surface every time: mesh=Road_Hollywood at Z 366. The north sidewalk exists, carries
collision and its top is Z 380, so the character stands 14 cm BELOW the pavement and reads as
floating against the kerb; its shadow falls on the road because the road is genuinely lower.

That is why lowering the spawn changed nothing: the capsule falls through to the road whatever
height it starts at. The question left is the player start's XY footprint, not its Z - the
sidewalk is right there but the capsule never lands on it.

Player start set to 469 (sidewalk top 380 + capsule half 88 + 1) so that, once the footprint is
fixed, the height is already right.
2026-11-09 17:18:23 +01:00
zwitschi ca73563060 test(review): ground-level cameras, and a null result that locates the float
Two cameras were added at pavement height - one on the feet, one on the wheels - because the
wide shots cannot settle whether anything touches the surface.

The feet shot settled it, and not the way I expected. Lowering the player start from 455 to 395
changed NOTHING in the capture: same framing, same float. The capsule falls onto the collider and
always rests at Z 456 with its feet at 369, while the rendered pavement is about a metre lower.

So the float is not a spawn-height problem, and no amount of tuning player_z will fix it: the
sidewalk's collision extends above its visible top, and the player stands on an invisible ledge.
The earlier 'top surface under player: Z 366' measurement was not wrong - it was measuring the
collider, which is the thing that is in the wrong place.

Next: measure the sidewalk mesh's rendered top against its collider and fix the asset, not the
spawn.

Also pulled the wheel camera back; it had been inside the bodywork.
2026-11-09 17:14:26 +01:00
zwitschi dde451fd69 test(review): floating is a judging criterion now, and the judge applies it
The spawn-view expectation states that nothing may float and that a shadow more than a hand's
width below an object means the object is floating. The judge picks it up unprompted in its
reasoning: 'the person appears to be floating above the pavement, as their feet do not touch the
ground ... shadows do not align correctly with the objects'.

That is the criterion working. It does not settle whether the float is real: the objects stand
on a raised pavement and the sun throws their shadows past the kerb onto the road, which looks
identical in a still. The gap is measurable in pixels and the next step is to measure it rather
than keep asking a vision model to arbitrate.

Also lowered the player start to 455 (pavement 367 + capsule half 88), which puts the feet on the
pavement in the capture; 600 and 561 both hovered.
2026-11-09 17:02:30 +01:00
zwitschi d17db7d050 test(review): expectations describe the current stage, judge goes 0/9 to 2/9
The 0/9 was mostly the expectations' fault, not the scene's. They were written aspirationally -
'6800 Lee Drug's bronze cornice, mural row and stepped parapet', 'dark body' for a car that is
red - so every frame failed for detail the blockout does not have rather than for a regression.
Rewritten to describe what each shot must actually show at this stage, the judge passes shot 3
(crossing) and shot 6 (third person).

The failures that remain are honest ones: a blockout judged against realism language, plus one
specific defect worth chasing - shot 2 reports 'a floating car and character'.

Screenshots/README.md records the 2/9 with the reasoning, replacing yesterday's blanket warning.
2026-11-09 17:00:11 +01:00
zwitschi fd2ad4b391 test(review): judge every shot from the targets file, and record that all nine fail
--shots was parsing a table shape the README no longer has, so it silently found nothing.
It now reads Tools/visual_targets.json, the same file the render gate uses, and reports one
line per shot with the model's verdict and reasoning.

The result is not good news and is committed as such: 0 of 9 shots judged 'yes'. Shot 7 shows
the scene itself wrong - a disassembled car floating over a blank surface with no street or
buildings in frame - and the others fail for missing detail rather than for a broken frame.
visual_loop --verify still reports 9/9, because it only measures exposure and size.

A warning now sits at the top of Screenshots/README.md: treat every image there as stale until
the scene is fixed. The cause is not yet identified - the map builder's recent changes are 15
lines of vehicle staging, which does not explain a missing street.
2026-11-09 16:55:59 +01:00
zwitschi 1da209a902 fix(placement): both heights now come from a measurement after settling
The probe was armed from BeginPlay but the delay was lost when I removed the dead block, so
it never ran. Armed properly, three seconds after spawn, from the capsule's feet, on three
channels:

  GigLine foot Visibility after settling: actor Z 456, feet 369, hit Z 366

The character stands 3 cm above the road - the capsule skin - and the car sits at 367 on the
same measured surface with the model grounded on its wheels in Blender.

Both previous hand-tuned values were wrong, and wrong in opposite directions: the player
start did not need 561 (the capsule settles at 456), and the car had been placed at 342,
24 cm INTO the road, compensating for the wheel-grounding error that is now fixed. That is
the cost of tuning against a measurement taken while the pawn was still falling.
2026-11-09 16:44:51 +01:00
zwitschi 15cc6cbdd0 fix(vehicle): the glazing reads as glass
The windows material was metallic 1.0 with roughness 0.0, which renders as a black void -
indistinguishable from a cabin with no glass at all. It is now tinted translucent: opacity
0.85, roughness 0.08, dark blue-grey base. The windscreen and side glass read as glass.

Opacity 0.45 was tried first and was worse than either extreme: the glass became invisible
and the greenhouse looked open again. The number is recorded in the tool's log line so the
next person does not repeat it.

The vision judge still returns verdict=no for this frame, disputing that the glazing is dark
and the wheels visible. The image shows both. It is an advisory helper - AGENTS.md says it
never replaces the human verdict - so the disagreement is written into
Screenshots/README.md rather than being resolved by iterating against the model.
2026-11-09 16:21:41 +01:00
zwitschi bb12ce8c33 fix(vehicle): the car is red in the engine, not black
Root cause was in the template, not the import path: 'car paint' is a legacy mix-shader
graph. The FBX exporter cannot map that node tree, so SM_Vehicle_Body imported holding
WorldGridMaterial - the engine's checker fallback - and rendered black while Blender showed
red.

Two changes:
  - Tools/vehicle_from_template.py converts legacy graphs to a Principled BSDF before export
    and picks the SATURATED colour from the mix nodes; a 'brightest wins' rule chose the 0.8
    grey diffuse beside the 0.49 red and produced a grey car.
  - Tools/ue_vehicle_materials.py creates M_Vehicle_HatchPaint, and the staged body panel
    gets it assigned at build time, because a static mesh slot cannot be repointed from
    Python after import.

Judge on the new capture: verdict=yes confidence=0.9 - 'a red hatch car with a red body and
dark wheels parked on a road'. The comparison table in Screenshots/README.md now shows both
columns agreeing on colour.

Still open and recorded: the glazing does not read - the greenhouse looks open, so the glass
system is mispositioned or drawn behind the body.
2026-11-09 16:13:35 +01:00
zwitschi a17e982561 fix(placement): character and car stand on the ground, not above it
Both floats had different causes and both were measured.

Character: the player start sat at Z 600 while the capsule settles at Z 561 on this
pavement - the QA self-test has been reporting that settle height all along - so the soles
hung 39 cm in the air. The start now uses the measured 561.

Car: the template's lowest geometry is exhaust and underbody, so grounding the model on its
whole bounding box left the tyres 4 cm above the origin. It is grounded on its WHEELS now.
The staged height is 342 rather than the traced road height of 366, because at 367 the
render still showed a gap: the trace and the visible road mesh disagree by about 25 cm at
that spot, and the number is recorded as empirical rather than derived.

Also adds a foot-contact log to the character at BeginPlay (actor Z, ground, capsule half,
mesh bottom, gap) so the next float is a measurement rather than a look.
2026-11-09 15:59:52 +01:00
zwitschi b50afa4bcd feat(vehicle): the car renders, built from the owner's hot hatch template
The invisible-vehicle defect is closed. Shot 9 now shows the car instead of an empty road.

Tools/vehicle_from_template.py converts Art/blender/vehicle/hot hatch.blend into UE-ready
assets, following two skills:

  vehicle-artist - systems split (body 113k tris, trim 10.5k, glass 20.5k, lights 18.6k,
  wheels 47.8k), one UCX_ hull 1.45 x 3.94 x 0.76 m, two decimated LODs at 39.7k and 13.6k.
  unreal-export - scale normalised to a documented 4.05 m hot hatch before export (the
  template measures 7.26 m, factor 0.5579), then verified after import: body bounds
  1.51 x 4.02 x 1.22 m against the 4.05 m target.

Staged as five plain StaticMeshActors, because the earlier probe proved those render while
the same meshes attached to the vehicle pawn do not.

Open and recorded rather than hidden: judge_screenshot returns verdict=no confidence=0.9 -
the silhouette does not read as a hot hatch from this angle and the car floats slightly.
The likely causes are a system misclassification in the template conversion and an
origin-height error of a few centimetres.
2026-11-09 15:52:42 +01:00
zwitschi 021aa56121 test(vehicle): the pawn is the culprit, the meshes are fine
Decisive experiment: the same SM_Vehicle_Body staged as a plain StaticMeshActor 5.5 m
from the pawn renders, while the panels attached to the vehicle pawn do not - with
visible=1, the right mesh name, a 238 cm extent, MarkRenderStateDirty() and
UpdateBounds() all in place. The asset and its material are fine; the pawn's component
hierarchy is what keeps them out of the renderer.

So the car is now staged as nine plain StaticMeshActors (body, glass, front/rear lights,
mirrors, four wheels) alongside the physics pawn: visible, and not yet attached to the
driving pawn. A visible car that does not drive yet beats an invisible one that does.

Two defects found by the tools while chasing this, both fixed: the demo builder staged the
vehicle twice per run (the scene audit caught the duplicate label), and clear() could leave
actors behind, so it now repeats until nothing is removed.
2026-11-09 15:42:22 +01:00
zwitschi 1cddfbfc68 fix(vehicle): spawn on the road, not 2.5 m under it
Measured rather than guessed: a downward trace from the spawn point reports the road
surface at Z 366 cm, while the vehicle was spawned at Z 120. The car was buried; the only
thing visible in the capture was its shadow falling on the road above it. Spawn is now
Z 470, the camera aims at 430, and it settles at Z 470.

Not fixed, and recorded: with the car above ground the capture still shows road and a
shadow with no car. Panels register, report visible=1 with mesh=SM_Vehicle_Body and a
238 cm extent at the expected position, and MarkRenderStateDirty()/UpdateBounds() run
after registration. The shadow proves a collider is there; the visible geometry is not.

Screenshots/README.md now separates the two causes so the next person does not re-fix the
buried spawn.
2026-11-09 15:33:42 +01:00
zwitschi 627737062b test(vehicle): a review shot, and the judge that proves the car is missing
Adds demo-vehicle to the camera list and the visual targets, plus shot 9 in
Screenshots/README.md - marked FAIL, because that is what it shows.

The vehicle is staged and runs: spawned at (-12950,-900,120), 9 visual panels attached,
panel 0 visible with a 238 cm extent, settled at Z 119 cm. The capture shows an empty road
with a soft shadow. Two checks disagree in a useful way: visual_loop --verify PASSES the
frame (it only tests size, blankness and tonal range, so a well-exposed empty road passes),
while judge_screenshot returns verdict=no confidence=1.0.

Strongest clue, recorded in TODO.md: a downward trace from the vehicle finds no ground at
all (ground at Z -9999), so the car sits over a surface without collision or inside
geometry - the shadow and the panels are not in the same place.

Diagnostics added along the way: mesh/visibility/bounds at BeginPlay, per-panel world
positions and extents, and the ground trace. The visual panels were also unhidden from the
physics mesh: SetVisibility(false, ...) hid them whether or not propagation was requested.
2026-11-09 15:27:58 +01:00