score
Home
Classes
Namespaces
Files
Loading...
Searching...
No Matches
HumanoidPose.hpp
1
#pragma once
2
3
// humanoid_pose: canonical intermediate for live mocap -> rigged-character
4
// retargeting. One fixed set of 22 bones that every source adapter populates and
5
// HumanoidRetarget consumes.
6
//
7
// Flows through halp's structured-value port machinery, matching the existing
8
// DetectedPose pattern; no new libossia port type.
9
//
10
// Rotations are local parent-relative quaternions (x, y, z, w); adapters convert
11
// their source's native representation into that shape. `validity` is a 0..1
12
// per-bone confidence -- BlazePose visibility, tracker occlusion -- that
13
// downstream uses to freeze a bone rather than trust it. `hip_position` is the
14
// only world-space translation that flows through, since every other bone's
15
// position is implied by the target rig's proportions, and it is used only with
16
// HumanoidRetarget's root-motion toggle on.
17
18
#include <halp/controls.hpp>
19
20
#include <array>
21
#include <cstdint>
22
#include <vector>
23
24
namespace
Threedim
25
{
26
27
// Canonical bone set. Indexed access via the enum; iterate with
28
// humanoid_bone_index::Count. Order is stable — adapters and retargeter
29
// presets both depend on it.
30
enum class
humanoid_bone_index : uint8_t
31
{
32
Hips = 0,
33
Spine,
34
Chest,
35
Neck,
36
Head,
37
38
LeftShoulder,
39
LeftUpperArm,
40
LeftLowerArm,
41
LeftHand,
42
43
RightShoulder,
44
RightUpperArm,
45
RightLowerArm,
46
RightHand,
47
48
LeftUpperLeg,
49
LeftLowerLeg,
50
LeftFoot,
51
LeftToes,
52
53
RightUpperLeg,
54
RightLowerLeg,
55
RightFoot,
56
RightToes,
57
58
Count
59
};
60
61
// Per-bone pose. 20-byte halp-structured record (5 floats).
62
struct
humanoid_bone
63
{
64
// Parent-relative rotation quaternion, (x, y, z, w). Identity = {0,0,0,1}.
65
float
qx{0.f};
66
float
qy{0.f};
67
float
qz{0.f};
68
float
qw{1.f};
69
70
// 0..1 confidence. 0 means "no reliable data for this bone, retargeter
71
// should ignore this frame for this bone". 1 = fully trusted.
72
float
validity{1.f};
73
74
halp_field_names(qx, qy, qz, qw, validity);
75
};
76
77
// Fixed-size bone array — std::array plays nicely with halp serialization
78
// (same way DetectedPose uses std::vector, except the size is known and
79
// we can index by enum without a lookup).
80
struct
humanoid_pose
81
{
82
std::array<
humanoid_bone
, std::size_t(humanoid_bone_index::Count)> bones{};
83
84
// World-space translation of the hip (Hips) root. Only consumed when
85
// root-motion is enabled on HumanoidRetarget; otherwise ignored.
86
float
hip_x{0.f};
87
float
hip_y{0.f};
88
float
hip_z{0.f};
89
90
// Frame counter, incremented on every adapter emit. Consumers use it for
91
// dirty tracking: skip the work when it has not advanced.
92
int64_t version{0};
93
94
humanoid_bone
& operator[](humanoid_bone_index b)
noexcept
95
{
96
return
bones[std::size_t(b)];
97
}
98
const
humanoid_bone
& operator[](humanoid_bone_index b)
const
noexcept
99
{
100
return
bones[std::size_t(b)];
101
}
102
103
halp_field_names(bones, hip_x, hip_y, hip_z, version);
104
};
105
106
// =============================================================================
107
// Keypoint ingestion type — structurally compatible with the DetectedPose
108
// struct from score-addon-onnx (same field names, same layout) so halp's
109
// field-name-based port marshalling can carry a DetectedPose through a
110
// port typed as keypoint_stream without cross-addon header dependency.
111
//
112
// Kept in Threedim deliberately: HumanoidRetarget consumes it, but we
113
// don't want score-plugin-threedim to link against score-addon-onnx.
114
// =============================================================================
115
struct
keypoint_3d
116
{
117
float
x{0.f};
118
float
y{0.f};
119
float
z{0.f};
120
float
confidence{0.f};
121
122
halp_field_names(x, y, z, confidence);
123
};
124
125
struct
keypoint_stream
126
{
127
std::vector<keypoint_3d> keypoints;
128
float
mean_confidence{0.f};
129
130
halp_field_names(keypoints, mean_confidence);
131
};
132
133
// =============================================================================
134
// Tracker bundle: 6 slots matching a common VR / optical-mocap full-body layout
135
// (head, hips, 2 hands, 2 feet). Each carries a world-space position, a
136
// world-space quaternion, and a validity, so lost tracking skips instead of
137
// slamming the character to the origin.
138
//
139
// Richer layouts (10-point Vive Full-Body, Xsens 17-IMU, OptiTrack marker sets)
140
// would be additional bundle_N struct types; users with those rigs can drive
141
// these 6 slots from the subset they trust.
142
// =============================================================================
143
struct
tracker_pose
144
{
145
// World-space translation.
146
float
x{0.f};
147
float
y{0.f};
148
float
z{0.f};
149
150
// World-space quaternion (x, y, z, w). Identity = {0, 0, 0, 1}.
151
float
qx{0.f};
152
float
qy{0.f};
153
float
qz{0.f};
154
float
qw{1.f};
155
156
// 0..1 tracking confidence. 0 = "tracker offline, ignore this frame".
157
float
validity{0.f};
158
159
halp_field_names(x, y, z, qx, qy, qz, qw, validity);
160
};
161
162
struct
tracker_bundle_6
163
{
164
tracker_pose
head;
165
tracker_pose
hips;
166
tracker_pose
left_hand;
167
tracker_pose
right_hand;
168
tracker_pose
left_foot;
169
tracker_pose
right_foot;
170
171
halp_field_names(head, hips, left_hand, right_hand, left_foot, right_foot);
172
};
173
174
}
// namespace Threedim
Threedim::humanoid_bone
Definition
HumanoidPose.hpp:63
Threedim::humanoid_pose
Definition
HumanoidPose.hpp:81
Threedim::keypoint_3d
Definition
HumanoidPose.hpp:116
Threedim::keypoint_stream
Definition
HumanoidPose.hpp:126
Threedim::tracker_bundle_6
Definition
HumanoidPose.hpp:163
Threedim::tracker_pose
Definition
HumanoidPose.hpp:144