Load and animate the Blender-authored NPC base mesh
Wire the skinned model from ADR-0013 into NpcAvatar: - _build_skinned_body() instantiates the imported npc_base.glb, binds the 14 armature bones, and keeps the procedural _build_body() as the offline fallback (use_skinned_model can force it in tests) - outfit_for()/layer_for() tint the five material slots through the new SurfaceMaterials.npc_slot(); accessories and hand items attach under Rig/Head - the existing limb pivots (Hip/Knee/Shoulder/Elbow/Hand + Head marker) keep the old animation math; _sync_skeleton() copies their rotations to bones. Bone pose rotation is absolute local orientation, so it is composed with the rest basis (otherwise the whole body snaps into a broken pose) - skinned rigs scale uniformly (non-uniform parent scale shears the skin) and keep Rig/Head for the focus cone, nametag, and reaction tag - commit the editable npc_base.blend plus a .gdignore: Godot's editor otherwise tries to import the blend and hangs during --import - npc_pipeline audit tests (contract, textures, clean GLB, committed source) Verification: headless 212/212, Python tooling 60/60, NPC budget 16 avatars = 144 meshes at ~6.9 ms, movement/focus/props smokes pass, compare 11 good / 0 bad. TODO Phases 0-3 checked; environment lift and release remain.
This commit is contained in:
1 parent
3989d7b2e5
commit
a231f7588a
20 files changed
+316
-37
No files matched your search
@@ -31,6 +31,15 @@ const PROFILES := {
|
||||
"rubber": {"roughness": 0.95, "metallic": 0.0},
|
||||
}
|
||||
|
||||
## NPC material slot: keep the baked albedo/normal maps from the imported model
|
||||
## and tint them with the seed-driven outfit colour.
|
||||
static func npc_slot(source: Material, tint: Color) -> StandardMaterial3D:
|
||||
var material := source.duplicate() as StandardMaterial3D
|
||||
if material == null:
|
||||
material = StandardMaterial3D.new()
|
||||
material.albedo_color = tint
|
||||
return material
|
||||
|
||||
static func profile(role: String) -> Dictionary:
|
||||
return PROFILES.get(role, PROFILES["concrete"])
|
||||
|
||||
|
||||
Reference in new issue
Block a user