NOTE: In an upcoming release of the Open SDK, we aim to support auto configuration of Hand Engine using a “command” OSC address which is listening on the Command Listening Port . Third party applications can send OSC messages to this address to toggle on/off OSC addresses they will receive data from. This allows their application to be setup without a user manually configuring the Hand Engine settings for the Open SDK.
Hand Engine 3.1.2-Open-SDK-Beta or higher supports the retargeting of Hand Engine data into various character rig formats and ships with VRM model retargeting built in. Additional retargeting models for character rig types are loaded from JSON files located in the end-user’s local application data folder. Hand Engine creates an OSC client and dispatches OSC messages which can be received by OSC servers listening on specified ports (e.g. OSC servers built in Unity).
To perform duplex data transfer between to applications in OSC, both applications must implement an OSC server for listening to incoming OSC messages, and an OSC client for dispatching OSC messages. Use a different port for each app you wish to receive Open SDK data from Hand Engine. These ports can be adjusted in the Hand Engine Settings menu under Open SDK.
TIP: By default, Hand Engine sends OSC data out on port 9400 . Receiving apps that implement our Open SDK specification in this document can listen on this port using an OSC server and receive animation data for StretchSense gloves.
Hand Engine currently implements the signed integer (i), 32-bit float (f) and string (s) OSC argument types which are compatible with all OSC libraries.
NOTE: Null values are represented by -2147483648, so you can ignore these values as they indicate that the particular OSC argument is not to be used by your application.
The following functionality is intended to service both non-VR and VR integrations. It assumes that first time setup of gloves and performers has been configured either from within the Hand Engine application or via other OSC addresses.
OSC does not support enums natively. Instead, enums are transmitted as integer values in OSC messages. Developers are expected to implement their own typecasting of the OSC argument value to a structured enum that works with their chosen application framework or language. We recommend this approach as it will make applications easier to adapt for future API changes in future releases based on beta feedback.
INFO: Non-animation OSC messages are dispatched by Hand Engine every second, while animation OSC messages are dispatched as soon as new data is available.
NOTE: In this document, each point that has animation position, rotation and slider values provided by the Open SDK is meant to approximately be the end of the bone closest to the wrist for the purposes of animating a 3D hand in space or communicating the gesture state of the user’s hand. They follow OpenXR naming conventions and the points don’t necessarily align with an anatomical joint. Throughout this document we refer to these points as Bones .
The following case-sensitive OSC addresses have been implemented as part of the Open SDK Core. These are often referred to these by their short name in documentation and the short name is used as a label in the Hand Engine settings screen. Animation data on these addresses has been retargeted to a particular character rig format, as described in the Retargeting section of this document:
| OSC Address (Case sensitive) | Short Name | Number of Bones Fingers | Number of Bones Thumb | Includes Metacarpal Bone | OpenXR Hand Rig Compatible |
|---|---|---|---|---|---|
/v1/animation/{performerId}/{handedness}/{fingerName}/rotation |
animation/rotation |
3 | 2 | ||
/v1/animation/{performerId}/{handedness}/{fingerName}/position |
animation/rotation |
3 | 2 | ||
/v1/animation/{performerId}/{handedness}/{fingerName}/rotationWithMetacarpals |
animation/rotationWithMetacarpals |
4 | 3 | ||
/v1/animation/{performerId}/{handedness}/{fingerName}/rotationWithMetacarpals |
animation/rotationWithMetacarpals |
4 | 3 |
Where:
performerId - the integer ID of the performer in Hand Engine you wish to get data for. The default performerId is 0 and subsequent performers added will be sequential. E.g. 1, 2, 3, 4, 5 etc.handedness - an integer representation of the hand you wish to get data for. We suggest setting up an enum in your application to represent the below possible values for handedness:
0 = Unknown (not used for getting data but can be used internally by your app if the hand state is not known.
1 = Left Hand2 = Right Handfinger - a string representation of the finger you wish to get bone data for. Note that these are case sensitive and start with a capital letter:
Thumb = bones belonging to the thumb
Index = bones belonging to the index fingerMiddle = bones belonging to the middle fingerRing = bones belonging to the ring fingerLittle = bones belonging to the little finger (also known as the “pinky” finger in some animation or interaction systems)In order to avoid issues with gimbal lock that commonly occur when using Euler angles for animation, this message structure provides quaternion values, suitable for character and hand rigs with 3 bones in the fingers and 2 bones in the thumb. Alternately proximal and intermediate bones can also be assigned to rigs with only 2 bones per finger.
The following Hand Engine remapping target profiles can be used with the animation/rotation OSC message data. Selecting the appropriate one of these are required for the quaternion data to be correctly retargeted to the hand rig in the application consuming the data:
RAYNOS-chan_1.0.4-Studio.json / RAYNOS-chan_1.0.4-Fidelity.json - Compatible with VRM based models from VRoid Hub or the Sony Mocopi SDK (found under RAYNOS-chan\Retargeting\Hand Engine Retargeting Models in the Sony Mocopi sample in StretchSense Plugin for Unity 3.2.0-RC3 or higher).Each message has 13 arguments that are structured with the following indexes when accessing data for the 3-bone animation/rotation OSC address. You can each arguments data by calculating the correct offset using the index below. Most OSC libraries will do this calculation, so you will just need to provide the index and argument type when reading the data.
| OSC Argument Index | OSC Argument Name | OSC Type |
|---|---|---|
| 0 | Timecode | integer |
| 1 | Proximal Rotation Quaternion X | float |
| 2 | Proximal Rotation Quaternion Y | float |
| 3 | Proximal Rotation Quaternion Z | float |
| 4 | Proximal Rotation Quaternion W | float |
| 5 | Intermediate Rotation Quaternion X | float |
| 6 | Intermediate Rotation Quaternion Y | float |
| 7 | Intermediate Rotation Quaternion Z | float |
| 8 | Intermediate Rotation Quaternion W | float |
| 9 | Distal Rotation Quaternion X | float |
| 10 | Distal Rotation Quaternion Y | float |
| 11 | Distal Rotation Quaternion Z | float |
| 12 | Distal Rotation Quaternion W | float |
These are suitable for character and hand rigs with 4 bones per finger and 3 bones in the thumb, commonly used in high-end animation or OpenXR. Unreal Engine 5 also uses 4 bones in its Manny, Quinn and MetaHuman character rigs.
The following Hand Engine remapping target profiles can be used with the animation/rotationWithMetacarpals OSC message data. Selecting the appropriate one of these are required for the quaternion data to be correctly retargeted to the hand rig in the application consuming the data:
HTC-VIVE-Wave-Hands-Studio.json / HTC-VIVE-Wave-Hands-Fidelity.json - Compatible with the VIVE-Wave SDK’s OpenXR hand model (found under Retargeting\Hand Engine Retargeting Models in the VIVE-Wave sample in StretchSense Plugin for Unity 3.2.0-RC3 or higher).Each message has 17 arguments that are structured with the following indexes when accessing data for the 4-bone animation/rotationWithMetacarpals OSC address. You can each arguments data by calculating the correct offset using the index below. Most OSC libraries will do this calculation, so you will just need to provide the index and argument type when reading the data.
| OSC Argument Index | OSC Argument Name | OSC Type |
|---|---|---|
| 0 | Timecode | integer |
| 1 | Metacarpal Rotation Quaternion X | float |
| 2 | Metacarpal Rotation Quaternion Y | float |
| 3 | Metacarpal Rotation Quaternion Z | float |
| 4 | Metacarpal Rotation Quaternion W | float |
| 5 | Proximal Rotation Quaternion X | float |
| 6 | Proximal Rotation Quaternion Y | float |
| 7 | Proximal Rotation Quaternion Z | float |
| 8 | Proximal Rotation Quaternion W | float |
| 9 | Intermediate Rotation Quaternion X | float |
| 10 | Intermediate Rotation Quaternion Y | float |
| 11 | Intermediate Rotation Quaternion Z | float |
| 12 | Intermediate Rotation Quaternion W | float |
| 13 | Distal Rotation Quaternion X | float |
| 14 | Distal Rotation Quaternion Y | float |
| 15 | Distal Rotation Quaternion Z | float |
| 16 | Distal Rotation Quaternion W | float |
The below descriptions are for arguments in the animation/rotation and animation/rotationWithMetacarpals OSC addresses.
Hand diagrams below are from Unity’s XR Hands package documentation Hand data model | XR Hands | 1.5.0-pre.1 (unity3d.com):
| Metacarpal Rot. |
Timecode | Metacarpal Rotation Quaternion X | Metacarpal Rotation Quaternion Y | Metacarpal Rotation Quaternion Z | Metacarpal Rotation Quaternion W |
|---|---|---|---|---|---|
| OSC type | integer | float | float | float | float |
| Language Type | int32 signed | float32 signed | float32 signed | float32 signed | float32 signed |
| Format | hhmmssfff | x float value to 17 d.p | y float value to 17 d.p | z float value to 17 d.p | w float value to 17 d.p |
| Example | 134255043 | -0.1692586 |
-0.1232476 |
-0.06889943 |
0.9754032 |
| Validation | Min: 0, Max: 2147483647 |
Min: -1, Max: 1 |
Min: -1, Max: 1 |
Min: -1, Max: 1 |
Min: -1, Max: 1 |
| Notes | fff in the format represents a 3-digit frame number for the given second. INFO: Hand Engine supports up to 120FPS data for Pro Fidelity gloves, and 60FPS for Studio gloves. | Quaternion x value of the Proximal bone of the finger. | Quaternion y value of the Proximal bone of the finger. | Quaternion z value of the Proximal bone of the finger. | Quaternion w value of the Proximal bone of the finger. |
| Proximal Rot. |
Timecode | Proximal Rotation Quaternion X | Proximal Rotation Quaternion Y | Proximal Rotation Quaternion Z | Proximal Rotation Quaternion W |
|---|---|---|---|---|---|
| OSC type | integer | float | float | float | float |
| Language Type | int32 signed | float32 signed | float32 signed | float32 signed | float32 signed |
| Format | hhmmssfff | x float value to 17 d.p | y float value to 17 d.p | z float value to 17 d.p | w float value to 17 d.p |
| Example | 134255043 | -0.1692586 |
-0.1232476 |
-0.06889943 |
0.9754032 |
| Validation | Min: 0, Max: 2147483647 |
Min: -1, Max: 1 |
Min: -1, Max: 1 |
Min: -1, Max: 1 |
Min: -1, Max: 1 |
| Notes | fff in the format represents a 3-digit frame number for the given second. INFO: Hand Engine supports up to 120FPS data for Pro Fidelity gloves, and 60FPS for Studio gloves. | Quaternion x value of the Proximal bone of the finger. | Quaternion y value of the Proximal bone of the finger. | Quaternion z value of the Proximal bone of the finger. | Quaternion w value of the Proximal bone of the finger. |
| Intermediate Rot. |
Intermediate Rotation Quaternion X | Intermediate Rotation Quaternion Y | Intermediate Rotation Quaternion Z | Intermediate Rotation Quaternion W | |
|---|---|---|---|---|---|
| OSC type | float | float | float | float | |
| Language Type | float32 signed | float32 signed | float32 signed | float32 signed | |
| Format | x float value to 17 d.p | y float value to 17 d.p | z float value to 17 d.p | w float value to 17 d.p | |
| Example | 0 |
-0.1936401 |
0 |
0.9810718 |
|
| Validation | Min: -1, Max: 1 |
Min: -1, Max: 1 |
Min: -1, Max: 1 |
Min: -1, Max: 1 |
|
| Notes | Quaternion x value of the Intermediate bone of the finger. WARNING: The thumb does not have this bone. | Quaternion y value of the Intermediate bone of the finger. WARNING: The thumb does not have this bone. | Quaternion z value of the Intermediate bone of the finger. WARNING: The thumb does not have this bone. | Quaternion w value of the Intermediate bone of the finger. WARNING: The thumb does not have this bone. |
NOTE: The thumb has one fewer bone than the other fingers because thumbs do not have an intermediate bone.
| Distal Rot. |
Distal Rotation Quaternion X | Distal Rotation Quaternion Y | Distal Rotation Quaternion Z | Distal Rotation Quaternion W | |
|---|---|---|---|---|---|
| OSC type | float | float | float | float | |
| Language Type | float32 signed | float32 signed | float32 signed | float32 signed | |
| Format | x float value to 17 d.p | y float value to 17 d.p | z float value to 17 d.p | w float value to 17 d.p | |
| Example | 0 |
-0.1936401 |
0 |
0.9810718 |
|
| Validation | Min: -1, Max: 1 |
Min: -1, Max: 1 |
Min: -1, Max: 1 |
Min: -1, Max: 1 |
|
| Notes | Quaternion x value of the Distal bone of the finger. | Quaternion y value of the Distal bone of the finger. | Quaternion z value of the Distal bone of the finger. | Quaternion w value of the Distal bone of the finger. |
This message structure provides rotation values, suitable for character and hand rigs with 3 bones. The proximal and intermediate bones can also be assigned to rigs with only 2 bones per finger.
It is primarily used for determining the bone positioning for applications and animation tools that are based on fixed points in space for every tracked body part, in relation to the root bone of your character rig’s hands (e.g. wrist).
For most use-cases we recommend using data from the animation/rotation or animation/rotationWithMetacarpals OSC addresses instead.
NOTE: These positions are not retargeted and are based on a fixed internal hand model within Hand Engine, so further processing is required in your application to adjust the bone lengths for your character rig.
| Proximal Position |
Timecode | Proximal Position X | Proximal Position Y | Proximal Position Z |
|---|---|---|---|---|
| OSC Argument Index | 0 | 1 | 2 | 3 |
| OSC type | integer | float | float | float |
| Language Type | int32 signed | float32 signed | float32 signed | float32 signed |
| Format | hhmmssfff | x position value to 17 d.p | y position value to 17 d.p | z position value to 17 d.p |
| Example | 134255043 | -0.07707334 |
-0.0002944469 |
0.0228914 |
| Validation | Min: 0, Max: 2147483647 |
|||
| Notes | fff in the format represents a 3-digit frame number for the given second. INFO: Hand Engine supports up to 120FPS data for Pro Fidelity gloves, and 60FPS for Studio gloves. | X position value of the Proximal bone of the finger. | Y position value of the Proximal bone of the finger. | Z position value of the Proximal bone of the finger. |
| Intermediate Position |
Intermediate Position X | Intermediate Position Y | Intermediate Position Z | |
|---|---|---|---|---|
| OSC Argument Index | 4 | 5 | 6 | |
| OSC type | float | float | float | |
| Language Type | float32 signed | float32 signed | float32 signed | |
| Format | x position value to 17 d.p | y position value to 17 d.p | z position value to 17 d.p | |
| Example | -0.03520012 |
-0.000001430511 |
0 |
|
| Validation | ||||
| Notes | X position value of the Intermediate bone of the finger. | Y position value of the Intermediate bone of the finger. | Z position value of the Intermediate bone of the finger. |
NOTE: The thumb has one fewer bone than the other fingers because thumbs do not have an intermediate bone.
| Distal Position |
Distal Position X | Distal Position Y | Distal Position Z | |
|---|---|---|---|---|
| OSC Argument Index | 7 | 8 | 9 | |
| OSC type | float | float | float | |
| Language Type | float32 signed | float32 signed | float32 signed | |
| Format | x position value to 17 d.p | y position value to 17 d.p | z position value to 17 d.p | |
| Example | -0.02065659 |
-0.000000834465 |
0 | |
| Validation | ||||
| Notes | X position value of the Distal bone of the finger. | Y position value of the Distal bone of the finger. | Z position value of the Distal bone of the finger. |
The current glove state is expressed by Hand Engine as float values ranging from -1 to 1 for the bend of the bone and splay of the fingers of the end-user’s hand. It is possible to derive basic hand poses from this data in your receiving application by testing these against minimum and maximum ranges for each slider.
The following terms and features are used when working with animation sliders:
| Slider Feature | Type | Description | Supports Studio? [Status: Rev g] | Supports Pro Fidelity? [Status: Rev f] | Animation Sliders |
|---|---|---|---|---|---|
| Bend | Bend | The curl rotation of the other bones in the finger. | ThumbBend1, ThumbBend2, IndexBend1, IndexBend2, MiddleBend1, MiddleBend2, RingBend1, RingBend2, PinkyBend1, PinkyBend2 | ||
| Distal Bend | Bend | The curl rotation of the end bone of the finger. | ThumbBend3, IndexBend3, MiddleBend3, RingBend3, PinkyBend3 | ||
| Per-finger Splay | Splay | The horizontal movement outwards of the index, middle, ring and thumb fingers. | IndexSplay, MiddleSplay, RingSplay, PinkySplay | ||
| Thumb Splay | Splay | The outward rotation of the thumb 90 degrees to the hand. | ThumbSplay | ||
| Global Splay | Splay | The aggregated outward splay of all the fingers on the Studio glove. Used to detect spread fingers and in detection of an open palm. | GlobalSplay |
The GloveRevision argument of the Animation Slider All OSC Message contains the string value of the glove revision which can be checked to determine whether or not to read the additional control rig slider values supported by that glove.
For glove revisions that don’t support Bend3 sliders on certain fingers, such as Studio Gloves, the OSC arguments for these will be sent as an integer value -2147483648 (the minimum supported value for int32 data type). These values should be interpreted as being null and discarded or ignored by your application.
Since a value of 0 is considered a valid value when determining the state of a bone, your application may opt to store ignored bone values as NaN. Many strongly typed languages require integers to have a value (they can't be null) but this can cause issues if you try and perform arithmetic or logical operations on a NaN value. Programming languages have options for testing for NaN like the C# Double.IsNaN(Double) method which could be used when testing control rig slider data for a specific hand gesture.
The Studio Glove supports up to 12 control rig sliders but does not include values for the Distal bone bend or individual finger splay. Aggregate splay for the entire hand is available by reading the GlobalSplay OSC argument and ThumbSplay is also available. See Animation Slider Types.
The Fidelity Glove supports the full 21 control rig sliders, including Distal bone and per-finger splay.
See Animation Slider Types.
| Glove Metadata | Timecode | PerformerId | Handedness | GloveId | GloveRevision |
|---|---|---|---|---|---|
| OSC Argument Index | 0 | 1 | 2 | 3 | 4 |
| OSC type | integer | integer | integer | string | string |
| Language Type | int32 signed | int32 signed | int32 signed | string | string |
| Format | hhmmssfff | integer value | enum value | ModelSizeHandOther | string value |
| Example | 134255043 | 0 (default performer) |
1 (Left hand) |
A2L230309 | RevG |
| Validation | Min: 0, Max: 2147483647 |
Min: 0, Max: 2147483647 |
Unknown: 0, Left: 1, Right: 2 |
[Status: Rev G] Max Length: 9 characters |
Max Length: 4 characters Studio Glove: RevG Pro Fidelity Glove: RevF |
| Notes | fff in the format represents a 3-digit frame number for the given second. Hand Engine supports up to 120fps data depending on the glove revision and your PC hardware capability. | NOTE: Hand Engine has a maximum limit to the number of performers that can be created, depending on whether Hand Engine Pro or Lite is used. | This OSC attribute should be typecast to an Enum type in your application or programming language. Refer to the validation row to see all possible integer values for constructing the enum. | NOTE: It’s possible that the max length or format of the string may change over time. [Status: Rev G] The handedness (shown in green) can be extracted from the GloveId, however we recommend using the Handedness field for this. Possible values are L and R.[Status: Rev G] The glove size is the character (shown in blue) immediately after the handedness. Possible values are 0, 1, 2, 3, 4 from smallest to largest hand size. Refer to the StretchSense glove size sheet on the store page for approximate dimensions.The remaining characters indicate information about the production of the glove. |
NOTE: The max length may change over time as new glove products are released by StretchSense. |
| [Status: Rev F] Pro Fidelity Glove Notes | WARNING: Rev F Blue Pro Fidelity gloves do not report the GloveId in the same way as other glove models, so you cannot infer the glove size from this OSC argument. |
| Thumb bones | ThumbBend1 | ThumbBend2 | ThumbBend3 | ThumbSplay | |
|---|---|---|---|---|---|
| OSC Argument Index | 5 | 6 | 7 | 8 | |
| OSC type | float | float | float | float | |
| Language Type | float32 signed | float32 signed | float32 signed or integer32 signed | float32 signed | |
| Format | float value | float value | float value or integer if not set | float value | |
| Example | 0.2414209 |
0 |
-2147483648 |
0 |
|
| Validation | Min: 0, Max: 1 |
Min: 0, Max: 1 |
Min: 0, Max: 1 |
[Status: Rev G] Min: 0, Max: 1 [Status: Rev F] Min: -1, Max: 1 |
|
| Notes | - 0: Fully relaxed/extended - 1: Fully bent |
- 0: Fully relaxed/extended - 1: Fully bent WARNING: Thumbs do not have a tracked Intermediate bone. |
The splay of the thumb. A value of 1 usually indicates the user is making a fist. |
||
| [Status: Rev G] Studio Glove Notes | [Status: Rev G] Represents the Distal thumb bone on Studio gloves. | [Status: Rev G] Represents the Distal thumb bone on Studio gloves. | WARNING: Rev G Green ThumbBend3 not present on Studio gloves. - -2147483648: Not present |
||
| [Status: Rev F] Pro Fidelity Glove Notes | [Status: Rev F] Represents the Metacarpal thumb bone on Fidelity gloves. | [Status: Rev F] Represents the Proximal thumb bone on Fidelity gloves. | [Status: Rev F] Represents the Distal thumb bone on Fidelity gloves. - 0: Fully relaxed/extended - 1: Fully bent |
NOTE: Rev F Blue Fidelity gloves can have a negative value for ThumbSplay . |
| Index bones | IndexBend1 | IndexBend2 | IndexBend3 | ||
|---|---|---|---|---|---|
| OSC Argument Index | 9 | 10 | 11 | ||
| OSC type | float | float | float | ||
| Language Type | float32 signed | float32 signed | float32 signed or integer32 signed | ||
| Format | float value to 17 d.p. | float value to 17 d.p. | float value to 17 d.p. or integer if not set | ||
| Example | 0.01531981 |
0.01222975 |
-2147483648 |
||
| Validation | Min: 0, Max: 1 |
Min: 0, Max: 1 |
Min: 0, Max: 1 |
||
| Notes | The Proximal index finger bone. - 0: Fully relaxed/extended - 1: Fully bent |
The Intermediate index finger bone. - 0: Fully relaxed/extended - 1: Fully bent |
The Distal index finger bone. | ||
| [Status: Rev G] Studio Glove Notes | WARNING: Rev G Green Studio Gloves do not have a tracked index Distal bone. - -2147483648: Not present |
||||
| [Status: Rev F] Pro Fidelity Glove Notes | - 0: Fully relaxed/extended - 1: Fully bent |
| Middle bones | MiddleBend1 | MiddleBend2 | MiddleBend3 | ||
|---|---|---|---|---|---|
| OSC Argument Index | 12 | 13 | 14 | ||
| OSC type | float | float | float | ||
| Language Type | float32 signed | float32 signed | float32 signed or integer32 signed | ||
| Format | float value to 17 d.p. | float value to 17 d.p. | float value to 17 d.p. or integer if not set | ||
| Example | 0.01649265 |
0.001687416 |
-2147483648 |
||
| Validation | Min: 0, Max: 1 |
Min: 0, Max: 1 |
Min: 0, Max: 1 |
||
| Notes | The Proximal middle finger bone. - 0: Fully relaxed/extended - 1: Fully bent |
The Intermediate middle finger bone. - 0: Fully relaxed/extended - 1: Fully bent |
The Distal middle finger bone. | ||
| [Status: Rev G] Studio Glove Notes | WARNING: Rev G Green Studio Gloves do not have a tracked middle finger Distal bone. - -2147483648: Not present |
||||
| [Status: Rev F] Pro Fidelity Glove Notes | - 0: Fully relaxed/extended - 1: Fully bent |
| Ring bones | RingBend1 | RingBend2 | RingBend3 | ||
|---|---|---|---|---|---|
| OSC Argument Index | 15 | 16 | 17 | ||
| OSC type | float | float | float | ||
| Language Type | float32 signed | float32 signed | float32 signed or integer32 signed | ||
| Format | float value to 17 d.p. | float value to 17 d.p. | float value to 17 d.p. or integer if not set | ||
| Example | 0.01537265 |
0.002264853 |
-2147483648 |
||
| Validation | Min: 0, Max: 1 |
Min: 0, Max: 1 |
Min: 0, Max: 1 |
||
| Notes | The Proximal ring finger bone. - 0: Fully relaxed/extended - 1: Fully bent |
The Intermediate ring finger bone. - 0: Fully relaxed/extended - 1: Fully bent |
The Distal ring finger bone. | ||
| [Status: Rev G] Studio Glove Notes | WARNING: Rev G Green Studio Gloves do not have a tracked ring finger Distal bone. - -2147483648: Not present |
||||
| [Status: Rev F] Pro Fidelity Glove Notes | - 0: Fully relaxed/extended - 1: Fully bent |
| Pinky bones | PinkyBend1 | PinkyBend2 | PinkyBend3 | ||
|---|---|---|---|---|---|
| OSC Argument Index | 18 | 19 | 20 | ||
| OSC type | float | float | float | ||
| Language Type | float32 signed | float32 signed | float32 signed or integer32 signed | ||
| Format | float value to 17 d.p. | float value to 17 d.p. | float value to 17 d.p. or integer if not set | ||
| Example | 0.01403146 |
0.003964114 |
-2147483648 |
||
| Validation | Min: 0, Max: 1 |
Min: 0, Max: 1 |
Min: 0, Max: 1 |
||
| Notes | The Proximal ring finger bone. - 0: Fully relaxed/extended - 1: Fully bent |
The Intermediate ring finger bone. - 0: Fully relaxed/extended - 1: Fully bent |
The Distal ring finger bone. | ||
| [Status: Rev G] Studio Glove Notes | WARNING: Rev G Green Studio Gloves do not have a tracked ring finger Distal bone. - -2147483648: Not present |
||||
| [Status: Rev F] Pro Fidelity Glove Notes | - 0: Fully relaxed/extended - 1: Fully bent |
| Bone splay | GlobalSplay | IndexSplay | MiddleSplay | RingSplay | PinkySplay |
|---|---|---|---|---|---|
| OSC Argument Index | 21 | 22 | 23 | 24 | 25 |
| OSC type | float | float | float | float | float |
| Language Type | float32 signed or integer32 signed | float32 signed or integer32 signed | float32 signed or integer32 signed | float32 signed or integer32 signed | float32 signed or integer32 signed |
| Format | float value to 17 d.p. or integer if not set | float value to 17 d.p. | float value to 17 d.p. or integer if not set | float value to 17 d.p. or integer if not set | float value to 17 d.p. or integer if not set |
| Example | 0.05598204 |
0.7150055 |
0.008420875 |
0.6059586 |
0.922945 |
| Validation | Min: 0, Max: 1 |
Min: -1, Max: 1 |
Min: -1, Max: 1 |
Min: -1, Max: 1 |
Min: -1, Max: 1 |
| Notes | The aggregate splay of all fingers in the hand, excluding the thumb. | The splay of the index finger in the left and right horizontal direction from the palm facing the user. | The splay of the middle finger in the left and right horizontal direction from the palm facing the user. | The splay of the ring finger in the left and right horizontal direction from the palm facing the user. | The splay of the pinky finger in the left and right horizontal direction from the palm facing the user. |
| [Status: Rev G] Studio Glove Notes | - 0: In relaxed/neutral position - 1: Fingers fully spread outward |
WARNING: Rev G Green Not present in Studio Gloves - -2147483648: Not present |
WARNING: Rev G Green Not present in Studio Gloves - -2147483648: Not present |
WARNING: Rev G Green Not present in Studio Gloves - -2147483648: Not present |
WARNING: Rev G Green Not present in Studio Gloves - -2147483648: Not present |
| [Status: Rev F] Pro Fidelity Glove Notes | WARNING: Rev F Blue Not present in Pro Fidelity Gloves - -2147483648: Not present |
- -1: Splayed left - 0: In relaxed/neutral position - 1: Splayed right |
- -1: Splayed left - 0: In relaxed/neutral position - 1: Splayed right |
- -1: Splayed left - 0: In relaxed/neutral position - 1: Splayed right |
- -1: Splayed left - 0: In relaxed/neutral position - 1: Splayed right |
NOTE: In rare cases it’s possible to overdrive some of the sensors, creating negative values in the control rig sliders. For gloves with individual finger SPLAY, like the Fidelity glove, the SPLAY value can go into the negative range for some fingers. If using control rig sliders to animate a character or hand rig, you may need to apply smoothing and avoid using value clamping to avoid stuttering or jumping between certain hand poses if a bone spends extended time clamped at a 0 value.
NOTE: Some rig slider ranges are impossible for certain end-users to achieve due to their hand shape or disability, so if detecting gestures using control rig sliders, use a customizable threshold of 10-20% and test across a range of users to find a range that works well for your population.
INFO: Control rig slider ranges and value curves can vary between StretchSense glove revisions and sizes, despite the normalization performed by Hand Engine. Consider also testing your application gestures across a range of users, including snug and loose-fitting glove sizes. You may wish to further process control rig slider data, so the curve of the data is consistent when driving your application state if you need to support multiple glove types.
TIP: Use Bend1 and Bend2 control rig sliders for reliable finger bend across all glove types.
The following device OSC addresses have been implemented as part of Open SDK Core which contain device OSC messages for all performers configured in Hand Engine:
/v1/performer/all| Dongle Metadata | PerformerId | IsStaged | PerformerName |
|---|---|---|---|
| OSC Argument Index | 0 | 1 | 2 |
| OSC type | integer | integer | string |
| Language Type | int32 signed | int32 signed | string |
| Format | integer value | boolean value | string value |
| Example | 0 (default performer) |
1 |
Performer1 |
| Validation | Min: 0, Max: 2147483647 |
Not staged: 0, Staged: 1 |
Max Length: 47 characters. Allowed characters: - letters (a-z, A-Z) - numbers (0-9) - symbols: , . _ - ~ ! @ # $ % ^ & + WARNING: Cannot start/end with a space. |
| Notes | NOTE: Hand Engine has a maximum limit to the number of performers that can be created, depending on whether Hand Engine Pro or Lite is used. | This OSC attribute should be typecast to a boolean type in your application or programming language. Refer to the validation row to see all possible integer values for constructing the enum. | NOTE: There is an upper limit on the size of an OSC packet, so very long performer names may cause this field to become truncated. |
Each glove and dongle’s status can also be received to show important information like the BatteryLevel, Handedness and if both gloves are connected to the dongle.
The following device OSC addresses have been implemented as part of Open SDK Core which contain device OSC messages for all devices connected to Hand Engine:
/v1/device/dongle/status - Status for each USB dongle connected to Hand Engine./v1/performer/glove/status - Status for each glove that is connected to a performer in Hand Engine.The GloveRevision OSC Argument contains these possible values as string OSC types:
| Name | String Value |
|---|---|
| Pro Fidelity | RevF |
| Studio | RevG |
/v1/device/dongle/status returns all the dongles connected to Hand Engine.
| Dongle Metadata | DongleId | GloveId | VersionStatus |
|---|---|---|---|
| OSC Argument Index | 0 | 1 | 2 |
| OSC type | string | string | integer |
| Language Type | string | string | int32 signed |
| Format | string value | ModelSizeHandOther | enum value |
| Example | [Status: Rev G] 6&4128014&0&0000 [Status: Rev F] 6&154A4FA3&2&0000 |
A2L230309 | 3 |
| Validation | [Status: Rev G] Max Length: 16 characters [Status: Rev F] Max Length: 17 characters |
[Status: Rev G] Max Length: 9 characters |
Unrecognized: -1 Version Status Error: 0 Version Status Unknown: 1 Version Status Behind: 2 Version Status Up To Date: 3 Version Status Ahead: 4 |
| Notes | NOTE: It’s possible that the max length or format of the string may change over time. [Status: Rev G] The handedness (shown in green) can be extracted from the GloveId, however we recommend using the Handedness field for this. Possible values are L and R.[Status: Rev G] The glove size is the character (shown in blue) immediately after the handedness. Possible values are 0, 1, 2, 3, 4 from smallest to largest hand size. Refer to the StretchSense glove size sheet on the store page for approximate dimensions.The remaining characters indicate information about the production of the glove. |
This OSC attribute should be typecast to an Enum type in your application or programming language. Refer to the validation row to see all possible integer values for constructing the enum. | |
| [Status: Rev F] Pro Fidelity Glove Notes | WARNING: Rev F Blue Pro Fidelity gloves do not report the GloveId in the same way as other glove models, so you cannot infer the glove size from this OSC argument. | VersionStatus |
/v1/performer/glove/status returns all gloves connected to staged performers. In later versions of the Open SDK an additional route will be added to get all gloves connected to Hand Engine, including gloves that are not currently assigned to a performer.
| Performer Glove Metadata | PerformerId | ProfileHandedness | DongleId | GloveId | GloveHandedness |
|---|---|---|---|---|---|
| OSC Argument Index | 0 | 1 | 2 | 3 | 4 |
| OSC type | integer | integer | string | string | integer |
| Language Type | int32 signed | int32 signed | string | string | int32 signed |
| Format | integer value | enum value | string value | ModelSizeHandOther | enum value |
| Example | 0 (default performer) |
1 (Left hand) |
[Status: Rev G] 6&4128014&0&0000 [Status: Rev F] 6&154A4FA3&2&0000 |
A2L230309 | 1 (Left hand) |
| Validation | Min: 0, Max: 2147483647 |
Unknown: 0, Left: 1, Right: 2 |
[Status: Rev G] Max Length: 16 characters [Status: Rev F] Max Length: 17 characters |
[Status: Rev G] Max Length: 9 characters |
Unknown: 0, Left: 1, Right: 2 |
| Notes | NOTE: Hand Engine has a maximum limit to the number of performers that can be created, depending on whether Hand Engine Pro or Lite is used. | This OSC attribute should be typecast to an Enum type in your application or programming language. Refer to the validation row to see all possible integer values for constructing the enum. | NOTE: It’s possible that the max length or format of the string may change over time. [Status: Rev G] The handedness (shown in green) can be extracted from the GloveId, however we recommend using the Handedness field for this. Possible values are L and R.[Status: Rev G] The glove size is the character (shown in blue) immediately after the handedness. Possible values are 0, 1, 2, 3, 4 from smallest to largest hand size. Refer to the StretchSense glove size sheet on the store page for approximate dimensions.The remaining characters indicate information about the production of the glove. |
This OSC attribute should be typecast to an Enum type in your application or programming language. Refer to the validation row to see all possible integer values for constructing the enum. | |
| [Status: Rev F] Pro Fidelity Glove Notes | WARNING: Rev F Blue Pro Fidelity gloves do not report the GloveId in the same way as other glove models, so you cannot infer the glove size from this OSC argument. |
| Glove Metadata | IsCalibrated | GloveRevision | ProductName | FirmwareVersion | VersionStatus |
|---|---|---|---|---|---|
| OSC Argument Index | 5 | 6 | 7 | 8 | 9 |
| OSC type | integer | string | string | string | integer |
| Language Type | int32 signed | string | string | string | int32 signed |
| Format | boolean value | string value | string value | string value | enum value |
| Example | 1 |
RevG |
Studio Glove | [Status: Rev G] 2.1.16 [Status: Rev F] 01.00.02 |
3 |
| Validation | Not calibrated: 0, Calibrated: 1 |
Max Length: 4 characters Studio Glove: RevG Pro Fidelity Glove: RevF |
Studio Glove: Studio Glove Pro Fidelity: Mocap Pro Fidelity |
[Status: Rev G] Max Length: 6 characters [Status: Rev F] Max Length: 8 characters |
Unrecognized: -1 Version Status Error: 0 Version Status Unknown: 1 Version Status Behind: 2 Version Status Up To Date: 3 Version Status Ahead: 4 |
| Notes | This OSC attribute should be typecast to a boolean type in your application or programming language. Refer to the validation row to see all possible integer values for constructing the enum. | NOTE: The max length may change over time as new glove products are released by StretchSense. | NOTE: Use the GloveRevision instead when determining which glove is connected in your application state. Use ProductName for display only. | NOTE: It’s possible that the max length or format of the string may change over time. | This OSC attribute should be typecast to an Enum type in your application or programming language. Refer to the validation row to see all possible integer values for constructing the enum. |
| Glove Hardware Metadata | BatteryLevel | IsSdCardPresent | IsJamSynced | ||
|---|---|---|---|---|---|
| OSC Argument Index | 10 | 11 | 12 | ||
| OSC type | float | integer | integer | ||
| Language Type | float32 signed | int32 signed | int32 signed | ||
| Format | float value | enum value | enum value | ||
| Example | 0.58 |
1 |
0 |
||
| Validation | Min: 0, Max: 1 |
Min: 0, Max: 1 [Status: Rev G] -2147483648: Not present |
Min: 0, Max: 1 [Status: Rev G] -2147483648: Jam sync not supported on this device |
||
| Notes | A max value of 1 indicates the battery is fully charged, a value of 0 indicates the battery is empty. |
||||
| [Status: Rev G] Studio Glove Notes | WARNING: Studio Gloves do not have an SD card slot. | WARNING: Studio Gloves do not support jam sync |
The diagram shown in the Open SDK Core API Diagram section shows accepted OSC message arguments for each OSC address when receiving animation data for one or more calibrated performers.
Retargeted animation data is sent via OSC as each glove data packet comes in from the hardware.
The Animation Bone OSC address will apply a retargeting model based on a currently selected retargeting model of the respective hand. retargeting models are imported by Hand Engine as JSON files from C:\Users\{YOUR_USER}\AppData\Local\Programs\HandEngine-3.0.11-PRO\assets\retargeting where YOUR_USER is the name of your Windows user.
A user can select which retargeting model they want using a dropdown beside each hand in the Hand Engine main screen.
INFO: In a future version of Hand Engine, new custom retargeting models will be created by end users, developers or technical artists using StretchSense provided tools.
These are the core OSC addresses needed for an application to receive glove data and provide a good user experience.
Download Open SDK UML API Diagram.drawio
OSC messages may be received out of order, so all /v1/animation/* messages include a timecode OSC argument. This allows you to timecode sync the resulting messages if you are processing them as part of a larger motion capture system or need accuracy. For most live performance use-cases and for XR the messages should be processable by your application in a timely manner and any delay will be imperceivable by the end user, as long as messages are processed on the background thread.
Note that some Open SDK toggle settings may be unavailable in your version of Hand Engine, depending on your licence entitlements.
4. Close the settings menu.
5. Connect the USB dongle to your PC.
6. Turn on your gloves by pressing the power button on each glove once.
7. Wait for the gloves to start blinking blue at regular intervals.
8. For the left glove, select it from the dropdown menu.
9. If using a VRM character rig in your application, ensure the Retargeting Model is set
default-retargeting-revg for Studio Gloves or default-retargeting-revf for Fidelity gloves.
10. Click Calibrate under the left glove.
Perform the calibration routine for each pose as prompted:
12. Repeat steps 8-11 for the right-hand glove.
0.0.0.0 (all addresses), port 9400.Bind to the server to listen for the /v1/animation/{performerId}/{handedness}/{fingerName}/rotation OSC address, substituting the following variables in the address:
performerId: 0 (the default/first performer)
1 (left hand)Index/v1/animation/{performerId}/{handedness}/{fingerName}/rotationWithMetacarpals OSC address, substituting variables as above and using the HTC-VIVE-Wave-Hands retargeting model.If your OSC library supports processing incoming OSC messages on the background thread, setup handler functions to take these messages and store them in a way that is accessible by your main thread.
TIP: Using the background thread to process data will help avoid overloading the main rendering thread if lots of OSC messages come in at once. This avoids choppy or lagging animation as you perform hand movements in real-time using StretchSense gloves.
This is the preferred approach.
performerId (used to later match the data back to the performer assigned to your animated character when the data is processed on the main thread). If you are planning to sync the data with other full body tracked data sources that use a timecode, you must also store the timecode OSC argument from the OSC message.handedness, fingerName and bone name as the key for later reference e.g. LeftThumbProximal.This is an approach that works with functional programming languages or plugin scripting languages with simpler data types.
handedness and fingerName as the key for later reference.performerId and timecode.
2. Every frame in your game engine or animation software’s animation loop, read the latest values from the stored animation data.
3. (optional) filter the data so it matches the current timecode if you are wanting the animation to sync with another timecode source.
4. For each bone in your character or hand rig, read the list of data classes containing each bones information and find the matching data class instance for the current bone.
5. Apply the data to the bone transform in the game or animation engine.
TIP: Some engines like Unity support efficient and parallel ways to apply data, like using the Unity jobs system to adjust Transform rotations in the background thread , so consider using this where possible. Note that these jobs may be run out of order or in parallel, so they are mainly intended for real-time applications and are perfect for XR apps where application frame rate is critical for a good user experience.
NOTE: You may need powerful PC hardware to ensure all tracking sources can be processed at the desired frame rate, especially for higher rates like 120FPS.
WARNING: It can be hard to hit a 120FPS frame rate on standalone XR headsets with the timecode syncing approach, especially when performed on the main thread. Drop older frames behind the current frame / implement frame skipping with this approach, otherwise the animation of the character or hand rig will lag behind your physical movements.
The same approach to receiving animation rotation data can be applied to the position data for each bone. For some animation systems they rely on positions of each bone instead of rotations in order to calculate frame animation for a character rig.
NOTE: The position data is based on fixed model bone lengths that are the same regardless of what retargeting model has been selected in Hand Engine. The lengths do not change based on StretchSense glove size worn by the end-user, so you cannot infer the hand size or proportions from the animation positions received of each bone.
/v1/animation/{performerId}/{handedness}/{fingerName}/position instead of the animation rotation OSC address.INFO: The GloveID from animation/slider/all or performer/glove/status contains information about the size of the glove which can be used to infer the size of the end-user's hand. You could use this to adjust character rig bone lengths, so the user’s hand is more accurately represented in XR apps. This is especially important in AR apps where the virtual representation of the user’s hand needs to align closely with their real-world hand size for immersion.
Hand Engine sends additional data about the current state of the hand in a simple format that can be used for adjusting the application’s state for the character or hand rig.
There are a number of ways to use animation control rig data in your application or plugin:
In XR applications, the control rig slider values have parity with gesture systems offered by other AR/VR frameworks and can drive the same functionality if a translation layer is created to map these to inputs. For example, the Unity XR Interaction System (XRI) v3.0 or higher supports Input Readers which allow the manual manipulation of the XRI state for selecting or activating objects (e.g. picking up or dropping XRGrabInteractables). While it is possible to integrate with XRI v2.5.x it requires several workarounds due to its reliance on Unity Input System Actions to drive application state, with no easy mechanism for simulating Input System Actions programmatically.
For a basic gesture recognition system within your application, it’s recommended to only detect up to 3 gestures on a single hand. We recommend the following single-handed gestures:
Bend1 sliders at a threshold indicating all fingers are bent. Optionally also check the sliders for the thumb, but you will need to tweak these so it is comfortable for the user and so the gesture can be held reliably, especially when using the gesture to hold objects in the user's hand.Bend1 slider for index finger close to zero at a comfortable level. Other finger sliders for Bend1 should be similar to the Closed hand gesture.To accommodate different users hand range of motion we recommend setting generous slider thresholds when detecting gestures as there may be some variance depending on the user’s calibration or the fit of their glove.
You will also need to debounce rapid changes in gestures in your application if gestures are too similar and wherever possible, give the detected gestures context by using a different gesture set while holding specific objects (e.g. a trigger pull gesture driven by Bend1 of the index finger that animates and activates a trigger while holding a pistol).
Multi-handed gestures can also be implemented as per the above method, but by checking both hands at once. This allows for a larger possible gesture space for driving behavior in your XR app.
TIP: A more advanced native gesture system is coming in future versions of Hand Engine that will be available in the Open SDK.
In animation programs, a plugin could use the control rig sliders to automatically select a hand gesture from a library to add as a keyframe, allowing gestures to be animated quickly outside of a mocap stage in post-production and having the consistency and precision, no matter which artist is producing the animation.
Unity and other animation software supports driving animations using a node graph-based approach. This allows technical artists and animations to have greater control over animation blending based on incoming data. Each control rig slider exposed from animation/slider/all can be mapped to a finger bone rotation to drive the overall blending of an animation.
Aggregating multiple Bend sliders together can be used to animate the bend of a finger, with the animation graph providing final adjustment to avoid issues with mesh penetration or variable bone lengths. This also allows the gloves to drive characters with less than 5 fingers.
Some examples of this include:
Other data can be received and handled from Hand Engine in a similar way to animation rotation data. This includes animation positional data (for bone lengths), dongle/glove data and performer data. Take the same approach to storing this data in data objects or a lookup table in the background thread, then apply this in your main thread.
Here are some ideas for how to use the data. We show an example of this in our Open SDK OSC sample in the StretchSense Plugin for Unity:
/v1/animation/slider/all to make a gesture recognition system for your application. Show an effect when the user makes a peace gesture or a thumbs up.The most expensive OSC addresses to listen to are as follows due to the high rate of messages transmitted based on the StretchSense glove model used:
animation/rotation (60-120Hz per hand, with 5 OSC messages per hand)
animation/rotationWithMetacarpals (60-120Hz per hand, with 5 OSC messages per hand)animation/position (60-120Hz per hand, with 5 OSC messages per hand)animation/slider/all (60-120Hz per hand, with 1 OSC message per hand)StretchSense glove models transmit at different rates, also dependent on your PCs CPU load:
Pro Fidelity: ~120Hz
Unity C#
virtual-cast/OscCore: A performance-oriented OSC library for Unity (github.com). This library avoids garbage collection related issues that other Unity C# libraries have. [Status: Recommended]
| Changelog | Version | Publish Date (YYYY/MM/DD) |
|---|---|---|
| Add note on default OSC port | v1.0.2 | 2024/09/18 |
| Fix pinky bone and bone splay OSC argument indexes in Animation Slider All OSC Message format tables to match actual format output in Hand Engine 3.1.2 or higher. | v1.0.1 | 2024/07/29 |
| Initial version. | v1.0.0 | 2024/05/14 |