Kucraft game assets and free examples

KUCRAFT · ANIMATION FIELD NOTE 01

The ankle stays put.
Why does the knee swing sideways?

A procedural leg can hit both target poses and still twist between them. In this two-bone example, the ankle barely moves sideways, while the knee drifts 5.24 mm out of its intended plane. The cause is the way each bone’s orientation was constructed.

This small reproduction came from fixing an original character rig. It isolates the mechanism using two 30 cm bones, two keyframes and no character model. You can inspect every input and rerun the measurements.

Across the interval between two keyframes, the tracked-up frame's sideways knee offset rises from zero to 5.24 mm and returns to zero. The projected-X frame stays at zero.
Scroll the chart horizontally on narrow screens. 101 samples per version, including both keys. Each sample interpolates local translations, rotations and scales, then composes the parent and child transforms. Values come from the included CSV.

Reproduce it in two steps

Download the complete example — ZIP, 101 kB. Includes the guide, editable source, recorded measurements and native Godot project. Free under the MIT licence.

You have the complete example: this guide, source, input transforms, measured output and the Godot extension. See README.txt to choose the mathematical or native engine route. No sign-up or external assets are needed.

blender --background --factory-startup --threads 2 --python reproduce.py
python3 measure.py

The first command uses Blender’s mathutils to write output/endpoints.json. The second uses only the Python standard library to evaluate the two-key animation and write report.json, samples.csv and the chart. Blender 4.5.14 LTS was used for the recorded run. The saved JSON lets you run the second step without Blender.

The missing information is roll

A head and tail specify a bone’s direction. They leave its rotation around that direction undetermined. This fixture points each local Y axis along its bone and asks to_track_quat('Y', 'Z') to choose the remaining orientation. The leg moves from one degree either side of vertical to the other. Near the chosen up direction, the resulting thigh frames differ by almost 180 degrees.

The child shin compensates at the endpoints, so the joint positions look right there. Between those endpoints, interpolating the local rotations sends the knee sideways. A check that watches only the ankle would miss this example.

The measurement script uses shortest-path quaternion interpolation and treats opposite quaternion signs as the same rotation. That still leaves a real, almost half-turn change in the authored thigh frame. glTF’s animation sampler guidance calls for spherical interpolation when a LINEAR sampler targets a rotation. The discontinuity here is already present in the supplied transforms.

Choose a stable transverse axis

For this planar leg, X is always transverse to the intended motion. Project that reference axis onto the plane perpendicular to the bone direction, then build an orthonormal frame. The generated orientation now changes by two degrees between the keys.

# head, tail and reference_x use the same coordinate frame.
# reference_x must be a unit vector.
direction = tail - head
if direction.length < 1e-8:
    raise ValueError("Head and tail must differ")
y = direction.normalized()
x = reference_x - y * reference_x.dot(y)
if x.length < 0.1:
    raise ValueError("Reference axis is too close to the bone direction")
x.normalize()
z = x.cross(y).normalized()
rotation = Matrix((x, y, z)).transposed()
pose = Matrix.Translation(head) @ rotation.to_4x4()

In a procedural rig, a bone’s rest X axis can supply the reference when it stays suitably transverse throughout the intended motion. This example uses Vector((1, 0, 0)). Keep the guard: a fixed reference axis also becomes ambiguous when the bone points along it. More general motion needs a deliberately continuous frame strategy; choosing a different fallback axis independently at each key can introduce another jump.

What changed in this example

MeasurementTracked upProjected X
Thigh rotation between keys180.00°2.00°
Largest sideways knee offset5.236 mm0.000 mm
Largest sideways ankle offset< 0.001 mm0.000 mm
Ankle error at either key< 0.001 mm< 0.001 mm

These are results for this constructed fixture. The fixed version straightens the leg between the bent endpoints, so its ankle height changes slightly; the fix preserves the intended motion plane, rather than enforcing a planted-foot constraint.

The same path after a real glTF import

Version 1.1.0 adds two original GLB files and a small Godot project. Each GLB contains two rigid-weighted box segments, two joints and a two-key animation. Open native-example/godot/project.godot in Godot and run the scene to compare them. The slider and Play/Pause button control native animation; the knee readouts come from the imported skeleton.

Actual Godot midpoint render. Two narrow leg segments appear side by side. The tracked-up knee is 5.236 millimetres sideways; the projected-X knee is at zero. The slider is halfway through the interval.
Actual Linux Godot 4.7.2 midpoint render using Mesa llvmpipe on the CPU. The geometry is shown at true spatial scale, so the small bend is easier to quantify in the chart above. The animation is slowed 96 times for inspection.

The GLB animation lasts two seconds instead of 1/48 second, with the same endpoint transforms and LINEAR samplers. At 101 positions per version, Godot reproduced the 5.236 mm sideways knee excursion and the fixed version's planar motion. Every compared knee and ankle coordinate agreed with the separate Python evaluator within 0.001 mm. The largest observed component difference was 0.000234 mm.

The script uses GLTFDocument with a bake rate of 30 and immutable tracks retained, then updates AnimationPlayer explicitly while sampling. Skeleton bone poses are transformed into world coordinates before comparison. See the native example instructions for the exact commands and limits.

python3 native-example/build_glb.py
godot --headless --path native-example/godot --script measure_native.gd
python3 native-example/compare_native.py

This checks the included fixture's runtime import and playback. It does not test the original-speed clip through every editor import setting, other engines, or general character deformation. Actual renders at both endpoints and the midpoint were inspected. Programmatic scrub/play/pause paths passed; human pointer and keyboard use remains untested.

Scope and reuse

This package isolates one orientation-construction problem with a separate Python evaluator and a matching native Godot example. It is not a general rig repair tool, foot-plant constraint or performance benchmark. Engine import resampling and optimisation remain separate variables to check on your final asset. Linux Godot 4.7.2 is the only engine and platform combination tested here.

The guide, code, simple geometry and animation were generated with AI and checked with executable measurements and native renders. No third-party character, motion capture or paid asset is included. The source and example data are available under the included MIT licence.