Simulated Reality SDK 7500c78d v1.30.2.51085 2024-04-26T11:23:03Z
Stable
HeadTracker API

The HeadTracker API works similarly to the EyeTracker API, but also exposes the user's head position and orientation and the user's ear positions in addition to the user's eye positions.

Classes

The HeadTracker API consists out of the following classes

  • SRContext is an essential element of any SR application, it maintains a list of all SR components that are in use and cleans them up when the application ends. It also allows different components of the application to share the same Sense implementations.
  • Sense is an interface used by the SRContext to keep track of any input or output devices.
  • HeadTracker is an interface providing access to the data.
  • HeadStream connects HeadTracker implementations with user defined HeadListener implementations.
  • HeadListener is an interface to be implemented by any components of the user's application that want to receive the data.
  • SR_head contains the output data.

Head Pose Data

The SR_head struct is at the center of the HeadTracker interface, this is what applications can subscribe to.

typedef struct {
uint64_t frameId;
uint64_t time;
SR_headPose headPose;
SR_eyePair eyes;
SR_earPair ears;
Definition: head.h:26
C-compatible struct containing the position of two eyes.
Definition: eyepair.h:28
Definition: head.h:16
C-compatible struct containing the position of head.
Definition: head.h:43

The SR_head struct contains the head pose, eye positions and ear positions. For more information on the head pose data, you can take a look at the HeadPoseTracker API. For more information on the eye position data, see the EyeTracker API.

The ear position data is only available through the HeadTracker interface. Currently, the ear positions are simply calculated as a constant offset from the head position, but this may change in the future.

The ear position data is contained in the SR_earPair struct:

typedef struct {
uint64_t frameId;
uint64_t time;
union {
SR_point3d ears[2];
struct {
SR_point3d left;
SR_point3d right;
};
};
C-compatible 3d double vector representation.
Definition: types.h:81

The head positions are relative to the normal SR output coordinate system.

HeadTracker usage

Application developers should define how to handle the head pose data by implementing an HeadListener. It is advisable to include an InputStream<SR::HeadStream> member, this will come into play when the actual head pose tracker is constructed.

class HeadListenerImplementation : public SR::HeadListener
{
public:
// Ensures HeadStream is cleaned up when Listener object is out of scope
// The accept function can process the head data as soon as it becomes available
virtual void accept(const SR_head& frame) override {
// Use head data
}
};
Interface for listening to SR_head updates This interface is supported from Eye Tracker version 1....
Definition: headlistener.h:21
virtual void accept(const SR_head &frame)=0
Accept an SR_head frame.
Template class to wrap data stream to a listener object.
Definition: inputstream.h:25

To get access to head pose data, users will have to construct an SRContext and call the static factory function HeadTracker::create as follows:

int main() {
// Create HeadTracker
SR::SRContext context;
SR::HeadTracker* headTracker = SR::HeadTracker::create(context);
Sense class which provides face tracking functionality to the SR system.
Definition: headtracker.h:36
static HeadTracker * create(SRContext &context)
Creates a functional HeadTracker instance.
Maintains WorldObject and Sense objects during the application lifetime.
Definition: srcontext.h:80

Then we need to construct a listener that follows the desired way of processing the data. By calling set on the InputStream<SR::HeadStream> field we ensure that the stream is destructed correctly when the HeadListenerImplementation goes out of scope. When everything is set up context.initialize() starts using any newly constructed streams to listeners.

// Construct listener
HeadListenerImplementation listener;
listener.stream.set(headTracker->openHeadStream(&listener));
// Start tracking
context.initialize();
virtual std::shared_ptr< HeadStream > openHeadStream(HeadListener *listener)=0
Creates a HeadStream for listener to be connected to.
void initialize()
Initialize all senses.

If the main function of our application returns, all deconstructors will be called and we will no longer receive data. We should ensure that the application remains open as long as we want.

// Ensure that the program does not exit immediately.
char inchar;
std::cin >> inchar; //wait for key press
}