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
@@ -58,8 +58,8 @@ warnings = []
|
||||
weights_authored = True
|
||||
|
||||
|
||||
def check(ok, label, detail="", needs_authored_weights=False):
|
||||
soft = needs_authored_weights and not weights_authored
|
||||
def check(ok, label, detail="", needs_authored_weights=False, advisory=False):
|
||||
soft = advisory or (needs_authored_weights and not weights_authored)
|
||||
tag = "PASS" if ok else ("WARN" if soft else "FAIL")
|
||||
print(f" [{tag}] {label}" + (f" — {detail}" if detail else ""))
|
||||
if ok:
|
||||
@@ -134,8 +134,20 @@ check(bleed_frac < 0.005, "cross-leg blending is limited to draping cloth",
|
||||
check(four < 0.5, "influences look authored, not solved",
|
||||
f"{four * 100:.0f}% of verts carry 4 influences; spread {dict(sorted(infl.items()))}",
|
||||
needs_authored_weights=True)
|
||||
check(len(meshes) > 1, "model keeps its per-part meshes", f"{len(meshes)} meshes",
|
||||
needs_authored_weights=True)
|
||||
# ADVISORY, not a gate. Several meshes is what we want — it is how body, cloth
|
||||
# and hair stay separable for materials, for the outline pass and for the cloth
|
||||
# solver's hull extraction — but the OUTPUT cannot tell "the pipeline joined
|
||||
# them" from "the artist authored one mesh". Quaternius' mannequin is a single
|
||||
# mesh on purpose and was failing a check about damage that had not happened.
|
||||
#
|
||||
# The join path leaves two signatures that ARE unambiguous, and both are hard
|
||||
# checks above: cross-leg weight bleed, and the 4-influences-everywhere spread
|
||||
# of a nearest-bone rebind. Those catch what this was standing in for.
|
||||
check(len(meshes) > 1, "model keeps its per-part meshes",
|
||||
f"{len(meshes)} mesh{'es' if len(meshes) != 1 else ''}"
|
||||
+ (" — fine for a single-piece model; a costume should be several"
|
||||
if len(meshes) == 1 else ""),
|
||||
advisory=True)
|
||||
|
||||
# ------------------------------------------------------------------- skeleton
|
||||
def is_rootish(b):
|
||||
|
||||
Reference in New Issue
Block a user