Skip to main content

SkeletonData

class (plain C++) C++ only
class AR51SDK_API SkeletonData

A plain C++ class — not a USTRUCT, not Blueprint-exposed. Holds one frame of skeleton joint data: a parallel pair of arrays (Positions + Confidence) indexed by the Keypoints scheme, plus indexer access and a set of derived-rotation helpers that compute body/limb orientations from triangles of keypoints. This is the raw frame the SDK receives and feeds to the solver; USkeletonConsumer drives characters from it each frame.

Units

Unreal works in cm / degrees. Positions are vectors indexed by Keypoints; treat them as cm after SDK scaling. ⚠️ The space/units of this raw container are unverified — the IK pipeline operates in UE world-space cm, but the container may carry meters before scaling. Treat the index → joint mapping as authoritative; treat units as cm-after-scaling unless you confirm otherwise.

Fields

FieldTypeDescription
PositionsTArray<FVector>joint positions, indexed by Keypoints (or raw int). ⚠️ space/units unverified — see caution above (treat as cm after scaling)
ConfidenceTArray<float>per-joint confidence, parallel to Positions, roughly 0–1. Low-confidence joints are de-weighted or ignored by the solver

The two arrays are parallel: Confidence[i] is the confidence for Positions[i], where i is a Keypoints index.

Constructors

methodC++ only
SkeletonData(const TArray<FVector>& positions, const TArray<float>& confidence);
SkeletonData(int capacity);

Construct from an existing positions+confidence pair, or pre-size an empty frame to capacity joints.

Parameters
positionsTArray<FVector>joint positions, indexed by Keypoints
confidenceTArray<float>per-joint confidence, parallel to positions
capacityintnumber of joints to reserve for an empty frame

Indexer

methodC++ only
FVector& operator[](Keypoints joint);
const FVector& operator[](Keypoints joint) const;
FVector& operator[](int index);
const FVector& operator[](int index) const;

Read or write a joint position by Keypoints value or by raw integer index (const and mutable overloads). Prefer the Keypoints overload — it is self-documenting and immune to index drift for the auto-numbered joints.

Exampleinferred
// Read the head/wrist positions from a frame (UE cm, after scaling)
const FVector Nose = Frame[Keypoints::Nose];
const FVector LWrist = Frame[Keypoints::LWrist];

if (Frame.Confidence[(int)Keypoints::LWrist] > 0.5f)
{
// ...use LWrist
}

Derived-rotation helpers

methodC++ only
FQuat GetHipRotation();
FQuat GetHipRotation(FVector& forward);
FQuat GetHeadRotation();
FQuat GetSpineRotation();
FQuat GetSpineRotation(FVector& forward);
FQuat GetUpperChestRotation();
FQuat GetUpperChestRotation(FVector& forward);

FQuat GetLShoulderRotation(); FQuat GetLShoulderRotation(FVector& forward);
FQuat GetRShoulderRotation(); FQuat GetRShoulderRotation(FVector& forward);
FQuat GetLHipRotation(); FQuat GetLHipRotation(FVector& forward);
FQuat GetRHipRotation(); FQuat GetRHipRotation(FVector& forward);

FQuat GetLimbRotation(Keypoints top, Keypoints mid, Keypoints bottom, FVector& forward);

FQuat GetRotation(Keypoints rBottom, Keypoints lBottom, Keypoints rTop, Keypoints lTop, FVector& forward);
static FQuat GetRotation(FVector rightPoint, FVector leftPoint, FVector topPoint, FVector& forward);

Compute joint/body orientations from triangles of keypoints in this frame. Each has a (FVector& forward) overload that also returns the body/limb forward vector as an out-param. GetLimbRotation is the general form — pass the three keypoints that define a limb; GetRotation builds an orientation from a left/right/top point set (the static overload takes raw FVectors instead of keypoint indices).

The internals are a black box, but the methods are public and useful when a game wants to read body or limb orientation directly from a frame rather than from a driven character.

ReturnsFQuatthe computed joint/body orientation

Keypoints

enum class (plain C++) C++ only
enum class Keypoints : int

A plain C++ enum class, int-backed — not a UENUM, not Blueprint-exposed. The canonical joint-index scheme: the joint/bone naming that the whole data model uses to index SkeletonData::Positions and Confidence.

The body joints (OpenPose-style) have fixed integer indices — safe to rely on:

enum class Keypoints : int
{
Unknown = -1,
Nose = 0,
Neck = 1,
RShoulder = 2,
RElbow = 3,
RWrist = 4,
LShoulder = 5,
LElbow = 6,
LWrist = 7,
MidHip = 8,
RHip = 9,
RKnee = 10,
RAnkle = 11,
LHip = 12,
LKnee = 13,
LAnkle = 14,
REye = 15,
LEye = 16,
REar = 17,
LEar = 18,
LBigToe = 19,
LSmallToe = 20,
LHeel = 21,
RBigToe = 22,
RSmallToe = 23,
RHeel = 24,
// ...auto-numbered hand + extra joints follow (see below)
};

After RHeel, the enum continues with auto-numbered entries (the compiler assigns sequential values; order-dependent):

  • Right-hand fingers: RightWrist, then R{Thumb,Index,Middle,Ring,Pinky}Finger0..3 — 4 joints per finger, 0 = base → 3 = tip.
  • Left-hand fingers: LeftWrist, then L{Thumb,Index,Middle,Ring,Pinky}Finger0..3 — same layout.
  • Extra body joints: UpperChest, Spine, RClavicle, LClavicle, RForearmeTwist0, LForearmeTwist0, RForearmeTwist1, LForearmeTwist1.
  • Sentinels: Background, then Last (the count sentinel — equals the number of keypoints).
caution

Do not hardcode the integer values of the hand/extra joints. Only the fixed body block Nose=0 … RHeel=24 is guaranteed stable. The finger, twist, clavicle, chest/spine, and sentinel values are auto-numbered and will shift if the enum changes. Always reference them by name (Keypoints::RIndexFinger2), never by literal index.

KeypointsHelper::AllKeypoints

methodC++ onlystatic
static const TArray<Keypoints>& KeypointsHelper::AllKeypoints();

Every enumerated keypoint, in order — iterate this instead of writing your own range, so hand/extra joints are included without hardcoding bounds.

Returnsconst TArray<Keypoints>&all enumerated keypoints
Exampleinferred
for (Keypoints K : KeypointsHelper::AllKeypoints())
{
const FVector P = Frame[K]; // UE cm, after scaling
// ...
}

See also

  • USkeletonConsumer — receives these frames and drives characters from them
  • UAR51Character — the mocap-driven mesh whose Solve(positions, confidence) consumes Keypoints-indexed data
  • BoneTransform — per-bone handle the solver hands out
  • Class index — all Unreal SDK types
Was this page helpful?