private bool TryGetAndTouchDeviceIndexByType(WVR_DeviceType type, out uint deviceIndex)
        {
            if (type < 0 || (int)type >= s_type2index.Length)
            {
                deviceIndex = INVALID_DEVICE_INDEX;
                return(false);
            }

            deviceIndex = s_type2index[(int)type];
            if (VRModule.IsValidDeviceIndex(deviceIndex))
            {
                m_index2deviceTouched[deviceIndex] = true;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 2
0
            // deviceSN must be valid
            // device must be bound
            // device can be whether connected or not
            private void InternalUnbind(string deviceSN, int boundRoleValue)
            {
                var deviceIndex = VRModule.GetConnectedDeviceIndex(deviceSN);

                if (!m_sn2role.Remove(deviceSN))
                {
                    throw new Exception("device([" + deviceIndex + "]" + deviceSN + ") already unbound");
                }

                if (VRModule.IsValidDeviceIndex(deviceIndex))
                {
                    InternalRemoveRoleBoundDevice(deviceSN, deviceIndex, boundRoleValue);
                }

                if (m_handler != null)
                {
                    m_handler.OnBindingRoleValueChanged(deviceSN, true, boundRoleValue, false, m_info.InvalidRoleValue);
                }
            }
    public void UpdateStatus()
    {
        if (!VivePose.IsConnected(m_deviceIndex))
        {
            m_deviceIndex = VRModule.INVALID_DEVICE_INDEX;

            textDeviceIndex.text = string.Empty;
            textDeviceClass.text = string.Empty;
            textSerialNum.text   = string.Empty;
            textModelNum.text    = string.Empty;
        }
        else
        {
            var deviceState = VRModule.GetCurrentDeviceState(m_deviceIndex);
            textDeviceIndex.text = m_deviceIndex.ToString();
            textDeviceClass.text = deviceState.deviceClass.ToString();;
            textSerialNum.text   = deviceState.serialNumber;
            textModelNum.text    = deviceState.modelNumber;
        }
    }
Exemplo n.º 4
0
    /// <summary>
    /// When scalingActivated is true and both triggers are pressed,
    /// scale the game object base on the change of distance between two controllers
    /// </summary>
    void Update()
    {
        if (scalingActivated &&
            ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.Trigger) &&
            ViveInput.GetPressEx(HandRole.LeftHand, ControllerButton.Trigger))
        // Conditions for active scaling
        {
            var rightHandIndex = ViveRole.GetDeviceIndexEx(HandRole.RightHand);
            var leftHandIndex  = ViveRole.GetDeviceIndexEx(HandRole.LeftHand);

            if (VRModule.IsValidDeviceIndex(rightHandIndex) && VRModule.IsValidDeviceIndex(leftHandIndex))
            {
                var rightHandState = VRModule.GetDeviceState(rightHandIndex);
                var leftHandState  = VRModule.GetDeviceState(leftHandIndex);
                // Get device state for both hands

                float dist = Vector3.Distance(rightHandState.position, leftHandState.position);

                if (prevDist == 0)
                {
                    prevDist = dist;
                }
                else
                {
                    // Scaling the object based on distance change
                    gameObject.transform.localScale *= (1 + scalingFactor * (dist - prevDist));
                    prevDist = dist;
                }
            }
            else
            {
                Debug.Log("Scaling: controller state error");
            }
        }

        if (ViveInput.GetPressUpEx(HandRole.RightHand, ControllerButton.Trigger) ||
            ViveInput.GetPressUpEx(HandRole.LeftHand, ControllerButton.Trigger))
        {
            prevDist = 0.0f;
        }
    }
Exemplo n.º 5
0
        private static int CompareDirection(uint d1, uint d2)
        {
            var d1Point = s_deviceDirPoint[d1];
            var d2Point = s_deviceDirPoint[d2];
            var d1Valid = VRModule.IsValidDeviceIndex(d1) && d1Point >= 0f;
            var d2Valid = VRModule.IsValidDeviceIndex(d2) && d2Point >= 0f;

            if (!d1Valid || !d2Valid)
            {
                if (d1Valid)
                {
                    return(-1);
                }
                if (d2Valid)
                {
                    return(1);
                }

                if (d1 < d2)
                {
                    return(-1);
                }
                if (d1 > d2)
                {
                    return(1);
                }

                return(0);
            }

            if (d1Point < d2Point)
            {
                return(-1);
            }
            if (d1Point > d2Point)
            {
                return(1);
            }

            return(0);
        }
        private static void OnDeviceConnected(uint deviceIndex, bool connected)
        {
            var prevState = VRModule.GetPreviousDeviceState(deviceIndex);
            var currState = VRModule.GetCurrentDeviceState(deviceIndex);

            // update serial number table and model number table
            if (connected)
            {
                for (int i = s_mapTable.Count - 1; i >= 0; --i)
                {
                    s_mapTable.GetValueByIndex(i).OnConnectedDeviceChanged(deviceIndex, currState.deviceClass, currState.serialNumber, true);
                }
            }
            else
            {
                for (int i = s_mapTable.Count - 1; i >= 0; --i)
                {
                    s_mapTable.GetValueByIndex(i).OnConnectedDeviceChanged(deviceIndex, prevState.deviceClass, prevState.serialNumber, false);
                }
            }
        }
        public void Refresh()
        {
            var deviceIndex = 0u;

            for (var role = RoleInfo.MinValidRole; role <= RoleInfo.MaxValidRole && deviceIndex < VRModule.MAX_DEVICE_COUNT; ++role, ++deviceIndex)
            {
                if (!RoleInfo.IsValidRole(role))
                {
                    continue;
                }

                if (VRModule.GetCurrentDeviceState(deviceIndex).isConnected)
                {
                    MappingRoleIfUnbound(role, deviceIndex);
                }
                else
                {
                    UnmappingRole(role);
                }
            }
        }
 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) || m_modelObj == null)
             {
                 ReloadedStaticModel(m_currentLoadedStaticModel);
             }
             else
             {
                 m_modelObj.SetActive(true);
             }
         }
         else
         {
             m_modelObj.SetActive(false);
         }
     }
 }
