feat: hero asset batch 2 — yatai, koban, phone booths, bus stops, bikes
Second round of original Blender-kitbashed street furniture (tools/build_hero_assets.py): - yatai.glb: ramen cart — noren curtain strips on a hanger bar, counter, wheels, three stools, paper lantern, red roof with ink trim; one at every market mouth (wood collider) - koban.glb: police box with teal roof, door, framed window, sign board and red lamp — watches the central crossing from the SE plaza corner - phonebooth.glb: green-framed glass booth on ~25% of retail corners - busstop.glb: bench + glass canopy + yellow sign disc, alternating blocks along the central avenue, both directions - bicycle.glb: torus-wheeled bikes with frame/seat/basket, parked in seeded rows of 2-4 beside building fronts All toonified with ink outlines; colliders acoustics-tagged (wood/ concrete/glass/metal). Movement 11/11, smoke 0, acoustics ALL PASSED. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Fable 5
parent
7f9a579b63
commit
18f50adb78
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -468,6 +468,17 @@ func _standard_block(c: Vector3, bx: int, bz: int) -> void:
|
|||||||
var y := float(f) * FLOOR_H - 0.4
|
var y := float(f) * FLOOR_H - 0.4
|
||||||
_box_static(c + Vector3(-2.0 + float(f) * 1.3, y, 4.0), Vector3(2.2, 0.16, 2.2), METAL,
|
_box_static(c + Vector3(-2.0 + float(f) * 1.3, y, 4.0), Vector3(2.2, 0.16, 2.2), METAL,
|
||||||
"Esc_%d_%d_%d" % [bx, bz, f], "metal")
|
"Esc_%d_%d_%d" % [bx, bz, f], "metal")
|
||||||
|
# Sidewalk life: phone booth on some corners, bike rows by the fronts
|
||||||
|
if _rng.randi() % 4 == 0:
|
||||||
|
_hero("phonebooth", c + Vector3(-half - 0.6, 0.1, -half - 0.6), _rng.randf_range(0.0, 360.0),
|
||||||
|
Vector3(1.2, 2.7, 1.2), 1.35, "glass")
|
||||||
|
if _rng.randi() % 2 == 0:
|
||||||
|
var bikes := 2 + _rng.randi() % 3
|
||||||
|
var bside := 1.0 if _rng.randi() % 2 == 0 else -1.0
|
||||||
|
for b in bikes:
|
||||||
|
_kit_prop_path("res://assets/props/hero/bicycle.glb",
|
||||||
|
c + Vector3(bside * (half + 1.0), 0.1, -6.0 + float(b) * 1.5),
|
||||||
|
90.0 * bside + _rng.randf_range(-14.0, 14.0), 1.0)
|
||||||
if _rng.randi() % 3 == 0:
|
if _rng.randi() % 3 == 0:
|
||||||
_spawn_points.append(c + Vector3(0, 1.5, 0))
|
_spawn_points.append(c + Vector3(0, 1.5, 0))
|
||||||
|
|
||||||
@@ -577,9 +588,10 @@ func _market_block(c: Vector3, bx: int, bz: int) -> void:
|
|||||||
# Lantern string over each row
|
# Lantern string over each row
|
||||||
for l in 6:
|
for l in 6:
|
||||||
_deco_box(Vector3(x, 3.6, c.z - 17.5 + float(l) * 7.0), Vector3(0.32, 0.45, 0.32), Color(1.0, 0.62, 0.25), true)
|
_deco_box(Vector3(x, 3.6, c.z - 17.5 + float(l) * 7.0), Vector3(0.32, 0.45, 0.32), Color(1.0, 0.62, 0.25), true)
|
||||||
# Hand carts at the market mouths
|
# Hand cart + kitbashed yatai ramen stand at the market mouths
|
||||||
_kit_prop_path("res://assets/props/town/cart.glb", c + Vector3(0, 0.02, 19.0), _rng.randf_range(-30, 30), 3.0)
|
_kit_prop_path("res://assets/props/town/cart.glb", c + Vector3(0, 0.02, 19.0), _rng.randf_range(-30, 30), 3.0)
|
||||||
_kit_prop_path("res://assets/props/town/cart-high.glb", c + Vector3(2.0, 0.02, -19.0), _rng.randf_range(150, 210), 3.0)
|
_hero("yatai", c + Vector3(2.0, 0.02, -19.0), _rng.randf_range(150.0, 210.0),
|
||||||
|
Vector3(3.0, 2.8, 1.8), 1.4, "wood")
|
||||||
# Vending pair at the north entry
|
# Vending pair at the north entry
|
||||||
for v in 2:
|
for v in 2:
|
||||||
_box_static(c + Vector3(-1.5 + 3.0 * float(v), 1.0, -BLOCK * 0.5 + 3.0), Vector3(1.1, 2.0, 0.9),
|
_box_static(c + Vector3(-1.5 + 3.0 * float(v), 1.0, -BLOCK * 0.5 + 3.0), Vector3(1.1, 2.0, 0.9),
|
||||||
@@ -599,6 +611,10 @@ func _plaza_block(c: Vector3, bx: int, bz: int) -> void:
|
|||||||
# Kitbashed clock tower on the south-west plaza cell
|
# Kitbashed clock tower on the south-west plaza cell
|
||||||
if bx == 4 and bz == 5:
|
if bx == 4 and bz == 5:
|
||||||
_hero("clock", c + Vector3(0, 0.1, 0), 0.0, Vector3(3.2, 10.5, 3.2), 5.25, "concrete")
|
_hero("clock", c + Vector3(0, 0.1, 0), 0.0, Vector3(3.2, 10.5, 3.2), 5.25, "concrete")
|
||||||
|
# Koban police box watching the central crossing
|
||||||
|
if bx == 5 and bz == 5:
|
||||||
|
_hero("koban", c + Vector3(-BLOCK * 0.5 + 4.0, 0.02, -BLOCK * 0.5 + 4.0), 225.0,
|
||||||
|
Vector3(3.7, 3.4, 3.5), 1.7, "concrete")
|
||||||
# The Crossing screen tower on the single centre-most plaza cell
|
# The Crossing screen tower on the single centre-most plaza cell
|
||||||
if bx == 5 and bz == 4:
|
if bx == 5 and bz == 4:
|
||||||
_box_static(c + Vector3(0, 9.0, 0), Vector3(6.0, 18.0, 6.0), METAL.darkened(0.2), n + "_ScreenTower", "metal")
|
_box_static(c + Vector3(0, 9.0, 0), Vector3(6.0, 18.0, 6.0), METAL.darkened(0.2), n + "_ScreenTower", "metal")
|
||||||
@@ -766,6 +782,12 @@ func _build_avenues() -> void:
|
|||||||
# Traffic signal on the opposite diagonal corner of each crossing
|
# Traffic signal on the opposite diagonal corner of each crossing
|
||||||
_kit_prop_path("res://assets/props/roads/light-square-cross.glb",
|
_kit_prop_path("res://assets/props/roads/light-square-cross.glb",
|
||||||
Vector3(x, 0, z - side * (ROAD_W * 0.5 + 0.8)), 90.0 if side > 0 else -90.0, lamp_scale * 0.8)
|
Vector3(x, 0, z - side * (ROAD_W * 0.5 + 0.8)), 90.0 if side > 0 else -90.0, lamp_scale * 0.8)
|
||||||
|
# Bus stop shelters on alternating blocks along the avenue
|
||||||
|
if int(roundf(z / PITCH)) % 2 == 0:
|
||||||
|
_hero("busstop", Vector3(ROAD_W * 0.5 + 2.0, 0.02, z + 18.0), -90.0,
|
||||||
|
Vector3(3.8, 2.6, 1.6), 1.3, "metal")
|
||||||
|
_hero("busstop", Vector3(-ROAD_W * 0.5 - 2.0, 0.02, z - 18.0), 90.0,
|
||||||
|
Vector3(3.8, 2.6, 1.6), 1.3, "metal")
|
||||||
for x in lines:
|
for x in lines:
|
||||||
if absf(x) < 1.0:
|
if absf(x) < 1.0:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -215,3 +215,89 @@ station()
|
|||||||
clock()
|
clock()
|
||||||
torii()
|
torii()
|
||||||
print("hero: all assets built")
|
print("hero: all assets built")
|
||||||
|
|
||||||
|
|
||||||
|
# ── Batch 2: street furniture ────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def yatai():
|
||||||
|
"""Ramen cart: body, roof, noren curtain strips, stools, lantern."""
|
||||||
|
clear()
|
||||||
|
box("body", (2.6, 1.2, 1.1), (0, 0, 0.75), WOOD, 0.03)
|
||||||
|
box("counter", (2.8, 1.35, 0.08), (0, 0, 1.34), mat("counter", (0.62, 0.45, 0.28)), 0.02)
|
||||||
|
for sx in (-1, 1):
|
||||||
|
box("post", (0.08, 0.08, 1.3), (sx * 1.2, -0.45, 2.0), INK, 0.0)
|
||||||
|
cyl("wheel", 0.28, 0.1, (sx * 0.9, 0.62, 0.28), INK, rot=(math.radians(90), 0, 0))
|
||||||
|
box("roof", (3.0, 1.5, 0.12), (0, 0, 2.7), RED, 0.02)
|
||||||
|
box("roof_trim", (3.1, 1.6, 0.06), (0, 0, 2.62), INK, 0.0)
|
||||||
|
# noren curtain strips across the front
|
||||||
|
for i in range(5):
|
||||||
|
x = -1.1 + i * 0.55
|
||||||
|
box("noren", (0.42, 0.04, 0.6), (x, 0.72, 2.28), mat("noren", (0.92, 0.9, 0.85)), 0.0)
|
||||||
|
box("noren_bar", (2.7, 0.05, 0.05), (0, 0.72, 2.6), INK, 0.0)
|
||||||
|
for i, x in enumerate((-0.9, 0.0, 0.9)):
|
||||||
|
cyl("stool", 0.18, 0.5, (x, 1.05, 0.25), RED, verts=12)
|
||||||
|
cyl("lantern", 0.16, 0.42, (1.35, 0.7, 2.3), mat("lamp", (0.98, 0.62, 0.25)), verts=12)
|
||||||
|
export(os.path.join(OUT, "yatai.glb"))
|
||||||
|
|
||||||
|
|
||||||
|
def koban():
|
||||||
|
"""Police box: small building, sign board, red lamp."""
|
||||||
|
clear()
|
||||||
|
W, D, H = 3.2, 3.0, 3.2
|
||||||
|
box("body", (W, D, H), (0, 0, H / 2), CREAM, 0.03)
|
||||||
|
box("roof", (W + 0.5, D + 0.5, 0.3), (0, 0, H + 0.15), TEAL, 0.03)
|
||||||
|
box("door", (0.95, 0.1, 2.1), (-0.6, D / 2, 1.05), INK, 0.01)
|
||||||
|
box("window", (1.1, 0.1, 1.0), (0.7, D / 2, 1.7), GLASS, 0.01)
|
||||||
|
box("winframe", (1.25, 0.06, 1.15), (0.7, D / 2 - 0.02, 1.7), INK, 0.01)
|
||||||
|
box("sign", (1.6, 0.12, 0.5), (0, D / 2 + 0.1, 2.75), WHITE, 0.01)
|
||||||
|
cyl("lamp", 0.12, 0.24, (0, D / 2 + 0.2, 3.05), RED, verts=10)
|
||||||
|
export(os.path.join(OUT, "koban.glb"))
|
||||||
|
|
||||||
|
|
||||||
|
def phonebooth():
|
||||||
|
clear()
|
||||||
|
box("frame", (1.1, 1.1, 2.5), (0, 0, 1.25), mat("booth", (0.2, 0.45, 0.3)), 0.03)
|
||||||
|
for a in range(4):
|
||||||
|
ang = math.pi / 2 * a
|
||||||
|
dx, dy = math.cos(ang), math.sin(ang)
|
||||||
|
box("glass", (0.06 if a % 2 == 0 else 0.85, 0.85 if a % 2 == 0 else 0.06, 1.6),
|
||||||
|
(dx * 0.53, dy * 0.53, 1.35), GLASS, 0.0)
|
||||||
|
box("cap", (1.25, 1.25, 0.18), (0, 0, 2.6), INK, 0.02)
|
||||||
|
export(os.path.join(OUT, "phonebooth.glb"))
|
||||||
|
|
||||||
|
|
||||||
|
def busstop():
|
||||||
|
clear()
|
||||||
|
box("bench", (2.6, 0.5, 0.1), (0, 0.2, 0.55), WOOD, 0.02)
|
||||||
|
for sx in (-1, 1):
|
||||||
|
box("leg", (0.1, 0.45, 0.55), (sx * 1.1, 0.2, 0.27), INK, 0.0)
|
||||||
|
box("cpost", (0.1, 0.1, 2.4), (sx * 1.5, -0.25, 1.2), METAL, 0.0)
|
||||||
|
box("croof", (3.6, 1.3, 0.1), (0, 0.15, 2.45), GLASS, 0.02)
|
||||||
|
box("croof_trim", (3.7, 1.4, 0.05), (0, 0.15, 2.38), INK, 0.0)
|
||||||
|
box("signpole", (0.08, 0.08, 3.0), (2.1, -0.3, 1.5), METAL, 0.0)
|
||||||
|
cyl("signdisc", 0.35, 0.06, (2.1, -0.3, 2.85), YELLOW, rot=(math.radians(90), 0, 0), verts=16)
|
||||||
|
export(os.path.join(OUT, "busstop.glb"))
|
||||||
|
|
||||||
|
|
||||||
|
def bicycle():
|
||||||
|
clear()
|
||||||
|
for wy in (-0.55, 0.55):
|
||||||
|
bpy.ops.mesh.primitive_torus_add(major_radius=0.32, minor_radius=0.035,
|
||||||
|
location=(0, wy, 0.32),
|
||||||
|
rotation=(math.radians(90), 0, math.radians(90)))
|
||||||
|
o = bpy.context.active_object
|
||||||
|
o.data.materials.append(INK)
|
||||||
|
box("frame1", (0.05, 0.7, 0.05), (0, 0.1, 0.55), RED, 0.0, rot=(math.radians(25), 0, 0))
|
||||||
|
box("frame2", (0.05, 0.6, 0.05), (0, -0.2, 0.5), RED, 0.0, rot=(math.radians(-35), 0, 0))
|
||||||
|
box("bar", (0.4, 0.05, 0.05), (0, -0.52, 0.85), INK, 0.0)
|
||||||
|
box("seat", (0.14, 0.3, 0.06), (0, 0.28, 0.85), INK, 0.01)
|
||||||
|
box("basket", (0.32, 0.3, 0.25), (0, -0.72, 0.72), METAL, 0.01)
|
||||||
|
export(os.path.join(OUT, "bicycle.glb"))
|
||||||
|
|
||||||
|
|
||||||
|
yatai()
|
||||||
|
koban()
|
||||||
|
phonebooth()
|
||||||
|
busstop()
|
||||||
|
bicycle()
|
||||||
|
print("hero: batch 2 built")
|
||||||
|
|||||||
Reference in New Issue
Block a user