Example #1
0
 private void UpdateInputFocusState()
 {
     if (ChangeProp.Set(ref m_hasInputFocus, inputFocus))
     {
         InvokeInputFocusEvent(m_hasInputFocus);
     }
 }
Example #2
0
        // set by value name to preserve the enum element, since different enum element could have same enum value
        public void Set(string typeFullName, string valueName)
        {
            m_isTypeDirty  |= ChangeProp.Set(ref m_roleTypeFullName, typeFullName);
            m_isValueDirty |= ChangeProp.Set(ref m_roleValueName, valueName);

            Update();
        }
Example #3
0
            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 <VIUSteamVRRenderModel>();
                    }

                    // set render model index
                    m_model.gameObject.SetActive(true);
                    m_model.shaderOverride = hook.overrideShader;
                    m_model.SetDeviceIndex(m_index);
                }
                else
                {
                    // deacitvate object for render model
                    if (m_model != null)
                    {
                        m_model.gameObject.SetActive(false);
                    }
                }
            }
Example #4
0
        public override void ResetSegments()
        {
            var velocityChanged = ChangeProp.Set(ref m_velocity, velocity);
            var gravityChanged  = ChangeProp.Set(ref m_gravity, gravity);

            if (gravityChanged)
            {
                CalculateAcc();
            }

            if (velocityChanged || gravityChanged)
            {
                CalculatePeekDistanceMax();
            }

            systemY = -gravity;
            systemX = transform.forward;
            Vector3.OrthoNormalize(ref systemY, ref systemX);

            v0          = transform.forward * velocity;
            v0X         = Vector3.Dot(v0, systemX);
            v0Y         = Vector3.Dot(v0, systemY);
            isHeighPeek = Mathf.Abs(v0Y) > Mathf.Abs(v0X);

            contactPointTime = v0Y / accY;
            halfJourney      = Mathf.Abs(contactPointTime);

            rayDistance = nextRayDistance = 0f;
        }
        private void OnCameraPreCull(Camera cam)
        {
#if UNITY_EDITOR
            // skip pre cull from scene camera (editor only?)
            // because at this point, the LastPoses seems not updated yet (the result is same as last frame)
            // shell wait till next game camera pre cull (top game camera)
            if (cam.depth == 0 && cam.name == "SceneCamera")
            {
                return;
            }
#endif
            // update only once per frame
            if (!ChangeProp.Set(ref m_poseUpdatedFrame, Time.frameCount))
            {
                return;
            }

            m_isUpdating = true;

            UpdateActivatedModule();

            UpdateDeviceStates();

            if (m_isDestoryed)
            {
                CleanUp();
            }

            m_isUpdating = false;
        }
 protected void SetIsValid(bool value, bool forceSet = false)
 {
     if (ChangeProp.Set(ref isValid, value) || forceSet)
     {
         onIsValidChanged.Invoke(value);
     }
 }
 private static void SetRoleIndex(int index, uint value)
 {
     if (ChangeProp.Set(ref roleIndice[index], value) && !ReferenceEquals(indexChangedHandlers[index], null))
     {
         indexChangedHandlers[index].Invoke((int)value);
     }
 }
Example #8
0
    public void UpdateMaterialState()
    {
        Material targetMat;

        if (drags.Count > 0)
        {
            targetMat = dragged;
        }
        else if (presses.Count > 0)
        {
            targetMat = Pressed;
        }
        else if (hovers.Count > 0)
        {
            targetMat = Hovered;
        }
        else
        {
            targetMat = Normal;
        }

        if (ChangeProp.Set(ref currentMat, targetMat))
        {
            SetChildRendererMaterial(targetMat);
        }
    }
Example #9
0
    private void UpdateMaterialState()
    {
        var targetMat = default(Material);

        if (drags.Count > 0)
        {
            drags.RemoveAll(e => !e.isDragging);
        }

        if (drags.Count > 0)
        {
            targetMat = dragged;
        }
        else if (presses.Count > 0)
        {
            targetMat = Pressed;
        }
        else if (hovers.Count > 0)
        {
            targetMat = Heightlight;
        }
        else
        {
            targetMat = Normal;
        }

        if (ChangeProp.Set(ref currentMat, targetMat))
        {
            SetChildRendererMaterial(targetMat);
        }
    }
 private void UpdateDefaultModel()
 {
     if (ChangeProp.Set(ref m_currentDeviceIndex, GetCurrentDeviceIndex()))
     {
         if (VRModule.IsValidDeviceIndex(m_currentDeviceIndex))
         {
             if (ChangeProp.Set(ref m_currentLoadedStaticModel, VRModule.GetCurrentDeviceState(m_currentDeviceIndex).deviceModel))
             {
                 ReloadedStaticModel(m_currentLoadedStaticModel);
             }
             else
             {
                 if (m_modelObj != null)
                 {
                     m_modelObj.SetActive(true);
                 }
             }
         }
         else
         {
             if (m_modelObj != null)
             {
                 m_modelObj.SetActive(false);
             }
         }
     }
 }
Example #11
0
 public bool SetLeftCustomModelActive(bool value)
 {
     if (ChangeProp.Set(ref m_leftCustomModelActive, value))
     {
         if (value)
         {
             m_leftLaserPointerActive = false; m_leftCurvePointerActive = false;
         }
         return(true);
     }
     return(false);
 }
            public override void UpdateRenderModel()
            {
                var index = hook.GetModelDeviceIndex();

                if (!VRModule.IsValidDeviceIndex(index))
                {
                    if (m_model != null)
                    {
                        m_model.SetActive(false);
                    }
                }
                else
                {
                    var loadModelEnum = VRModuleDeviceModel.Unknown;
                    if (hook.m_overrideModel != OverrideModelEnum.DontOverride)
                    {
                        loadModelEnum = (VRModuleDeviceModel)hook.m_overrideModel;
                    }
                    else
                    {
                        loadModelEnum = VRModule.GetCurrentDeviceState(index).deviceModel;
                    }

                    if (ChangeProp.Set(ref m_loadedModelEnum, loadModelEnum))
                    {
                        CleanUpRenderModel();

                        var prefab = Resources.Load <GameObject>("Models/VIUModel" + m_loadedModelEnum.ToString());
                        if (prefab != null)
                        {
                            m_model = Instantiate(prefab);
                            m_model.transform.SetParent(hook.transform, false);
                            m_model.gameObject.name = "VIUModel" + m_loadedModelEnum.ToString();

                            if (hook.m_overrideShader != null)
                            {
                                var renderer = m_model.GetComponentInChildren <Renderer>();
                                if (renderer != null)
                                {
                                    renderer.material.shader = hook.m_overrideShader;
                                }
                            }
                        }
                    }

                    if (m_model != null)
                    {
                        m_model.SetActive(true);
                    }
                }
            }