Exemplo n.º 9
0
 public void CheckInputDeviceSN(string inputStr)
 {
     if (string.IsNullOrEmpty(inputStr))
     {
         m_buttonCheck.interactable = false;
         m_modelIcon.gameObject.SetActive(false);
     }
     else
     {
         m_buttonCheck.interactable = true;
         m_modelIcon.gameObject.SetActive(true);
         uint deviceIndex;
         if (VRModule.TryGetConnectedDeviceIndex(inputStr, out deviceIndex))
         {
             BindingInterfaceSpriteManager.SetupDeviceIcon(m_modelIcon, VRModule.GetCurrentDeviceState(deviceIndex).deviceModel, true);
         }
         else
         {
             BindingInterfaceSpriteManager.SetupDeviceIcon(m_modelIcon, ViveRoleBindingsHelper.GetDeviceModelHint(inputStr), false);
         }
     }
 }
        private void UpdateModel()
        {
            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
                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));
                }
            }
        }
Exemplo n.º 11
0
 private void UpdateExCamActivity()
 {
     if (!enabled)
     {
         SetValid(false);
         VivePose.RemoveNewPosesListener(this);
     }
     else if (VRModule.IsValidDeviceIndex(m_viveRole.GetDeviceIndex()))
     {
         SetValid(m_quadViewEnabled);
         VivePose.AddNewPosesListener(this);
     }
     else if (m_staticExCamEnabled)
     {
         SetValid(m_quadViewEnabled);
         VivePose.AddNewPosesListener(this);
     }
     else
     {
         SetValid(false);
         VivePose.RemoveNewPosesListener(this);
     }
 }
