"Rigging an AI-generated (rigless) character mesh"
- AI character arrives as a static textured mesh (no armature).
- Blender automatic weights fail with:
Bone Heat Weighting: failed to find solution. - All vertex groups empty — even for a tiny 2-bone rig on a cleaned single-island mesh.
- Euclidean "nearest bone" weights look plausible in the viewport but cheeks follow arms, etc. on chibi proportions.
Bone-heat auto-weights fail wholesale on many AI-generated meshes. Topology/island quirks that look fine visually still break the heat solver.
Euclidean nearest-bone assignment is not enough — chibi proportions put cheek verts closer to arm bones than the head bone in 3D space, even when they should belong to the head along the surface.
Also: Blender's OBJ importer puts the Y-up→Z-up fix on the object transform — mesh.vertices[i].co stays file-local Y-up. Any scripted landmark/seed math must use obj.matrix_world @ v.co or seeds are silently wrong.
Proven local lane (headless Blender):
- Copy the mesh out of any regenerating AI delivery folder (re-runs overwrite).
- Hand-build (or script) an armature — pelvis as true root; no extra roots above it.
- Scripted geodesic weights (along-surface Dijkstra) to per-bone seed tubes:
- top-3 bones
- inverse-power blend
- ~10 diffusion passes
- cap 4 influences
- Scripted keyframe clips; keep quaternion keys hemisphere-continuous (
if dot(prev, new) < 0: negate). - Export FBX per fbx-export-recipe.
- Animated
.vmdlusing citizen as schema reference; scale withModelModifier_ScaleAndMirror0.3937 (cm sources), not per-fileimport_scaleon the mesh alone (that leaves AnimFile data unscaled).
Blender meters → FBX centimeters (apply_unit_scale) → ScaleAndMirror 0.3937 → engine inchesAnimationList wants default_root_bone_name = "pelvis"; set bone_cull_type = "None" to keep helper bones. Schema reference: addons/citizen/Assets/models/citizen/citizen.vmdl + its prefabs/*.vmdl_prefab.
Runtime: play sequences on SkinnedModelRenderer (Sequence.Name = "..."). Enable crossfade-without-animgraph for smooth switches. Do not rely on SetBoneTransform / SetIk for secondary motion on a sequence-only rig — see setbonetransform-silently-noop.
Geodesic distance follows the mesh surface, so influence regions match anatomical adjacency instead of 3D proximity through empty space. Cap + diffusion keeps skinning engine-friendly (≤4 influences). ScaleAndMirror is the citizen convention that scales mesh and animations together; splitting scale across import_scale vs anim files is what produces correctly sized meshes with microscopic (or gigantic) motion.