17using System.Runtime.InteropServices;
25#if (UNITY_IPHONE || UNITY_WEBGL) && !UNITY_EDITOR
26 public const string PLUGIN_LIBRARY =
@"__Internal";
28 public const string PLUGIN_LIBRARY =
@"TiltFiveUnity";
31 internal const int T5_RESULT_SUCCESS = 0;
32 internal const int T5_RESULT_UNKNOWN_ERROR = 1;
34 #region Native Functions
37 [DllImport(PLUGIN_LIBRARY)]
38 internal static extern int SetApplicationInfo(
39 T5_StringUTF8 appName,
41 T5_StringUTF8 appVersion);
43 [DllImport(PLUGIN_LIBRARY)]
44 internal static extern int SetPlatformContext(
45 IntPtr platformContext);
47 [DllImport(PLUGIN_LIBRARY)]
48 [
return: MarshalAs(UnmanagedType.I4)]
51 [DllImport(PLUGIN_LIBRARY)]
52 internal static extern int IsTiltFiveUIRequestingAttention(ref T5_Bool attentionRequested);
55 [DllImport(PLUGIN_LIBRARY)]
56 internal static extern int RefreshGlassesAvailable();
64 [DllImport(PLUGIN_LIBRARY)]
65 internal static extern void SetMaxDesiredGlasses(
byte maxCount);
68 [DllImport(PLUGIN_LIBRARY)]
69 internal static extern int GetGlassesHandles(
71 [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] UInt64[] glassesHandle);
74 [DllImport(PLUGIN_LIBRARY)]
75 internal static extern int GetGlassesFriendlyName(UInt64 glassesHandle, ref T5_StringUTF8 glassesFriendlyName);
78 [DllImport(PLUGIN_LIBRARY)]
79 internal static extern int GetGlassesPose(
81 ref T5_GlassesPose glassesPose,
82 [MarshalAs(UnmanagedType.I4)] T5_GlassesPoseUsage glassesPoseUsage);
85 [DllImport(PLUGIN_LIBRARY)]
86 internal static extern int GetGameboardPoses(UInt64 glassesHandle,
87 [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] T5_GameboardPose[] gameboardPoses,
90 [DllImport(PLUGIN_LIBRARY)]
91 internal static extern int ConfigureCameraStream(UInt64 glassesHandle,
T5_CameraStreamConfig cameraConfig);
93 [DllImport(PLUGIN_LIBRARY)]
94 internal static extern int GetFilledCamImageBuffer(UInt64 glassesHandle, ref
T5_CamImage camImageBuffer);
96 [DllImport(PLUGIN_LIBRARY)]
97 internal static extern int SubmitEmptyCamImageBuffer(UInt64 glassesHandle, IntPtr camImageBuffer, UInt32 bufferSize);
99 [DllImport(PLUGIN_LIBRARY)]
100 internal static extern int CancelCamImageBuffer(UInt64 glassesHandle, IntPtr buffer);
102 [DllImport(PLUGIN_LIBRARY)]
103 internal static extern int GetDewarpedPixelCoordinate(UInt64 glassesHandle, ref
T5_PixelDewarp pixelDewarp);
105#if TILT_FIVE_ENABLE_PROJECTOR_EXTRINSICS_ADJUSTMENTS
106 [DllImport(PLUGIN_LIBRARY)]
107 internal static extern int SetProjectorExtrinsicsAdjustment(UInt64 glassesHandle,
108 [MarshalAs(UnmanagedType.LPArray, SizeConst = 14)]
float[] args);
112 [DllImport(PLUGIN_LIBRARY)]
113 internal static extern int GetGameboardDimensions(
118 [DllImport(PLUGIN_LIBRARY)]
119 internal static extern int GetWandAvailability(
120 UInt64 glassesHandle,
121 ref T5_Bool wandAvailable,
125 [DllImport(PLUGIN_LIBRARY)]
126 internal static extern int ScanForWands();
129 [DllImport(PLUGIN_LIBRARY)]
130 internal static extern int GetControllerState(
131 UInt64 glassesHandle,
133 ref T5_ControllerState controllerState);
135 [DllImport(PLUGIN_LIBRARY)]
136 internal static extern int SendImpulse(UInt64 glassesHandle,
137 [MarshalAs(UnmanagedType.I4)]
ControllerIndex controllerIndex,
float amplitude, ushort duration);
140 [DllImport(PLUGIN_LIBRARY)]
141 internal static extern int QueueStereoImages(UInt64 glassesHandle, T5_FrameInfo frameInfo);
143 [DllImport(PLUGIN_LIBRARY)]
144 internal static extern IntPtr GetSendFrameCallback();
146 [DllImport(PLUGIN_LIBRARY)]
147 internal static extern int GetMaxDisplayDimensions(
148 UInt64 glassesHandle,
149 out UInt16 framebufferWidth,
150 out UInt16 framebufferHeight);
152 [DllImport(PLUGIN_LIBRARY)]
153 internal static extern int GetGlassesIPD(UInt64 glassesHandle, ref
float glassesIPD);
155 [DllImport(PLUGIN_LIBRARY)]
156 internal static extern void UnloadWorkaround();
158#if UNITY_WEBGL && !UNITY_EDITOR
159 [DllImport (
"__Internal")]
160 internal static extern void RegisterPlugin();
163 #endregion Native Functions
171 internal struct T5_Bool
173 private readonly
byte booleanByte;
175 public T5_Bool(
bool boolean)
177 booleanByte = Convert.ToByte(
boolean);
180 public static implicit
operator bool(T5_Bool t5_boolean)
181 => Convert.ToBoolean(t5_boolean.booleanByte);
182 public static implicit
operator T5_Bool(
bool boolean) =>
new T5_Bool(
boolean);
190 [StructLayout(LayoutKind.Sequential)]
191 internal struct T5_Position
193 public float X, Y, Z;
195 public T5_Position(Vector3 position)
202 public static implicit
operator Vector3(T5_Position t5_position)
203 =>
new Vector3(t5_position.X, t5_position.Y, t5_position.Z);
204 public static implicit
operator T5_Position(Vector3 position) =>
new T5_Position(position);
212 [StructLayout(LayoutKind.Sequential)]
213 internal struct T5_Rotation
215 public float W, X, Y, Z;
217 public T5_Rotation(Quaternion rotation)
225 public static implicit
operator Quaternion(T5_Rotation t5_rotation)
226 =>
new Quaternion(t5_rotation.X, t5_rotation.Y, t5_rotation.Z, t5_rotation.W);
227 public static implicit
operator T5_Rotation(Quaternion rotation) =>
new T5_Rotation(rotation);
230 internal struct GlassesHandle : IEquatable<GlassesHandle>
232 private UInt64 glassesHandle;
233 public static implicit
operator UInt64(GlassesHandle handle) => handle.glassesHandle;
234 public static implicit
operator GlassesHandle(UInt64 handle) =>
new GlassesHandle() { glassesHandle = handle };
235 public override int GetHashCode() => glassesHandle.GetHashCode();
236 public bool Equals(GlassesHandle other) => glassesHandle == other.glassesHandle;
237 public override string ToString()
239 return glassesHandle.ToString();
246 [StructLayout(LayoutKind.Sequential)]
247 internal struct T5_GlassesPose
249 public UInt64 TimestampNanos;
251 private T5_Position posOfGLS_STAGE;
252 private T5_Rotation rotationToGLS_STAGE;
254 public GameboardType GameboardType;
256 public Vector3 PosOfGLS_STAGE {
get => posOfGLS_STAGE;
set => posOfGLS_STAGE = value; }
257 public Quaternion RotationToGLS_STAGE {
get => rotationToGLS_STAGE;
set => rotationToGLS_STAGE = value; }
263 [StructLayout(LayoutKind.Sequential)]
264 internal struct T5_GameboardPose
266 public UInt64 TimestampNanos;
268 private T5_Position posOfBOARD_STAGE;
269 private T5_Rotation rotationToBOARD_STAGE;
271 public GameboardType GameboardType;
274 public Vector3 PosOfBOARD_STAGE {
get => posOfBOARD_STAGE;
set => posOfBOARD_STAGE = value; }
275 public Quaternion RotationToBOARD_STAGE {
get => rotationToBOARD_STAGE;
set => rotationToBOARD_STAGE = value; }
285 [StructLayout(LayoutKind.Sequential)]
286 public struct T5_CamImage
288 public UInt16 ImageBufferWidth_PIX;
289 public UInt16 ImageBufferHeight_PIX;
290 public UInt16 ImageBufferStride_PIX;
291 public UInt32 ImageBufferSize_PIX;
292 public IntPtr ImageBuffer;
293 private T5_Position posOfCAM_STAGE;
294 private T5_Rotation rotToCAM_STAGE;
295 public Vector3 PosOfCAM_STAGE {
get => posOfCAM_STAGE;
set => posOfCAM_STAGE = value; }
296 public Quaternion RotToCAM_STAGE {
get => rotToCAM_STAGE;
set => rotToCAM_STAGE = value; }
298 [Obsolete(
"T5_CamImage.PosOfCAM_GBD is deprecated. Please use T5_CamImage.PosOfCAM_STAGE instead.")]
299 public Vector3 PosOfCAM_GBD => PosOfCAM_STAGE;
300 [Obsolete(
"T5_CamImage.RotToCAM_GBD is deprecated. Please use T5_CamImage.RotToCAM_STAGE instead.")]
301 public Quaternion RotToCAM_GBD => RotToCAM_STAGE;
303 public T5_CamImage(UInt16 bufferWidth, UInt16 bufferHeight, UInt16 bufferStride, UInt32 bufferSize)
305 ImageBuffer = IntPtr.Zero;
306 ImageBufferWidth_PIX = bufferWidth;
307 ImageBufferHeight_PIX = bufferHeight;
308 ImageBufferStride_PIX = bufferStride;
309 ImageBufferSize_PIX = bufferSize;
310 posOfCAM_STAGE = Vector3.zero;
311 rotToCAM_STAGE = Quaternion.identity;
318 [StructLayout(LayoutKind.Sequential)]
321 public byte cameraIndex;
322 private T5_Bool streamEnabled;
323 public bool enabled {
get => streamEnabled;
set => streamEnabled = value; }
329 [StructLayout(LayoutKind.Sequential)]
332 public Vector2 pixelCoord_PIX {
get => pixelCoord_PIX;
set => pixelCoord_PIX = value; }
333 public Vector2 pixelCoord_IMG {
get => pixelCoord_IMG;
set => pixelCoord_IMG = value; }
334 public byte cameraIndex;
340 [StructLayout(LayoutKind.Sequential)]
341 internal struct T5_ControllerState
343 [StructLayout(LayoutKind.Sequential)]
348 public static implicit
operator Vector2(
Joystick joystick) =>
new Vector2(joystick.X, joystick.Y);
351 [StructLayout(LayoutKind.Sequential)]
363 public bool T5 {
get => t5;
set => t5 = value; }
364 public bool One {
get => one;
set => one = value; }
365 public bool Two {
get => two;
set => two = value; }
366 public bool Three {
get => three;
set => three = value; }
367 public bool A {
get => a;
set => a = value; }
368 public bool B {
get => b;
set => b = value; }
369 public bool X {
get => x;
set => x = value; }
370 public bool Y {
get => y;
set => y = value; }
371 [Obsolete(
"Buttons.System is deprecated, please use Wandbutton.T5 instead.",
true)]
372 public bool System => T5;
373 [Obsolete(
"Buttons.Z is deprecated, please use Wandbutton.Three instead.",
true)]
374 public bool Z => Three;
377 public UInt64 TimestampNanos;
379 private T5_Bool analogValid;
380 private T5_Bool batteryValid;
381 private T5_Bool buttonsValid;
382 private T5_Bool poseValid;
384 public float Trigger;
389 private T5_Rotation rotToWND_STAGE;
390 private T5_Position aimPos_STAGE;
391 private T5_Position fingertipsPos_STAGE;
392 private T5_Position gripPos_STAGE;
396 public bool AnalogValid {
get => analogValid;
set => analogValid = value; }
397 public bool BatteryValid {
get => batteryValid;
set => batteryValid = value; }
398 public bool ButtonsValid {
get => buttonsValid;
set => buttonsValid = value; }
399 public bool PoseValid {
get => poseValid;
set => poseValid = value; }
401 public Quaternion RotToWND_STAGE {
get => rotToWND_STAGE;
set => rotToWND_STAGE = value; }
402 public Vector3 AimPos_STAGE {
get => aimPos_STAGE;
set => aimPos_STAGE = value; }
403 public Vector3 FingertipsPos_STAGE {
get => fingertipsPos_STAGE;
set => fingertipsPos_STAGE = value; }
404 public Vector3 GripPos_STAGE {
get => gripPos_STAGE;
set => gripPos_STAGE = value; }
412 [StructLayout(LayoutKind.Sequential)]
413 internal struct T5_VCI
415 public float StartX_VCI;
416 public float StartY_VCI;
417 public float Width_VCI;
418 public float Height_VCI;
420 public T5_VCI(Rect rect)
424 Width_VCI = rect.width;
425 Height_VCI = rect.height;
428 public static implicit
operator Rect(T5_VCI vci)
429 =>
new Rect(vci.StartX_VCI, vci.StartY_VCI, vci.Width_VCI, vci.Height_VCI);
430 public static implicit
operator T5_VCI(Rect rect) =>
new T5_VCI(rect);
436 [StructLayout(LayoutKind.Sequential)]
437 internal struct T5_FrameInfo
439 public IntPtr LeftTexHandle;
440 public IntPtr RightTexHandle;
441 public UInt16 TexWidth_PIX;
442 public UInt16 TexHeight_PIX;
444 private T5_Bool isSrgb;
445 private T5_Bool isUpsideDown;
449 private T5_Rotation rotToLVC_STAGE;
450 private T5_Position posOfLVC_STAGE;
452 private T5_Rotation rotToRVC_STAGE;
453 private T5_Position posOfRVC_STAGE;
455 public bool IsSrgb {
get => isSrgb;
set => isSrgb = value; }
456 public bool IsUpsideDown {
get => isUpsideDown;
set => isUpsideDown = value; }
457 public Rect VCI {
get => vci;
set => vci = value; }
458 public Quaternion RotToLVC_STAGE {
get => rotToLVC_STAGE;
set => rotToLVC_STAGE = value; }
459 public Vector3 PosOfLVC_STAGE {
get => posOfLVC_STAGE;
set => posOfLVC_STAGE = value; }
460 public Quaternion RotToRVC_STAGE {
get => rotToRVC_STAGE;
set => rotToRVC_STAGE = value; }
461 public Vector3 PosOfRVC_STAGE {
get => posOfRVC_STAGE;
set => posOfRVC_STAGE = value; }
471 [StructLayout(LayoutKind.Explicit, Pack = 4)]
472 internal struct T5_StringUTF8 : IDisposable
474 [FieldOffset(0)]
private UInt32 maxBufferSize;
475 [FieldOffset(4)]
private UInt32 length;
476 [FieldOffset(8)]
private IntPtr pStringBytesUTF8;
478 public T5_StringUTF8(
string text)
480 pStringBytesUTF8 = IntPtr.Zero;
482 maxBufferSize = 16 * 1024;
487 byte[] textBytesUTF8 = System.Text.Encoding.UTF8.GetBytes(text);
490 length = (UInt32)Math.Min(textBytesUTF8.Length, maxBufferSize);
491 pStringBytesUTF8 = Marshal.AllocHGlobal((
int)maxBufferSize);
494 Marshal.Copy(textBytesUTF8, 0, pStringBytesUTF8, (
int)length);
498 public static implicit
operator string(T5_StringUTF8 t5_StringUTF8)
499 => ToString(t5_StringUTF8);
501 public static implicit
operator T5_StringUTF8(
string text) =>
new T5_StringUTF8(text);
503 private static string ToString(T5_StringUTF8 t5_StringUTF8)
505 if (t5_StringUTF8.pStringBytesUTF8 == IntPtr.Zero)
510 var managedBytes =
new byte[t5_StringUTF8.length];
513 Marshal.Copy(t5_StringUTF8.pStringBytesUTF8, managedBytes, 0, (
int)t5_StringUTF8.length);
514 return System.Text.Encoding.UTF8.GetString(managedBytes);
518 Debug.LogError($
"Failed to copy string from unmanaged memory: {e}");
526 public void Dispose()
530 Marshal.FreeHGlobal(pStringBytesUTF8);
531 pStringBytesUTF8 = IntPtr.Zero;
618 [StructLayout(LayoutKind.Sequential)]
619 public struct T5_GameboardSize
646 public T5_GameboardSize(
float viewableExtentPositiveX,
float viewableExtentNegativeX,
647 float viewableExtentPositiveZ,
float viewableExtentNegativeZ,
648 float viewableExtentPositiveY)
657 [Obsolete(
"This version of the T5_GameboardSize constructor is obsolete. " +
658 "Please use T5_GameboardSize(float viewableExtentPositiveX, float viewableExtentNegativeX, " +
659 "float viewableExtentPositiveZ, float viewableExtentNegativeZ, float viewableExtentPositiveY) instead.",
true)]
660 public T5_GameboardSize(
float playableSpaceX,
float playableSpaceZ,
float borderWidth)
715 internal enum T5_GlassesPoseUsage : Int32
727 GlassesPresentation = 1,
737 SpectatorPresentation = 2,
ServiceCompatibility
Whether the running service is compatible.
ControllerPosition
Points of interest along the wand controller, such as the handle position or wand tip.
@ Fingertips
The typical resting position of the player's fingertips, near the wand joystick and trigger.
@ Aim
The tip of the wand.
@ Grip
The center of the wand handle.
ControllerIndex
Since wands are all physically identical (they have no "handedness"), it doesn't make sense to addres...
@ Right
The wand held in the player's right hand.
@ Left
The wand held in the player's left hand.
GameboardType
The type of Gameboard being tracked by the glasses.
@ GameboardType_None
No Gameboard at all.
@ GameboardType_LE
The LE Gameboard.
@ GameboardType_XE
The XE Gameboard, laid out flat.
@ GameboardType_XE_Raised
The XE Gameboard, folded upward using its kickstand.
T5_Hand
Reported wand hand.
PlayerIndex
The Player index (e.g. Player One, Player Two, etc)
Represents a wrapper on a buffer comtaining a camera image.
Camera Stream Configuration.
Physical dimensions of a gameboard, in meters.
float ViewableExtentNegativeX
The distance in meters from the gameboard origin to the edge of the viewable area in the negative X d...
float ViewableExtentPositiveY
The distance in meters above the gameboard origin that the viewable area extends in the positive Y di...
float ViewableExtentPositiveX
The distance in meters from the gameboard origin to the edge of the viewable area in the positive X d...
float ViewableExtentPositiveZ
The distance in meters from the gameboard origin to the edge of the viewable area in the positive Z d...
float ViewableExtentNegativeZ
The distance in meters from the gameboard origin to the edge of the viewable area in the negative Z d...
Pixel Coordinate Dewarp Wrapper.