Exemplo n.º 12
0
        public void EnableTracking()
        {
            if (m_trackingEnabled)
            {
                return;
            }
            m_trackingEnabled = true;

            Initialize();

            m_inputDeviceSN.text = string.Empty;
            CheckInputDeviceSN(string.Empty);

            for (uint deviceIndex = 0, imax = VRModule.GetDeviceStateCount(); deviceIndex < imax; ++deviceIndex)
            {
                if (VRModule.GetCurrentDeviceState(deviceIndex).isConnected)
                {
                    OnDeviceConnected(deviceIndex, true);
                }
            }

            VRModule.onDeviceConnected += OnDeviceConnected;
        }
Exemplo n.º 13
0
        private void MappingTrackers()
        {
            var deviceIndex = 0u;

            for (var role = RoleInfo.MinValidRole; role <= RoleInfo.MaxValidRole; ++role)
            {
                if (!RoleInfo.IsValidRole(role))
                {
                    continue;
                }
                if (RoleMap.IsRoleBound(role))
                {
                    continue;
                }

                // find next valid device
                if (VRModule.IsValidDeviceIndex(deviceIndex))
                {
                    while (!IsTracker(deviceIndex) || RoleMap.IsDeviceConnectedAndBound(deviceIndex))
                    {
                        if (!VRModule.IsValidDeviceIndex(++deviceIndex))
                        {
                            break;
                        }
                    }
                }

                if (VRModule.IsValidDeviceIndex(deviceIndex))
                {
                    MappingRole(role, deviceIndex++);
                }
                else
                {
                    UnmappingRole(role);
                }
            }
        }
Exemplo n.º 14
0
            public void MappingRoleValue(int roleValue, uint deviceIndex)
            {
                if (!m_info.IsValidRoleValue(roleValue))
                {
                    throw new ArgumentException("Cannot mapping invalid roleValue(" + m_info.RoleEnumType.Name + "[" + roleValue + "])");
                }

                if (!VRModule.IsValidDeviceIndex(deviceIndex))
                {
                    throw new ArgumentException("Cannot mapping invalid deviceIndex(" + deviceIndex + ")");
                }

                if (IsRoleValueBound(roleValue))
                {
                    throw new ArgumentException("roleValue(" + m_info.RoleEnumType.Name + "[" + roleValue + "]) is already bound, unbind first.");
                }

                if (IsDeviceConnectedAndBound(deviceIndex))
                {
                    throw new ArgumentException("deviceIndex(" + deviceIndex + ") is already bound, unbind first");
                }

                InternalMapping(roleValue, deviceIndex);
            }
Exemplo n.º 15
0
            // deviceSN must be valid
            // device can be whether bound or not
            // device can be whether connected or not
            private void InternalBind(string deviceSN, int roleValue)
            {
                var deviceIndex = VRModule.GetConnectedDeviceIndex(deviceSN);

                bool previousIsBound        = false;
                int  previousBoundRoleValue = m_info.InvalidRoleValue;

                if (m_sn2role.TryGetValue(deviceSN, out previousBoundRoleValue))
                {
                    if (previousBoundRoleValue == roleValue)
                    {
                        return;
                    }

                    previousIsBound = true;

                    m_sn2role.Remove(deviceSN);

                    if (VRModule.IsValidDeviceIndex(deviceIndex))
                    {
                        InternalRemoveRoleBoundDevice(deviceSN, deviceIndex, previousBoundRoleValue);
                    }
                }

                m_sn2role[deviceSN] = roleValue;

                if (VRModule.IsValidDeviceIndex(deviceIndex))
                {
                    InternalInsertRoleBoundDevice(deviceSN, deviceIndex, roleValue);
                }

                if (m_handler != null)
                {
                    m_handler.OnBindingRoleValueChanged(deviceSN, previousIsBound, previousBoundRoleValue, true, roleValue);
                }
            }
