Skip to main content

Overview

The IFilter interface is the base class for all filter plugins. Filters process raw tracking data to reduce jitter, apply smoothing, implement deadzones, and perform other transformations before the data reaches the output protocol.

Interface Definition

Methods

initialize()

Initializes the filter and validates configuration.
module_status
Returns status_ok() on success, or error(message) on failure.
Description:
  • Called once when the filter is created
  • Validate settings and parameters
  • Initialize internal state, buffers, or data structures
  • Usually just returns status_ok()
Example:

filter()

Processes tracking data and writes filtered result.
const double*
Input pose array: [TX, TY, TZ, Yaw, Pitch, Roll] in cm/degrees
double*
Output pose array to fill with filtered data in same format
This method is called at 250Hz. Keep it fast and deterministic.
Description:
  • Called at 250Hz from tracking pipeline thread
  • Read from input array, write to output array
  • Apply smoothing, deadzone, or other transformations
  • Manage your own timing (dt) if needed
  • Don’t block or perform heavy computation
Data format:
  • input[TX]: X translation in centimeters
  • input[TY]: Y translation in centimeters
  • input[TZ]: Z translation in centimeters
  • input[Yaw]: Yaw rotation in degrees (-180 to 180)
  • input[Pitch]: Pitch rotation in degrees (-90 to 90)
  • input[Roll]: Roll rotation in degrees (-180 to 180)
Example implementations:

center()

Called when user requests to center/reset tracking. Description:
  • Called from UI thread when center hotkey pressed
  • Reset internal filter state if needed
  • Clear history buffers
  • Default implementation does nothing
Example:

Dialog Interface

register_filter()

Receives a pointer to the active filter instance.
IFilter*
Pointer to the running filter instance
Description:
  • Called from UI thread when filter starts
  • Store pointer for runtime interaction (optional)
  • Usually implemented as empty function
Example:

unregister_filter()

Called when filter is about to be destroyed. Example:

Complete Example

Common Filter Patterns

Reduces high-frequency jitter using exponential moving average.
Ignores small movements to reduce micro-jitter.
Applies more smoothing when moving slowly, less when moving fast.
Optimal estimator combining measurements with predictions.

Handling Rotation Wrap-Around

Rotation angles wrap around at ±180°. Handle this carefully in filters.
Problem: Rotation values jump from 179° to -179° when crossing the boundary. Solution: Detect and handle wrap-around when computing deltas.

Time Management

Filters often need accurate time measurement for velocity-based algorithms:

Performance Tips

See Also