Skip to content

Vhi.StandardPose

VHI_godot

Vhi

StandardPose Class

The one place that knows what a standard value means in rig degrees.

public static class StandardPose

Inheritance System.Object → StandardPose

Remarks

A standard +1 is the direction the DOF's name denotes, 0 is rest, and the domain is [-1, 1]. AtPlusOne states, per joint and axis, the rotation that +1 produces — so a target multiplies, a reader divides, and neither carries a sign of its own.

Positive X is flexion on this rig. That is not what MovementPoses appears to say, and the appearance is what this class exists to end. Those rows were authored in Unity's convention and reached the skeleton through ApplyMovementPose, which interpolated with a negated sine and so rendered their opposite: a held Fist put bone 4 at +85°, never the tabulated -85°. Reading the table alone gave the wrong answer, and everything that did — both skeletons' gain tables, this class's own sign vector, the contract suite's direction gate — agreed with each other and disagreed with the hand. The table is now stated in rig degrees and the animation interpolates plainly, so there is one convention and it is this one.

Channel 1 is abduction and the fist's thumb is adducted, so a standard fist is [+1, -1, +1, +1, +1, +1, …] — the thumb comes across the fingers as it curls. That is a fact about hands, not a quirk of the rig, and it is why the thumb is the digit that exposes a direction error: it is the only one whose flexion is not symmetric front-to-back, so a hand bending entirely the wrong way still looks plausible until you watch the thumb.

Fields

StandardPose.AtPlusOne Field

Rig degrees produced by standard +1, per joint: (X, Y, Z).

public static readonly Dictionary<int,float[]> AtPlusOne;

Field Value

System.Collections.Generic.Dictionary<System.Int32,System.Single[]>

Remarks

Keyed by the joint indices both skeletons use — 0 wrist, 1-3 thumb, 4-6 index, 7-9 middle, 10-12 ring, 13-15 pinky. X is flexion, Z abduction; a zero means the channel does not move that joint on that axis, which is not the same as it moving by nothing (see JointsMovableOnAxis). Declared after Wrist because it uses it — a static initializer runs in declaration order, and the other way round joint 0 silently becomes null and the wrist stops moving.

StandardPose.Wrist Field

Joint 0's rotation at standard +1, in degrees: (X, Y, Z).

public static readonly float[] Wrist;

Field Value

System.Single[]

Remarks

The wrist. Joint 0 is WaveBone_1, the common ancestor of all five digit chains, so rotating it turns the whole hand — which is what a wrist does.

Every number here is a calibration, not a derivation. An earlier version of this comment derived X from the finger bones — Fist against IndexExtension — and that reasoning was wrong twice over: it read the pose table without the animation's negation, and a bone's local basis is its own. Nothing about the fingers constrains which way joint 0 turns.

X = +30 — WristUpDown gives the magnitude as ±30; the sign says standard +1 flexes, matching the digits.

Z = +20 — WristLeftRight gives ±20 and names neither side: "left/right" says which axis, not which is abduction.

Y = +179 has no rig-side evidence at all. No movement in the library touches joint 0's Y, so both magnitude and sign are picked: 179° each way to stay clear of the ±180° Euler ambiguity, positive so that +1 is pronation. There is no forearm, so what twists is the hand about its own long axis.

All three want confirming against the hand rather than by reading, and X now has the digits to check against. Flip a sign here and nothing else needs to change.

Methods

StandardPose.Clamp(float) Method

A standard value clamped to its domain, for storing in a pose vector.

public static float Clamp(float standard);

Returns

System.Single

StandardPose.Clamp(List\<float>) Method

Clamp a whole pose in place, for as many channels as are present.

public static void Clamp(System.Collections.Generic.List<float> pose);

StandardPose.Standard(int, int, float) Method

Rendered degrees → the standard value that produced them. The inverse of Degrees in range, so a read-back round-trips rather than flipping.

public static float Standard(int joint, int axis, float degrees);

Returns

System.Single