You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
12 KiB
206 lines
12 KiB
3 years ago
|
//========= Copyright 2016-2018, HTC Corporation. All rights reserved. ===========
|
||
|
|
||
|
#if VIU_OCULUSVR
|
||
|
using UnityEngine;
|
||
|
using HTC.UnityPlugin.Utility;
|
||
|
using HTC.UnityPlugin.Vive;
|
||
|
#if UNITY_2017_2_OR_NEWER
|
||
|
using UnityEngine.XR;
|
||
|
#else
|
||
|
using XRDevice = UnityEngine.VR.VRDevice;
|
||
|
using XRSettings = UnityEngine.VR.VRSettings;
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
namespace HTC.UnityPlugin.VRModuleManagement
|
||
|
{
|
||
|
public sealed class OculusVRModule : VRModule.ModuleBase
|
||
|
{
|
||
|
#if VIU_OCULUSVR
|
||
|
private static readonly OVRPlugin.Node[] s_index2node;
|
||
|
private static readonly uint[] s_node2index;
|
||
|
private static readonly VRModuleDeviceClass[] s_node2class;
|
||
|
|
||
|
private OVRPlugin.TrackingOrigin m_prevTrackingSpace;
|
||
|
|
||
|
static OculusVRModule()
|
||
|
{
|
||
|
s_index2node = new OVRPlugin.Node[VRModule.MAX_DEVICE_COUNT];
|
||
|
for (int i = 0; i < s_index2node.Length; ++i) { s_index2node[i] = OVRPlugin.Node.None; }
|
||
|
s_index2node[0] = OVRPlugin.Node.Head;
|
||
|
s_index2node[1] = OVRPlugin.Node.HandLeft;
|
||
|
s_index2node[2] = OVRPlugin.Node.HandRight;
|
||
|
s_index2node[3] = OVRPlugin.Node.TrackerZero;
|
||
|
s_index2node[4] = OVRPlugin.Node.TrackerOne;
|
||
|
s_index2node[5] = OVRPlugin.Node.TrackerTwo;
|
||
|
s_index2node[6] = OVRPlugin.Node.TrackerThree;
|
||
|
|
||
|
s_node2index = new uint[(int)OVRPlugin.Node.Count];
|
||
|
for (int i = 0; i < s_node2index.Length; ++i) { s_node2index[i] = INVALID_DEVICE_INDEX; }
|
||
|
s_node2index[(int)OVRPlugin.Node.Head] = 0;
|
||
|
s_node2index[(int)OVRPlugin.Node.HandLeft] = 1;
|
||
|
s_node2index[(int)OVRPlugin.Node.HandRight] = 2;
|
||
|
s_node2index[(int)OVRPlugin.Node.TrackerZero] = 3;
|
||
|
s_node2index[(int)OVRPlugin.Node.TrackerOne] = 4;
|
||
|
s_node2index[(int)OVRPlugin.Node.TrackerTwo] = 5;
|
||
|
s_node2index[(int)OVRPlugin.Node.TrackerThree] = 6;
|
||
|
|
||
|
s_node2class = new VRModuleDeviceClass[(int)OVRPlugin.Node.Count];
|
||
|
for (int i = 0; i < s_node2class.Length; ++i) { s_node2class[i] = VRModuleDeviceClass.Invalid; }
|
||
|
s_node2class[(int)OVRPlugin.Node.Head] = VRModuleDeviceClass.HMD;
|
||
|
s_node2class[(int)OVRPlugin.Node.HandLeft] = VRModuleDeviceClass.Controller;
|
||
|
s_node2class[(int)OVRPlugin.Node.HandRight] = VRModuleDeviceClass.Controller;
|
||
|
s_node2class[(int)OVRPlugin.Node.TrackerZero] = VRModuleDeviceClass.TrackingReference;
|
||
|
s_node2class[(int)OVRPlugin.Node.TrackerOne] = VRModuleDeviceClass.TrackingReference;
|
||
|
s_node2class[(int)OVRPlugin.Node.TrackerTwo] = VRModuleDeviceClass.TrackingReference;
|
||
|
s_node2class[(int)OVRPlugin.Node.TrackerThree] = VRModuleDeviceClass.TrackingReference;
|
||
|
}
|
||
|
|
||
|
public override bool ShouldActiveModule() { return VIUSettings.activateOculusVRModule && XRSettings.enabled && XRSettings.loadedDeviceName == "Oculus"; }
|
||
|
|
||
|
public override void OnActivated()
|
||
|
{
|
||
|
m_prevTrackingSpace = OVRPlugin.GetTrackingOriginType();
|
||
|
UpdateTrackingSpaceType();
|
||
|
}
|
||
|
|
||
|
public override void OnDeactivated()
|
||
|
{
|
||
|
OVRPlugin.SetTrackingOriginType(m_prevTrackingSpace);
|
||
|
}
|
||
|
|
||
|
public override void UpdateTrackingSpaceType()
|
||
|
{
|
||
|
switch (VRModule.trackingSpaceType)
|
||
|
{
|
||
|
case VRModuleTrackingSpaceType.RoomScale:
|
||
|
OVRPlugin.SetTrackingOriginType(OVRPlugin.TrackingOrigin.FloorLevel);
|
||
|
break;
|
||
|
case VRModuleTrackingSpaceType.Stationary:
|
||
|
OVRPlugin.SetTrackingOriginType(OVRPlugin.TrackingOrigin.EyeLevel);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void Update()
|
||
|
{
|
||
|
// set physics update rate to vr render rate
|
||
|
if (VRModule.lockPhysicsUpdateRateToRenderFrequency && Time.timeScale > 0.0f)
|
||
|
{
|
||
|
// FIXME: VRDevice.refreshRate returns zero in Unity 5.6.0 or older version
|
||
|
#if !UNITY_5_6_0 && UNITY_5_6_OR_NEWER
|
||
|
Time.fixedDeltaTime = 1f / XRDevice.refreshRate;
|
||
|
#else
|
||
|
Time.fixedDeltaTime = 1f / 90f;
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override uint GetLeftControllerDeviceIndex()
|
||
|
{
|
||
|
return s_node2index[(int)OVRPlugin.Node.HandLeft];
|
||
|
}
|
||
|
|
||
|
public override uint GetRightControllerDeviceIndex()
|
||
|
{
|
||
|
return s_node2index[(int)OVRPlugin.Node.HandRight];
|
||
|
}
|
||
|
|
||
|
private static RigidPose ToPose(OVRPlugin.Posef value)
|
||
|
{
|
||
|
var ovrPose = value.ToOVRPose();
|
||
|
return new RigidPose(ovrPose.position, ovrPose.orientation);
|
||
|
}
|
||
|
|
||
|
public override void UpdateDeviceState(IVRModuleDeviceState[] prevState, IVRModuleDeviceStateRW[] currState)
|
||
|
{
|
||
|
for (uint i = 0; i < MAX_DEVICE_COUNT; ++i)
|
||
|
{
|
||
|
var node = s_index2node[i];
|
||
|
if (node == OVRPlugin.Node.None) { continue; }
|
||
|
|
||
|
currState[i].isConnected = OVRPlugin.GetNodePresent(node);
|
||
|
|
||
|
if (currState[i].isConnected)
|
||
|
{
|
||
|
if (!prevState[i].isConnected)
|
||
|
{
|
||
|
currState[i].deviceClass = s_node2class[(int)node];
|
||
|
// FIXME: how to get product id from OVRPlugin?
|
||
|
currState[i].serialNumber = OVRPlugin.productName + " " + node.ToString();
|
||
|
currState[i].modelNumber = OVRPlugin.productName + " " + node.ToString();
|
||
|
currState[i].renderModelName = OVRPlugin.productName + " " + node.ToString();
|
||
|
|
||
|
SetupKnownDeviceModel(currState[i]);
|
||
|
}
|
||
|
|
||
|
// update device status
|
||
|
currState[i].pose = ToPose(OVRPlugin.GetNodePose(node, OVRPlugin.Step.Render));
|
||
|
currState[i].velocity = OVRPlugin.GetNodeVelocity(node, OVRPlugin.Step.Render).FromFlippedZVector3f();
|
||
|
currState[i].angularVelocity = OVRPlugin.GetNodeAngularVelocity(node, OVRPlugin.Step.Render).FromFlippedZVector3f();
|
||
|
|
||
|
currState[i].isPoseValid = currState[i].pose != RigidPose.identity;
|
||
|
|
||
|
// update device input
|
||
|
switch (currState[i].deviceModel)
|
||
|
{
|
||
|
case VRModuleDeviceModel.OculusTouchLeft:
|
||
|
{
|
||
|
var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.LTouch);
|
||
|
|
||
|
currState[i].SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.Y) != 0u);
|
||
|
currState[i].SetButtonPress(VRModuleRawButton.A, (ctrlState.Buttons & (uint)OVRInput.RawButton.X) != 0u);
|
||
|
currState[i].SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & (uint)OVRInput.RawButton.LThumbstick) != 0u);
|
||
|
currState[i].SetButtonPress(VRModuleRawButton.Trigger, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.Trigger), ctrlState.LIndexTrigger, 0.55f, 0.45f));
|
||
|
currState[i].SetButtonPress(VRModuleRawButton.Grip, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.Grip), ctrlState.LHandTrigger, 0.55f, 0.45f));
|
||
|
currState[i].SetButtonPress(VRModuleRawButton.CapSenseGrip, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.CapSenseGrip), ctrlState.LHandTrigger, 0.55f, 0.45f));
|
||
|
|
||
|
currState[i].SetButtonTouch(VRModuleRawButton.ApplicationMenu, (ctrlState.Touches & (uint)OVRInput.RawTouch.Y) != 0u);
|
||
|
currState[i].SetButtonTouch(VRModuleRawButton.A, (ctrlState.Touches & (uint)OVRInput.RawTouch.X) != 0u);
|
||
|
currState[i].SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & (uint)OVRInput.RawTouch.LThumbstick) != 0u);
|
||
|
currState[i].SetButtonTouch(VRModuleRawButton.Trigger, (ctrlState.Touches & (uint)OVRInput.RawTouch.LIndexTrigger) != 0u);
|
||
|
currState[i].SetButtonTouch(VRModuleRawButton.CapSenseGrip, AxisToPress(currState[i].GetButtonTouch(VRModuleRawButton.CapSenseGrip), ctrlState.LHandTrigger, 0.25f, 0.20f));
|
||
|
|
||
|
currState[i].SetAxisValue(VRModuleRawAxis.TouchpadX, ctrlState.LThumbstick.x);
|
||
|
currState[i].SetAxisValue(VRModuleRawAxis.TouchpadY, ctrlState.LThumbstick.y);
|
||
|
currState[i].SetAxisValue(VRModuleRawAxis.Trigger, ctrlState.LIndexTrigger);
|
||
|
currState[i].SetAxisValue(VRModuleRawAxis.CapSenseGrip, ctrlState.LHandTrigger);
|
||
|
break;
|
||
|
}
|
||
|
case VRModuleDeviceModel.OculusTouchRight:
|
||
|
{
|
||
|
var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.RTouch);
|
||
|
|
||
|
currState[i].SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.B) != 0u);
|
||
|
currState[i].SetButtonPress(VRModuleRawButton.A, (ctrlState.Buttons & (uint)OVRInput.RawButton.A) != 0u);
|
||
|
currState[i].SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & (uint)OVRInput.RawButton.RThumbstick) != 0u);
|
||
|
currState[i].SetButtonPress(VRModuleRawButton.Trigger, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.Trigger), ctrlState.RIndexTrigger, 0.55f, 0.45f));
|
||
|
currState[i].SetButtonPress(VRModuleRawButton.Grip, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.Grip), ctrlState.RHandTrigger, 0.55f, 0.45f));
|
||
|
currState[i].SetButtonPress(VRModuleRawButton.CapSenseGrip, AxisToPress(currState[i].GetButtonPress(VRModuleRawButton.CapSenseGrip), ctrlState.RHandTrigger, 0.55f, 0.45f));
|
||
|
|
||
|
currState[i].SetButtonTouch(VRModuleRawButton.ApplicationMenu, (ctrlState.Touches & (uint)OVRInput.RawTouch.B) != 0u);
|
||
|
currState[i].SetButtonTouch(VRModuleRawButton.A, (ctrlState.Touches & (uint)OVRInput.RawTouch.A) != 0u);
|
||
|
currState[i].SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & (uint)OVRInput.RawTouch.RThumbstick) != 0u);
|
||
|
currState[i].SetButtonTouch(VRModuleRawButton.Trigger, (ctrlState.Touches & (uint)OVRInput.RawTouch.RIndexTrigger) != 0u);
|
||
|
currState[i].SetButtonTouch(VRModuleRawButton.CapSenseGrip, AxisToPress(currState[i].GetButtonTouch(VRModuleRawButton.CapSenseGrip), ctrlState.RHandTrigger, 0.25f, 0.20f));
|
||
|
|
||
|
currState[i].SetAxisValue(VRModuleRawAxis.TouchpadX, ctrlState.RThumbstick.x);
|
||
|
currState[i].SetAxisValue(VRModuleRawAxis.TouchpadY, ctrlState.RThumbstick.y);
|
||
|
currState[i].SetAxisValue(VRModuleRawAxis.Trigger, ctrlState.RIndexTrigger);
|
||
|
currState[i].SetAxisValue(VRModuleRawAxis.CapSenseGrip, ctrlState.RHandTrigger);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (prevState[i].isConnected)
|
||
|
{
|
||
|
currState[i].Reset();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|