feat(characters): import the Quaternius mannequin as a selectable skin
A third playable character, built with the pipeline skill from a source that was already in the repo: the animation library ships a rigged Mannequin mesh on the exact 53-joint reference skeleton, CC0, so it needed no download and retargets perfectly. 18 clips, 0.3% cross-leg bleed, 7% of verts at four influences — a clean authored-weight import. Licence recorded in mannequin.license.json as the other skins do. It has no cloth chains, correctly: it is a mannequin and has neither hair nor clothes. Importing it turned up two real bugs, both of which would have hit any flat-coloured or single-piece model: - LevelMaterials.apply_character_look treated ANY untextured surface on a character as the model's own outline shell and hid it, so the mannequin rendered as a solid black silhouette — its body and joint materials are untextured flat colours, not ink. _is_line_work() now asks whether the surface is named eyes*, is drawn front-face-culled (the inverted-hull setup), or is near-black. Taila and Miku are unaffected: their materials are textured and never reach that branch. Verified by render. - verify_character.py failed the build for having one mesh. That check cannot tell "the pipeline joined them" from "the artist authored one mesh" — Quaternius' mannequin is one piece on purpose. It is advisory now; the join path's two unambiguous signatures, cross-leg bleed and the 4-influences-everywhere spread, are still hard checks. Also restored Miku's description, which the re-import had blanked. 3 GLB skins selectable (6 with the built-in colour skins). Smoke 0 failures, 11/11 movement tests, cloth idle 0.024-0.078 deg/frame. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
270d5f0973
commit
cd0d1b2d99
@@ -126,6 +126,32 @@ const CHARACTER_INK := Color(0.07, 0.06, 0.09)
|
||||
## almost-invisible second step so the painted shading carries the form.
|
||||
##
|
||||
## Props and level geometry keep the crisp banding they were calibrated with.
|
||||
## Is this untextured surface part of the model's own DRAWING, or is it just an
|
||||
## untextured surface?
|
||||
##
|
||||
## "No albedo texture" alone is not the question, and answering it that way made
|
||||
## every flat-coloured model render as a black silhouette — Quaternius' mannequin
|
||||
## has two untextured materials, a yellow body and lilac joints, and both were
|
||||
## being hidden as though they were an outline shell.
|
||||
##
|
||||
## What actually distinguishes line-work:
|
||||
##
|
||||
## DARK an ink shell or a lash card is black or nearly so. A flat-coloured
|
||||
## character is any colour at all. This is the discriminator that
|
||||
## does the work.
|
||||
## INVERTED the classic inverted-hull outline is drawn front-face-culled so
|
||||
## only its backfaces show. Nothing else on a character is.
|
||||
## NAMED eye cards say so — they are kept, not hidden, and need to reach
|
||||
## the branch below whatever colour they are.
|
||||
static func _is_line_work(src: BaseMaterial3D) -> bool:
|
||||
if src.resource_name.to_lower().begins_with("eyes"):
|
||||
return true
|
||||
if src.cull_mode == BaseMaterial3D.CULL_FRONT:
|
||||
return true
|
||||
var c: Color = src.albedo_color
|
||||
return maxf(maxf(c.r, c.g), c.b) < 0.18
|
||||
|
||||
|
||||
static func apply_character_look(root: Node) -> void:
|
||||
for mi in root.find_children("*", "MeshInstance3D", true, false):
|
||||
if not mi.mesh:
|
||||
@@ -134,8 +160,8 @@ static func apply_character_look(root: Node) -> void:
|
||||
var src: BaseMaterial3D = mi.mesh.surface_get_material(s) as BaseMaterial3D
|
||||
if src == null:
|
||||
continue
|
||||
if src.albedo_texture == null:
|
||||
# Untextured surface on a character = the model's own line-work.
|
||||
if src.albedo_texture == null and _is_line_work(src):
|
||||
# Untextured AND dark or inside-out — the model's own line-work.
|
||||
var name := src.resource_name.to_lower()
|
||||
var flat := StandardMaterial3D.new()
|
||||
flat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
|
||||
Reference in New Issue
Block a user