Exemplo n.º 16
0
        public static void InjectCustomDependencies(BuildTarget target, StrippingInfo strippingInfo, HashSet <UnityType> nativeClasses, HashSet <string> nativeModules)
        {
            UnityType item = UnityType.FindTypeByName("UnityAnalyticsManager");

            if (nativeClasses.Contains(item))
            {
                if (PlayerSettings.submitAnalytics)
                {
                    strippingInfo.RegisterDependency("UnityAnalyticsManager", "Required by HW Statistics (See Player Settings)");
                    strippingInfo.SetIcon("Required by HW Statistics (See Player Settings)", "class/PlayerSettings");
                }
                if (AnalyticsSettings.enabled)
                {
                    strippingInfo.RegisterDependency("UnityAnalyticsManager", "Required by Unity Analytics (See Services Window)");
                    strippingInfo.SetIcon("Required by Unity Analytics (See Services Window)", "class/PlayerSettings");
                }
            }
            if (VRModule.ShouldInjectVRDependenciesForBuildTarget(target))
            {
                nativeModules.Add("VR");
                strippingInfo.RegisterDependency("VR", "Required by Scripts");
                strippingInfo.SetIcon("Required because VR is enabled in PlayerSettings", "class/PlayerSettings");
            }
        }
Exemplo n.º 17
0
 /// <param name="roleType">
 /// Can be DeviceRole, TrackerRole or any other enum type that have ViveRoleEnumAttribute.
 /// Use ViveRole.ValidateViveRoleEnum() to validate role type
 /// </param>
 public static void TriggerHapticPulseEx(Type roleType, int roleValue, ushort durationMicroSec = 500)
 {
     VRModule.TriggerViveControllerHaptic(ViveRole.GetDeviceIndexEx(roleType, roleValue), durationMicroSec);
 }
Exemplo n.º 18
0
 /// <typeparam name="TRole">
 /// Can be DeviceRole, TrackerRole or any other enum type that have ViveRoleEnumAttribute.
 /// Use ViveRole.ValidateViveRoleEnum() to validate role type
 /// </typeparam>
 /// <param name="role">
 /// TRole can be DeviceRole, TrackerRole or any other enum type that have ViveRoleEnumAttribute.
 /// Use ViveRole.ValidateViveRoleEnum() to validate role type
 /// </param>
 public static void TriggerHapticPulseEx <TRole>(TRole role, ushort durationMicroSec = 500)
 {
     VRModule.TriggerViveControllerHaptic(ViveRole.GetDeviceIndexEx(role), durationMicroSec);
 }
 private void OnEnable()
 {
     VRModule.onActiveModuleChanged += OnActiveModuleChanged;
     VRModule.Initialize();
 }
