diff --git a/assets/models/blender/manifest.json b/assets/models/blender/manifest.json index 641856a..caaff2e 100644 --- a/assets/models/blender/manifest.json +++ b/assets/models/blender/manifest.json @@ -262,14 +262,14 @@ "fire_hydrant": { "bounds_godot": { "max": [ - 0.24, - 0.76, - 0.19 + 0.265, + 0.815, + 0.235 ], "min": [ - -0.24, + -0.265, 0, - -0.19 + -0.235 ] }, "category": "props", @@ -279,8 +279,8 @@ ], "path": "assets/models/blender/props/fire_hydrant.glb", "replaces": "generated/fire_hydrant.glb", - "triangles": 466, - "vertices": 725 + "triangles": 610, + "vertices": 902 }, "firefighter_helmet": { "attach": "head", diff --git a/assets/models/blender/props/fire_hydrant.glb b/assets/models/blender/props/fire_hydrant.glb index 39fe53b..ee5aabe 100644 Binary files a/assets/models/blender/props/fire_hydrant.glb and b/assets/models/blender/props/fire_hydrant.glb differ diff --git a/docs/3d-model-review.md b/docs/3d-model-review.md index a7a687d..91c3a28 100644 --- a/docs/3d-model-review.md +++ b/docs/3d-model-review.md @@ -144,7 +144,7 @@ the first candidates for a `vegetation-artist`/lookdev pass. | `trash_bin` | 228 | — | | `planter_box` | 1,324 | — | | `newspaper_box` | 244 | — | -| `fire_hydrant` | 466 | — | +| `fire_hydrant` | 610 | accept (2026-11-03 rebuild: bolted flange, bonnet cap nut, larger side + front outlets) | | `street_lamp` | 428 | — | | `street_tree` | 2,592 | P1 candidate (flat-shaded clumps) | | `palm_tree` | 400 | P1 candidate (same foliage language) | diff --git a/docs/screenshots/10-prop-gallery.png b/docs/screenshots/10-prop-gallery.png index eb00db6..5a7ff0f 100644 Binary files a/docs/screenshots/10-prop-gallery.png and b/docs/screenshots/10-prop-gallery.png differ diff --git a/tools/blender_assets.py b/tools/blender_assets.py index 5787cdc..a7be8cb 100644 --- a/tools/blender_assets.py +++ b/tools/blender_assets.py @@ -1303,17 +1303,26 @@ def build_prop(name): p.append(box("Paper", (0.26, 0.004, 0.14), (0, -0.168, 0.60), M("paper"))) p.append(box("Handle", (0.14, 0.03, 0.02), (0, -0.18, 0.47), M("steel"), bevel=0.006)) p.append(box("Coin", (0.06, 0.02, 0.08), (0.14, -0.175, 0.76), M("steel"), bevel=0.005)) - elif name == "fire_hydrant": # r 0.15-0.19, h ~0.74 - p.append(lathe("Hydrant", [(0.19, 0.0), (0.19, 0.06), (0.15, 0.09), (0.14, 0.52), + elif name == "fire_hydrant": # r 0.19 body, h ~0.76 + flange, bonnet and outlets + # Bolted base flange so the ground seam reads as a bolted fitting. + p.append(lathe("Flange", [(0.235, 0.0), (0.235, 0.03), (0.19, 0.06)], + M("hydrant_red"), seg=12, sharp=30)) + p.append(lathe("Hydrant", [(0.19, 0.06), (0.15, 0.09), (0.14, 0.52), (0.17, 0.55), (0.17, 0.60), (0.12, 0.66), (0.05, 0.72), (0.05, 0.75), (0.0, 0.76)], M("hydrant_red"), seg=12, sharp=30)) + # Bonnet cap nut on top so the dome reads as a valve, not a bottle. + p.append(sphere("BonnetNut", 0.035, (0, 0, 0.78), M("chrome"), seg=8, rings=5)) for s in (-1.0, 1.0): - p.append(cyl("Nozzle", 0.05, 0.05, 0.10, (0.17 * s, 0, 0.40), M("hydrant_red"), + # Larger side outlets so they register in profile. + p.append(cyl("Nozzle", 0.062, 0.055, 0.12, (0.17 * s, 0, 0.40), M("hydrant_red"), seg=10, rot=(0, math.radians(90), 0))) - p.append(cyl("Cap", 0.055, 0.055, 0.03, (0.225 * s, 0, 0.40), M("chrome"), seg=6, + p.append(cyl("Cap", 0.068, 0.068, 0.04, (0.245 * s, 0, 0.40), M("chrome"), seg=6, rot=(0, math.radians(90), 0), smooth=False)) - p.append(cyl("FrontCap", 0.065, 0.065, 0.05, (0, -0.16, 0.40), M("chrome"), seg=6, + # Front outlet (faces -Y = the street) with a proper chrome cap. + p.append(cyl("FrontNozzle", 0.072, 0.06, 0.06, (0, -0.155, 0.40), M("hydrant_red"), + seg=10, rot=(math.radians(90), 0, 0))) + p.append(cyl("FrontCap", 0.082, 0.082, 0.04, (0, -0.215, 0.40), M("chrome"), seg=6, rot=(math.radians(90), 0, 0), smooth=False)) for a in range(6): ang = math.tau * a / 6