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

The WeaverTracker API provides similar data to the EyeTracker in that it tracks the position of the user. The big difference is that there is only one landmark position being communicated. This SR_weaverPosition represents the point between the user's eyes and is used internally to seperate the left from the right image presented to the user.

As a developer you will rarely have to use this interface directly.

Classes

The WeaverTracker interface is an important piece of the SR puzzle.

  • 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.
  • WeaverTracker is an interface providing access to weavertracker data.
  • WeaverPositionStream connects WeaverTracker implementations with user defined WeaverPositionListener implementations.
  • WeaverPositionListener is an interface to be implemented by any components of the user's application that want to receive weavertracker data.
  • SR_weaverPosition defines the actual weavertracker data.

WeaverTracker Data

The SR_weaverPosition is at the center of the WeaverTracker interface, this is what applications can subscribe to.

typedef struct {
uint64_t frameId;
uint64_t time;
SR_point3d weaverPosition;
C-compatible struct containing the weaver position.
Definition: weaverposition.h:20
C-compatible 3d double vector representation.
Definition: types.h:81

WeaverTracker usage

Direct use of the WeaverTracker interface might not be required in your application but is very similar to use of the EyeTracker interface.

A specific listener object is defined, a WeaverTracker is created and attached to the listener as follows.

class WeaverPositionListenerImplementation : public SR::WeaverPositionListener
{
public:
// Ensures WeaverPositionStream is cleaned up when Listener object is out of scope
// The accept function can process the weaver position data as soon as it becomes available
virtual void accept(const SR_weaverPosition& frame) override {
// Use WeaverTracker data
}
};
int main() {
// Create WeaverTracker
SR::SRContext context;
SR::WeaverTracker* weaverTracker = SR::WeaverTracker::create(context);
// Construct listener
WeaverPositionListenerImplementation listener;
listener.stream.set(weaverTracker->openWeaverPositionStream(&listener));
// Start tracking
context.initialize();
// Ensure that the program does not exit immediately.
char inchar;
std::cin >> inchar; //wait for key press
}
Template class to wrap data stream to a listener object.
Definition: inputstream.h:25
Maintains WorldObject and Sense objects during the application lifetime.
Definition: srcontext.h:80
void initialize()
Initialize all senses.
Interface for listening to SR_weaverPosition updates.
Definition: weaverpositionlistener.h:20
virtual void accept(const SR_weaverPosition &frame)=0
Accept an SR_weaverPosition frame.
Sense class which provides weave tracking functionality to the SR system.
Definition: weavertracker.h:40
static WeaverTracker * create(SRContext &context)
Creates a functional WeaverTracker instance.
virtual std::shared_ptr< WeaverPositionStream > openWeaverPositionStream(WeaverPositionListener *listener)=0
Creates a WeaverPositionStream for listener to be connected to.

Prediction

To ensure that your application is as responsive as possible a specific WeaverTracker implementation can be constructed. (this is done by default in the available weaver classes for OpenGL and DirectX) The following is a short description of relevant classes.

  • PredictingWeaverTracker is an implementation of the WeaverTracker interface that offers more control over the filtering of the output values to the application developer.
  • WeaverPositionPredictor is an implementation of the PredictiveFilter<SR_weaverPosition, uint64_t> interface that defines how SR_weaverPosition data is filtered to provide accurate predictions.

PredictingWeaverTracker usage

The PredictingWeaverTracker::create function can be used in exactly the same way as the WeaverTracker::create function but the PredictingWeaverTracker will only provide output to connected WeaverPositionListener instances when one of the predict functions is called.

An application might define the same type of EyePairListener.

class WeaverPositionListenerImplementation : public SR::WeaverPositionListener
{
public:
// Ensures WeaverPositionStream is cleaned up when Listener object is out of scope
// The accept function can process the weaver position data as soon as it becomes available
virtual void accept(const SR_weaverPosition& frame) override {
// Use WeaverTracker data
}
};
int main() {
// Create WeaverTracker
SR::SRContext context;

The WeaverTracker::create call is replaced with PredictingWeaverTracker::create.

// Construct listener
WeaverPositionListenerImplementation listener;
listener.stream.set(weaverTracker->openWeaverPositionStream(&listener));
// Start tracking
context.initialize();
Sense class which provides predictive weaver position tracking functionality.
Definition: predictingweavertracker.h:33
virtual std::shared_ptr< WeaverPositionStream > openWeaverPositionStream(WeaverPositionListener *listener) override
Creates a WeaverPositionStream for listener to be connected to.
static PredictingWeaverTracker * create(SRContext &context)
Returns a class of PredictingWeaverTracker.

To trigger the listener to receive new data the predict function can be called as follows.

// Program loop
while (true) {
weaverTracker->predict(80);
// Sleep in between predictions to simulate actual work being done in between frames
using namespace std::chrono_literals;
std::this_thread::sleep_for(16ms);
}
}
void predict(uint64_t latency, SR_weaverPosition &output)
Predict for a certain latency and trigger stream output Should not be used directly,...

Synchronous use of PredictingWeaverTracker

In the above example, the work associated with filtering will be executed asynchronously. This can be useful to increase parallelization but might be difficult to control.

Since the PredictingWeaverTracker is an EyePairListener implementation. This still maintains a similar structure in your application. A single SR_weaverPosition is derived from the incoming unfiltered SR_eyePair data.

The developer does not have to define their own listener implementation in this case.

int main() {
// Create WeaverTracker
SR::SRContext context;
// Start tracking
context.initialize();
// Program loop
while (true) {
SR_weaverPosition weaverPosition;
weaverTracker->predict(80, eyePair);
// Use WeaverTracker data
// Sleep in between predictions to simulate actual work being done in between frames
using namespace std::chrono_literals;
std::this_thread::sleep_for(16ms);
}
}