@@ -28,9 +28,10 @@ use diagnostic::{
2828} ;
2929use geometry:: { bake_scale_into_geometry, collect_mesh_statistics, estimate_height_cm} ;
3030use skeleton:: {
31- ensure_target_bones_exist_after_rename, normalize_sl_bone_rotations,
32- promote_pelvis_to_scene_root, reconstruct_sl_core_hierarchy, regenerate_inverse_bind_matrices,
33- rename_bones, set_skin_skeleton_root, validate_bone_conversion_preconditions,
31+ correct_mesh_vertices_for_bind_pose_change, ensure_target_bones_exist_after_rename,
32+ normalize_sl_bone_rotations, promote_pelvis_to_scene_root, reconstruct_sl_core_hierarchy,
33+ regenerate_inverse_bind_matrices, rename_bones, set_skin_skeleton_root,
34+ validate_bone_conversion_preconditions,
3435} ;
3536use skinning:: { optimize_skinning_weights_and_joints, remap_unmapped_bone_weights} ;
3637use validation:: {
@@ -348,7 +349,11 @@ fn transform_and_write_glb(
348349 // the inverse-bind-matrix translations and applies its own (identity)
349350 // orientations in the SL skeleton; any non-identity rotation baked into
350351 // the node hierarchy will therefore cause incorrect deformation.
351- normalize_sl_bone_rotations ( & mut json, humanoid_bone_nodes) ;
352+ let pre_normalization_worlds = normalize_sl_bone_rotations ( & mut json, humanoid_bone_nodes) ;
353+ // Counter-rotate mesh vertices so the mesh shape stays visually identical
354+ // under the new identity-rotation bind pose. This is the programmatic
355+ // equivalent of Blender's "Apply Rotation and Scale" on the armature.
356+ correct_mesh_vertices_for_bind_pose_change ( & json, & mut bin, & pre_normalization_worlds) ?;
352357 // Remap weights from unmapped VRM bones (e.g. upperChest, spring bones)
353358 // to their nearest mapped-SL ancestor so that only valid SL bones remain
354359 // in the skin joints list after optimization.
0 commit comments