Skip to content

Animating tails the rigger never gave a bone

By Oleg Sidorkin, CTO and Co-Founder of Cinevva

A user rigged an anthropomorphic fox in our rigger and played the Walk clip. The body was fine. The tail folded up against the left leg like a wet towel, and where the left and right leg weights met, it tore. That fox is the running example below, and the fix is now live in the rigger and in the runtime library that plays its clips.

Three copies of a walking fox from behind: the original rig with its tail folded around the left leg, a rigid tail hanging straight down, and a tail on a bone chain carried up and back

Left to right, mid-stride at the same frame: the rig as it came out of the rigger, the same rig with the tail handed to the pelvis as one piece, and the tail on its own bone chain with the runtime swinging it. You can orbit all three further down.

Why a humanoid rigger does this

Our Fast engine is built on Make-It-Animatable, which predicts a fixed Mixamo-style skeleton: 22 body bones, or 65 with fingers. Every vertex in the mesh has to be assigned to one of those bones. A tail isn't on the list, so the model does the next best thing it knows and hands the tail's vertices to whatever body part is nearest in its learned feature space. For this fox that was the left shin, with the rest split between the two thighs.

That is not a bug in the weights. It is the template. No prompt or setting makes the model emit a tail bone, because there is no tail bone for it to emit. The same thing happens to wings, capes, long hair and anything else that hangs off the torso.

We measured what that costs on the fox's 1,582 tail vertices before touching anything. The distance from each vertex to the bones that actually move it (weighted by the weights) averaged 47 cm on a 191 cm model. The tail was being driven from half a metre away.

Finding the tail

The rigged GLB is all we have at this point, and it is all we need. The pass runs on any rigger's output, not only ours.

A distance field over the skeleton. For every vertex p and every bone segment from joint a to joint b in bind space, the distance to the segment is

d(p,ab)=p(a+t(ba)),t=clamp((pa)(ba)ba2,0,1)

and a vertex's skeleton distance is the minimum over all segments. Leaf joints get a short stub past the joint so a snout or a hand isn't counted as far from its own bone. A vertex is far when that distance exceeds 7% of the model's height. For the fox that's 13 cm.

Connected pieces of far skin. Far vertices are grouped into connected components along the mesh's own faces. One detail cost us an hour: exporters split vertices at UV and hard-normal seams, so this mesh has 23,129 vertices but only 29,081 triangles, and the face graph alone breaks one tail into dozens of islands. We weld vertices by position first, run connectivity on the welded graph, and write weights back per original vertex.

Where does it attach? The collar of a piece is the ring of non-far vertices next to it. Its centre tells us where the piece hangs from, by nearest joint, with one bias: a torso or thigh joint within 1.5 times the nearest distance wins, because around the pelvis the thigh heads sit exactly as close as the hips do and a tail root between them belongs to the body. We deliberately don't trust the collar's weights for this. On a tail modelled as its own shell (most game models), the collar is the tail's own root ring, carrying the same bad weights we're trying to fix.

Is it an appendage or is it body? Two tests. A thick torso's far-off skin wraps around a bone, so its centre of mass lands back on the bone. A tail sticks out to one side, so its centre of mass is far from every bone. We require the centroid's skeleton distance to be at least 40% of the piece's reach. Then a shape test: with λ1λ2 the two largest eigenvalues of the piece's covariance, elongation is λ1/λ2. A tail scores around 2.6 here; a cape or a skirt scores near 1. Only long pieces hanging from the pelvis become chains. Long pieces hanging from the spine (a sheath, a quiver, a strap) are worn, not grown, and ride rigidly on the bone they attach to. Ears hanging off the head are left alone: rigid with the head is exactly what ears want.

The fox's tail came out as two overlapping shells (fur over skin, never welded), so pieces on the same attachment whose bounding boxes overlap by more than half are merged. One tail, one chain.

Step one: make it rigid

The honest first fix takes an afternoon. Every vertex of the piece gets weight 1.0 on Hips. The tail stops tearing and moves as one piece with the pelvis. It looks like a plank, and that is the middle fox in the picture. We shipped this as a milestone because its stretch is exactly zero by construction, which makes it a useful reference for the measurement below.

Step two: grow a chain along it

A coordinate along the tail. We run Dijkstra from the collar into the piece over mesh edges weighted by edge length. Every tail vertex gets a geodesic distance g from the root, and the 99th percentile of g is the tail length L: 81 cm for the fox, 42% of its height.

Joints. The number of segments is K=clamp(round(L/0.1H),3,8), four for the fox. Joint J0 is the collar centroid and joint Ji is the centroid of the skin whose geodesic distance falls within half a segment of iL/K. Two passes of Ji12Ji+14(Ji1+Ji+1) stop the chain zigzagging where the cross-section is lopsided, which a bushy tail tip always is. The bones are Tail_1 through Tail_K plus a weightless Tail_End, parented under Hips, sharing the Hips bind rotation so each is a pure translation in its parent's frame. Their inverse bind matrices follow directly, and the existing clips never mention them, so nothing downstream breaks.

