55 public class Wand : Singleton<Wand>
57 #region Private Fields
62 private Dictionary<GlassesHandle, WandPair> wandCores =
new Dictionary<GlassesHandle, WandPair>();
70 private static readonly Vector3 DEFAULT_WAND_POSITION_GAME_BOARD_SPACE =
new Vector3(0f, 0.25f, -0.25f);
75 private static readonly Vector3 DEFAULT_WAND_HANDEDNESS_OFFSET_GAME_BOARD_SPACE =
new Vector3(0.125f, 0f, 0f);
84 private static readonly Quaternion DEFAULT_WAND_ROTATION_GAME_BOARD_SPACE = Quaternion.Euler(
new Vector3(-33f, 0f, 0f));
88 private HashSet<GlassesHandle> incomingHandles =
new HashSet<GlassesHandle>();
90 private HashSet<GlassesHandle> lostHandles =
new HashSet<GlassesHandle>();
92 private HashSet<WandCore> lostWands =
new HashSet<WandCore>();
96 private static DateTime lastScanAttempt = System.DateTime.MinValue;
99 private static readonly
double wandScanInterval = 0.5d;
101 private static bool wandAvailabilityErroredOnce =
false;
105 private static int currentFrame = -1;
107 #endregion Private Fields
110 #region Private Structs
112 private struct WandPair
114 public WandCore RightWand;
115 public WandCore LeftWand;
117 public WandPair(WandCore right, WandCore left)
127 switch (controllerIndex)
140 public bool TryGet(
ControllerIndex controllerIndex, out WandCore wandCore)
142 wandCore =
this[controllerIndex];
143 return wandCore !=
null;
147 #endregion Private Structs
150 #region Public Functions
164 if(!
Player.TryGetGlassesHandle(playerIndex, out var glassesHandle)
165 || !Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
166 || !wandPair.TryGet(controllerIndex, out var wandCore))
171 switch (controllerPosition)
174 return wandCore.fingertipsPose_UnityWorldSpace.position;
176 return wandCore.aimPose_UnityWorldSpace.position;
178 return wandCore.Pose_UnityWorldSpace.position;
192 if (!
Player.TryGetGlassesHandle(playerIndex, out var glassesHandle)
193 || !Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
194 || !wandPair.TryGet(controllerIndex, out var wandCore))
196 return Quaternion.identity;
199 return wandCore.Pose_UnityWorldSpace.rotation;
204 if (!
Player.TryGetGlassesHandle(playerIndex, out var glassesHandle)
205 || !Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
206 || !wandPair.TryGet(controllerIndex, out var wandCore))
211 return wandCore.IsTracked;
223 if(!
Player.TryGetGlassesHandle(playerIndex, out var glassesHandle)
224 || !Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
225 || !wandPair.TryGet(controllerIndex, out var wandCore))
231 connected = wandCore.IsConnected;
235#if UNITY_2019_1_OR_NEWER && INPUTSYSTEM_AVAILABLE
248 if(!
Player.TryGetGlassesHandle(playerIndex, out var glassesHandle) || !Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
249 || !wandPair.TryGet(controllerIndex, out var wandCore) || !(wandCore is WandDeviceCore wandDeviceCore))
255 wandDevice = wandDeviceCore.wandDevice;
270 if (!
Player.TryGetGlassesHandle(playerIndex, out var glassesHandle)
271 || !Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
272 || !wandPair.TryGet(controllerIndex, out var wandCore))
279 if (
NativePlugin.SendImpulse(glassesHandle, controllerIndex, amplitude, (UInt16)(Mathf.Clamp(duration, 0.0f, 0.320f) * 1000)) == 0)
288 catch (DllNotFoundException e)
290 Log.
Info(
"Tilt Five library missing. Could not connect to wand: {0}", e.Message);
296 "Failed to send impulse to wand: {0}",
302 #region Deprecated Public Functions
305 [Obsolete(
"Converted to be an internal function.",
true)]
308 Update(playerIndex, wandSettings, scaleSettings, gameBoardSettings);
311 [Obsolete(
"Converted to be an internal function.",
true)]
312 public static void ScanForWands()
317 #endregion Deprecated Public Functions
319 #endregion Public Functions
322 #region Internal Functions
324 internal static void Update(
PlayerIndex playerIndex, WandSettings wandSettings, ScaleSettings scaleSettings, GameBoardSettings gameBoardSettings)
327 if (Player.TryGetGlassesHandle(playerIndex, out var glassesHandle))
329 Update(glassesHandle, wandSettings, scaleSettings, gameBoardSettings);
333 internal static void Update(GlassesHandle glassesHandle, WandSettings wandSettings, ScaleSettings scaleSettings, GameBoardSettings gameBoardSettings)
335 if (Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
336 && wandPair.TryGet(wandSettings.controllerIndex, out var wandCore))
338 wandCore.Update(wandSettings, scaleSettings, gameBoardSettings);
342 internal static void OnDisable()
344 foreach (var wandPair
in Instance.wandCores.Values)
346 wandPair.RightWand?.Dispose();
347 wandPair.LeftWand?.Dispose();
349 Instance.wandCores.Clear();
352 internal static void Scan()
358 var connectedGlassesHandles = Glasses.GetAllConnectedGlassesHandles();
362 var wandCores = Instance.wandCores;
363 var incomingHandles = Instance.incomingHandles;
364 var lostHandles = Instance.lostHandles;
365 var lostWands = Instance.lostWands;
367 incomingHandles.Clear();
372 for (
int i = 0; i < connectedGlassesHandles.Length; i++)
374 var glassesHandle = connectedGlassesHandles[i];
375 incomingHandles.Add(glassesHandle);
377 var rightWandCore = Instance.ObtainWandCore(glassesHandle,
ControllerIndex.Right);
378 var leftWandCore = Instance.ObtainWandCore(glassesHandle,
ControllerIndex.Left);
383 wandCores[glassesHandle] =
new WandPair(rightWandCore, leftWandCore);
387 foreach (var glassesHandle
in wandCores.Keys)
390 if (!incomingHandles.Contains(glassesHandle))
392 lostHandles.Add(glassesHandle);
397 if (wandCores.TryGetValue(glassesHandle, out var wandPair))
400 && (!TryGetWandAvailability(out
bool leftWandConnected, glassesHandle,
ControllerIndex.Left) || !leftWandConnected))
402 lostWands.Add(leftWandCore);
405 && (!TryGetWandAvailability(out
bool rightWandConnected, glassesHandle,
ControllerIndex.Right) || !rightWandConnected))
407 lostWands.Add(rightWandCore);
413 foreach (var lostHandle
in lostHandles)
415 var lostWandPair = wandCores[lostHandle];
419 lostWands.Add(lostRightWand);
424 lostWands.Add(lostLeftWand);
426 wandCores.Remove(lostHandle);
429 foreach (var lostWand
in lostWands)
435 internal static void GetLatestInputs()
440 if (Time.frameCount == currentFrame)
444 currentFrame = Time.frameCount;
446 foreach (var wandPair
in Instance.wandCores.Values)
448 wandPair.RightWand?.GetLatestInputs();
449 wandPair.LeftWand?.GetLatestInputs();
453 internal static bool GetButton(WandButton button, GlassesHandle glassesHandle,
456 if(!Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
457 || !wandPair.TryGet(controllerIndex, out var wandCore))
461 return wandCore.GetButton(button);
464 internal static bool TryGetButton(WandButton button, out
bool pressed,
467 if (!Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
468 || !wandPair.TryGet(controllerIndex, out var wandCore))
474 return wandCore.TryGetButton(button, out pressed);
477 internal static bool GetButtonDown(WandButton button,
480 if (!Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
481 || !wandPair.TryGet(controllerIndex, out var wandCore))
486 return wandCore.GetButtonDown(button);
489 internal static bool TryGetButtonDown(WandButton button, out
bool buttonDown,
492 if (!Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
493 || !wandPair.TryGet(controllerIndex, out var wandCore))
499 return wandCore.TryGetButtonDown(button, out buttonDown);
502 internal static bool GetButtonUp(WandButton button,
505 if (Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
506 || !wandPair.TryGet(controllerIndex, out var wandCore))
513 return wandCore.GetButtonUp(button);
516 internal static bool TryGetButtonUp(WandButton button, out
bool buttonUp,
519 if (!Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
520 || !wandPair.TryGet(controllerIndex, out var wandCore))
528 return wandCore.TryGetButtonUp(button, out buttonUp);
533 if (Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
534 || !wandPair.TryGet(controllerIndex, out var wandCore))
539 return wandCore.GetStickTilt();
542 internal static bool TryGetStickTilt(out Vector2 stickTilt,
545 if (!Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
546 || !wandPair.TryGet(controllerIndex, out var wandCore))
548 stickTilt = Vector2.zero;
552 return wandCore.TryGetStickTilt(out stickTilt);
557 if (!Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
558 || !wandPair.TryGet(controllerIndex, out var wandCore))
563 return wandCore.GetTrigger();
566 internal static bool TryGetTrigger(out
float triggerDisplacement,
569 if (!Instance.wandCores.TryGetValue(glassesHandle, out var wandPair)
570 || !wandPair.TryGet(controllerIndex, out var wandCore))
572 triggerDisplacement = 0f;
576 return wandCore.TryGetTrigger(out triggerDisplacement);
579 internal static bool TryGetWandControlsState(GlassesHandle glassesHandle, out T5_ControllerState? controllerState,
582 int result = NativePlugin.T5_RESULT_UNKNOWN_ERROR;
586 T5_ControllerState state =
new T5_ControllerState();
587 result = NativePlugin.GetControllerState(glassesHandle, controllerIndex, ref state);
588 controllerState = (result == NativePlugin.T5_RESULT_SUCCESS)
590 : (T5_ControllerState?)null;
594 controllerState =
null;
595 Log.Error(e.Message);
598 return result == NativePlugin.T5_RESULT_SUCCESS;
601 #endregion Internal Functions
604 #region Private Functions
606 private static bool TryScanForWands()
608 var currentTime = System.DateTime.Now;
609 var timeSinceLastScan = currentTime - lastScanAttempt;
612 if (timeSinceLastScan.TotalSeconds >= wandScanInterval)
614 int result = NativePlugin.T5_RESULT_UNKNOWN_ERROR;
618 result = NativePlugin.ScanForWands();
620 catch (System.DllNotFoundException e)
623 "Could not connect to Tilt Five plugin to scan for wands: {0}",
628 Log.Error(e.Message);
631 lastScanAttempt = currentTime;
632 return (result == NativePlugin.T5_RESULT_SUCCESS);
638 private static bool TryGetWandAvailability(out
bool connected, GlassesHandle glassesHandle,
ControllerIndex controllerIndex)
640 if (!wandAvailabilityErroredOnce)
644 T5_Bool wandAvailable =
false;
645 int result = NativePlugin.GetWandAvailability(glassesHandle, ref wandAvailable, controllerIndex);
647 if (result == NativePlugin.T5_RESULT_SUCCESS)
649 connected = wandAvailable;
653 catch (DllNotFoundException e)
655 Log.Info(
"Could not connect to Tilt Five plugin for wand: {0}", e.Message);
656 wandAvailabilityErroredOnce =
true;
661 "Failed to connect to Tilt Five plugin for wand availability: {0}",
663 wandAvailabilityErroredOnce =
true;
671 private WandCore ObtainWandCore(GlassesHandle glassesHandle,
ControllerIndex controllerIndex)
673 WandCore wandCore =
null;
674 var glassesAlreadyMonitored = wandCores.TryGetValue(glassesHandle, out var wandPair);
677 if (TryGetWandAvailability(out var wandConnected, glassesHandle, controllerIndex) && wandConnected)
680 if (!glassesAlreadyMonitored || !wandPair.TryGet(controllerIndex, out wandCore))
682#if UNITY_2019_1_OR_NEWER && INPUTSYSTEM_AVAILABLE
683 wandCore =
new WandDeviceCore(glassesHandle, controllerIndex);
685 wandCore =
new WandCore(glassesHandle, controllerIndex);
691 else if(glassesAlreadyMonitored && wandPair.TryGet(controllerIndex, out var lostWandCore))
693 lostWands.Add(lostWandCore);
699 #endregion Private Functions
702 #region Private Classes
707 private class WandCore : TrackableCore<WandSettings, T5_ControllerState>, IDisposable
709 #region Public Fields
711 public readonly GlassesHandle glassesHandle;
714 public Pose fingertipsPose_GameboardSpace =
new Pose(DEFAULT_WAND_POSITION_GAME_BOARD_SPACE, Quaternion.identity);
715 public Pose aimPose_GameboardSpace =
new Pose(DEFAULT_WAND_POSITION_GAME_BOARD_SPACE, Quaternion.identity);
717 public Pose gripPose_UnityWorldSpace => pose_UWRLD;
718 public Pose fingertipsPose_UnityWorldSpace;
719 public Pose aimPose_UnityWorldSpace;
721 protected T5_ControllerState? currentState;
722 protected T5_ControllerState? previousState;
724 #endregion Public Fields
727 #region Public Functions
729 public WandCore(GlassesHandle glassesHandle,
ControllerIndex controllerIndex)
731 this.glassesHandle = glassesHandle;
732 this.controllerIndex = controllerIndex;
734 Glasses.TryGetFriendlyName(glassesHandle, out var friendlyName);
735 Log.Info($
"Glasses {glassesHandle} (\"{friendlyName}\") {Enum.GetName(typeof(ControllerIndex), controllerIndex)} Wand connected");
738 public virtual void GetLatestInputs()
740 previousState = currentState;
744 T5_ControllerState state =
new T5_ControllerState();
746 var result = NativePlugin.GetControllerState(glassesHandle, controllerIndex, ref state);
748 currentState = (result == NativePlugin.T5_RESULT_SUCCESS)
750 : (T5_ControllerState?)null;
755 Log.Error(e.Message);
759 public bool GetButton(WandButton button)
762 return currentState?.GetButton(button) ??
false;
765 public bool TryGetButton(WandButton button, out
bool pressed)
767 pressed = currentState?.GetButton(button) ??
false;
770 return currentState.HasValue;
773 public bool GetButtonDown(WandButton button)
778 var pressed = currentState?.GetButton(button) ??
false;
782 var previouslyPressed = previousState?.GetButton(button) ??
false;
785 if (!previousState.HasValue && currentState.HasValue)
790 return pressed && !previouslyPressed;
793 public bool TryGetButtonDown(WandButton button, out
bool buttonDown)
796 buttonDown = GetButtonDown(button);
797 return currentState.HasValue;
800 public bool GetButtonUp(WandButton button)
804 var pressed = currentState?.GetButton(button) ??
false;
808 var previouslyPressed = previousState?.GetButton(button) ??
false;
811 return previousState.HasValue
812 ? !pressed && previouslyPressed
819 public bool TryGetButtonUp(WandButton button, out
bool buttonUp)
822 buttonUp = GetButtonUp(button);
823 return currentState.HasValue;
826 public Vector2 GetStickTilt()
828 return currentState?.Stick ?? Vector2.zero;
831 public bool TryGetStickTilt(out Vector2 stickTilt)
833 stickTilt = GetStickTilt();
834 return currentState.HasValue;
837 public float GetTrigger()
839 return currentState?.Trigger ?? 0.0f;
842 public bool TryGetTrigger(out
float triggerDisplacement)
844 triggerDisplacement = GetTrigger();
845 return currentState.HasValue;
848 #endregion Public Functions
853 public new void Reset(WandSettings wandSettings)
855 base.Reset(wandSettings);
858 public new virtual void Update(WandSettings wandSettings, ScaleSettings scaleSettings, GameBoardSettings gameBoardSettings)
860 if (wandSettings ==
null)
862 Log.Error(
"WandSettings configuration required for Wand tracking updates.");
866 base.Update(wandSettings, scaleSettings, gameBoardSettings);
869 protected override void SetDefaultPoseGameboardSpace(WandSettings settings)
871 pose_USTAGE = GetDefaultPoseGameboardSpace(settings);
873 fingertipsPose_GameboardSpace = pose_USTAGE;
874 aimPose_GameboardSpace = pose_USTAGE;
877 protected static Pose GetDefaultPoseGameboardSpace(WandSettings settings)
879 Vector3 defaultPosition = DEFAULT_WAND_POSITION_GAME_BOARD_SPACE;
881 defaultPosition += DEFAULT_WAND_HANDEDNESS_OFFSET_GAME_BOARD_SPACE
882 * (settings.controllerIndex == ControllerIndex.Right ? 1f : -1f);
883 return new Pose(defaultPosition, DEFAULT_WAND_ROTATION_GAME_BOARD_SPACE);
886 protected override void SetPoseUnityWorldSpace(ScaleSettings scaleSettings, GameBoardSettings gameBoardSettings)
888 pose_UWRLD = GameboardToWorldSpace(pose_USTAGE, scaleSettings, gameBoardSettings);
889 fingertipsPose_UnityWorldSpace = GameboardToWorldSpace(fingertipsPose_GameboardSpace, scaleSettings, gameBoardSettings);
890 aimPose_UnityWorldSpace = GameboardToWorldSpace(aimPose_GameboardSpace, scaleSettings, gameBoardSettings);
893 protected override bool TryCheckConnected(out
bool connected)
895 if (!wandAvailabilityErroredOnce)
899 T5_Bool wandAvailable =
false;
900 int result = NativePlugin.GetWandAvailability(glassesHandle, ref wandAvailable, controllerIndex);
902 if (result == NativePlugin.T5_RESULT_SUCCESS)
904 isConnected = wandAvailable;
905 connected = wandAvailable;
909 catch (DllNotFoundException e)
911 Log.Info(
"Could not connect to Tilt Five plugin for wand: {0}", e.Message);
912 wandAvailabilityErroredOnce =
true;
917 "Failed to connect to Tilt Five plugin for wand availability: {0}",
919 wandAvailabilityErroredOnce =
true;
928 protected override bool TryGetStateFromPlugin(out T5_ControllerState controllerState, out
bool poseIsValid)
930 if (!TryGetWandControlsState(glassesHandle, out var controllerStateResult, controllerIndex))
933 controllerState =
new T5_ControllerState();
938 controllerState = controllerStateResult.Value;
939 poseIsValid = Glasses.IsTracked(glassesHandle) && controllerState.PoseValid;
944 protected override void SetPoseGameboardSpace(in T5_ControllerState controllerState,
945 WandSettings wandSettings, ScaleSettings scaleSettings, GameBoardSettings gameboardSettings)
961 Vector3 gripPosition_USTAGE = ConvertPosSTAGEToUSTAGE(controllerState.GripPos_STAGE);
962 Vector3 fingertipsPosition_USTAGE = ConvertPosSTAGEToUSTAGE(controllerState.FingertipsPos_STAGE);
963 Vector3 aimPosition_USTAGE = ConvertPosSTAGEToUSTAGE(controllerState.AimPos_STAGE);
964 var rotation_USTAGE = CalculateRotation(controllerState.RotToWND_STAGE);
966 ProcessTrackingData(gripPosition_USTAGE, fingertipsPosition_USTAGE, aimPosition_USTAGE,
967 rotation_USTAGE, wandSettings, scaleSettings, gameboardSettings,
968 out pose_USTAGE, out fingertipsPose_GameboardSpace, out aimPose_GameboardSpace);
978 protected override void SetInvalidPoseGameboardSpace(in T5_ControllerState t5_ControllerState, WandSettings settings, ScaleSettings scaleSettings, GameBoardSettings gameboardSettings)
980 SetPoseGameboardSpace(t5_ControllerState, settings, scaleSettings, gameboardSettings);
983 protected override void SetDrivenObjectTransform(WandSettings wandSettings, ScaleSettings scaleSettings, GameBoardSettings gameBoardSettings)
985 if (wandSettings.GripPoint !=
null)
987 wandSettings.GripPoint.transform.SetPositionAndRotation(gripPose_UnityWorldSpace.position, gripPose_UnityWorldSpace.rotation);
990 if (wandSettings.FingertipPoint !=
null)
992 wandSettings.FingertipPoint.transform.SetPositionAndRotation(fingertipsPose_UnityWorldSpace.position, fingertipsPose_UnityWorldSpace.rotation);
995 if (wandSettings.AimPoint !=
null)
997 wandSettings.AimPoint.transform.SetPositionAndRotation(aimPose_UnityWorldSpace.position, aimPose_UnityWorldSpace.rotation);
1001 public virtual void Dispose()
1003 Log.Info($
"Glasses {glassesHandle} {controllerIndex} Wand disconnected");
1006 #endregion Overrides
1009 #region Private Helper Functions
1011 protected Quaternion CalculateRotation(Quaternion rotToWND_STAGE)
1013 Quaternion rotToDW_STAGE = Quaternion.AngleAxis(90f, Vector3.right);
1014 Quaternion rotToSTAGE_DW = Quaternion.Inverse(rotToDW_STAGE);
1015 Quaternion rotToWND_DW = rotToWND_STAGE * rotToSTAGE_DW;
1016 Quaternion rotToUSTAGE_UWND =
new Quaternion(rotToWND_DW.x, -rotToWND_DW.y, rotToWND_DW.z, rotToWND_DW.w);
1017 return rotToUSTAGE_UWND;
1020 protected void ProcessTrackingData(Vector3 gripPosition_USTAGE, Vector3 fingertipsPosition_USTAGE, Vector3 aimPosition_USTAGE, Quaternion rotToUSTAGE_WND,
1021 WandSettings wandSettings, ScaleSettings scaleSettings, GameBoardSettings gameBoardSettings,
1022 out Pose gripPose_USTAGE, out Pose fingertipsPose_USTAGE, out Pose aimPose_USTAGE)
1024 var incomingGripPose_USTAGE =
new Pose(gripPosition_USTAGE, rotToUSTAGE_WND);
1025 var incomingFingertipsPose_USTAGE =
new Pose(fingertipsPosition_USTAGE, rotToUSTAGE_WND);
1026 var incomingAimPose_USTAGE =
new Pose(aimPosition_USTAGE, rotToUSTAGE_WND);
1035 var staleGripPose_USTAGE = pose_USTAGE;
1036 var staleFingertipsPose_USTAGE = fingertipsPose_GameboardSpace;
1037 var staleAimPose_USTAGE = aimPose_GameboardSpace;
1039 var gripPointOffsetDistance = 0f;
1040 var fingertipsPointOffsetDistance = Mathf.Max((fingertipsPosition_USTAGE - gripPosition_USTAGE).magnitude,
1041 (staleFingertipsPose_USTAGE.position - staleGripPose_USTAGE.position).magnitude);
1042 var aimPointOffsetDistance = Mathf.Max((aimPosition_USTAGE - gripPosition_USTAGE).magnitude,
1043 (staleAimPose_USTAGE.position - staleGripPose_USTAGE.position).magnitude);
1046 gripPose_USTAGE = FilterTrackingPointPose(staleGripPose_USTAGE, staleGripPose_USTAGE, incomingGripPose_USTAGE, gripPointOffsetDistance, wandSettings);
1047 fingertipsPose_USTAGE = FilterTrackingPointPose(staleGripPose_USTAGE, staleFingertipsPose_USTAGE, incomingFingertipsPose_USTAGE, fingertipsPointOffsetDistance, wandSettings);
1048 aimPose_USTAGE = FilterTrackingPointPose(staleGripPose_USTAGE, staleAimPose_USTAGE, incomingAimPose_USTAGE, aimPointOffsetDistance, wandSettings);
1052 protected Pose FilterTrackingPointPose(Pose staleGripPointPose, Pose staleTrackingPointPose,
1053 Pose newTrackingPointPose,
float trackingPointOffsetDistance, WandSettings settings)
1055 if (!isTracked && settings.RejectUntrackedPositionData)
1057 switch (settings.FailureMode)
1061 case TrackableSettings.TrackingFailureMode.FreezePosition:
1065 var extrapolatedPosition = staleGripPointPose.position +
1066 Quaternion.Inverse(newTrackingPointPose.rotation) * Vector3.forward * trackingPointOffsetDistance;
1067 return new Pose(extrapolatedPosition, newTrackingPointPose.rotation);
1068 case TrackableSettings.TrackingFailureMode.FreezePositionAndRotation:
1069 return staleTrackingPointPose;
1070 case TrackableSettings.TrackingFailureMode.SnapToDefault:
1071 return GetDefaultPoseGameboardSpace(settings);
1076 return newTrackingPointPose;
1080 #endregion Private Helper Functions
1083#if UNITY_2019_1_OR_NEWER && INPUTSYSTEM_AVAILABLE
1084 private class WandDeviceCore : WandCore
1086 internal WandDevice wandDevice;
1088 private enum TrackingState :
int
1095 public WandDeviceCore(GlassesHandle glassesHandle, ControllerIndex controllerIndex) : base(glassesHandle, controllerIndex)
1097 if(Glasses.TryGetGlassesDevice(glassesHandle, out var glassesDevice))
1100 Input.AddWandDevice(glassesDevice.PlayerIndex, controllerIndex);
1101 wandDevice = Input.GetWandDevice(glassesDevice.PlayerIndex, controllerIndex);
1102 InputSystem.QueueConfigChangeEvent(wandDevice);
1103 if(controllerIndex == ControllerIndex.Right)
1105 glassesDevice.RightWand = wandDevice;
1109 glassesDevice.LeftWand = wandDevice;
1111 if(TiltFiveManager2.IsInstantiated){
1112 TiltFiveManager2.Instance.RefreshInputDevicePairings();
1117 public override void Dispose()
1121 if (Player.TryGetPlayerIndex(glassesHandle, out var playerIndex))
1123 Input.RemoveWandDevice(playerIndex, controllerIndex);
1127 public override void GetLatestInputs()
1129 base.GetLatestInputs();
1133 if (!wandDevice.added || !wandDevice.enabled)
1138 InputSystem.QueueDeltaStateEvent(wandDevice.TiltFive, currentState.HasValue && currentState.Value.TryGetButton(WandButton.T5));
1139 InputSystem.QueueDeltaStateEvent(wandDevice.One, currentState.HasValue && currentState.Value.TryGetButton(WandButton.One));
1140 InputSystem.QueueDeltaStateEvent(wandDevice.Two, currentState.HasValue && currentState.Value.TryGetButton(WandButton.Two));
1141 InputSystem.QueueDeltaStateEvent(wandDevice.Three, currentState.HasValue && currentState.Value.TryGetButton(WandButton.Three));
1142 InputSystem.QueueDeltaStateEvent(wandDevice.A, currentState.HasValue && currentState.Value.TryGetButton(WandButton.A));
1143 InputSystem.QueueDeltaStateEvent(wandDevice.B, currentState.HasValue && currentState.Value.TryGetButton(WandButton.B));
1144 InputSystem.QueueDeltaStateEvent(wandDevice.X, currentState.HasValue && currentState.Value.TryGetButton(WandButton.X));
1145 InputSystem.QueueDeltaStateEvent(wandDevice.Y, currentState.HasValue && currentState.Value.TryGetButton(WandButton.Y));
1147 InputSystem.QueueDeltaStateEvent(wandDevice.Stick, currentState.HasValue ? currentState.Value.TryGetStick() : Vector2.zero);
1148 InputSystem.QueueDeltaStateEvent(wandDevice.Trigger, currentState.HasValue ? currentState.Value.TryGetTrigger() : 0f);
1151 protected override void SetDrivenObjectTransform(WandSettings wandSettings, ScaleSettings scaleSettings, GameBoardSettings gameBoardSettings)
1153 base.SetDrivenObjectTransform(wandSettings, scaleSettings, gameBoardSettings);
1157 if (!wandDevice.added || !wandDevice.enabled)
1163 QueueDeltaStateEvent(wandDevice.devicePosition, pose_UWRLD.position);
1164 QueueDeltaStateEvent(wandDevice.FingertipsPosition, fingertipsPose_UnityWorldSpace.position);
1165 QueueDeltaStateEvent(wandDevice.AimPosition, aimPose_UnityWorldSpace.position);
1167 QueueDeltaStateEvent(wandDevice.RawGripPosition, pose_USTAGE.position);
1168 QueueDeltaStateEvent(wandDevice.RawFingertipsPosition, fingertipsPose_GameboardSpace.position);
1169 QueueDeltaStateEvent(wandDevice.RawAimPosition, aimPose_GameboardSpace.position);
1171 QueueDeltaStateEvent(wandDevice.deviceRotation, pose_UWRLD.rotation);
1172 QueueDeltaStateEvent(wandDevice.RawRotation, pose_USTAGE.rotation);
1174 InputSystem.QueueDeltaStateEvent(wandDevice.isTracked, isTracked);
1176 var trackingState = TrackingState.Tracking;
1179 trackingState = wandSettings.FailureMode == TrackableSettings.TrackingFailureMode.FreezePosition
1180 ? TrackingState.Limited
1181 : TrackingState.None;
1184 InputSystem.QueueDeltaStateEvent(wandDevice.trackingState, (
int)trackingState);
1187 private static void QueueDeltaStateEvent(Vector3Control vector3Control, Vector3 delta)
1189 InputSystem.QueueDeltaStateEvent(vector3Control.x, delta.x);
1190 InputSystem.QueueDeltaStateEvent(vector3Control.y, delta.y);
1191 InputSystem.QueueDeltaStateEvent(vector3Control.z, delta.z);
1196 private static void QueueDeltaStateEvent(QuaternionControl quaternionControl, Quaternion delta)
1198 InputSystem.QueueDeltaStateEvent(quaternionControl.w, delta.w);
1199 InputSystem.QueueDeltaStateEvent(quaternionControl.x, delta.x);
1200 InputSystem.QueueDeltaStateEvent(quaternionControl.y, delta.y);
1201 InputSystem.QueueDeltaStateEvent(quaternionControl.z, delta.z);
1206 #endregion Private Classes
1209 #region Public Classes
1246 public class WaitUntilWandConnected : CustomYieldInstruction
1256 this.playerIndex = playerIndex;
1257 this.controllerIndex = controllerIndex;