Exemplo n.º 20
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);
            }
 public static bool IsValidIndex(uint index)
 {
     return(VRModule.IsValidDeviceIndex(index));
 }
 public static string GetSerialNumber(uint deviceIndex)
 {
     return(IsValidIndex(deviceIndex) ? VRModule.GetCurrentDeviceState(deviceIndex).serialNumber : string.Empty);
 }
 public static bool TryGetDeviceIndexBySerialNumber(string serialNumber, out uint deviceIndex)
 {
     return(VRModule.TryGetConnectedDeviceIndex(serialNumber, out deviceIndex));
 }
            private void OnGUI()
            {
                if (!VIUSettings.enableSimulatorKeyboardMouseControl)
                {
                    return;
                }

                if (!showGUI || simulator == null)
                {
                    return;
                }

                var hints = string.Empty;

                if (simulator.hasControlFocus)
                {
                    GUI.skin.box.stretchWidth     = false;
                    GUI.skin.box.stretchHeight    = false;
                    GUI.skin.box.alignment        = TextAnchor.UpperLeft;
                    GUI.skin.button.alignment     = TextAnchor.MiddleCenter;
                    GUI.skin.box.normal.textColor = Color.white;

                    // device status grids
                    GUI.skin.box.padding = new RectOffset(10, 10, 5, 5);

                    GUILayout.BeginArea(new Rect(5f, 5f, Screen.width, 30f));
                    GUILayout.BeginHorizontal();

                    for (uint i = 0u; i < SIMULATOR_MAX_DEVICE_COUNT; ++i)
                    {
                        var isHmd            = i == VRModule.HMD_DEVICE_INDEX;
                        var isSelectedDevice = i == simulator.selectedDeviceIndex;
                        var isConndected     = VRModule.GetCurrentDeviceState(i).isConnected;

                        var deviceName = isHmd ? "HMD 0" : i.ToString();
                        var colorName  = !isConndected ? "grey" : isSelectedDevice ? "lime" : "white";

                        GUILayout.Box(SetColor(Bold(deviceName), colorName));
                    }

                    GUILayout.EndHorizontal();
                    GUILayout.EndArea();

                    var selectedDeviceClass = VRModule.GetCurrentDeviceState(simulator.selectedDeviceIndex).deviceClass;
                    // instructions
                    if (selectedDeviceClass == VRModuleDeviceClass.Invalid)
                    {
                        hints += "Pause simulator: " + Bold("ESC") + "\n";
                        hints += "Toggle instructions: " + Bold("F1") + "\n";
                        hints += "Align devices to HMD: " + Bold("F2") + "\n";
                        hints += "Reset all devices to initial state: " + Bold("F3") + "\n\n";

                        hints += "Move: " + Bold("WASD / QE") + "\n";
                        hints += "Rotate: " + Bold("Mouse") + "\n";
                        hints += "Add and select a device: \n";
                        hints += "    [N] " + Bold("Num 0~9") + "\n";
                        hints += "    [10+N] " + Bold("` + Num 0~5") + "\n";
                        hints += "Remove and deselect a device: \n";
                        hints += "    [N] " + Bold("Shift + Num 0~9") + "\n";
                        hints += "    [10+N] " + Bold("Shift + ` + Num 0~5") + "\n";
                    }
                    else
                    {
                        hints += "Toggle instructions: " + Bold("F1") + "\n";
                        hints += "Align devices with HMD: " + Bold("F2") + "\n";
                        hints += "Reset all devices to initial state: " + Bold("F3") + "\n\n";

                        hints += "Currently controlling ";
                        hints += SetColor(Bold("Device " + simulator.selectedDeviceIndex.ToString()) + " " + Bold("(" + selectedDeviceClass.ToString() + ")") + "\n", "lime");
                        if (simulator.selectedDeviceIndex <= 9)
                        {
                            hints += "Deselect this device: " + Bold("ESC") + " / " + Bold("Num " + simulator.selectedDeviceIndex) + "\n";
                        }
                        else
                        {
                            hints += "Deselect this device: " + Bold("ESC") + " / " + Bold("` + Num " + simulator.selectedDeviceIndex) + "\n";
                        }
                        hints += "Add and select a device: \n";
                        hints += "    [N] " + Bold("Num 0~9") + "\n";
                        hints += "    [10+N] " + Bold("` + Num 0~5") + "\n";
                        hints += "Remove and deselect a device: \n";
                        hints += "    [N] " + Bold("Shift + Num 0~9") + "\n";
                        hints += "    [10+N] " + Bold("Shift + ` + Num 0~5") + "\n";

                        hints += "\n";
                        hints += "Move: " + Bold("WASD / QE") + "\n";
                        hints += "Rotate (pitch and yaw): " + Bold("Mouse") + " or " + Bold("Arrow Keys") + "\n";
                        hints += "Rotate (roll): " + Bold("ZC") + "\n";
                        hints += "Reset roll: " + Bold("X") + "\n";

                        if (selectedDeviceClass == VRModuleDeviceClass.Controller || selectedDeviceClass == VRModuleDeviceClass.GenericTracker)
                        {
                            hints += "\n";
                            hints += "Trigger press: " + Bold("Mouse Left") + "\n";
                            hints += "Grip press: " + Bold("Mouse Middle") + "\n";
                            hints += "Trackpad press: " + Bold("Mouse Right") + "\n";
                            hints += "Trackpad touch: " + Bold("Hold Shift") + " + " + Bold("Mouse") + "\n";
                            hints += "Menu button press: " + Bold("M") + "\n";
                        }
                    }

                    hints += "\n";
                    hints += "HMD Move: " + Bold("TFGH / RY") + "\n";
                    hints += "HMD Rotate (pitch and yaw): " + Bold("IJKL") + "\n";
                    hints += "HMD Rotate (roll): " + Bold("VN") + "\n";
                    hints += "HMD Reset roll: " + Bold("B");

                    GUI.skin.box.padding = new RectOffset(10, 10, 10, 10);

                    GUILayout.BeginArea(new Rect(5f, 35f, Screen.width, Screen.height));
                    GUILayout.Box(hints);
                    GUILayout.EndArea();
                }
                else
                {
                    // simulator resume button
                    int  buttonHeight = 30;
                    int  buttonWidth  = 130;
                    Rect ButtonRect   = new Rect((Screen.width * 0.5f) - (buttonWidth * 0.5f), (Screen.height * 0.5f) - buttonHeight, buttonWidth, buttonHeight);

                    if (GUI.Button(ButtonRect, Bold("Back to simulator")))
                    {
                        simulator.hasControlFocus = true;
                    }

                    GUI.skin.box.padding = new RectOffset(10, 10, 5, 5);

                    GUILayout.BeginArea(new Rect(5f, 5f, Screen.width, 30f));
                    GUILayout.BeginHorizontal();

                    hints += "Toggle instructions: " + Bold("F1");
                    GUILayout.Box(hints);

                    GUILayout.EndHorizontal();
                    GUILayout.EndArea();
                }
            }
 public static VRModuleDeviceClass GetDeviceClass(uint deviceIndex)
 {
     return(IsValidIndex(deviceIndex) ? VRModule.GetCurrentDeviceState(deviceIndex).deviceClass : VRModuleDeviceClass.Invalid);
 }