Weights. With s=Kg/L and k=s, f=sk, a vertex in segment k is owned by bone k+1 and shares the ends with its neighbours:

wprev=clamp(0.52f, 0, 0.5),wnext=clamp(2f1.5, 0, 0.5),wself=1wprevwnext

At a joint the two bones meet at 50/50; in the middle of a segment one bone owns the skin outright. For the root segment, "prev" is Hips, so the tail blends into the body instead of creasing at the collar.

After the pass, the weighted bone distance on the tail dropped from 47 cm to 17 cm, which is about the tail's own radius. That is as close as skin gets to the bone that drives it.

Side view of the walking fox with its skeleton drawn over the mesh; four tail bones run from the pelvis along the tail, carried up and back

Step three: something has to move the bones

No clip in our library has tail tracks, so without more work the chain holds its bind pose and the fox walks around with a plank. Games solve this with procedural secondary motion, and so do we, in the runtime library every rigged model already loads.

Each joint tip is a particle p with velocity v. Its rest target T is where the bind pose says the tip should be, computed each frame from the parent bone's current world transform. The particle follows a damped spring:

p¨=ω2(Tp)2ζωp˙+g

with ω=2πf. The root segment swings at f=0.9 Hz and the tip at half that, because a tail is muscle at the base and fur at the end. The damping ratio is ζ=0.45, so it overshoots a couple of times and settles. Gravity is 1 m/s², not 9.8; a tail has muscle in it. We integrate with semi-implicit Euler, then enforce the rope constraint by projecting p back onto the sphere of the bone's length around the bone's head. The correction is also removed from the velocity, or the particle keeps pushing into the rope and buzzes. Finally the bone's rotation is read back: the quaternion that takes its bind direction onto the direction to the particle.

Because the particles live in world space, turning or accelerating the hips makes the tail lag behind and swing on its own. Nothing is scripted.

Our first version got this wrong in two ways worth admitting. It pulled each particle a fixed fraction of the way to its target every frame, 12% at 60 fps. Written as a spring that is ω0.12/Δt21 rad/s, a 3.4 Hz jitter. And because that stiffness barely let the root segments move, all the motion piled up at the tip. Writing the spring in physical units fixed both at once.

Clipping. The tail was modelled hanging straight down between the legs, and the walk cycle put the feet through it. The rest pose the spring aims for is therefore not the mesh's own: a carry of 50° rotates the rest targets backward and up around the hips' side axis, the way a fox holds its tail when moving. And no particle may cross the plane through the tail root that faces forward, so the tail can never swing between the legs.

Measuring it

Stills don't prove anything about tearing, so we measure edge stretch under the clip. For every mesh edge whose two vertices are both on the tail, we take the ratio of its skinned length to its bind length at 24 evenly spaced times through the Walk clip. A ratio of 1 is undeformed skin. An edge stretched past 1.5 or squashed below 0.67 counts as torn. Body edges are measured the same way as a baseline for what normal skinning distortion looks like.

Walk clip, 97,848 tail edge samplesp95p99maxtorn
Original rig1.592.414.0311.3%
Rigid to Hips1.001.001.000%
Tail chain1.011.031.050%
Body, for reference1.121.261.88

The original rig stretched one in nine tail edges past tearing, and its worst edge was four times its bind length. The chain's worst edge is 5% long, well inside the body's own baseline. The rigid tail sits at exactly 1.00 because it moves as one piece; that's the number that told us the harness itself was right before we trusted it on the chain.

The live comparison

Three copies of the fox, same clip, same frame. Drag to orbit, wheel to zoom. Switch clips, turn the tail physics off to see the chain in its carried rest pose, and turn on the bones to see where the chain sits.

The same chain from the side, alone, with the skeleton drawn. Sprint is the clip that shows the spring best.

What this changes for you

If you rig a character with a tail at cinevva.com/tools/rigger, the tail comes back on its own bone chain, the job status carries an appendages entry describing what was found, and the preview swings it. Models rigged through the platform API get the same file. In a game built with the runtime, createAnimator from rt/1.1.11 finds Tail_* bones and drives them with no extra code; the spring's frequency, damping, gravity and carry angle are options if you want a heavier or a lazier tail. Files rigged before today can be run through the pass again by re-rigging.

The pass is deliberately conservative. It grows a chain only for a long piece hanging from the pelvis. A cape, a skirt or a strap goes rigid on its torso bone, which is usually right and never worse than following a forearm. Ears, hair and sleeves are untouched. There is no collision with the legs beyond the forward plane, and no idle sway when the character stands still, so a standing fox's tail hangs quietly at its carried pose. Those are the next two things on the list, along with the same treatment for wings, which want a different rest pose and a different spring.