-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBhapticsSDK2Wrapper.cs
More file actions
396 lines (351 loc) · 20.3 KB
/
Copy pathBhapticsSDK2Wrapper.cs
File metadata and controls
396 lines (351 loc) · 20.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
/*
* BhapticsSDK2Wrapper.cs
* Copyright bHaptics Inc. All rights reserved
*
* Original Source: https://github.com/bhaptics/tact-csharp2/blob/master/tact-csharp2/tact-csharp2/BhapticsSDK2Wrapper.cs
*
* This is a thoroughly commented and documented version of the above source.
*
* Available Exports (SDK 2.0.0):
* // Initialization & Connection
* bool registryAndInit(string sdkAPIKey, string workspaceId, string initData)
* bool registryAndInitHost(string sdkAPIKey, string workspaceId, string initData, string url)
* bool wsIsConnected()
* void wsClose()
* bool reInitMessage(string sdkAPIKey, string workspaceId, string initData)
*
* // Playback Controls (event-centric with request IDs)
* int play(string eventId)
* int playParam(string eventId, int requestId, float intensity, float duration, float angleX, float offsetY)
* void playWithStartTime(string eventId, int requestId, int startMillis, float intensity, float duration, float angleX, float offsetY)
* int playLoop(string eventId, int requestId, float intensity, float duration, float angleX, float offsetY, int interval, int maxCount)
* int pause(string eventId)
* bool resume(string eventId)
* bool stop(int requestId)
* bool stopByEventId(string eventId)
* bool stopAll()
* bool isPlaying()
* bool isPlayingByRequestId(int requestId)
* bool isPlayingByEventId(string eventId)
*
* // Low-Level Pattern Playback (requestId-first)
* int playDot(int requestId, int position, int durationMillis, int[] motors, int size)
* int playWaveform(int requestId, int position, int[] motorValues, int[] playTimeValues, int[] shapeValues, int motorLen)
* int playPath(int requestId, int position, float[] xValues, float[] yValues, int[] intensityValues, int Len)
*
* // Device & Connectivity Utilities
* bool isbHapticsConnected(int position)
* bool ping(string address)
* bool pingAll()
* bool swapPosition(string address)
* bool setDeviceVsm(string address, int vsm)
* IntPtr getDeviceInfoJson()
*
* // Player Application Controls
* bool isPlayerInstalled()
* bool isPlayerRunning()
* bool launchPlayer(bool tryLaunch)
*
* // Mapping & Timing Retrieval
* int getEventTime(string eventId)
* IntPtr getHapticMappingsJson()
*
* Notes on removed legacy exports (kept here for reference only):
* - playPos, playPosParam -> replaced by playParam(eventId, requestId, ...)
* - playGlove -> removed upstream
* - playWithoutResult -> removed upstream
* - bHapticsGetHapticMessage / bHapticsGetHapticMappings -> replaced by getHapticMappingsJson()
*/
using System;
using System.Runtime.InteropServices;
namespace tact_csharp2
{
/// <summary>
/// Wrapper class for the bHaptics SDK native library functions (bhaptics_library.dll).
/// Provides P/Invoke signatures to interact with the bHaptics haptic feedback system.
/// </summary>
public class BhapticsSDK2Wrapper
{
/// <summary>
/// Name of the native library module (without file extension) to load via DllImport.
/// </summary>
private const string ModuleName = "bhaptics_library";
#region Initialization and Connection
/// <summary>
/// Registers the SDK client and initializes the connection using default host.
/// </summary>
/// <param name="sdkAPIKey">Your bHaptics SDK API key.</param>
/// <param name="workspaceId">Workspace identifier used to segregate sessions.</param>
/// <param name="initData">Initialization parameters in JSON or serialized format.</param>
/// <returns>True if registration and initialization succeed; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool registryAndInit(string sdkAPIKey, string workspaceId, string initData);
/// <summary>
/// Registers and initializes the SDK client, specifying a custom host URL.
/// </summary>
/// <param name="sdkAPIKey">Your bHaptics SDK API key.</param>
/// <param name="workspaceId">Workspace identifier used to segregate sessions.</param>
/// <param name="initData">Initialization parameters in JSON or serialized format.</param>
/// <param name="url">Custom WebSocket server URL (e.g., ws://localhost:9000).</param>
/// <returns>True if registration and initialization succeed; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool registryAndInitHost(string sdkAPIKey, string workspaceId, string initData, string url);
/// <summary>
/// Checks whether the WebSocket connection to the bHaptics service is currently established.
/// </summary>
/// <returns>True if connected; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool wsIsConnected();
/// <summary>
/// Closes the WebSocket connection to the bHaptics service.
/// </summary>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
public static extern void wsClose();
/// <summary>
/// Re-initializes the SDK connection without restarting the entire SDK.
/// </summary>
/// <param name="sdkAPIKey">Your bHaptics SDK API key.</param>
/// <param name="workspaceId">Workspace identifier used to segregate sessions.</param>
/// <param name="initData">Initialization parameters in JSON or serialized format.</param>
/// <returns>True if re-initialization succeeded; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool reInitMessage(string sdkAPIKey, string workspaceId, string initData);
#endregion
#region Playback Controls
/// <summary>
/// Plays a pre-defined haptic event by its string identifier.
/// </summary>
/// <param name="eventId">Identifier for the haptic pattern (event id/key).</param>
/// <returns>Request ID (>0) if playback started; otherwise, negative or zero.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
public static extern int play(string eventId);
/// <summary>
/// Plays a haptic pattern with custom parameters (intensity/duration/rotation/offset).
/// </summary>
/// <param name="eventId">Identifier for the haptic pattern.</param>
/// <param name="requestId">Caller-assigned request identifier used for tracking/stop calls.</param>
/// <param name="intensity">Intensity multiplier (0.0 to 1.0).</param>
/// <param name="duration">Duration multiplier (seconds).</param>
/// <param name="angleX">Rotation angle around X axis for spatial mapping.</param>
/// <param name="offsetY">Vertical offset for spatial mapping.</param>
/// <returns>Request ID (>0) if playback started; otherwise, negative or zero.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
public static extern int playParam(string eventId, int requestId, float intensity, float duration, float angleX, float offsetY);
/// <summary>
/// Plays a haptic pattern starting at a specific time offset, with custom parameters.
/// </summary>
/// <param name="eventId">Identifier for the haptic pattern.</param>
/// <param name="requestId">Caller-assigned request identifier.</param>
/// <param name="startMillis">Start offset in milliseconds from the beginning of the pattern.</param>
/// <param name="intensity">Intensity multiplier (0.0 to 1.0).</param>
/// <param name="duration">Duration multiplier (seconds).</param>
/// <param name="angleX">Rotation angle around X axis for spatial mapping.</param>
/// <param name="offsetY">Vertical offset for spatial mapping.</param>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
public static extern void playWithStartTime(string eventId, int requestId, int startMillis, float intensity, float duration, float angleX, float offsetY);
/// <summary>
/// Plays a looping haptic pattern with specified interval and maximum loop count.
/// </summary>
/// <param name="eventId">Identifier for the haptic pattern.</param>
/// <param name="requestId">Caller-assigned request identifier.</param>
/// <param name="intensity">Intensity multiplier (0.0 to 1.0).</param>
/// <param name="duration">Duration multiplier (seconds).</param>
/// <param name="angleX">Rotation angle around X axis for spatial mapping.</param>
/// <param name="offsetY">Vertical offset for spatial mapping.</param>
/// <param name="interval">Milliseconds between loop iterations.</param>
/// <param name="maxCount">Maximum number of loops (0 for infinite).</param>
/// <returns>Request ID (>0) if playback started; otherwise, negative or zero.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
public static extern int playLoop(string eventId, int requestId, float intensity, float duration, float angleX, float offsetY, int interval, int maxCount);
/// <summary>
/// Pauses a currently playing haptic event by its identifier.
/// </summary>
/// <param name="eventId">Identifier for the haptic pattern to pause.</param>
/// <returns>Status or remaining time depending on native implementation.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
public static extern int pause(string eventId);
/// <summary>
/// Resumes a previously paused haptic event by its identifier.
/// </summary>
/// <param name="eventId">Identifier for the haptic pattern to resume.</param>
/// <returns>True if the event was resumed; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool resume(string eventId);
/// <summary>
/// Stops a specific haptic playback by request ID.
/// </summary>
/// <param name="requestId">Request ID returned from play/playParam/playLoop.</param>
/// <returns>True if playback stopped; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool stop(int requestId);
/// <summary>
/// Stops playback of a haptic event by its event identifier (string id).
/// </summary>
/// <param name="eventId">Event id/key to stop.</param>
/// <returns>True if playback stopped; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool stopByEventId(string eventId);
/// <summary>
/// Stops all active haptic feedback.
/// </summary>
/// <returns>True if all playback stopped; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool stopAll();
/// <summary>
/// Checks if any haptic feedback is currently playing.
/// </summary>
/// <returns>True if any pattern is playing; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool isPlaying();
/// <summary>
/// Checks if a specific request ID is still playing.
/// </summary>
/// <param name="requestId">Request ID to query.</param>
/// <returns>True if still playing; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool isPlayingByRequestId(int requestId);
/// <summary>
/// Checks if a haptic event identified by string id is playing.
/// </summary>
/// <param name="eventId">Event id/key to query.</param>
/// <returns>True if still playing; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool isPlayingByEventId(string eventId);
#endregion
#region Low-Level Pattern Playback
/// <summary>
/// Plays a dot pattern: activates specific motors for a given duration.
/// </summary>
/// <param name="requestId">Caller-assigned request identifier.</param>
/// <param name="position">Device position index.</param>
/// <param name="durationMillis">Duration of each dot in milliseconds.</param>
/// <param name="motors">Array of motor indices to activate.</param>
/// <param name="size">Length of the motors array.</param>
/// <returns>Request ID (>0) if playback started; otherwise, negative or zero.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
public static extern int playDot(int requestId, int position, int durationMillis, int[] motors, int size);
/// <summary>
/// Plays a waveform pattern by specifying motor intensities, play times, and shape values.
/// </summary>
/// <param name="requestId">Caller-assigned request identifier.</param>
/// <param name="position">Device position index.</param>
/// <param name="motorValues">Array of intensity values per motor.</param>
/// <param name="playTimeValues">Array of play durations per motor.</param>
/// <param name="shapeValues">Array specifying waveform shape parameters.</param>
/// <param name="motorLen">Length of the motor arrays.</param>
/// <returns>Request ID (>0) if playback started; otherwise, negative or zero.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
public static extern int playWaveform(int requestId, int position, int[] motorValues, int[] playTimeValues, int[] shapeValues, int motorLen);
/// <summary>
/// Plays a path-based haptic effect by specifying x/y coordinates and intensities.
/// </summary>
/// <param name="requestId">Caller-assigned request identifier.</param>
/// <param name="position">Device position index.</param>
/// <param name="xValues">Array of X-axis coordinates for each point.</param>
/// <param name="yValues">Array of Y-axis coordinates for each point.</param>
/// <param name="intensityValues">Array of intensity values for each point.</param>
/// <param name="Len">Length of the coordinate and intensity arrays.</param>
/// <returns>Request ID (>0) if playback started; otherwise, negative or zero.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
public static extern int playPath(int requestId, int position, float[] xValues, float[] yValues, int[] intensityValues, int Len);
#endregion
#region Device and Connectivity Utilities
/// <summary>
/// Verifies whether a bHaptics device is connected at the given position index.
/// </summary>
/// <param name="position">Device position index (e.g., vest, arms, etc.).</param>
/// <returns>True if device at that position is connected; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool isbHapticsConnected(int position);
/// <summary>
/// Sends a ping to a specific bHaptics device.
/// </summary>
/// <param name="address">Device address to ping.</param>
/// <returns>True if device responded; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool ping(string address);
/// <summary>
/// Sends a ping to all known bHaptics devices.
/// </summary>
/// <returns>True if at least one device responded; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool pingAll();
/// <summary>
/// Swaps the primary and secondary device positions (e.g., left/right swap) for a given address.
/// </summary>
/// <param name="address">Device address to apply swap.</param>
/// <returns>True if swap succeeded; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool swapPosition(string address);
/// <summary>
/// Sets the VSM (vibration sequence mode) for a device.
/// </summary>
/// <param name="address">Device address.</param>
/// <param name="vsm">VSM setting value.</param>
/// <returns>True if the operation succeeded; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool setDeviceVsm(string address, int vsm);
/// <summary>
/// Retrieves connected device information as a JSON string.
/// </summary>
/// <returns>Pointer to a null-terminated C string containing device info in JSON format.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr getDeviceInfoJson();
#endregion
#region Player Application Controls
/// <summary>
/// Checks if the bHaptics Player application is installed on the system.
/// </summary>
/// <returns>True if the Player is installed; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool isPlayerInstalled();
/// <summary>
/// Checks if the bHaptics Player application is currently running.
/// </summary>
/// <returns>True if the Player is running; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool isPlayerRunning();
/// <summary>
/// Launches the bHaptics Player application.
/// </summary>
/// <param name="tryLaunch">True to launch the Player.</param>
/// <returns>True if the operation succeeded; otherwise, false.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool launchPlayer(bool tryLaunch);
#endregion
#region Mapping & Timing Retrieval
/// <summary>
/// Retrieves the event timing metadata for a given event identifier.
/// </summary>
/// <param name="eventId">Event id/key to query timing for.</param>
/// <returns>Integer representing timing data (e.g., duration in ms).</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
public static extern int getEventTime(string eventId);
/// <summary>
/// Retrieves the full JSON payload of haptic mappings from the native library.
/// </summary>
/// <returns>Pointer to a null-terminated C string containing all mappings in JSON format.</returns>
[DllImport(ModuleName, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr getHapticMappingsJson();
#endregion
}
}