🎮 Game
Humanoid Retargeter is a code-only library that takes an animation source (FBX, BVH, glTF/GLB/VRM, EA ANT, Renderware DFF/ANM, MMD PMX/PMD/VMD) plus a target humanoid rig and produces retargeted clips as DMX plus vmdl/KV3 ModelDoc text. Around that core it has a bone mapper with rig presets and topology fallback, geometric, planar and a managed SAME graph-network solver, foot-plant and root-motion cleanup, sprite baking, a ported Bullet physics stack for MMD rigid bodies and soft bodies, and MMD playback components with a game resource. All file IO and asset compilation is left to the caller; the library works on byte arrays and strings.
🔧 Editor
An editor extension that retargets humanoid animation clips onto s&box models. It reads source files (FBX, GLB, MMD PMX/PMD, sprite rigs), maps bones through presets or auto-detection, shows a skinned preview with trimming and camera controls, and writes out DMX clips, vmdl files and anim graphs, including a Smart Port path that copies an existing character's graph onto a new model. Much of the bulk is vendored code it needs to decompile compiled Source 2 resources: an embedded ValveResourceFormat copy, ZstdSharp, an LZ4 decoder, a DMX datamodel library and Valve KeyValues3 readers, plus editor-side dev gates (M0Gate, UiSmokeGate, the Citizen and stock-animation gates) that only arm when an env var and matching marker file are both present and that refuse to run outside the hr-editor-rig scratch project.
🐞 Possible Bugs
Code/HumanoidRetargeter/Core/Formats/Mmd/Bullet/BulletCollision/CollisionDispatch/InternalEdgeUtility.csGenerateInternalEdgeInfo reads indexList[triangleIndex], [triangleIndex+1], [triangleIndex+2] instead of triangleIndex*3, so triangles overlap and the last one reads past the end of the index array.
The edge 0 branch in AdjustInternalEdgeContacts uses the nearest point left over from the edge 2-0 search because only the edge 1 and edge 2 branches recompute it.
For SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE the trimesh assignment is commented out, so trimesh stays null and GetTriangleInfoMap throws a NullReferenceException.
Code/HumanoidRetargeter/Core/Formats/Mmd/Bullet/BulletDynamics/RaycastVehicle.csRayCast ignores the hit body and always writes s_fixedObject into m_raycastInfo.m_groundObject, with the correct line commented out directly below it, so UpdateFriction's reaction impulse never reaches the body the wheel is standing on.
m_sideImpulse, m_forwardImpulse, m_axle and m_forwardWS are hardcoded to 4 entries while AddWheel appends to m_wheelInfo without a limit, so calling AddWheel a fifth time makes UpdateVehicle/UpdateFriction throw IndexOutOfRangeException on the first frame.
Editor/Embedded/ValveResourceFormat/Blocks/VBIB.csGetBlendWeightsArray handles R16G16B16A16_UNORM by reading 4 bytes per vector and dividing by 255, so 16-bit weights come out as garbage; it needs 16-bit reads and a 65535 divisor.
GetBlendIndicesArray routes R16G16B16A16_UINT into the R8G8B8A8_UINT byte-reading branch, so 16-bit joint indices are read one byte at a time and the upper bytes are ignored.