Example #13
0
        private void UpdateState()
        {
            if (!ChangeProp.Set(ref m_updatedFrameCount, Time.frameCount))
            {
                return;
            }

            m_prevPressState = m_currPressState;
            m_currPressState = false;

            if (m_inputs.Count == 0)
            {
                return;
            }

            switch (m_combineInputsOperator)
            {
            case InputsOperatorEnum.Or:

                m_currPressState = false;

                for (int i = 0, imax = m_inputs.Count; i < imax; ++i)
                {
                    if (ViveInput.GetPress(m_inputs[i].viveRole, m_inputs[i].button))
                    {
                        m_currPressState = true;


                        break;
                    }
                }

                break;

            case InputsOperatorEnum.And:

                m_currPressState = true;

                for (int i = 0, imax = m_inputs.Count; i < imax; ++i)
                {
                    if (!ViveInput.GetPress(m_inputs[i].viveRole, m_inputs[i].button))
                    {
                        m_currPressState = false;
                        break;
                    }
                }

                break;
            }
        }
    public virtual void OnNewPoses()
    {
        var valid = VivePose.IsValidEx(viveRole.roleType, viveRole.roleValue);

        if (valid)
        {
            TrackPose(VivePose.GetPoseEx(viveRole.roleType, viveRole.roleValue), m_origin);
        }

        if (ChangeProp.Set(ref m_isValid, valid))
        {
            SetValid(m_isValid);
        }
    }
 public void UpdateRenderModel()
 {
     if (ChangeProp.Set(ref m_currentDeviceIndex, GetCurrentDeviceIndex()))
     {
         if (!ViveRole.IsValidIndex(m_currentDeviceIndex))
         {
             m_renderModel.gameObject.SetActive(false);
         }
         else
         {
             m_renderModel.gameObject.SetActive(true);
             m_renderModel.SetDeviceIndex((int)m_currentDeviceIndex);
         }
     }
 }
        private void UpdateSteamVRModel()
        {
            if (ChangeProp.Set(ref m_currentDeviceIndex, GetCurrentDeviceIndex()))
            {
                if (VRModule.IsValidDeviceIndex(m_currentDeviceIndex))
                {
                    if (m_modelObj != null && m_renderModel == null)
                    {
                        CleanUpModelObj();
                    }

                    if (m_modelObj == null)
                    {
                        // find SteamVR_RenderModel in child object
                        for (int i = 0, imax = transform.childCount; i < imax; ++i)
                        {
                            if ((m_renderModel = GetComponentInChildren <VIUSteamVRRenderModel>()) != null)
                            {
                                m_modelObj = m_renderModel.gameObject;
                                break;
                            }
                        }
                        // create SteamVR_RenderModel in child object if not found
                        if (m_renderModel == null)
                        {
                            m_modelObj = new GameObject("Model");
                            m_modelObj.transform.SetParent(transform, false);
                            m_renderModel = m_modelObj.AddComponent <VIUSteamVRRenderModel>();
                        }

                        if (m_overrideShader != null)
                        {
                            m_renderModel.shaderOverride = m_overrideShader;
                        }
                    }

                    m_modelObj.SetActive(true);
                    m_renderModel.SetDeviceIndex(m_currentDeviceIndex);
                }
                else
                {
                    if (m_modelObj != null)
                    {
                        m_modelObj.SetActive(false);
                    }
                }
            }
        }
        private void UpdateModel()
        {
            if (m_isQuiting)
            {
                return;
            }

            var overrideModelChanged = ChangeProp.Set(ref m_currentOverrideModel, m_overrideModel);

            if (m_currentOverrideModel == OverrideModelEnum.DontOverride)
            {
                switch (VRModule.activeModule)
                {
#if VIU_STEAMVR
                case VRModuleActiveEnum.SteamVR:
                    UpdateSteamVRModel();
                    break;
#endif
#if VIU_WAVEVR
                case VRModuleActiveEnum.WaveVR:
                    UpdateWaveVRModel();
                    break;
#endif
                case VRModuleActiveEnum.Uninitialized:
                    if (m_modelObj != null)
                    {
                        m_modelObj.SetActive(false);
                    }
                    break;

                default:
                    UpdateDefaultModel();
                    break;
                }
            }
            else
            {
                if (overrideModelChanged)
                {
                    ReloadedStaticModel((VRModuleDeviceModel)m_currentOverrideModel);
                }

                if (ChangeProp.Set(ref m_currentDeviceIndex, GetCurrentDeviceIndex()) && m_modelObj != null)
                {
                    m_modelObj.SetActive(VRModule.IsValidDeviceIndex(m_currentDeviceIndex));
                }
            }
        }
Example #18
0
        // update type and value if type string or value string is/are dirty
        private void Update()
        {
            if (!m_isTypeDirty && !m_isValueDirty)
            {
                return;
            }

            var changed = false;

            if (m_isTypeDirty)
            {
                m_isTypeDirty = false;

                Type newType;
                if (string.IsNullOrEmpty(m_roleTypeFullName) || !ViveRoleEnum.ValidViveRoleTable.TryGetValue(m_roleTypeFullName, out newType))
                {
                    newType = DefaultRoleType;
                }

                changed = ChangeProp.Set(ref m_roleType, newType);
            }

            if (m_isValueDirty || changed)
            {
                m_isValueDirty = false;

                int newValue;
                var info = ViveRoleEnum.GetInfo(m_roleType);
                if (string.IsNullOrEmpty(m_roleValueName) || !info.TryGetRoleValueByName(m_roleValueName, out newValue))
                {
                    newValue = info.InvalidRoleValue;
                }

                changed |= ChangeProp.Set(ref m_roleValue, newValue);
            }

            if (changed && Changed != null)
            {
                Changed.Invoke();
            }
        }
