|
|
//========= Copyright 2016-2020, HTC Corporation. All rights reserved. ===========
using HTC.UnityPlugin.Utility;using HTC.UnityPlugin.Vive;using System;using System.Collections.Generic;using System.Runtime.InteropServices;using UnityEngine;#if VIU_WAVEVR && UNITY_ANDROID
using wvr;using Object = UnityEngine.Object;#endif
namespace HTC.UnityPlugin.VRModuleManagement{ public partial class VRModule : SingletonBehaviour<VRModule> { public static readonly bool isWaveVRPluginDetected =#if VIU_WAVEVR
true;#else
false;#endif
public static readonly bool isWaveVRSupported =#if VIU_WAVEVR_SUPPORT
true;#else
false;#endif
}
public sealed class WaveVRModule : VRModule.ModuleBase { public override int moduleOrder { get { return (int)DefaultModuleOrder.WaveVR; } }
public override int moduleIndex { get { return (int)VRModuleSelectEnum.WaveVR; } }
#if VIU_WAVEVR && UNITY_ANDROID
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 (hook.GetComponent<WaveVR_Render>() == null) { hook.gameObject.AddComponent<WaveVR_Render>();#if VIU_WAVEVR_3_1_3_OR_NEWER && UNITY_EDITOR
wvr.Interop.WVR_PostInit();#endif
} if (hook.GetComponent<VivePoseTracker>() == null) { hook.gameObject.AddComponent<VivePoseTracker>().viveRole.SetEx(DeviceRole.Hmd); } if (hook.GetComponent<AudioListener>() != null) { Object.Destroy(hook.GetComponent<AudioListener>()); } } }
private class RenderModelCreator : RenderModelHook.RenderModelCreator { private uint m_index = INVALID_DEVICE_INDEX; private GameObject m_model; private WVR_DeviceType m_loadedHandType;
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; }
var hasValidModel = false; var handType = default(WVR_DeviceType); if (VRModule.IsValidDeviceIndex(m_index)) { if (m_index == VRModule.GetRightControllerDeviceIndex()) { hasValidModel = true; handType = WVR_DeviceType.WVR_DeviceType_Controller_Right; } else if (m_index == VRModule.GetLeftControllerDeviceIndex()) { hasValidModel = true; handType = WVR_DeviceType.WVR_DeviceType_Controller_Left; } }
// NOTE: load renderModel only if it hasn't been loaded or user changes handType
if (hasValidModel) { if (m_model != null && m_loadedHandType != handType) { CleanUpRenderModel(); }
if (m_model == null) { // Create WaveVR_ControllerLoader silently (to avoid Start and OnEnable)
var loaderGO = new GameObject("Loader"); loaderGO.transform.SetParent(hook.transform, false); loaderGO.SetActive(false); var loader = loaderGO.AddComponent<WaveVR_ControllerLoader>(); loader.TrackPosition = false; loader.TrackRotation = false; loader.showIndicator = false; // Call onLoadController to create model (chould be Finch/Link/Pico/QIYIVR)
switch (handType) { case WVR_DeviceType.WVR_DeviceType_Controller_Right:#if VIU_WAVEVR_3_0_0_OR_NEWER
loader.WhichHand = s_moduleInstance.m_deviceHands[RIGHT_INDEX];#else
loader.WhichHand = WaveVR_ControllerLoader.ControllerHand.Controller_Right;#endif
loaderGO.SetActive(true);
if (WaveVR.Instance.getDeviceByType(handType).pose.pose.Is6DoFPose && WaveVR_Controller.IsLeftHanded) { loaderGO.SendMessage("onLoadController", WVR_DeviceType.WVR_DeviceType_Controller_Left); } else { loaderGO.SendMessage("onLoadController", WVR_DeviceType.WVR_DeviceType_Controller_Right); } break; case WVR_DeviceType.WVR_DeviceType_Controller_Left:#if VIU_WAVEVR_3_0_0_OR_NEWER
loader.WhichHand = s_moduleInstance.m_deviceHands[LEFT_INDEX];#elif VIU_WAVEVR_2_1_0_OR_NEWER
if (Interop.WVR_GetWaveRuntimeVersion() >= 3 && WaveVR_Controller.IsLeftHanded) { loader.WhichHand = WaveVR_ControllerLoader.ControllerHand.Controller_Right; } else { loader.WhichHand = WaveVR_ControllerLoader.ControllerHand.Controller_Left; }#else
loader.WhichHand = WaveVR_ControllerLoader.ControllerHand.Controller_Left;#endif
loaderGO.SetActive(true);
if (WaveVR.Instance.getDeviceByType(handType).pose.pose.Is6DoFPose && WaveVR_Controller.IsLeftHanded) { loaderGO.SendMessage("onLoadController", WVR_DeviceType.WVR_DeviceType_Controller_Right); } else { loaderGO.SendMessage("onLoadController", WVR_DeviceType.WVR_DeviceType_Controller_Left); } break; }
// Find transform that only contains controller model (include animator, exclude PoseTracker/Beam/UIPointer)
// and remove other unnecessary objects
var ctrllerActions = FindWaveVRControllerActionsObjInChildren(); if (ctrllerActions != null) { ctrllerActions.transform.SetParent(hook.transform, false); ctrllerActions.transform.SetAsFirstSibling(); for (int i = hook.transform.childCount - 1; i >= 1; --i) { Object.Destroy(hook.transform.GetChild(i).gameObject); } ctrllerActions.gameObject.SetActive(true); m_model = ctrllerActions.gameObject; } else { Debug.LogWarning("FindWaveVRControllerActionsObjInChildren failed"); for (int i = hook.transform.childCount - 1; i >= 0; --i) { Object.Destroy(hook.transform.GetChild(i).gameObject); } }
m_loadedHandType = handType; }
m_model.SetActive(true); } else { if (m_model != null) { m_model.SetActive(false); } } }
public override void CleanUpRenderModel() { if (m_model != null) { Object.Destroy(m_model); m_model = null; } }
// FIXME: This is for finding Controller model with animator, is reliable?
private Transform FindWaveVRControllerActionsObjInChildren() { var nodes = new List<Transform>(); nodes.Add(hook.transform); for (int i = 0; i < nodes.Count; ++i) { var parent = nodes[i]; for (int j = 0, jmax = parent.childCount; j < jmax; ++j) { var child = parent.GetChild(j); nodes.Add(child); if (child.GetComponent<WaveVR_PoseTrackerManager>() != null) { continue; } if (child.GetComponent<WaveVR_Beam>() != null) { continue; } if (child.GetComponent<WaveVR_ControllerPointer>() != null) { continue; } if (child.GetComponent<WaveVR_ControllerLoader>() != null) { continue; } return child; } }
return null; } }
private const uint DEVICE_COUNT = 3; private const uint HEAD_INDEX = 0; private const uint RIGHT_INDEX = 1; private const uint LEFT_INDEX = 2;
public static readonly Vector3 RIGHT_ARM_MULTIPLIER = new Vector3(1f, 1f, 1f); public static readonly Vector3 LEFT_ARM_MULTIPLIER = new Vector3(-1f, 1f, 1f); public const float DEFAULT_ELBOW_BEND_RATIO = 0.6f; public const float MIN_EXTENSION_ANGLE = 7.0f; public const float MAX_EXTENSION_ANGLE = 60.0f; public const float EXTENSION_WEIGHT = 0.4f; private static WaveVRModule s_moduleInstance; private static readonly WVR_DeviceType[] s_index2type; private static readonly uint[] s_type2index; private static readonly VRModuleDeviceClass[] s_type2class;
private IVRModuleDeviceStateRW m_headState; private IVRModuleDeviceStateRW m_rightState; private IVRModuleDeviceStateRW m_leftState; private WaveVR_ControllerLoader.ControllerHand[] m_deviceHands = new WaveVR_ControllerLoader.ControllerHand[DEVICE_COUNT];
#region 6Dof Controller Simulation
private enum Simulate6DoFControllerMode { KeyboardWASD, KeyboardModifierTrackpad, }
private static Simulate6DoFControllerMode s_simulationMode = Simulate6DoFControllerMode.KeyboardWASD; private static Vector3[] s_simulatedCtrlPosArray;
#endregion
static WaveVRModule() { s_index2type = new WVR_DeviceType[DEVICE_COUNT]; s_index2type[0] = WVR_DeviceType.WVR_DeviceType_HMD; s_index2type[1] = WVR_DeviceType.WVR_DeviceType_Controller_Right; s_index2type[2] = WVR_DeviceType.WVR_DeviceType_Controller_Left;
s_type2index = new uint[EnumUtils.GetMaxValue(typeof(WVR_DeviceType)) + 1]; for (int i = 0; i < s_type2index.Length; ++i) { s_type2index[i] = INVALID_DEVICE_INDEX; } s_type2index[(int)WVR_DeviceType.WVR_DeviceType_HMD] = 0u; s_type2index[(int)WVR_DeviceType.WVR_DeviceType_Controller_Right] = 1u; s_type2index[(int)WVR_DeviceType.WVR_DeviceType_Controller_Left] = 2u;
s_type2class = new VRModuleDeviceClass[s_type2index.Length]; for (int i = 0; i < s_type2class.Length; ++i) { s_type2class[i] = VRModuleDeviceClass.Invalid; } s_type2class[(int)WVR_DeviceType.WVR_DeviceType_HMD] = VRModuleDeviceClass.HMD; s_type2class[(int)WVR_DeviceType.WVR_DeviceType_Controller_Right] = VRModuleDeviceClass.Controller; s_type2class[(int)WVR_DeviceType.WVR_DeviceType_Controller_Left] = VRModuleDeviceClass.Controller;
s_simulatedCtrlPosArray = new Vector3[s_type2index.Length]; }
public override bool ShouldActiveModule() {#if VIU_WAVEVR_3_1_3_OR_NEWER && UNITY_EDITOR
return UnityEditor.EditorPrefs.GetBool("WaveVR/DirectPreview/Enable Direct Preview", false);#elif !VIU_WAVEVR_2_1_0_OR_NEWER && UNITY_EDITOR
return false;#else
return VIUSettings.activateWaveVRModule;#endif
}
public override void OnActivated() { if (Object.FindObjectOfType<WaveVR_Init>() == null) { VRModule.Instance.gameObject.AddComponent<WaveVR_Init>(); }
#if !UNITY_EDITOR && VIU_WAVEVR_3_1_0_OR_NEWER
if (Object.FindObjectOfType<WaveVR_ButtonList>() == null) { VRModule.Instance.gameObject.AddComponent<WaveVR_ButtonList>();
var buttonList = VRModule.Instance.gameObject.GetComponent<WaveVR_ButtonList>(); if (buttonList != null) { buttonList.HmdButtons = new List<WaveVR_ButtonList.EHmdButtons>() { WaveVR_ButtonList.EHmdButtons.Enter }; buttonList.DominantButtons = new List<WaveVR_ButtonList.EControllerButtons>() { WaveVR_ButtonList.EControllerButtons.Grip, WaveVR_ButtonList.EControllerButtons.Menu, WaveVR_ButtonList.EControllerButtons.Touchpad, WaveVR_ButtonList.EControllerButtons.Trigger }; buttonList.NonDominantButtons = new List<WaveVR_ButtonList.EControllerButtons>() { WaveVR_ButtonList.EControllerButtons.Grip, WaveVR_ButtonList.EControllerButtons.Menu, WaveVR_ButtonList.EControllerButtons.Touchpad, WaveVR_ButtonList.EControllerButtons.Trigger }; } }#elif !UNITY_EDITOR && VIU_WAVEVR_3_0_0_OR_NEWER
if (Object.FindObjectOfType<WaveVR_ButtonList>() == null) { VRModule.Instance.gameObject.AddComponent<WaveVR_ButtonList>();
var buttonList = VRModule.Instance.gameObject.GetComponent<WaveVR_ButtonList>(); if (buttonList != null) { buttonList.HmdButtons = new List<WaveVR_ButtonList.EButtons>() { WaveVR_ButtonList.EButtons.HMDEnter }; buttonList.DominantButtons = new List<WaveVR_ButtonList.EButtons>() { WaveVR_ButtonList.EButtons.Grip, WaveVR_ButtonList.EButtons.Menu, WaveVR_ButtonList.EButtons.Touchpad, WaveVR_ButtonList.EButtons.Trigger }; buttonList.NonDominantButtons = new List<WaveVR_ButtonList.EButtons>() { WaveVR_ButtonList.EButtons.Grip, WaveVR_ButtonList.EButtons.Menu, WaveVR_ButtonList.EButtons.Touchpad, WaveVR_ButtonList.EButtons.Trigger }; } }#endif
EnsureDeviceStateLength(DEVICE_COUNT);
UpdateTrackingSpaceType();
s_moduleInstance = this;
WaveVR_Utils.Event.Listen(WaveVR_Utils.Event.NEW_POSES, OnNewPoses); }
public override void OnDeactivated() { WaveVR_Utils.Event.Remove(WaveVR_Utils.Event.NEW_POSES, OnNewPoses);
m_headState = null; m_rightState = null; m_leftState = null;
s_moduleInstance = null; }
public override void UpdateTrackingSpaceType() { if (WaveVR_Render.Instance != null) { // Only effected when origin is OnHead or OnGround
// This way you can manually set WaveVR_Render origin to other value lik OnTrackingObserver or OnHead_3DoF
if (VRModule.trackingSpaceType == VRModuleTrackingSpaceType.RoomScale) { if (WaveVR_Render.Instance.origin == WVR_PoseOriginModel.WVR_PoseOriginModel_OriginOnHead) { WaveVR_Render.Instance.origin = WVR_PoseOriginModel.WVR_PoseOriginModel_OriginOnGround; } } else if (VRModule.trackingSpaceType == VRModuleTrackingSpaceType.Stationary) { if (WaveVR_Render.Instance.origin == WVR_PoseOriginModel.WVR_PoseOriginModel_OriginOnGround) { WaveVR_Render.Instance.origin = WVR_PoseOriginModel.WVR_PoseOriginModel_OriginOnHead; } } } }
public override void Update() { var rightDevice = GetWVRControllerDevice(WVR_DeviceType.WVR_DeviceType_Controller_Right); UpdateDeviceInput(1, rightDevice); var leftDevice = GetWVRControllerDevice(WVR_DeviceType.WVR_DeviceType_Controller_Left); UpdateDeviceInput(2, leftDevice);
ProcessDeviceInputChanged(); }
private WaveVR_Controller.Device GetWVRControllerDevice(WVR_DeviceType deviceType) { switch (deviceType) { case WVR_DeviceType.WVR_DeviceType_Controller_Right: return WaveVR_Controller.Input(WaveVR_Controller.IsLeftHanded ? WVR_DeviceType.WVR_DeviceType_Controller_Left : WVR_DeviceType.WVR_DeviceType_Controller_Right); case WVR_DeviceType.WVR_DeviceType_Controller_Left: return WaveVR_Controller.Input(WaveVR_Controller.IsLeftHanded ? WVR_DeviceType.WVR_DeviceType_Controller_Right : WVR_DeviceType.WVR_DeviceType_Controller_Left); default: return null; } }
private WaveVR.Device GetWVRDevice(WVR_DeviceType deviceType) { switch (deviceType) { case WVR_DeviceType.WVR_DeviceType_HMD: return WaveVR.Instance.getDeviceByType(deviceType); case WVR_DeviceType.WVR_DeviceType_Controller_Right: return WaveVR.Instance.getDeviceByType(WaveVR_Controller.IsLeftHanded ? WVR_DeviceType.WVR_DeviceType_Controller_Left : WVR_DeviceType.WVR_DeviceType_Controller_Right); case WVR_DeviceType.WVR_DeviceType_Controller_Left: return WaveVR.Instance.getDeviceByType(WaveVR_Controller.IsLeftHanded ? WVR_DeviceType.WVR_DeviceType_Controller_Right : WVR_DeviceType.WVR_DeviceType_Controller_Left); default: return null; } }
private void UpdateDeviceInput(uint deviceIndex, WaveVR_Controller.Device deviceInput) {#if VIU_WAVEVR_2_1_0_OR_NEWER
const WVR_InputId digitalTrggerBumpID = WVR_InputId.WVR_InputId_Alias1_Digital_Trigger;#else
const WVR_InputId digitalTrggerBumpID = WVR_InputId.WVR_InputId_Alias1_Bumper;#endif
IVRModuleDeviceState prevState; IVRModuleDeviceStateRW currState;
if (!TryGetValidDeviceState(deviceIndex, out prevState, out currState) || !deviceInput.connected) { return; }
if (deviceInput != null) { var systemPressed = deviceInput.GetPress(WVR_InputId.WVR_InputId_Alias1_System); var menuPressed = deviceInput.GetPress(WVR_InputId.WVR_InputId_Alias1_Menu); var triggerPressed = deviceInput.GetPress(WVR_InputId.WVR_InputId_Alias1_Trigger); var digitalTriggerPressed = deviceInput.GetPress(digitalTrggerBumpID); var gripPressed = deviceInput.GetPress(WVR_InputId.WVR_InputId_Alias1_Grip); var touchpadPressed = deviceInput.GetPress(WVR_InputId.WVR_InputId_Alias1_Touchpad); var dpadLeftPressed = deviceInput.GetPress(WVR_InputId.WVR_InputId_Alias1_DPad_Left); var dpadUpPressed = deviceInput.GetPress(WVR_InputId.WVR_InputId_Alias1_DPad_Up); var dpadRightPressed = deviceInput.GetPress(WVR_InputId.WVR_InputId_Alias1_DPad_Right); var dpadDownPressed = deviceInput.GetPress(WVR_InputId.WVR_InputId_Alias1_DPad_Down); currState.SetButtonPress(VRModuleRawButton.System, systemPressed); currState.SetButtonPress(VRModuleRawButton.ApplicationMenu, menuPressed); currState.SetButtonPress(VRModuleRawButton.Touchpad, touchpadPressed || dpadLeftPressed || dpadUpPressed || dpadRightPressed || dpadDownPressed); currState.SetButtonPress(VRModuleRawButton.Trigger, triggerPressed || digitalTriggerPressed); currState.SetButtonPress(VRModuleRawButton.Grip, gripPressed); currState.SetButtonPress(VRModuleRawButton.DPadLeft, dpadLeftPressed); currState.SetButtonPress(VRModuleRawButton.DPadUp, dpadUpPressed); currState.SetButtonPress(VRModuleRawButton.DPadRight, dpadRightPressed); currState.SetButtonPress(VRModuleRawButton.DPadDown, dpadDownPressed);
var systemTouched = deviceInput.GetTouch(WVR_InputId.WVR_InputId_Alias1_System); var menuTouched = deviceInput.GetTouch(WVR_InputId.WVR_InputId_Alias1_Menu); var triggerTouched = deviceInput.GetTouch(WVR_InputId.WVR_InputId_Alias1_Trigger); var digitalTriggerTouched = deviceInput.GetTouch(digitalTrggerBumpID); var gripTouched = deviceInput.GetTouch(WVR_InputId.WVR_InputId_Alias1_Grip); var touchpadTouched = deviceInput.GetTouch(WVR_InputId.WVR_InputId_Alias1_Touchpad); var dpadLeftTouched = deviceInput.GetTouch(WVR_InputId.WVR_InputId_Alias1_DPad_Left); var dpadUpTouched = deviceInput.GetTouch(WVR_InputId.WVR_InputId_Alias1_DPad_Up); var dpadRightTouched = deviceInput.GetTouch(WVR_InputId.WVR_InputId_Alias1_DPad_Right); var dpadDownTouched = deviceInput.GetTouch(WVR_InputId.WVR_InputId_Alias1_DPad_Down); currState.SetButtonTouch(VRModuleRawButton.System, systemTouched); currState.SetButtonTouch(VRModuleRawButton.ApplicationMenu, menuTouched); currState.SetButtonTouch(VRModuleRawButton.Touchpad, touchpadTouched || dpadLeftTouched || dpadUpTouched || dpadRightTouched || dpadDownTouched); currState.SetButtonTouch(VRModuleRawButton.Trigger, triggerTouched || digitalTriggerTouched); currState.SetButtonTouch(VRModuleRawButton.Grip, gripTouched); currState.SetButtonTouch(VRModuleRawButton.DPadLeft, dpadLeftTouched); currState.SetButtonTouch(VRModuleRawButton.DPadUp, dpadUpTouched); currState.SetButtonTouch(VRModuleRawButton.DPadRight, dpadRightTouched); currState.SetButtonTouch(VRModuleRawButton.DPadDown, dpadDownTouched);
var triggerAxis = deviceInput.GetAxis(WVR_InputId.WVR_InputId_Alias1_Trigger); var touchAxis = deviceInput.GetAxis(WVR_InputId.WVR_InputId_Alias1_Touchpad); currState.SetAxisValue(VRModuleRawAxis.Trigger, triggerAxis.x); currState.SetAxisValue(VRModuleRawAxis.TouchpadX, touchAxis.x); currState.SetAxisValue(VRModuleRawAxis.TouchpadY, touchAxis.y); } else { currState.buttonPressed = 0u; currState.buttonTouched = 0u; currState.ResetAxisValues(); } }
private IVRModuleDeviceStateRW UpdateDevicePose(uint deviceIndex, WaveVR.Device content) { IVRModuleDeviceState prevState; IVRModuleDeviceStateRW currState; EnsureValidDeviceState(deviceIndex, out prevState, out currState);
var deviceConnected = content.type == WVR_DeviceType.WVR_DeviceType_HMD ? true : content.connected;
if (!deviceConnected) { if (prevState.isConnected) { currState.Reset();
switch (content.type) { case WVR_DeviceType.WVR_DeviceType_HMD: m_headState = null; break; case WVR_DeviceType.WVR_DeviceType_Controller_Right: m_rightState = null; break; case WVR_DeviceType.WVR_DeviceType_Controller_Left: m_leftState = null; break; } } } else { if (!prevState.isConnected) { string renderModelName; if (!TryGetWVRStringParameter(s_index2type[(int)deviceIndex], "GetRenderModelName", out renderModelName)) { renderModelName = "wvr_unknown_device"; }
currState.isConnected = true; currState.deviceClass = s_type2class[(int)content.type]; currState.serialNumber = content.type.ToString(); currState.modelNumber = renderModelName; currState.renderModelName = renderModelName; currState.input2DType = VRModuleInput2DType.TouchpadOnly;
SetupKnownDeviceModel(currState); }
// update pose
var devicePose = content.pose.pose; currState.velocity = new Vector3(devicePose.Velocity.v0, devicePose.Velocity.v1, -devicePose.Velocity.v2); currState.angularVelocity = new Vector3(-devicePose.AngularVelocity.v0, -devicePose.AngularVelocity.v1, devicePose.AngularVelocity.v2);
var rigidTransform = content.rigidTransform; currState.position = rigidTransform.pos; currState.rotation = rigidTransform.rot;
currState.isPoseValid = devicePose.IsValidPose; }
return currState; }
private void OnNewPoses(params object[] args) { if (WaveVR.Instance == null) { return; }
FlushDeviceState();
var headDevice = GetWVRDevice(WVR_DeviceType.WVR_DeviceType_HMD); m_headState = UpdateDevicePose(0, headDevice); var rightDevice = GetWVRDevice(WVR_DeviceType.WVR_DeviceType_Controller_Right); m_rightState = UpdateDevicePose(1, rightDevice); var leftDevice = GetWVRDevice(WVR_DeviceType.WVR_DeviceType_Controller_Left); m_leftState = UpdateDevicePose(2, leftDevice);
#if VIU_WAVEVR_3_0_0_OR_NEWER
if (WaveVR_Controller.IsLeftHanded) { m_deviceHands[RIGHT_INDEX] = WaveVR_ControllerLoader.ControllerHand.Non_Dominant; m_deviceHands[LEFT_INDEX] = WaveVR_ControllerLoader.ControllerHand.Dominant; } else { m_deviceHands[RIGHT_INDEX] = WaveVR_ControllerLoader.ControllerHand.Dominant; m_deviceHands[LEFT_INDEX] = WaveVR_ControllerLoader.ControllerHand.Non_Dominant; }#endif
if (m_rightState != null && !rightDevice.pose.pose.Is6DoFPose) { ApplyVirtualArmAndSimulateInput(m_rightState, m_headState, RIGHT_ARM_MULTIPLIER); }
if (m_leftState != null && !leftDevice.pose.pose.Is6DoFPose) { ApplyVirtualArmAndSimulateInput(m_leftState, m_headState, LEFT_ARM_MULTIPLIER); }
ProcessConnectedDeviceChanged(); ProcessDevicePoseChanged(); }
// FIXME: WVR_IsInputFocusCapturedBySystem currently not implemented yet
//public override bool HasInputFocus()
//{
// return m_hasInputFocus;
//}
public override uint GetRightControllerDeviceIndex() { return RIGHT_INDEX; }
public override uint GetLeftControllerDeviceIndex() { return LEFT_INDEX; }
private void ApplyVirtualArmAndSimulateInput(IVRModuleDeviceStateRW ctrlState, IVRModuleDeviceStateRW headState, Vector3 handSideMultiplier) { if (!ctrlState.isConnected) { return; } if (!VIUSettings.waveVRAddVirtualArmTo3DoFController && !VIUSettings.simulateWaveVR6DofController) { return; } var deviceType = (int)s_index2type[ctrlState.deviceIndex];
#if !UNITY_EDITOR
if (Interop.WVR_GetDegreeOfFreedom((WVR_DeviceType)deviceType) == WVR_NumDoF.WVR_NumDoF_6DoF) { return; }#elif VIU_WAVEVR_3_1_3_OR_NEWER && UNITY_EDITOR
if (!WaveVR.EnableSimulator || WVR_DirectPreview.WVR_GetDegreeOfFreedom_S(0) == (int)WVR_NumDoF.WVR_NumDoF_6DoF) { return; }#elif VIU_WAVEVR_3_1_0_OR_NEWER && UNITY_EDITOR
if (!WaveVR.EnableSimulator || WVR_Simulator.WVR_GetDegreeOfFreedom_S(0) == (int)WVR_NumDoF.WVR_NumDoF_6DoF) { return; }#elif VIU_WAVEVR_2_1_0_OR_NEWER && UNITY_EDITOR
if (!WaveVR.Instance.isSimulatorOn || WaveVR_Utils.WVR_GetDegreeOfFreedom_S() == (int)WVR_NumDoF.WVR_NumDoF_6DoF) { return; }#endif
if (VIUSettings.simulateWaveVR6DofController) { if (Input.GetKeyDown(KeyCode.Alpha1)) { s_simulationMode = Simulate6DoFControllerMode.KeyboardWASD; } if (Input.GetKeyDown(KeyCode.Alpha2)) { s_simulationMode = Simulate6DoFControllerMode.KeyboardModifierTrackpad; } if (Input.GetKeyDown(KeyCode.BackQuote)) { s_simulatedCtrlPosArray[deviceType] = Vector3.zero; }
var deltaMove = Time.unscaledDeltaTime; var rotY = Quaternion.Euler(0f, ctrlState.rotation.eulerAngles.y, 0f); var moveForward = rotY * Vector3.forward; var moveRight = rotY * Vector3.right;
switch (s_simulationMode) { case Simulate6DoFControllerMode.KeyboardWASD: { if (Input.GetKey(KeyCode.D)) { s_simulatedCtrlPosArray[deviceType] += moveRight * deltaMove; } if (Input.GetKey(KeyCode.A)) { s_simulatedCtrlPosArray[deviceType] -= moveRight * deltaMove; } if (Input.GetKey(KeyCode.E)) { s_simulatedCtrlPosArray[deviceType] += Vector3.up * deltaMove; } if (Input.GetKey(KeyCode.Q)) { s_simulatedCtrlPosArray[deviceType] -= Vector3.up * deltaMove; } if (Input.GetKey(KeyCode.W)) { s_simulatedCtrlPosArray[deviceType] += moveForward * deltaMove; } if (Input.GetKey(KeyCode.S)) { s_simulatedCtrlPosArray[deviceType] -= moveForward * deltaMove; }
break; }
case Simulate6DoFControllerMode.KeyboardModifierTrackpad: { float speedModifier = 2f; float x = ctrlState.GetAxisValue(VRModuleRawAxis.TouchpadX) * speedModifier; float y = ctrlState.GetAxisValue(VRModuleRawAxis.TouchpadY) * speedModifier;
if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) { s_simulatedCtrlPosArray[deviceType] += x * moveRight * deltaMove; s_simulatedCtrlPosArray[deviceType] += y * moveForward * deltaMove; }
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) { s_simulatedCtrlPosArray[deviceType] += x * moveRight * deltaMove; s_simulatedCtrlPosArray[deviceType] += y * Vector3.up * deltaMove; }
break; } } }
if (VIUSettings.waveVRAddVirtualArmTo3DoFController) { var neckPose = new RigidPose(s_simulatedCtrlPosArray[deviceType], Quaternion.identity) * GetNeckPose(headState.pose); ctrlState.position = GetControllerPositionWithVirtualArm(neckPose, ctrlState.rotation, handSideMultiplier); } else { ctrlState.position += s_simulatedCtrlPosArray[deviceType]; } }
private static RigidPose GetNeckPose(RigidPose headPose) { var headForward = headPose.forward; return new RigidPose(headPose.pos + VIUSettings.waveVRVirtualNeckPosition, Quaternion.FromToRotation(Vector3.forward, new Vector3(headForward.x, 0f, headForward.z))); }
private static float GetExtensionRatio(Vector3 v) { var xAngle = 90f - Vector3.Angle(v, Vector3.up); return Mathf.Clamp01(Mathf.InverseLerp(MIN_EXTENSION_ANGLE, MAX_EXTENSION_ANGLE, xAngle)); }
private static Quaternion GetLerpRotation(Quaternion xyRotation, float extensionRatio) { float totalAngle = Quaternion.Angle(xyRotation, Quaternion.identity); float lerpSuppresion = 1.0f - Mathf.Pow(totalAngle / 180.0f, 6.0f); float inverseElbowBendRatio = 1.0f - DEFAULT_ELBOW_BEND_RATIO; float lerpValue = inverseElbowBendRatio + DEFAULT_ELBOW_BEND_RATIO * extensionRatio * EXTENSION_WEIGHT; lerpValue *= lerpSuppresion; return Quaternion.Lerp(Quaternion.identity, xyRotation, lerpValue); }
private static Vector3 GetControllerPositionWithVirtualArm(RigidPose neckPose, Quaternion ctrlRot, Vector3 sideMultiplier) { var localCtrlForward = (Quaternion.Inverse(neckPose.rot) * ctrlRot) * Vector3.forward; var localCtrlXYRot = Quaternion.FromToRotation(Vector3.forward, localCtrlForward); var extensionRatio = GetExtensionRatio(localCtrlForward); var lerpRotation = GetLerpRotation(localCtrlXYRot, extensionRatio);
var elbowPose = new RigidPose( Vector3.Scale(VIUSettings.waveVRVirtualElbowRestPosition, sideMultiplier) + Vector3.Scale(VIUSettings.waveVRVirtualArmExtensionOffset, sideMultiplier) * extensionRatio, Quaternion.Inverse(lerpRotation) * localCtrlXYRot); var wristPose = new RigidPose( Vector3.Scale(VIUSettings.waveVRVirtualWristRestPosition, sideMultiplier), lerpRotation); var palmPose = new RigidPose( Vector3.Scale(VIUSettings.waveVRVirtualHandRestPosition, sideMultiplier), Quaternion.identity);
var finalCtrlPose = neckPose * elbowPose * wristPose * palmPose; return finalCtrlPose.pos; }
public override void TriggerViveControllerHaptic(uint deviceIndex, ushort durationMicroSec = 500) { var deviceInput = WaveVR_Controller.Input(s_index2type[deviceIndex]); if (deviceInput != null) { deviceInput.TriggerHapticPulse(durationMicroSec); } }
private bool TryGetWVRStringParameter(WVR_DeviceType device, string paramName, out string result) { result = default(string); var resultLen = 0u; try { const int resultMaxLen = 128; var resultBuffer = resultMaxLen; var resultPtr = Marshal.AllocHGlobal(resultBuffer); var paramNamePtr = Marshal.StringToHGlobalAnsi(paramName); resultLen = Interop.WVR_GetParameters(device, paramNamePtr, resultPtr, resultMaxLen);
if (resultLen > 0u) { result = Marshal.PtrToStringAnsi(resultPtr); } } catch (Exception e) { Debug.LogException(e); }
return resultLen > 0u; }
#if VIU_WAVEVR_3_1_0_OR_NEWER
public override void TriggerHapticVibration(uint deviceIndex, float durationSeconds = 0.01f, float frequency = 85, float amplitude = 0.125f, float startSecondsFromNow = 0) { var deviceInput = WaveVR_Controller.Input(s_index2type[deviceIndex]); var intensity = default(WVR_Intensity); if (deviceInput != null) { if (0 <= amplitude || amplitude <= 0.2) { intensity = WVR_Intensity.WVR_Intensity_Weak; } else if (0.2 < amplitude || amplitude <= 0.4) { intensity = WVR_Intensity.WVR_Intensity_Light; } else if (0.4 < amplitude || amplitude <= 0.6) { intensity = WVR_Intensity.WVR_Intensity_Normal; } else if (0.6 < amplitude || amplitude <= 0.8) { intensity = WVR_Intensity.WVR_Intensity_Strong; } else if (0.8 < amplitude || amplitude <= 1) { intensity = WVR_Intensity.WVR_Intensity_Severe; } } Interop.WVR_TriggerVibration(deviceInput.DeviceType, WVR_InputId.WVR_InputId_Alias1_Touchpad, (uint)(durationSeconds * 1000000), (uint)frequency, intensity); }#endif
#endif
}}
|