Exemplo n.º 26
0
    public void UpdateState()
    {
        if (m_isUpdating)
        {
            return;
        }

        m_isUpdating = true;

        m_mappedDevice  = m_map.GetMappedDeviceByRoleValue(m_roleValue);
        m_boundDeviceSN = m_map.GetBoundDeviceByRoleValue(m_roleValue);

        var mappedDeviceState = VRModule.GetCurrentDeviceState(m_mappedDevice);

        m_mappedDeviceSN = mappedDeviceState.serialNumber;

        var isMapped            = VRModule.IsValidDeviceIndex(m_mappedDevice);
        var isBound             = !string.IsNullOrEmpty(m_boundDeviceSN);
        var isSelectedValid     = VivePose.IsConnected(m_selectedDevice);
        var isSelectingThisItem = isSelectedValid && (m_selectedDeviceSN == m_boundDeviceSN || m_selectedDevice == m_mappedDevice);

        // set background color
        imgBG.color = new Color(0f, 1f, 0f, isBound ? 1f : 0f);

        if (isMapped)
        {
            if (m_isPointed)
            {
                imgInnerBG.color = Color.yellow;
            }
            else
            {
                imgInnerBG.color = Color.white;
            }
        }
        else
        {
            imgInnerBG.color = Color.gray;
        }

        if (VRModule.IsValidDeviceIndex(m_selectedDevice))
        {
            toggleBind.gameObject.SetActive(false);
        }
        else
        {
            toggleBind.gameObject.SetActive(isBound || isMapped);
            toggleBind.isOn = isBound;
        }

        buttonBind.SetActive(!isBound && isSelectedValid);

        textRoleName.text = m_map.RoleValueInfo.GetNameByRoleValue(m_roleValue);

        // update device icon
        if (mappedDeviceState.deviceClass == VRModuleDeviceClass.Invalid)
        {
            imgDeviceIcon.transform.parent.gameObject.SetActive(false);
        }
        else
        {
            imgDeviceIcon.transform.parent.gameObject.SetActive(true);
            imgDeviceIcon.sprite = deviceIconSprites[(int)mappedDeviceState.deviceClass - 1];
        }


        if (isMapped)
        {
            textDeviceName.text = "[" + m_mappedDevice + "]" + " " + m_mappedDeviceSN;
        }
        else if (isBound)
        {
            textDeviceName.text = m_boundDeviceSN;
        }
        else
        {
            textDeviceName.text = string.Empty;
        }

        // heighLight selected item
        if (isSelectingThisItem)
        {
            textRoleName.color   = Color.blue;
            textArrow.color      = Color.blue;
            textDeviceName.color = Color.blue;
        }
        else
        {
            textRoleName.color   = Color.black;
            textArrow.color      = Color.black;
            textDeviceName.color = Color.black;
        }

        m_isUpdating = false;
    }