Example #19
0
    public void SetGravityEnabled(bool value, bool forceSet = false)
    {
        if (ChangeProp.Set(ref m_gravityEnabled, value) || forceSet)
        {
            // change the apperence the switch
            switchObject.localEulerAngles = new Vector3(0f, 0f, value ? 15f : -15f);

            StopAllCoroutines();

            // Change the global gravity in the scene
            if (value)
            {
                Physics.gravity = previousGravity;
            }
            else
            {
                previousGravity = Physics.gravity;

                StartCoroutine(DisableGravity());
            }
        }

        gravityEnabled = m_gravityEnabled;
    }
    public virtual void OnNewPoses()
    {
        previousScannedDevice = currentScannedDevice;
        currentScannedDevice  = ViveRole.INVALID_DEVICE_INDEX;

        for (uint i = 0; i < ViveRole.MAX_DEVICE_COUNT; ++i)
        {
            if (ChangeProp.Set(ref deviceConnected[i], VivePose.IsConnected(i)))
            {
                connectedDeviceChanged = true;

                if (!deviceConnected[i] && sentDevice == i)
                {
                    if (sentDevice == i)
                    {
                        sentDevice = ViveRole.INVALID_DEVICE_INDEX;
                    }

                    if (scannedReticle != null)
                    {
                        scannedReticle.gameObject.SetActive(false);
                    }
                }
            }

            if (!deviceConnected[i])
            {
                continue;
            }

            var pose = VivePose.GetPose(i, VROrigin);

            if (sentDevice == i && scannedReticle != null)
            {
                scannedReticle.position = pose.pos;
            }

            hits[0] = null;
            var hitCount = Physics.OverlapSphereNonAlloc(pose.pos, radius, hits);
            if (hitCount > 0 && hits[0].transform.IsChildOf(transform))
            {
                if (!ViveRole.IsValidIndex(currentScannedDevice))
                {
                    // not scanned any device yet this frame
                    currentScannedDevice = i;
                }
                else
                {
                    // multiple device scanned this frame
                    currentScannedDevice = ViveRole.INVALID_DEVICE_INDEX;
                    break;
                }

                hits[0] = null;
            }
        }

        if (previousScannedDevice != currentScannedDevice)
        {
            lastScannedChangedTime = Time.time;
        }
    }
            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];
#else
                            if (Interop.WVR_GetWaveRuntimeVersion() >= 3 && WaveVR_Controller.IsLeftHanded)
                            {
                                loader.WhichHand = WaveVR_ControllerLoader.ControllerHand.Controller_Right;
                            }
                            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);
                    }
                }
            }
Example #22
0
    protected virtual void LateUpdate()
    {
        var needUpdate = false;

        switch (laserPointerActiveMode)
        {
        case LaserPointerActiveModeEnum.None:
            needUpdate |= SetRightLaserPointerActive(false);
            needUpdate |= SetLeftLaserPointerActive(false);
            break;

        case LaserPointerActiveModeEnum.ToggleByMenuClick:
            if (ViveInput.GetPressUpEx(HandRole.RightHand, ControllerButton.Menu))
            {
                ToggleRightLaserPointer();
                needUpdate = true;
            }

            if (ViveInput.GetPressUpEx(HandRole.LeftHand, ControllerButton.Menu))
            {
                ToggleLeftLaserPointer();
                needUpdate = true;
            }
            break;
        }

        switch (curvePointerActiveMode)
        {
        case CurvePointerActiveModeEnum.None:
            needUpdate |= SetRightCurvePointerActive(false);
            needUpdate |= SetLeftCurvePointerActive(false);
            break;

        case CurvePointerActiveModeEnum.ActiveOnPadPressed:
            needUpdate |= SetRightCurvePointerActive(ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Pad));
            needUpdate |= SetLeftCurvePointerActive(ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Pad));
            break;

        case CurvePointerActiveModeEnum.ToggleByPadDoubleClick:
            if (ViveInput.GetPressDownEx(HandRole.RightHand, ControllerButton.Pad) && ViveInput.ClickCountEx(HandRole.RightHand, ControllerButton.Pad) == 2)
            {
                ToggleRightCurvePointer();
                needUpdate = true;
            }

            if (ViveInput.GetPressDownEx(HandRole.LeftHand, ControllerButton.Pad) && ViveInput.ClickCountEx(HandRole.LeftHand, ControllerButton.Pad) == 2)
            {
                ToggleLeftCurvePointer();
                needUpdate = true;
            }
            break;
        }

        switch (customModelActiveMode)
        {
        case CustomModelActiveModeEnum.None:
            needUpdate |= ChangeProp.Set(ref m_rightCustomModelActive, false);
            needUpdate |= ChangeProp.Set(ref m_leftCustomModelActive, false);
            break;

        case CustomModelActiveModeEnum.ActiveOnGripped:
            needUpdate |= SetRightCustomModelActive(ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Grip));
            needUpdate |= SetLeftCustomModelActive(ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Grip));
            break;

        case CustomModelActiveModeEnum.ToggleByDoubleGrip:
            if (ViveInput.GetPressDownEx(HandRole.RightHand, ControllerButton.Grip) && ViveInput.ClickCountEx(HandRole.RightHand, ControllerButton.Grip) == 2)
            {
                ToggleRightCustomModel();
                needUpdate = true;
            }
            if (ViveInput.GetPressDownEx(HandRole.LeftHand, ControllerButton.Grip) && ViveInput.ClickCountEx(HandRole.LeftHand, ControllerButton.Grip) == 2)
            {
                ToggleLeftCustomModel();
                needUpdate = true;
            }
            break;
        }

        if (needUpdate)
        {
            UpdateActivity();
        }
    }
