Skip to content

Commit 1e0f30a

Browse files
committed
Fix VIUSyntheticDevice issue
Remove PoseControl dependency to compatible with InputSystem before v1.1 Fix VIUSyntheticXRController left hand not working Add VIUSyntheticXRHMD (with fake eye pose)
1 parent e00eb58 commit 1e0f30a

File tree

2 files changed

+149
-51
lines changed

2 files changed

+149
-51
lines changed

Assets/HTC.UnityPlugin/VRModule/Modules/Editor/UnityEngineVRModuleEditor.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,19 @@ public UnityEngineVRSymbolRequirementCollection()
151151
"PoseControl.cs",
152152
},
153153
});
154+
155+
Add(new VRModuleManagerEditor.SymbolRequirement()
156+
{
157+
symbol = "VIU_UIS_POSE_CONTROL",
158+
reqTypeNames = new string[]
159+
{
160+
"UnityEngine.InputSystem.XR.PoseControl",
161+
},
162+
reqFileNames = new string[]
163+
{
164+
"PoseControl.cs",
165+
},
166+
});
154167
}
155168
}
156169
}

Assets/HTC.UnityPlugin/ViveInputUtility/Scripts/VIUSyntheticDevice.cs

Lines changed: 136 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System;
77
using System.Collections.Generic;
88
using System.Linq;
9+
using System.Runtime.InteropServices;
910
using System.Text.RegularExpressions;
1011
using UnityEngine;
1112
using UnityEngine.InputSystem;
@@ -15,7 +16,9 @@
1516
using UnityEngine.InputSystem.Utilities;
1617
using UnityEngine.InputSystem.XR;
1718
using TrackingState = UnityEngine.XR.InputTrackingState;
19+
#if VIU_UIS_POSE_CONTROL
1820
using UnityPoseControl = UnityEngine.InputSystem.XR.PoseControl;
21+
#endif
1922
#if VIU_OPENXR_PLUGIN_POSE_CONTROL
2023
using OpenXRPoseControl = UnityEngine.XR.OpenXR.Input.PoseControl;
2124
#endif
@@ -26,6 +29,25 @@ public struct VIUSyntheticDeviceState : IInputStateTypeInfo
2629
{
2730
public FourCC format => new FourCC('V', 'I', 'U', 'D');
2831

32+
[StructLayout(LayoutKind.Explicit, Size = kSizeInBytes)]
33+
public struct PoseState : IInputStateTypeInfo
34+
{
35+
internal const int kSizeInBytes = 60;
36+
public FourCC format => new FourCC('P', 'o', 's', 'e');
37+
[FieldOffset(0), InputControl(displayName = "Is Tracked", layout = "Button")]
38+
public bool isTracked;
39+
[FieldOffset(4), InputControl(displayName = "Tracking State", layout = "Integer")]
40+
public TrackingState trackingState;
41+
[FieldOffset(8), InputControl(displayName = "Position", noisy = true)]
42+
public Vector3 position;
43+
[FieldOffset(20), InputControl(displayName = "Rotation", noisy = true)]
44+
public Quaternion rotation;
45+
[FieldOffset(36), InputControl(displayName = "Velocity", noisy = true)]
46+
public Vector3 velocity;
47+
[FieldOffset(48), InputControl(displayName = "Angular Velocity", noisy = true)]
48+
public Vector3 angularVelocity;
49+
}
50+
2951
[InputControl(name = "pose", layout = "Pose")]
3052
public PoseState pose;
3153

@@ -270,7 +292,9 @@ private void OnRoleValueMappingChanged(ViveRole.IMap map, ViveRole.MappingChange
270292
public StickControl pad { get; private set; }
271293
public StickControl joystick { get; private set; }
272294

295+
#if VIU_UIS_POSE_CONTROL
273296
public UnityPoseControl pose { get; private set; }
297+
#endif
274298
#if VIU_OPENXR_PLUGIN_POSE_CONTROL
275299
public OpenXRPoseControl openxr_pose { get; private set; }
276300
#endif
@@ -443,7 +467,7 @@ void IInputUpdateCallbackReceiver.OnUpdate()
443467
middlePinch = ctrlState.GetAxis(ControllerAxis.MiddlePinch),
444468
ringPinch = ctrlState.GetAxis(ControllerAxis.RingPinch),
445469
pinkyPinch = ctrlState.GetAxis(ControllerAxis.PinkyPinch),
446-
pose = new PoseState()
470+
pose = new VIUSyntheticDeviceState.PoseState()
447471
{
448472
isTracked = deviceState.isPoseValid,
449473
trackingState = TrackingState.Position | TrackingState.Rotation | TrackingState.Velocity | TrackingState.AngularVelocity,
@@ -509,10 +533,11 @@ protected override void FinishSetup()
509533
{
510534
base.FinishSetup();
511535

512-
var poseGeneric = GetChildControl("pose");
513-
pose = poseGeneric as UnityPoseControl;
536+
#if VIU_UIS_POSE_CONTROL
537+
pose = GetChildControl("pose") as UnityPoseControl;
538+
#endif
514539
#if VIU_OPENXR_PLUGIN_POSE_CONTROL
515-
openxr_pose = poseGeneric as OpenXRPoseControl;
540+
openxr_pose = GetChildControl("pose") as OpenXRPoseControl;
516541
#endif
517542
isTracked = GetChildControl<ButtonControl>("pose/isTracked");
518543
trackingState = GetChildControl<IntegerControl>("pose/trackingState");
@@ -543,62 +568,134 @@ protected override void FinishSetup()
543568
}
544569
}
545570

571+
[StructLayout(LayoutKind.Explicit, Size = kSizeInBytes)]
546572
public struct VIUSyntheticXRHMDState : IInputStateTypeInfo
547573
{
574+
public const int kSizeInBytes = 120;
548575
public FourCC format => new FourCC('V', 'I', 'U', 'H');
549-
550-
public TrackingState trackingState;
576+
[FieldOffset(0), InputControl(layout = "Button")]
551577
public bool isTracked;
578+
[FieldOffset(4), InputControl(layout = "Integer")]
579+
public TrackingState trackingState;
580+
[FieldOffset(8), InputControl(noisy = true)]
552581
public Vector3 devicePosition;
582+
[FieldOffset(20), InputControl(noisy = true)]
553583
public Quaternion deviceRotation;
554584

585+
[FieldOffset(36), InputControl(noisy = true)]
555586
public Vector3 leftEyePosition;
587+
[FieldOffset(48), InputControl(noisy = true)]
556588
public Quaternion leftEyeRotation;
589+
[FieldOffset(64), InputControl(noisy = true)]
557590
public Vector3 rightEyePosition;
591+
[FieldOffset(76), InputControl(noisy = true)]
558592
public Quaternion rightEyeRotation;
593+
[FieldOffset(92), InputControl(noisy = true)]
559594
public Vector3 centerEyePosition;
595+
[FieldOffset(104), InputControl(noisy = true)]
560596
public Quaternion centerEyeRotation;
561597
}
562598

563-
//[InputControlLayout(displayName = "VIU Synthetic XR HMD", stateType = typeof(VIUSyntheticXRHMDState), hideInUI = true)]
564-
//public class VIUSyntheticXRHMD : XRHMD, IInputUpdateCallbackReceiver
565-
//{
566-
// //private
567-
// private ViveRole.IMap<DeviceRole> roleMap;
568-
569-
// void IInputUpdateCallbackReceiver.OnUpdate()
570-
// {
571-
// if (roleMap == null) { return; }
572-
// var deviceIndex = roleMap.GetMappedDeviceByRoleValue((int)DeviceRole.Hmd);
573-
// var deviceState = VRModule.GetCurrentDeviceState(deviceIndex);
574-
// var UnityEngine.XR.InputDevices.GetDeviceAtXRNode(UnityEngine.XR.XRNode.Head);
575-
// InputSystem.QueueStateEvent(this, new VIUSyntheticXRHMDState()
576-
// {
577-
// isTracked = deviceState.isPoseValid,
578-
// trackingState = TrackingState.Position | TrackingState.Rotation | TrackingState.Velocity | TrackingState.AngularVelocity,
579-
// position = deviceState.position,
580-
// rotation = deviceState.rotation,
581-
// velocity = deviceState.velocity,
582-
// angularVelocity = deviceState.angularVelocity,
583-
// });
584-
// }
585-
586-
// protected override void FinishSetup()
587-
// {
588-
// base.FinishSetup();
589-
590-
// roleMap = ViveRole.GetMap<DeviceRole>();
591-
// }
592-
//}
599+
#if UNITY_EDITOR
600+
[UnityEditor.InitializeOnLoad]
601+
#endif
602+
[InputControlLayout(displayName = "VIU Synthetic XR HMD", stateType = typeof(VIUSyntheticXRHMDState), hideInUI = true)]
603+
public class VIUSyntheticXRHMD : XRHMD, IInputUpdateCallbackReceiver
604+
{
605+
private ViveInput.ICtrlState<DeviceRole> ctrlState;
606+
private static VIUSyntheticXRHMD hmdDevice;
607+
private static readonly RigidPose leftEyeLocalPose = new RigidPose(new Vector3(-0.033f, 0f, 0f), Quaternion.identity);
608+
private static readonly RigidPose rightEyeLocalPose = new RigidPose(new Vector3(0.033f, 0f, 0f), Quaternion.identity);
609+
610+
static VIUSyntheticXRHMD()
611+
{
612+
InputSystem.RegisterLayout<VIUSyntheticXRHMD>();
613+
614+
#if UNITY_EDITOR
615+
if (UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode)
616+
#endif
617+
{
618+
var roleMap = ViveRole.GetMap<DeviceRole>();
619+
620+
HandleDevice(ref hmdDevice, VRModule.IsValidDeviceIndex(roleMap.GetMappedDeviceByRole(DeviceRole.Hmd)));
593621

622+
roleMap.onRoleMappingChanged += (map, arg) =>
623+
{
624+
if (arg.role == DeviceRole.Hmd)
625+
{
626+
HandleDevice(ref hmdDevice, VRModule.IsValidDeviceIndex(arg.currentDeviceIndex));
627+
}
628+
};
629+
}
630+
}
594631

632+
private static void HandleDevice(ref VIUSyntheticXRHMD device, bool connected)
633+
{
634+
try
635+
{
636+
if (connected)
637+
{
638+
if (device == null)
639+
{
640+
device = InputSystem.AddDevice<VIUSyntheticXRHMD>("VIUSyntheticXRHMD");
641+
device.ctrlState = ViveInput.GetState(DeviceRole.Hmd);
642+
}
643+
else
644+
{
645+
InputSystem.AddDevice(device);
646+
}
647+
}
648+
else
649+
{
650+
if (device != null)
651+
{
652+
InputSystem.RemoveDevice(device);
653+
}
654+
}
655+
}
656+
catch (Exception e)
657+
{
658+
Debug.LogException(e);
659+
}
660+
}
661+
662+
void IInputUpdateCallbackReceiver.OnUpdate()
663+
{
664+
if (ctrlState == null) { return; }
665+
666+
var deviceIndex = ctrlState.RoleMap.GetMappedDeviceByRoleValue(ctrlState.RoleValue);
667+
var deviceState = VRModule.GetCurrentDeviceState(deviceIndex);
668+
var leftEyePose = deviceState.pose * leftEyeLocalPose;
669+
var rightEyePose = deviceState.pose * rightEyeLocalPose;
670+
InputSystem.QueueStateEvent(this, new VIUSyntheticXRHMDState()
671+
{
672+
isTracked = deviceState.isPoseValid,
673+
trackingState = TrackingState.Position | TrackingState.Rotation,
674+
devicePosition = deviceState.position,
675+
deviceRotation = deviceState.rotation,
676+
// TODO: should get eye pose from IPD property or eye tracking sdk
677+
leftEyePosition = leftEyePose.pos,
678+
leftEyeRotation = leftEyePose.rot,
679+
rightEyePosition = rightEyePose.pos,
680+
rightEyeRotation = rightEyePose.rot,
681+
centerEyePosition = deviceState.position,
682+
centerEyeRotation = deviceState.rotation,
683+
});
684+
}
685+
}
686+
687+
[StructLayout(LayoutKind.Explicit, Size = kSizeInBytes)]
595688
public struct VIUSyntheticXRControllerState : IInputStateTypeInfo
596689
{
690+
public const int kSizeInBytes = 36;
597691
public FourCC format => new FourCC('V', 'I', 'U', 'C');
598-
599-
public TrackingState trackingState;
692+
[FieldOffset(0), InputControl(layout = "Button")]
600693
public bool isTracked;
694+
[FieldOffset(4), InputControl(layout = "Integer")]
695+
public TrackingState trackingState;
696+
[FieldOffset(8), InputControl(noisy = true)]
601697
public Vector3 devicePosition;
698+
[FieldOffset(20), InputControl(noisy = true)]
602699
public Quaternion deviceRotation;
603700
}
604701

@@ -649,13 +746,7 @@ private static void HandleDevice(ref VIUSyntheticXRController device, HandRole h
649746
if (device == null)
650747
{
651748
device = InputSystem.AddDevice<VIUSyntheticXRController>("VIUSyntheticXRController" + hand.ToString());
652-
//device = InputSystem.AddDevice(new InputDeviceDescription()
653-
//{
654-
// interfaceName = typeof(VIUSyntheticXRController).Name,
655-
// manufacturer = "HTC ViveSoftware",
656-
//}) as VIUSyntheticXRController;
657-
658-
InputSystem.AddDeviceUsage(rightDevice, handStr);
749+
InputSystem.AddDeviceUsage(device, handStr);
659750
device.ctrlState = ViveInput.GetState(hand);
660751
}
661752
else
@@ -690,12 +781,6 @@ void IInputUpdateCallbackReceiver.OnUpdate()
690781
devicePosition = deviceState.position,
691782
deviceRotation = deviceState.rotation,
692783
});
693-
694-
//Debug.Log("IInputUpdateCallbackReceiver.OnUpdate " + name + " "
695-
// + isTracked.ReadValue() + " "
696-
// + trackingState.ReadValue() + " "
697-
// + devicePosition.ReadValue().ToString("0.00") + " "
698-
// + deviceRotation.ReadValue().eulerAngles.ToString("0"));
699784
}
700785
}
701786
}

0 commit comments

Comments
 (0)