Exemplo n.º 27
0
 public static string GetModelNumber(uint deviceIndex)
 {
     return IsValidIndex(deviceIndex) ? VRModule.GetCurrentDeviceState(deviceIndex).modelNumber : string.Empty;
 }
            // 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);
            }
Exemplo n.º 29
0
        // update type and value changes
        public void Update()
        {
            if (m_lockUpdate && (m_isTypeDirty || m_isValueDirty))
            {
                throw new Exception("Can't change value during onChange event callback");
            }

            var oldRoleType        = m_roleType;
            var oldRoleValue       = m_roleValue;
            var roleTypeChanged    = false;
            var roleValueChanged   = false;
            var deviceIndexChanged = false;

            if (m_isTypeDirty || m_roleType == null)
            {
                m_isTypeDirty = false;

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

                roleTypeChanged = oldRoleType != m_roleType;
            }

            // maintain m_roleMap cache
            // m_roleMap could be null on first update
            if (roleTypeChanged || m_roleMap == null)
            {
                if (m_onDeviceIndexChanged != null)
                {
                    if (m_roleMap != null)
                    {
                        m_roleMap.onRoleValueMappingChanged -= OnMappingChanged;
                        m_roleMap = ViveRole.GetMap(m_roleType);
                        m_roleMap.onRoleValueMappingChanged += OnMappingChanged;
                    }
                    else
                    {
                        m_roleMap     = ViveRole.GetMap(m_roleType);
                        m_deviceIndex = m_roleMap.GetMappedDeviceByRoleValue(m_roleValue); // update deviceIndex before first time listening to MappingChanged event
                        m_roleMap.onRoleValueMappingChanged += OnMappingChanged;
                    }
                }
                else
                {
                    m_roleMap = ViveRole.GetMap(m_roleType);
                }
            }

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

                var info = m_roleMap.RoleValueInfo;
                if (string.IsNullOrEmpty(m_roleValueName) || !info.TryGetRoleValueByName(m_roleValueName, out m_roleValue))
                {
                    m_roleValue = info.IsValidRoleValue(m_roleValueInt) ? m_roleValueInt : info.InvalidRoleValue;
                }

                roleValueChanged = oldRoleValue != m_roleValue;
            }

            if (roleTypeChanged || roleValueChanged)
            {
                if (m_onDeviceIndexChanged != null)
                {
                    var oldDeviceIndex = m_deviceIndex;
                    m_deviceIndex = m_roleMap.GetMappedDeviceByRoleValue(m_roleValue);

                    if (VRModule.IsValidDeviceIndex(oldDeviceIndex) || VRModule.IsValidDeviceIndex(m_deviceIndex))
                    {
                        deviceIndexChanged = oldDeviceIndex != m_deviceIndex;
                    }
                }

                m_lockUpdate = true;

                if (m_onChanged != null)
                {
                    m_onChanged();
                }

                if (m_onRoleChanged != null)
                {
                    m_onRoleChanged();
                }

                if (m_onRoleChangedEx != null)
                {
                    m_onRoleChangedEx(oldRoleType, oldRoleValue);
                }

                if (deviceIndexChanged)
                {
                    m_onDeviceIndexChanged(m_deviceIndex);
                }

                m_lockUpdate = false;
            }
        }
 /// <param name="roleType">
 /// Can be DeviceRole, TrackerRole or any other enum type that have ViveRoleEnumAttribute.
 /// Use ViveRole.ValidateViveRoleEnum() to validate role type
 /// </param>
 public static void TriggerHapticVibrationEx(Type roleType, int roleValue, float durationSeconds = 0.01f, float frequency = 85f, float amplitude = 0.125f, float startSecondsFromNow = 0f)
 {
     VRModule.TriggerHapticVibration(ViveRole.GetDeviceIndexEx(roleType, roleValue), durationSeconds, frequency, amplitude, startSecondsFromNow);
 }