wrote a Blender script to normalize hip height across mocap takes, tired of every clip starting at a different elevation
The problem I kept running into: shoot 6 takes in the same session with the same actor and somehow every clip has the hip bone sitting at a slightly different world-space height. Actor stands a little differently at calibration, the suit vest shifts, capture software picks a slightly different reference pose. Small variance, but in-engine when you transition between clips the root lurches up or down at the cut.
Wrote a script that goes through every action in the .blend, finds the Z location FCurve for the root/hip bone, samples it at a reference frame, and shifts every keyframe uniformly by the delta to a target baseline. Not stretching the animation, just translating the whole Z curve up or down.
import bpy
HIP_BONE = 'mixamorig:Hips' # update to match your rig
TARGET_HEIGHT = 1.0 # world-space Z at rest, in meters
REF_FRAME = 1 # frame to sample for baseline height
def normalize_hip_heights():
armature = bpy.context.object
if not armature or armature.type != 'ARMATURE':
print('Select an armature first.')
return
for action in bpy.data.actions:
bone_path = 'pose.bones["{}"].location'.format(HIP_BONE)
z_curve = next(
(fc for fc in action.fcurves
if fc.data_path == bone_path and fc.array_index == 2),
None
)
if z_curve is None:
continue
ref_z = z_curve.evaluate(REF_FRAME)
delta = TARGET_HEIGHT - ref_z
if abs(delta) < 0.005:
print('[skip] {}: already near target ({:.4f}m)'.format(action.name, ref_z))
continue
for kp in z_curve.keyframe_points:
kp.co[1] += delta
kp.handle_left[1] += delta
kp.handle_right[1] += delta
z_curve.update()
print('[ok] {}: shifted {:+.4f}m'.format(action.name, delta))
normalize_hip_heights()
Assumptions baked in:
- Root motion rig: the hip/root bone has actual world-space Z location keyframes. In-place rigs won't benefit from this.
- Z-up coordinate system (standard Blender import from most suit software)
- Frame 1 is a clean standing pose, not mid-action
- Update
HIP_BONEto match your naming:Hips,Root,mixamorig:Hips, etc.
What it doesn't fix: variance in hip height throughout the take from actor posture drift or floor contact differences. This is purely a per-action origin offset correction, the relative motion inside each clip stays untouched.
One thing I'm unsure about: whether sampling a median over the first 10–15 frames would be more robust than a single reference frame. Some takes have a small settle at frame 1 before the actor finds their natural stance, which skews the baseline. Anyone tackled this and found a better sampling approach?