Skip to content

When an animation has to touch the world

By Oleg Sidorkin, CTO and Co-Founder of Cinevva

A walking animation knows how the legs move. It does not know that one foot has reached a step. A reaching animation knows how the arm moves. It does not know where this particular keyhole is, or that somebody moved the cup.

This is the next problem after auto-rigging a character: making the animation respond to the scene while the game is running. We have implemented an experimental correction layer in Cinevva’s Three.js runtime. It reads the pose produced by the animation, queries the scene, and adjusts the character’s joints before the frame is rendered.

The examples below run that code in your browser. There is no motion-generation request in the per-frame loop.

Try the difference

The demo starts automatically. Choose an example and turn Corrections off and on. The left character shows the base pose; the right receives the live correction. Pause and drag the timeline to examine a particular instant. Drag either viewport to orbit around the character, scroll or pinch to zoom, and right-drag to pan. Both cameras stay synchronized, so you can inspect the same contact from exactly the same angle.

Every example uses the same Cinevva auto-rigged frog. The walking example plays Walk from the Universal Animation Library, retargeted through the same code used by Auto Rigger. Both viewports play the actual clip; the right adds runtime terrain corrections. Other examples retain the embedded Idle reference and their interaction controllers.

The walking clip supplies pelvis, torso, arm, and leg motion. Contact weights are inferred from the retargeted feet’s height cycle, and the steps move at a speed estimated from the clip’s stance motion. Ground IK adjusts foot placement on the terrain. This replaces the demo’s synthetic foot paths and fixed pelvis trajectory. It remains a contact-adaptation prototype: automatic footstep planning, complete toe/heel obstacle clearance, and physical balance are not established by loading a walking clip.

Climb a ladder transfers one limb at a time while three contacts hold their rungs. The ladder moves down to keep the climber in view. Explicit ankle and hand targets place the contacts, and elbow/knee guides keep the bends clear of the ladder. The body motion and contact sequence are authored; this is not an automatic climbing planner.

What is implemented

CapabilityWhat the runtime does today
Uneven groundQueries a support point for each foot, aligns its calibrated sole normal, and adjusts pelvis height.
Planted feetHolds a stance contact relative to the surface supporting it.
Moving platformsCarries that contact with a translating or rotating support.
Hand targetsSolves an arm toward a world-space position and orientation, with a blend weight.
Held objectsDerives the wrist target from the desired object pose and a fixed grip transform.
Impossible reachLimits the solve and reports that the character needs repositioning.

This is an opt-in runtime prototype. The interactive examples demonstrate the implementation; they do not mean every generated Cinevva game automatically enables it.

A planted foot needs a reference frame

Our existing retargeter already corrects some foot drift when transferring a clip between differently proportioned characters. Runtime grounding has another input: the surface the character is standing on now.

When a foot enters stance, the new layer records its contact point in the supporting object’s local coordinates. On a static floor, the foot stays put as the body moves. On a moving platform, the same stored point moves with the platform. Anchoring it only in world coordinates would leave the foot behind.

The pelvis then moves within a bounded height range that both legs can reach, and each leg solves toward its foot target. One early test caught a subtle failure: smoothing the pelvis across a reach boundary briefly left a foot floating on a slope. Smoothing now stays inside the feasible range.

The frog exposed a separate calibration error: touching the lowest toe does not mean the sole is seated. Its demo now fits a supporting plane to each posed foot mesh, calibrating both position and normal. The rendered regression measures three separated sole contacts as well as the lowest surface point throughout Idle.

All examples now use a shared body-support check. It estimates center of mass from weighted body segments, includes illustrative carried-object loads, and guides the pelvis toward the loaded feet while preserving contact. The on-screen support status is separate from target error. The earlier procedural walk exposed large body discontinuities despite small endpoint errors. The library-driven walk preserves an authored full-body source motion. Its pelvis correction has bounded speed and acceleration, with a final contact solve and a small knee-flexion reserve. Contact weights normalize the vertical correction, and partially blended swing feet no longer veto balance correction. The regression checks continuity and planted targets at 60 and 120 Hz; complete skinned-foot clearance remains a separate check. These are approximate kinematic checks, not a force simulation: the frog needs calibrated masses for physical accuracy, and the ladder explicitly reports that grip forces remain unverified.

Walking still needs timing. The game supplies a weight for each foot: how strongly it should be treated as planted at this instant. A swing foot must be released. The game also supplies the gait, the character’s movement, and clearance over the next step. Those decisions are not inferred by the IK solver.

Put the key in the hole, then solve for the hand

Pointing the wrist at a keyhole is not enough. The key has a length, an insertion axis, and a grip offset. Its tip can miss even when the wrist reaches its target perfectly.

In the demo, the interaction sequence defines the key’s desired position and rotation. The grip tells us where the wrist must be to put the key there. The arm then solves toward that wrist pose. The actual key remains attached to the solved hand, including when the requested position is unreachable.

The Unreachable target example deliberately demonstrates that failure. The limb does not stretch to make the metric look successful; the runtime reports that the character needs repositioning.

This example has authored approach, insertion and turn phases. It does not yet plan a finger grasp or check the key’s shape against the lock’s internal clearance.

Pouring is an orientation problem too

The pouring example keeps the vessel’s spout over the cup while tilting the vessel around it. As the vessel rotates, the necessary wrist position changes. The same hand-target mechanism follows that changing pose.

The blue stream is a visual effect enabled during the tilt. It is not a fluid simulation. Its purpose here is to make the alignment visible: without correction, it misses the cup; with correction, it falls into the receiving area.

Where the correction runs

The sequence in a game is:

Move the character → evaluate animation → apply pose offsets → solve scene contacts → update secondary motion → render.

The runtime exposes this through createAnimator with an optional sceneIK configuration. Games pass contact weights, hand targets and grounded state into update. It can also wrap an existing Three.js animation mixer.

Each rig needs meaningful foot and grip calibration. Bone-name mapping gets us to the right limb, but an ankle joint is not the bottom of a shoe. This version uses one calibrated support point per foot; it does not yet model the entire heel-and-toe support area.

The underlying techniques have established counterparts in Unity’s two-bone IK and Unreal’s IK solvers. Our implementation is a small, engine-side correction layer built around the needs of our auto-rigged characters.

What we checked—and what remains

The first verification pass included 14 numerical and integration tests, plus eight rendered scenarios sampled across 3,840 frames. We checked moving supports, slope contact, constant animation tracks, coordinate transforms, reach limits, and the runtime animator integration. Browser automation also compared the canvas with corrections enabled and disabled, and exercised the narrow layout.

The measurements check limb-target error. They are not proof that every part of the skinned mesh is collision-free, or that the result looks natural on every character. The examples are intentionally small enough to inspect alongside those numbers.

The next layers are footstep planning, better sole support, whole-body reach, finger grasping, and collision-aware interaction phases. Physically simulated liquid is a separate system again.

For now, the useful result is concrete: an animation can keep its underlying motion while its feet and hands respond to the scene each frame. That gives an auto-rigged character a starting point for interacting with the world around it.