Example #23
0
        private void UpdateDeviceConnectionAndPose(bool obj)
        {
            IVRModuleDeviceState   prevState;
            IVRModuleDeviceStateRW currState;

            FlushDeviceState();

            var vrSystem     = OpenVR.System;
            var vrCompositor = OpenVR.Compositor;

            if (vrSystem == null || vrCompositor == null)
            {
                // clear all device states if OpenVR disabled
                for (uint i = 0, imax = GetDeviceStateLength(); i < imax; ++i)
                {
                    if (TryGetValidDeviceState(i, out prevState, out currState) && currState.isConnected)
                    {
                        currState.Reset();
                    }
                }
            }
            else
            {
                vrCompositor.GetLastPoses(m_poses, m_gamePoses);

                for (uint i = 0u, imax = (uint)m_poses.Length; i < imax; ++i)
                {
                    if (!m_poses[i].bDeviceIsConnected)
                    {
                        uint moduleIndex;
                        if (m_indexMap.UnmapTracked(i, out moduleIndex))
                        {
                            if (TryGetValidDeviceState(moduleIndex, out prevState, out currState))
                            {
                                currState.Reset();
                            }
                        }
                    }
                    else
                    {
                        uint moduleIndex;
                        if (!m_indexMap.TryGetModuleIndex(i, out moduleIndex))
                        {
                            moduleIndex = FindAndEnsureUnusedNotHMDDeviceState(out prevState, out currState);
                            m_indexMap.Map(i, moduleIndex);
                        }
                        else
                        {
                            EnsureValidDeviceState(moduleIndex, out prevState, out currState);
                        }

                        if (!prevState.isConnected)
                        {
                            currState.isConnected     = true;
                            currState.deviceClass     = ToVRModuleDeviceClass(vrSystem.GetTrackedDeviceClass(i));
                            currState.serialNumber    = QueryDeviceStringProperty(vrSystem, i, ETrackedDeviceProperty.Prop_SerialNumber_String);
                            currState.modelNumber     = QueryDeviceStringProperty(vrSystem, i, ETrackedDeviceProperty.Prop_ModelNumber_String);
                            currState.renderModelName = QueryDeviceStringProperty(vrSystem, i, ETrackedDeviceProperty.Prop_RenderModelName_String);

                            SetupKnownDeviceModel(currState);
                        }

                        // update device status
                        currState.isPoseValid     = m_poses[i].bPoseIsValid;
                        currState.isOutOfRange    = m_poses[i].eTrackingResult == ETrackingResult.Running_OutOfRange || m_poses[i].eTrackingResult == ETrackingResult.Calibrating_OutOfRange;
                        currState.isCalibrating   = m_poses[i].eTrackingResult == ETrackingResult.Calibrating_InProgress || m_poses[i].eTrackingResult == ETrackingResult.Calibrating_OutOfRange;
                        currState.isUninitialized = m_poses[i].eTrackingResult == ETrackingResult.Uninitialized;
                        currState.velocity        = new Vector3(m_poses[i].vVelocity.v0, m_poses[i].vVelocity.v1, -m_poses[i].vVelocity.v2);
                        currState.angularVelocity = new Vector3(-m_poses[i].vAngularVelocity.v0, -m_poses[i].vAngularVelocity.v1, m_poses[i].vAngularVelocity.v2);

                        var rigidTransform = new SteamVR_Utils.RigidTransform(m_poses[i].mDeviceToAbsoluteTracking);
                        currState.position = rigidTransform.pos;
                        currState.rotation = rigidTransform.rot;
                    }
                }
            }

            m_submodules.UpdateAllModulesActivity();
            m_submodules.UpdateModulesDeviceConnectionAndPoses();

            // process hand role
            bool roleChanged = false;

            if (vrSystem == null)
            {
                m_openvrRightIndex = INVALID_DEVICE_INDEX;
                m_openvrLeftIndex  = INVALID_DEVICE_INDEX;
            }
            else
            {
                var right = vrSystem.GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole.RightHand);
                var left  = vrSystem.GetTrackedDeviceIndexForControllerRole(ETrackedControllerRole.LeftHand);

                uint openvrRight;
                m_indexMap.TryGetModuleIndex(right, out openvrRight);
                roleChanged |= ChangeProp.Set(ref m_openvrRightIndex, openvrRight);

                uint openvrLeft;
                m_indexMap.TryGetModuleIndex(left, out openvrLeft);
                roleChanged |= ChangeProp.Set(ref m_openvrLeftIndex, openvrLeft);
            }

            var moduleRight = m_openvrRightIndex != INVALID_DEVICE_INDEX ? m_openvrRightIndex : m_submodules.GetFirstRightHandedIndex();
            var moduleLeft  = m_openvrLeftIndex != INVALID_DEVICE_INDEX ? m_openvrLeftIndex : m_submodules.GetFirstLeftHandedIndex();

            roleChanged |= ChangeProp.Set(ref m_moduleRightIndex, moduleRight);
            roleChanged |= ChangeProp.Set(ref m_moduleLeftIndex, moduleLeft);

            UpdateHandJoints(m_openvrLeftIndex, skeletonActionHandleLeft, true);
            UpdateHandJoints(m_openvrRightIndex, skeletonActionHandleRight, false);

            ProcessConnectedDeviceChanged();
            ProcessDevicePoseChanged();

            if (roleChanged)
            {
                InvokeControllerRoleChangedEvent();
            }
        }
