Integrate the Blender character, gear and prop library
NpcAvatar - select one of 8 library character variants by role/seed (with npc_base and the procedural rig as fallbacks), keep Rig/Head and the existing bone animation - tint only skin/cloth/pants/accessory/hair; fixed detail materials keep their colour, npc_vest keeps its hi-vis vest, firefighter/guard use dark uniform tints - attach caps, hoods, helmets, backpacks, SCBA tanks, lanyards and hand items at the documented head/back/chest/hand points (primitive fallbacks retained) WorldBuilder - prefer assets/models/blender/props/ for the six replacements and the new street dressing (street lamp/tree, palms, planters, A-frame, cone, barrier, stanchion, podium, handrail, wall lantern, double door, marquee, sedan) - fit the same colliders/navigation obstacles and keep the placement validator; collect library emissives (bulbs, marquee face, wall lanterns, door LED, sedan lights) for set_night_mode() - add a library triangle counter + 60k budget check (current ~27,986); toggle prop gallery to the library models; fix the marquee label placement Tests/smoke - character selection/gear attach/fixed-material tint tests; library prop load, emissive and triangle-budget tests; smoke_props routes a guest around a stanchion in open sidewalk (the old bench route is now crowded by trees) - headless 222/222, Python 68/68, all smokes pass, compare 11 good / 0 bad Docs: TODO Phase 3.5 moved to DONE, README/architecture/blender-assets/plan describe the integrated runtime, MEMORY records the integration rules.
This commit is contained in:
1 parent
d513e0b82c
commit
d8cfddbf89
23 files changed
+531
-165
No files matched your search
@@ -201,6 +201,38 @@ func test_fallback_props_get_the_same_collider() -> bool:
|
||||
root.free()
|
||||
return a and b and c and d
|
||||
|
||||
func test_world_loads_the_blender_library_props() -> bool:
|
||||
var root := Node3D.new()
|
||||
var builder := WorldBuilder.new(root)
|
||||
builder.build()
|
||||
var a := TestUtils.check(builder.fallback_props.is_empty(),
|
||||
"no primitive prop fallback (fallbacks: %s)" % str(builder.fallback_props))
|
||||
var b := TestUtils.check(builder.library_props.has("street_lamp")
|
||||
and builder.library_props.has("street_tree")
|
||||
and builder.library_props.has("bollard")
|
||||
and builder.library_props.has("palm_tree")
|
||||
and builder.library_props.has("sedan"),
|
||||
"replacement and new props come from the library (%d)" % builder.library_props.size())
|
||||
var c := TestUtils.check(root.get_node_or_null("Building/LibraryDoubleDoor") != null
|
||||
and root.get_node_or_null("LibraryMarquee") != null
|
||||
and root.get_node_or_null("ParkedSedan") != null,
|
||||
"library door, marquee and sedan are placed")
|
||||
var d := TestUtils.check(not builder._lamp_bulb_mats.is_empty()
|
||||
and not builder._marquee_emissive.is_empty(),
|
||||
"library lamps/marquee expose emissive materials")
|
||||
builder.set_night_mode(true)
|
||||
var lit := (builder._lamp_bulb_mats[0].emission_energy_multiplier > 0.0
|
||||
and builder._marquee_emissive[0].emission_energy_multiplier > 0.0)
|
||||
builder.set_night_mode(false)
|
||||
var dark := builder._lamp_bulb_mats[0].emission_energy_multiplier <= 0.0
|
||||
var e := TestUtils.check(lit and dark, "night mode drives library emissives")
|
||||
var triangles := builder.library_triangle_count()
|
||||
var f := TestUtils.check(triangles > 0
|
||||
and triangles <= WorldBuilder.LIBRARY_TRIANGLE_BUDGET,
|
||||
"library prop triangles stay inside the budget (%d)" % triangles)
|
||||
root.free()
|
||||
return a and b and c and d and e and f
|
||||
|
||||
func test_world_facade_windows_light_at_night() -> bool:
|
||||
var root := Node3D.new()
|
||||
var builder := WorldBuilder.new(root)
|
||||
|
||||
Reference in new issue
Block a user