Skip to main content

Key Concepts

Articles

Interhaptics Engine and Providers Initialization

To use the Interhaptics Engine, it must be initialized. The following Engine API should be used for initialization:

/// <summary>
/// Initializes the different components and modules of the Interhaptics Engine:
/// - Haptic Material Manager: module in charge of loading and storing haptic effects
/// - Human Avatar Manager: module in charge of mapping between device, human avatar, and experience
/// - Haptic Event Manager: module in charge of the control of haptic sources
/// </summary>
/// <returns>Always true even if a module is not properly initialized.</returns>
DLLExport bool Init();

To properly finalize the usage of the Interhaptics Engine, it is essential to de-initialize it before quitting the application. The following Engine API is used for de-initialization:

/// <summary>
/// Cleans the different components and modules of the Interhaptics Engine.
/// To be called before the application is quit.
/// </summary>
DLLExport void Quit();

After initializing the Interhaptics Engine, the device providers must also be initialized. All Provider implementations follow a consistent interface that exposes the following APIs:

extern "C"
{
DLLExport bool ProviderInit();
DLLExport bool ProviderIsPresent();
DLLExport bool ProviderClean();
DLLExport void ProviderRenderHaptics();
}

ProviderInit handles the initialization process of the specific device's COM, haptic settings for rendering, and subscription to the Interhaptics Engine. It returns false if the initialization process fails.

ProviderClean is responsible for de-initializing the device's COM, if necessary, and unsubscribing the provider from the Interhaptics Engine. It returns false if the de-initialization process fails.

Please ensure that the Interhaptics Engine and device providers are initialized and de-initialized correctly to guarantee the proper functioning of the haptic system within the application.

Loading .haps Files

Before the Interhaptics Engine can render a haptic effect, the corresponding .haps file must be loaded into the engine. This requires the ability of the game engine to open and read the contents of the .haps file during runtime. It is recommended to treat .haps files as game assets, similar to sound effects and graphical assets.

To load a haptic effect from a .haps file, use the following Engine API call:

/// <summary>
/// Adds the content of an .haps file to the Interhaptics Engine for future use.
/// </summary>
/// <param name="_content">JSON content of the .haps file to be loaded. Needs to follow Interhaptics .haps format.</param>
/// <returns>ID of the haptic effect to be used in other engine calls. -1 if loading failed.</returns>
DLLExport int AddHM(const char* _content);

Haptic Rendering and Provider Loop

The core logic of the Interhaptics Engine involves two main elements: haptic rendering and the device provider loop.

Haptic Rendering

Haptic rendering refers to the computation of haptic buffers during each iteration of the rendering loop, based on the game events. To trigger the rendering of haptic buffers, use the following Engine API call:

/// <summary>
/// To be called in the application main loop to trigger the rendering of all haptic buffers
/// at a specific time. The Interhaptics Engine will compare the current time with the last
/// know value to build buffers large enough to cover frame drops.
/// Can be called from the main thread or in a parallel loop.
/// Must be called at least once before triggering the device update event.
/// </summary>
/// <param name="_curTime">Current time in seconds.</param>
/// <returns></returns>
DLLExport void ComputeAllEvents(double _curTime);

It is important to call ComputeAllEvents() every iteration of the rendering loop, either in the main thread or a parallel thread. This ensures that haptic buffers are generated in real-time based on the subscribed Providers. If no device has subscribed, no buffer will be generated. Refer to the section Interhaptics Engine and Providers Initialization for information on device subscription.

Provider Loop

The provider loop is responsible for rendering the haptic buffers on the devices for playback. All provider implementations follow a common interface, exposing the following APIs:

extern "C"
{
DLLExport bool ProviderInit();
DLLExport bool ProviderIsPresent();
DLLExport bool ProviderClean();
DLLExport void ProviderRenderHaptics();
}

The ProviderRenderHaptics() API triggers the rendering process for the provider by retrieving the necessary haptic buffers, transcoding them if required, and playing them back on the associated device. This API must be called for all targeted devices.

It is mandatory to call ComputeAllEvents() from the Interhaptics Engine before calling ProviderRenderHaptics() for synchronized haptic rendering. Typically, both APIs are implemented in the same loop, with ComputeAllEvents() called before the ProviderRenderHaptics() calls.

Additionally, you can use ProviderIsPresent() to check the availability of the device before triggering haptic playback. This optional step can help improve performance.

Haptic Sources and Targets

Haptic Sources are essential for linking the Interhaptics Engine to the game mechanics. Similar to audio sources, Haptic sources contain references to haptic effects, a list of targets within range of the source, and parameters such as volumes and offsets.

A haptic source must be linked to a loaded haptic effect. Refer to the section Loading .haps Files for details on loading .haps files.

Stopping a source transitions it to an inactive state, where parameters and targets do not need to be redefined when restarting the source. To completely remove a source, use the related ClearEvent APIs.

A target represents a virtual reference to the location of the haptic event. Instead of targeting a specific device, a haptic source targets a region on the human avatar, which can be a single body part or a group of body parts. This system acts as a mapping layer between the haptic experience and the cross-platform ecosystem of haptic devices. It ensures that a implemented haptic experience can be ported to a different haptic system without the need for re-implementing the experience.

Providers declare to the game engine which targets they support. If a haptic source is playing on a target not referenced by any provider, the output can either be ignored or remapped based on requirements.

For more details on the control of haptic sources and construction of targets, please refer to section Engine Control of the documentation.