Example #24
0
        public sealed override void BeforeRenderUpdate()
        {
            if (knownActiveInputSubsystem == VRModuleKnownXRInputSubsystem.Unknown)
            {
                knownActiveInputSubsystem = GetKnownActiveInputSubsystem();
            }

            // update device connection and poses
            IVRModuleDeviceState   prevState;
            IVRModuleDeviceStateRW currState;
            uint deviceIndex;

            FlushDeviceState();

            // mark all devices as disconnected
            // therefore, if a device should stay alive in this frame
            // should be set as connected in the next stage
            deviceIndex = 0u;
            for (var len = GetDeviceStateLength(); deviceIndex < len; ++deviceIndex)
            {
                if (TryGetValidDeviceState(deviceIndex, out prevState, out currState))
                {
                    currState.isConnected = false;
                }
            }

            InputDevices.GetDevices(connectedDevices);

            foreach (var device in connectedDevices)
            {
                if (!indexMap.TryGetIndex(device, out deviceIndex))
                {
                    if (indexMap.TryMapAsHMD(device))
                    {
                        deviceIndex = VRModule.HMD_DEVICE_INDEX;
                        EnsureValidDeviceState(deviceIndex, out prevState, out currState);
                    }
                    else
                    {
                        // this function will skip VRModule.HMD_DEVICE_INDEX (preserved index for HMD)
                        deviceIndex = FindAndEnsureUnusedNotHMDDeviceState(out prevState, out currState);
                        indexMap.MapNonHMD(device, deviceIndex);
                    }

                    currState.deviceClass     = GetDeviceClass(device.name, device.characteristics);
                    currState.serialNumber    = device.name + " " + device.serialNumber + " " + (int)device.characteristics;
                    currState.modelNumber     = device.name + " (" + device.characteristics + ")";
                    currState.renderModelName = device.name + " (" + device.characteristics + ")";

                    SetupKnownDeviceModel(currState);

                    Debug.LogFormat("Device connected: {0} / {1} / {2} / {3} / {4} / {5} ({6})",
                                    currState.deviceIndex,
                                    currState.deviceClass,
                                    currState.deviceModel,
                                    currState.modelNumber,
                                    currState.serialNumber,
                                    device.name,
                                    device.characteristics);

                    if ((device.characteristics & InputDeviceCharacteristics.Right) > 0u)
                    {
                        uxrRightIndex = deviceIndex;
                    }
                    else if ((device.characteristics & InputDeviceCharacteristics.Left) > 0u)
                    {
                        uxrLeftIndex = deviceIndex;
                    }

                    UpdateNewConnectedInputDevice(currState, device);
                }
                else
                {
                    EnsureValidDeviceState(deviceIndex, out prevState, out currState);
                }
                currState.isConnected = true;
                // update device Poses
                currState.isPoseValid     = GetDeviceFeatureValueOrDefault(device, CommonUsages.isTracked);
                currState.position        = GetDeviceFeatureValueOrDefault(device, CommonUsages.devicePosition);
                currState.rotation        = GetDeviceFeatureValueOrDefault(device, CommonUsages.deviceRotation);
                currState.velocity        = GetDeviceFeatureValueOrDefault(device, CommonUsages.deviceVelocity);
                currState.angularVelocity = GetDeviceFeatureValueOrDefault(device, CommonUsages.deviceAngularVelocity);

                // TODO: update hand skeleton pose
            }

            // unmap index for disconnected device state
            deviceIndex = 0u;
            for (var len = GetDeviceStateLength(); deviceIndex < len; ++deviceIndex)
            {
                if (indexMap.IsMapped(deviceIndex))
                {
                    EnsureValidDeviceState(deviceIndex, out prevState, out currState);
                    if (prevState.isConnected && !currState.isConnected)
                    {
                        indexMap.UnmapByIndex(deviceIndex);
                        currState.Reset();
                        if (uxrRightIndex == deviceIndex)
                        {
                            uxrRightIndex = INVALID_DEVICE_INDEX;
                        }
                        if (uxrLeftIndex == deviceIndex)
                        {
                            uxrLeftIndex = INVALID_DEVICE_INDEX;
                        }
                    }
                }
            }

            submodules.UpdateModulesDeviceConnectionAndPoses();

            // process hand role
            var subRightIndex = submodules.GetFirstRightHandedIndex();
            var currentRight  = (subRightIndex == INVALID_DEVICE_INDEX || (TryGetValidDeviceState(uxrRightIndex, out prevState, out currState) && currState.isPoseValid)) ? uxrRightIndex : subRightIndex;
            var subLeftIndex  = submodules.GetFirstLeftHandedIndex();
            var currentLeft   = (subLeftIndex == INVALID_DEVICE_INDEX || (TryGetValidDeviceState(uxrLeftIndex, out prevState, out currState) && currState.isPoseValid)) ? uxrLeftIndex : subLeftIndex;
            var roleChanged   = ChangeProp.Set(ref moduleRightIndex, currentRight);

            roleChanged |= ChangeProp.Set(ref moduleLeftIndex, currentLeft);

            if (roleChanged)
            {
                InvokeControllerRoleChangedEvent();
            }

            ProcessConnectedDeviceChanged();
            ProcessDevicePoseChanged();
        }
        private void UpdateWaveVRModel()
        {
            if (!ChangeProp.Set(ref m_currentDeviceIndex, GetCurrentDeviceIndex()))
            {
                return;
            }

            var hasValidModel = false;
            var handType      = default(wvr.WVR_DeviceType);

            if (VRModule.IsValidDeviceIndex(m_currentDeviceIndex))
            {
                if (m_currentDeviceIndex == VRModule.GetRightControllerDeviceIndex())
                {
                    hasValidModel = true;
                    handType      = wvr.WVR_DeviceType.WVR_DeviceType_Controller_Right;
                }
                else if (m_currentDeviceIndex == VRModule.GetLeftControllerDeviceIndex())
                {
                    hasValidModel = true;
                    handType      = wvr.WVR_DeviceType.WVR_DeviceType_Controller_Left;
                }
            }

            // NOTE: load renderModel only if it hasen't been loaded or user changes handType
            if (hasValidModel)
            {
                if (m_modelObj != null)
                {
                    if (!m_waveVRModelLoaded)
                    {
                        // Clean up model that created by other module
                        CleanUpModelObj();
                    }
                    else if (m_currentWaveVRHandType != handType)
                    {
                        // Clean up model if changed to different hand
                        CleanUpModelObj();
                    }
                }

                m_currentWaveVRHandType = handType;

                if (!m_waveVRModelLoaded)
                {
                    // Create WaveVR_ControllerLoader silently (to avoid Start and OnEnable)
                    var loaderGO = new GameObject("Loader");
                    loaderGO.transform.SetParent(transform, false);
                    loaderGO.SetActive(false);
                    var loader = loaderGO.AddComponent <WaveVR_ControllerLoader>();
                    loader.enabled       = false;
                    loader.TrackPosition = false;
                    loader.TrackRotation = false;
                    loader.showIndicator = false;
                    loaderGO.SetActive(true);
                    // Call onLoadController to create model (chould be Finch/Link/Pico/QIYIVR)
                    switch (handType)
                    {
                    case wvr.WVR_DeviceType.WVR_DeviceType_Controller_Right:
                        loader.WhichHand = WaveVR_ControllerLoader.ControllerHand.Controller_Right;
                        loaderGO.SendMessage("onLoadController", wvr.WVR_DeviceType.WVR_DeviceType_Controller_Right);
                        break;

                    case wvr.WVR_DeviceType.WVR_DeviceType_Controller_Left:
                        loader.WhichHand = WaveVR_ControllerLoader.ControllerHand.Controller_Left;
                        loaderGO.SendMessage("onLoadController", wvr.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(transform, false);
                        ctrllerActions.transform.SetAsFirstSibling();
                        for (int i = transform.childCount - 1; i >= 1; --i)
                        {
                            Destroy(transform.GetChild(i).gameObject);
                        }
                        ctrllerActions.gameObject.SetActive(true);
                        m_modelObj = ctrllerActions.gameObject;
                    }
                    else
                    {
                        Debug.LogWarning("FindWaveVRControllerActionsObjInChildren failed");
                        for (int i = transform.childCount - 1; i >= 0; --i)
                        {
                            Destroy(transform.GetChild(i).gameObject);
                        }
                    }

                    m_waveVRModelLoaded = true;
                }
                else
                {
                    if (m_modelObj != null)
                    {
                        m_modelObj.SetActive(true);
                    }
                }
            }
            else
            {
                if (m_modelObj != null)
                {
                    m_modelObj.SetActive(false);
                }
            }
        }
Example #26
0
            // return true if frame skipped
            public override bool Update()
            {
                if (!ChangeProp.Set(ref updatedFrameCount, Time.frameCount))
                {
                    return(true);
                }

                var deviceIndex = m_map.GetMappedDeviceByRoleValue(m_roleValue);

                // treat this frame as updated if both prevDeviceIndex and currentDeviceIndex are invalid
                if (!VRModule.IsValidDeviceIndex(prevDeviceIndex) && !VRModule.IsValidDeviceIndex(deviceIndex))
                {
                    return(false);
                }

                // get device state
                var currState = VRModule.GetCurrentDeviceState(deviceIndex);

                // copy to previous states
                prevDeviceIndex   = deviceIndex;
                prevButtonPressed = currButtonPressed;
                for (int i = CONTROLLER_AXIS_COUNT - 1; i >= 0; --i)
                {
                    prevAxisValue[i] = currAxisValue[i];
                }

                trackedDeviceModel = currState.deviceModel;

                // update button states
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.System, currState.GetButtonPress(VRModuleRawButton.System));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Menu, currState.GetButtonPress(VRModuleRawButton.ApplicationMenu));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.MenuTouch, currState.GetButtonTouch(VRModuleRawButton.ApplicationMenu));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Trigger, currState.GetButtonPress(VRModuleRawButton.Trigger));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.TriggerTouch, currState.GetButtonTouch(VRModuleRawButton.Trigger));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Pad, currState.GetButtonPress(VRModuleRawButton.Touchpad));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.PadTouch, currState.GetButtonTouch(VRModuleRawButton.Touchpad));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Grip, currState.GetButtonPress(VRModuleRawButton.Grip));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.GripTouch, currState.GetButtonTouch(VRModuleRawButton.Grip));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.CapSenseGrip, currState.GetButtonPress(VRModuleRawButton.CapSenseGrip));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.CapSenseGripTouch, currState.GetButtonTouch(VRModuleRawButton.CapSenseGrip));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.AKey, currState.GetButtonPress(VRModuleRawButton.A));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.AKeyTouch, currState.GetButtonTouch(VRModuleRawButton.A));

                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Axis3, currState.GetButtonPress(VRModuleRawButton.Axis3));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Axis3Touch, currState.GetButtonTouch(VRModuleRawButton.Axis3));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Axis4, currState.GetButtonPress(VRModuleRawButton.Axis4));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Axis4Touch, currState.GetButtonTouch(VRModuleRawButton.Axis4));

                // update axis values
                currAxisValue[(int)ControllerAxis.PadX]         = currState.GetAxisValue(VRModuleRawAxis.TouchpadX);
                currAxisValue[(int)ControllerAxis.PadY]         = currState.GetAxisValue(VRModuleRawAxis.TouchpadY);
                currAxisValue[(int)ControllerAxis.Trigger]      = currState.GetAxisValue(VRModuleRawAxis.Trigger);
                currAxisValue[(int)ControllerAxis.CapSenseGrip] = currState.GetAxisValue(VRModuleRawAxis.CapSenseGrip);
                currAxisValue[(int)ControllerAxis.IndexCurl]    = currState.GetAxisValue(VRModuleRawAxis.IndexCurl);
                currAxisValue[(int)ControllerAxis.MiddleCurl]   = currState.GetAxisValue(VRModuleRawAxis.MiddleCurl);
                currAxisValue[(int)ControllerAxis.RingCurl]     = currState.GetAxisValue(VRModuleRawAxis.RingCurl);
                currAxisValue[(int)ControllerAxis.PinkyCurl]    = currState.GetAxisValue(VRModuleRawAxis.PinkyCurl);

                // update hair trigger
                var currTriggerValue = currAxisValue[(int)ControllerAxis.Trigger];

                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.FullTrigger, currTriggerValue == 1f);
                if (EnumUtils.GetFlag(prevButtonPressed, (int)ControllerButton.HairTrigger))
                {
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.HairTrigger, currTriggerValue >= (hairTriggerLimit - hairDelta) && currTriggerValue > 0.0f);
                }
                else
                {
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.HairTrigger, currTriggerValue > (hairTriggerLimit + hairDelta) || currTriggerValue >= 1.0f);
                }

                if (EnumUtils.GetFlag(currButtonPressed, (int)ControllerButton.HairTrigger))
                {
                    hairTriggerLimit = Mathf.Max(hairTriggerLimit, currTriggerValue);
                }
                else
                {
                    hairTriggerLimit = Mathf.Min(hairTriggerLimit, currTriggerValue);
                }

                // record pad down axis values
                if (GetPressDown(ControllerButton.Pad))
                {
                    padDownAxis = new Vector2(currAxisValue[(int)ControllerAxis.PadX], currAxisValue[(int)ControllerAxis.PadY]);
                }

                if (GetPressDown(ControllerButton.PadTouch))
                {
                    padTouchDownAxis = new Vector2(currAxisValue[(int)ControllerAxis.PadX], currAxisValue[(int)ControllerAxis.PadY]);
                }

                // record press down time and click count
                var timeNow = Time.unscaledTime;

                for (int button = 0; button < CONTROLLER_BUTTON_COUNT; ++button)
                {
                    if (GetPressDown((ControllerButton)button))
                    {
                        if (timeNow - lastPressDownTime[button] < clickInterval)
                        {
                            ++clickCount[button];
                        }
                        else
                        {
                            clickCount[button] = 1;
                        }

                        lastPressDownTime[button] = timeNow;
                    }
                }

                // invoke event listeners
                for (ControllerButton button = 0; button < (ControllerButton)CONTROLLER_BUTTON_COUNT; ++button)
                {
                    if (GetPress(button))
                    {
                        if (GetPressDown(button))
                        {
                            // PressDown event
                            TryInvokeListener(button, ButtonEventType.Down);
                            TryInvokeTypeListener(button, ButtonEventType.Down);
                        }

                        // Press event
                        TryInvokeListener(button, ButtonEventType.Press);
                        TryInvokeTypeListener(button, ButtonEventType.Press);
                    }
                    else if (GetPressUp(button))
                    {
                        // PressUp event
                        TryInvokeListener(button, ButtonEventType.Up);
                        TryInvokeTypeListener(button, ButtonEventType.Up);

                        if (timeNow - lastPressDownTime[(int)button] < clickInterval)
                        {
                            // Click event
                            TryInvokeListener(button, ButtonEventType.Click);
                            TryInvokeTypeListener(button, ButtonEventType.Click);
                        }
                    }
                }

                return(false);
            }
            // return true if frame skipped
            public override bool Update()
            {
                if (!ChangeProp.Set(ref updatedFrameCount, Time.frameCount))
                {
                    return(true);
                }

                var deviceIndex = m_map.GetMappedDeviceByRoleValue(m_roleValue);

                // treat this frame as updated if both prevDeviceIndex and currentDeviceIndex are invalid
                if (!VRModule.IsValidDeviceIndex(prevDeviceIndex) && !VRModule.IsValidDeviceIndex(deviceIndex))
                {
                    return(false);
                }

                // get device state
                var currState = VRModule.GetCurrentDeviceState(deviceIndex);

                // copy to previous states and reset current state
                prevDeviceIndex = deviceIndex;

                prevButtonPressed  = currButtonPressed;
                currButtonPressed  = 0;
                currentInput2DType = currState.input2DType;

                for (int i = CONTROLLER_AXIS_COUNT - 1; i >= 0; --i)
                {
                    prevAxisValue[i] = currAxisValue[i];
                    currAxisValue[i] = 0f;
                }

                // update button states
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.System, currState.GetButtonPress(VRModuleRawButton.System));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Menu, currState.GetButtonPress(VRModuleRawButton.ApplicationMenu));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.MenuTouch, currState.GetButtonTouch(VRModuleRawButton.ApplicationMenu));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Trigger, currState.GetButtonPress(VRModuleRawButton.Trigger));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.TriggerTouch, currState.GetButtonTouch(VRModuleRawButton.Trigger));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Pad, currState.GetButtonPress(VRModuleRawButton.Touchpad));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.PadTouch, currState.GetButtonTouch(VRModuleRawButton.Touchpad));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Grip, currState.GetButtonPress(VRModuleRawButton.Grip));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.GripTouch, currState.GetButtonTouch(VRModuleRawButton.Grip));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.CapSenseGrip, currState.GetButtonPress(VRModuleRawButton.CapSenseGrip));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.CapSenseGripTouch, currState.GetButtonTouch(VRModuleRawButton.CapSenseGrip));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.ProximitySensor, currState.GetButtonPress(VRModuleRawButton.ProximitySensor));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.AKey, currState.GetButtonPress(VRModuleRawButton.A));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.AKeyTouch, currState.GetButtonTouch(VRModuleRawButton.A));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Bumper, currState.GetButtonPress(VRModuleRawButton.Bumper));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.BumperTouch, currState.GetButtonTouch(VRModuleRawButton.Bumper));

                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Axis4, currState.GetButtonPress(VRModuleRawButton.Axis4));
                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.Axis4Touch, currState.GetButtonTouch(VRModuleRawButton.Axis4));

                // update axis values
                currAxisValue[(int)ControllerAxis.PadX]         = currState.GetAxisValue(VRModuleRawAxis.TouchpadX);
                currAxisValue[(int)ControllerAxis.PadY]         = currState.GetAxisValue(VRModuleRawAxis.TouchpadY);
                currAxisValue[(int)ControllerAxis.Trigger]      = currState.GetAxisValue(VRModuleRawAxis.Trigger);
                currAxisValue[(int)ControllerAxis.CapSenseGrip] = currState.GetAxisValue(VRModuleRawAxis.CapSenseGrip);
                currAxisValue[(int)ControllerAxis.IndexCurl]    = currState.GetAxisValue(VRModuleRawAxis.IndexCurl);
                currAxisValue[(int)ControllerAxis.MiddleCurl]   = currState.GetAxisValue(VRModuleRawAxis.MiddleCurl);
                currAxisValue[(int)ControllerAxis.RingCurl]     = currState.GetAxisValue(VRModuleRawAxis.RingCurl);
                currAxisValue[(int)ControllerAxis.PinkyCurl]    = currState.GetAxisValue(VRModuleRawAxis.PinkyCurl);

                switch (currentInput2DType)
                {
                case VRModuleInput2DType.Unknown:
                case VRModuleInput2DType.TrackpadOnly:
                    currAxisValue[(int)ControllerAxis.PadX] = currState.GetAxisValue(VRModuleRawAxis.TouchpadX);
                    currAxisValue[(int)ControllerAxis.PadY] = currState.GetAxisValue(VRModuleRawAxis.TouchpadY);
                    if (!VIUSettings.individualTouchpadJoystickValue)
                    {
                        currAxisValue[(int)ControllerAxis.JoystickX] = currState.GetAxisValue(VRModuleRawAxis.TouchpadX);
                        currAxisValue[(int)ControllerAxis.JoystickY] = currState.GetAxisValue(VRModuleRawAxis.TouchpadY);
                    }
                    break;

                case VRModuleInput2DType.JoystickOnly:
                    currAxisValue[(int)ControllerAxis.JoystickX] = currState.GetAxisValue(VRModuleRawAxis.TouchpadX);
                    currAxisValue[(int)ControllerAxis.JoystickY] = currState.GetAxisValue(VRModuleRawAxis.TouchpadY);
                    if (!VIUSettings.individualTouchpadJoystickValue)
                    {
                        currAxisValue[(int)ControllerAxis.PadX] = currState.GetAxisValue(VRModuleRawAxis.TouchpadX);
                        currAxisValue[(int)ControllerAxis.PadY] = currState.GetAxisValue(VRModuleRawAxis.TouchpadY);
                    }
                    break;

                case VRModuleInput2DType.Both:
                    currAxisValue[(int)ControllerAxis.PadX]      = currState.GetAxisValue(VRModuleRawAxis.TouchpadX);
                    currAxisValue[(int)ControllerAxis.PadY]      = currState.GetAxisValue(VRModuleRawAxis.TouchpadY);
                    currAxisValue[(int)ControllerAxis.JoystickX] = currState.GetAxisValue(VRModuleRawAxis.JoystickX);
                    currAxisValue[(int)ControllerAxis.JoystickY] = currState.GetAxisValue(VRModuleRawAxis.JoystickY);
                    break;
                }

                // update d-pad
                var axis     = new Vector2(currAxisValue[(int)ControllerAxis.PadX], currAxisValue[(int)ControllerAxis.PadY]);
                var deadZone = VIUSettings.virtualDPadDeadZone;

                if (axis.sqrMagnitude >= deadZone * deadZone)
                {
                    var padPress = GetPress(ControllerButton.Pad);
                    var padTouch = GetPress(ControllerButton.PadTouch);

                    var right = Vector2.Angle(Vector2.right, axis) < 45f;
                    var up    = Vector2.Angle(Vector2.up, axis) < 45f;
                    var left  = Vector2.Angle(Vector2.left, axis) < 45f;
                    var down  = Vector2.Angle(Vector2.down, axis) < 45f;

                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadRight, padPress && right);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadUp, padPress && up);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadLeft, padPress && left);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadDown, padPress && down);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadRightTouch, padTouch && right);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadUpTouch, padTouch && up);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadLeftTouch, padTouch && left);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadDownTouch, padTouch && down);

                    var upperRight = axis.x > 0f && axis.y > 0f;
                    var upperLeft  = axis.x <0f && axis.y> 0f;
                    var lowerLeft  = axis.x < 0f && axis.y < 0f;
                    var lowerRight = axis.x > 0f && axis.y < 0f;

                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadUpperRight, padPress && upperRight);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadUpperLeft, padPress && upperLeft);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadLowerLeft, padPress && lowerLeft);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadLowerRight, padPress && lowerRight);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadUpperRightTouch, padTouch && upperRight);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadUpperLeftTouch, padTouch && upperLeft);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadLowerLeftTouch, padTouch && lowerLeft);
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.DPadLowerRightTouch, padTouch && lowerRight);
                }

                // update hair trigger
                var currTriggerValue = currAxisValue[(int)ControllerAxis.Trigger];

                EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.FullTrigger, currTriggerValue >= 0.99f);

                if (EnumUtils.GetFlag(prevButtonPressed, (int)ControllerButton.HairTrigger))
                {
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.HairTrigger, currTriggerValue >= (hairTriggerLimit - hairDelta) && currTriggerValue > 0.0f);
                }
                else
                {
                    EnumUtils.SetFlag(ref currButtonPressed, (int)ControllerButton.HairTrigger, currTriggerValue > (hairTriggerLimit + hairDelta) || currTriggerValue >= 1.0f);
                }

                if (EnumUtils.GetFlag(currButtonPressed, (int)ControllerButton.HairTrigger))
                {
                    hairTriggerLimit = Mathf.Max(hairTriggerLimit, currTriggerValue);
                }
                else
                {
                    hairTriggerLimit = Mathf.Min(hairTriggerLimit, currTriggerValue);
                }

                // record pad down axis values
                if (GetPressDown(ControllerButton.Pad))
                {
                    padDownAxis = new Vector2(currAxisValue[(int)ControllerAxis.PadX], currAxisValue[(int)ControllerAxis.PadY]);
                }

                if (GetPressDown(ControllerButton.PadTouch))
                {
                    padTouchDownAxis = new Vector2(currAxisValue[(int)ControllerAxis.PadX], currAxisValue[(int)ControllerAxis.PadY]);
                }

                // record press down time and click count
                var timeNow = Time.unscaledTime;

                for (int button = 0; button < CONTROLLER_BUTTON_COUNT; ++button)
                {
                    if (GetPressDown((ControllerButton)button))
                    {
                        if (timeNow - lastPressDownTime[button] < clickInterval)
                        {
                            ++clickCount[button];
                        }
                        else
                        {
                            clickCount[button] = 1;
                        }

                        lastPressDownTime[button] = timeNow;
                    }
                }

                // invoke event listeners
                for (ControllerButton button = 0; button < (ControllerButton)CONTROLLER_BUTTON_COUNT; ++button)
                {
                    if (GetPress(button))
                    {
                        if (GetPressDown(button))
                        {
                            // PressDown event
                            TryInvokeListener(button, ButtonEventType.Down);
                            TryInvokeTypeListener(button, ButtonEventType.Down);
                        }

                        // Press event
                        TryInvokeListener(button, ButtonEventType.Press);
                        TryInvokeTypeListener(button, ButtonEventType.Press);
                    }
                    else if (GetPressUp(button))
                    {
                        // PressUp event
                        TryInvokeListener(button, ButtonEventType.Up);
                        TryInvokeTypeListener(button, ButtonEventType.Up);

                        if (timeNow - lastPressDownTime[(int)button] < clickInterval)
                        {
                            // Click event
                            TryInvokeListener(button, ButtonEventType.Click);
                            TryInvokeTypeListener(button, ButtonEventType.Click);
                        }
                    }
                }

                return(false);
            }