2021년 4학년 1학기 기업연계프로젝트2 컴퓨터소프트웨어공학과 <원광투어팀> 팀장 : 송유진 팀원 : 김나영, 이경희, 한유진
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.
 
 
 
 
 

469 lines
24 KiB

//========= Copyright 2016-2020, HTC Corporation. All rights reserved. ===========
using HTC.UnityPlugin.Utility;
#if VIU_OCULUSVR
using UnityEngine;
using HTC.UnityPlugin.Vive;
using HTC.UnityPlugin.Vive.OculusVRExtension;
#if UNITY_2017_2_OR_NEWER
using UnityEngine.XR;
#else
using XRDevice = UnityEngine.VR.VRDevice;
using XRSettings = UnityEngine.VR.VRSettings;
#endif
#if VIU_XR_GENERAL_SETTINGS
using UnityEngine.XR.Management;
using UnityEngine.SpatialTracking;
#endif
#endif
namespace HTC.UnityPlugin.VRModuleManagement
{
public partial class VRModule : SingletonBehaviour<VRModule>
{
public static readonly bool isOculusVRPluginDetected =
#if VIU_OCULUSVR
true;
#else
false;
#endif
public static readonly bool isOculusVRDesktopSupported =
#if VIU_OCULUSVR_DESKTOP_SUPPORT
true;
#else
false;
#endif
public static readonly bool isOculusVRAndroidSupported =
#if VIU_OCULUSVR_ANDROID_SUPPORT
true;
#else
false;
#endif
public static readonly bool isOculusVRAvatarSupported =
#if VIU_OCULUSVR_AVATAR
true;
#else
false;
#endif
}
public sealed class OculusVRModule : VRModule.ModuleBase
{
public override int moduleOrder { get { return (int)DefaultModuleOrder.OculusVR; } }
public override int moduleIndex { get { return (int)VRModuleSelectEnum.OculusVR; } }
public const string OCULUS_XR_LOADER_NAME = "Oculus Loader";
public const string OCULUS_XR_LOADER_CLASS_NAME = "OculusLoader";
#if VIU_OCULUSVR
private class CameraCreator : VRCameraHook.CameraCreator
{
public override bool shouldActive { get { return s_moduleInstance == null ? false : s_moduleInstance.isActivated; } }
public override void CreateCamera(VRCameraHook hook)
{
#if UNITY_2019_3_OR_NEWER && VIU_XR_GENERAL_SETTINGS
if (hook.GetComponent<TrackedPoseDriver>() == null)
{
hook.gameObject.AddComponent<TrackedPoseDriver>();
}
#endif
}
}
#endif
#if VIU_OCULUSVR_1_32_0_OR_NEWER || VIU_OCULUSVR_1_36_0_OR_NEWER || VIU_OCULUSVR_1_37_0_OR_NEWER
private class RenderModelCreator : RenderModelHook.RenderModelCreator
{
private uint m_index = INVALID_DEVICE_INDEX;
private VIUOculusVRRenderModel m_model;
public override bool shouldActive { get { return s_moduleInstance == null ? false : s_moduleInstance.isActivated; } }
public override void UpdateRenderModel()
{
if (!ChangeProp.Set(ref m_index, hook.GetModelDeviceIndex())) { return; }
if (VRModule.IsValidDeviceIndex(m_index))
{
// create object for render model
if (m_model == null)
{
var go = new GameObject("Model");
go.transform.SetParent(hook.transform, false);
m_model = go.AddComponent<VIUOculusVRRenderModel>();
}
// set render model index
m_model.gameObject.SetActive(true);
m_model.shaderOverride = hook.overrideShader;
#if VIU_OCULUSVR_1_32_0_OR_NEWER || VIU_OCULUSVR_1_36_0_OR_NEWER
m_model.gameObject.AddComponent(System.Type.GetType("OvrAvatarTouchController"));
#endif
m_model.SetDeviceIndex(m_index);
}
else
{
// deacitvate object for render model
if (m_model != null)
{
m_model.gameObject.SetActive(false);
}
}
}
public override void CleanUpRenderModel()
{
if (m_model != null)
{
Object.Destroy(m_model.gameObject);
m_model = null;
m_index = INVALID_DEVICE_INDEX;
}
}
}
private static OculusVRModule s_moduleInstance;
#endif
#if VIU_OCULUSVR
public const int VALID_NODE_COUNT = 7;
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[VALID_NODE_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()
{
#if UNITY_2019_3_OR_NEWER && VIU_XR_GENERAL_SETTINGS
return VIUSettings.activateOculusVRModule && (UnityXRModule.HasActiveLoader(OCULUS_XR_LOADER_NAME) ||
XRSettings.enabled && XRSettings.loadedDeviceName == "Oculus");
#else
return VIUSettings.activateOculusVRModule && XRSettings.enabled && XRSettings.loadedDeviceName == "Oculus";
#endif
}
public override void OnActivated()
{
m_prevTrackingSpace = OVRPlugin.GetTrackingOriginType();
UpdateTrackingSpaceType();
EnsureDeviceStateLength(VALID_NODE_COUNT);
#if VIU_OCULUSVR_1_32_0_OR_NEWER || VIU_OCULUSVR_1_36_0_OR_NEWER || VIU_OCULUSVR_1_37_0_OR_NEWER
s_moduleInstance = this;
#endif
}
public override void OnDeactivated()
{
OVRPlugin.SetTrackingOriginType(m_prevTrackingSpace);
}
public override void UpdateTrackingSpaceType()
{
switch (VRModule.trackingSpaceType)
{
case VRModuleTrackingSpaceType.RoomScale:
#if !VIU_OCULUSVR_19_0_OR_NEWER
if (OVRPlugin.GetSystemHeadsetType().Equals(OVRPlugin.SystemHeadset.Oculus_Go))
{
OVRPlugin.SetTrackingOriginType(OVRPlugin.TrackingOrigin.EyeLevel);
}
else
#endif
{
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 BeforeRenderUpdate()
{
FlushDeviceState();
for (uint i = 0u, imax = GetDeviceStateLength(); i < imax; ++i)
{
var node = s_index2node[i];
if (node == OVRPlugin.Node.None) { continue; }
IVRModuleDeviceState prevState;
IVRModuleDeviceStateRW currState;
EnsureValidDeviceState(i, out prevState, out currState);
if (!OVRPlugin.GetNodePresent(node))
{
if (prevState.isConnected)
{
currState.Reset();
}
continue;
}
// update device connected state
if (!prevState.isConnected)
{
var platform = OVRPlugin.GetSystemHeadsetType();
var ovrProductName = platform.ToString();
var deviceClass = s_node2class[(int)node];
currState.isConnected = true;
currState.deviceClass = deviceClass;
// FIXME: how to get device id from OVRPlugin?
currState.modelNumber = ovrProductName + " " + deviceClass;
currState.renderModelName = ovrProductName + " " + deviceClass;
currState.serialNumber = ovrProductName + " " + node;
switch (deviceClass)
{
case VRModuleDeviceClass.HMD:
currState.deviceModel = VRModuleDeviceModel.OculusHMD;
break;
case VRModuleDeviceClass.TrackingReference:
currState.deviceModel = VRModuleDeviceModel.OculusSensor;
break;
case VRModuleDeviceClass.Controller:
switch (platform)
{
#if !VIU_OCULUSVR_19_0_OR_NEWER
case OVRPlugin.SystemHeadset.Oculus_Go:
currState.deviceModel = VRModuleDeviceModel.OculusGoController;
currState.input2DType = VRModuleInput2DType.TouchpadOnly;
break;
case OVRPlugin.SystemHeadset.GearVR_R320:
case OVRPlugin.SystemHeadset.GearVR_R321:
case OVRPlugin.SystemHeadset.GearVR_R322:
case OVRPlugin.SystemHeadset.GearVR_R323:
case OVRPlugin.SystemHeadset.GearVR_R324:
case OVRPlugin.SystemHeadset.GearVR_R325:
currState.deviceModel = VRModuleDeviceModel.OculusGearVrController;
currState.input2DType = VRModuleInput2DType.TouchpadOnly;
break;
#endif
case OVRPlugin.SystemHeadset.Rift_DK1:
case OVRPlugin.SystemHeadset.Rift_DK2:
case OVRPlugin.SystemHeadset.Rift_CV1:
switch (node)
{
case OVRPlugin.Node.HandLeft:
currState.deviceModel = VRModuleDeviceModel.OculusTouchLeft;
break;
case OVRPlugin.Node.HandRight:
default:
currState.deviceModel = VRModuleDeviceModel.OculusTouchRight;
break;
}
currState.input2DType = VRModuleInput2DType.JoystickOnly;
break;
#if VIU_OCULUSVR_16_0_OR_NEWER
case OVRPlugin.SystemHeadset.Oculus_Link_Quest:
#endif
#if VIU_OCULUSVR_1_37_0_OR_NEWER
case OVRPlugin.SystemHeadset.Oculus_Quest:
case OVRPlugin.SystemHeadset.Rift_S:
switch (node)
{
case OVRPlugin.Node.HandLeft:
currState.deviceModel = VRModuleDeviceModel.OculusQuestControllerLeft;
break;
case OVRPlugin.Node.HandRight:
default:
currState.deviceModel = VRModuleDeviceModel.OculusQuestControllerRight;
break;
}
currState.input2DType = VRModuleInput2DType.JoystickOnly;
break;
#endif
}
break;
}
}
// update device pose
currState.pose = ToPose(OVRPlugin.GetNodePose(node, OVRPlugin.Step.Render));
currState.velocity = OVRPlugin.GetNodeVelocity(node, OVRPlugin.Step.Render).FromFlippedZVector3f();
currState.angularVelocity = OVRPlugin.GetNodeAngularVelocity(node, OVRPlugin.Step.Render).FromFlippedZVector3f();
currState.isPoseValid = currState.pose != RigidPose.identity;
currState.isConnected = OVRPlugin.GetNodePresent(node);
// update device input
switch (currState.deviceModel)
{
case VRModuleDeviceModel.OculusTouchLeft:
case VRModuleDeviceModel.OculusQuestControllerLeft:
{
var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.LTouch);
currState.SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.Y) != 0u);
currState.SetButtonPress(VRModuleRawButton.A, (ctrlState.Buttons & (uint)OVRInput.RawButton.X) != 0u);
currState.SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & (uint)OVRInput.RawButton.LThumbstick) != 0u);
currState.SetButtonPress(VRModuleRawButton.Trigger, AxisToPress(currState.GetButtonPress(VRModuleRawButton.Trigger), ctrlState.LIndexTrigger, 0.55f, 0.45f));
currState.SetButtonPress(VRModuleRawButton.Grip, AxisToPress(currState.GetButtonPress(VRModuleRawButton.Grip), ctrlState.LHandTrigger, 0.55f, 0.45f));
currState.SetButtonPress(VRModuleRawButton.CapSenseGrip, AxisToPress(currState.GetButtonPress(VRModuleRawButton.CapSenseGrip), ctrlState.LHandTrigger, 0.55f, 0.45f));
currState.SetButtonPress(VRModuleRawButton.System, (ctrlState.Buttons & (uint)OVRInput.RawButton.Start) != 0u);
currState.SetButtonTouch(VRModuleRawButton.ApplicationMenu, (ctrlState.Touches & (uint)OVRInput.RawTouch.Y) != 0u);
currState.SetButtonTouch(VRModuleRawButton.A, (ctrlState.Touches & (uint)OVRInput.RawTouch.X) != 0u);
currState.SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & (uint)OVRInput.RawTouch.LThumbstick) != 0u);
currState.SetButtonTouch(VRModuleRawButton.Trigger, (ctrlState.Touches & (uint)OVRInput.RawTouch.LIndexTrigger) != 0u);
currState.SetButtonTouch(VRModuleRawButton.Grip, AxisToPress(currState.GetButtonTouch(VRModuleRawButton.Grip), ctrlState.LHandTrigger, 0.25f, 0.20f));
currState.SetButtonTouch(VRModuleRawButton.CapSenseGrip, AxisToPress(currState.GetButtonTouch(VRModuleRawButton.CapSenseGrip), ctrlState.LHandTrigger, 0.25f, 0.20f));
currState.SetAxisValue(VRModuleRawAxis.TouchpadX, ctrlState.LThumbstick.x);
currState.SetAxisValue(VRModuleRawAxis.TouchpadY, ctrlState.LThumbstick.y);
currState.SetAxisValue(VRModuleRawAxis.Trigger, ctrlState.LIndexTrigger);
currState.SetAxisValue(VRModuleRawAxis.CapSenseGrip, ctrlState.LHandTrigger);
break;
}
case VRModuleDeviceModel.OculusTouchRight:
case VRModuleDeviceModel.OculusQuestControllerRight:
{
var ctrlState = OVRPlugin.GetControllerState((uint)OVRPlugin.Controller.RTouch);
currState.SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.B) != 0u);
currState.SetButtonPress(VRModuleRawButton.A, (ctrlState.Buttons & (uint)OVRInput.RawButton.A) != 0u);
currState.SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & (uint)OVRInput.RawButton.RThumbstick) != 0u);
currState.SetButtonPress(VRModuleRawButton.Trigger, AxisToPress(currState.GetButtonPress(VRModuleRawButton.Trigger), ctrlState.RIndexTrigger, 0.55f, 0.45f));
currState.SetButtonPress(VRModuleRawButton.Grip, AxisToPress(currState.GetButtonPress(VRModuleRawButton.Grip), ctrlState.RHandTrigger, 0.55f, 0.45f));
currState.SetButtonPress(VRModuleRawButton.CapSenseGrip, AxisToPress(currState.GetButtonPress(VRModuleRawButton.CapSenseGrip), ctrlState.RHandTrigger, 0.55f, 0.45f));
currState.SetButtonTouch(VRModuleRawButton.ApplicationMenu, (ctrlState.Touches & (uint)OVRInput.RawTouch.B) != 0u);
currState.SetButtonTouch(VRModuleRawButton.A, (ctrlState.Touches & (uint)OVRInput.RawTouch.A) != 0u);
currState.SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & (uint)OVRInput.RawTouch.RThumbstick) != 0u);
currState.SetButtonTouch(VRModuleRawButton.Trigger, (ctrlState.Touches & (uint)OVRInput.RawTouch.RIndexTrigger) != 0u);
currState.SetButtonTouch(VRModuleRawButton.Grip, AxisToPress(currState.GetButtonTouch(VRModuleRawButton.Grip), ctrlState.RHandTrigger, 0.25f, 0.20f));
currState.SetButtonTouch(VRModuleRawButton.CapSenseGrip, AxisToPress(currState.GetButtonTouch(VRModuleRawButton.CapSenseGrip), ctrlState.RHandTrigger, 0.25f, 0.20f));
currState.SetAxisValue(VRModuleRawAxis.TouchpadX, ctrlState.RThumbstick.x);
currState.SetAxisValue(VRModuleRawAxis.TouchpadY, ctrlState.RThumbstick.y);
currState.SetAxisValue(VRModuleRawAxis.Trigger, ctrlState.RIndexTrigger);
currState.SetAxisValue(VRModuleRawAxis.CapSenseGrip, ctrlState.RHandTrigger);
break;
}
#if !VIU_OCULUSVR_19_0_OR_NEWER
case VRModuleDeviceModel.OculusGoController:
case VRModuleDeviceModel.OculusGearVrController:
switch (node)
{
case OVRPlugin.Node.HandLeft:
{
var ctrlState = OVRPlugin.GetControllerState4((uint)OVRPlugin.Controller.LTrackedRemote);
currState.SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & (uint)OVRInput.RawButton.LTouchpad) != 0u);
currState.SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.Back) != 0u);
currState.SetButtonPress(VRModuleRawButton.Trigger, (ctrlState.Buttons & (uint)(OVRInput.RawButton.A | OVRInput.RawButton.LIndexTrigger)) != 0u);
currState.SetButtonPress(VRModuleRawButton.DPadLeft, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadLeft) != 0u);
currState.SetButtonPress(VRModuleRawButton.DPadUp, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadUp) != 0u);
currState.SetButtonPress(VRModuleRawButton.DPadRight, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadRight) != 0u);
currState.SetButtonPress(VRModuleRawButton.DPadDown, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadDown) != 0u);
currState.SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & (uint)OVRInput.RawTouch.LTouchpad) != 0u);
currState.SetAxisValue(VRModuleRawAxis.TouchpadX, ctrlState.LTouchpad.x);
currState.SetAxisValue(VRModuleRawAxis.TouchpadY, ctrlState.LTouchpad.y);
}
break;
case OVRPlugin.Node.HandRight:
default:
{
var ctrlState = OVRPlugin.GetControllerState4((uint)OVRPlugin.Controller.RTrackedRemote);
currState.SetButtonPress(VRModuleRawButton.Touchpad, (ctrlState.Buttons & unchecked((uint)OVRInput.RawButton.RTouchpad)) != 0u);
currState.SetButtonPress(VRModuleRawButton.ApplicationMenu, (ctrlState.Buttons & (uint)OVRInput.RawButton.Back) != 0u);
currState.SetButtonPress(VRModuleRawButton.Trigger, (ctrlState.Buttons & (uint)(OVRInput.RawButton.A | OVRInput.RawButton.RIndexTrigger)) != 0u);
currState.SetButtonPress(VRModuleRawButton.DPadLeft, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadLeft) != 0u);
currState.SetButtonPress(VRModuleRawButton.DPadUp, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadUp) != 0u);
currState.SetButtonPress(VRModuleRawButton.DPadRight, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadRight) != 0u);
currState.SetButtonPress(VRModuleRawButton.DPadDown, (ctrlState.Buttons & (uint)OVRInput.RawButton.DpadDown) != 0u);
currState.SetButtonTouch(VRModuleRawButton.Touchpad, (ctrlState.Touches & unchecked((uint)OVRInput.RawTouch.RTouchpad)) != 0u);
currState.SetAxisValue(VRModuleRawAxis.TouchpadX, ctrlState.RTouchpad.x);
currState.SetAxisValue(VRModuleRawAxis.TouchpadY, ctrlState.RTouchpad.y);
}
break;
}
break;
#endif
}
}
ProcessConnectedDeviceChanged();
ProcessDevicePoseChanged();
ProcessDeviceInputChanged();
}
#endif
}
}