/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
        public override void UpdateValue(SteamVR_Input_Sources inputSource)
        {
            lastActionData[inputSource] = actionData[inputSource];
            lastActive[inputSource]     = active[inputSource];

            EVRInputError err = OpenVR.Input.GetAnalogActionData(handle, ref tempActionData, actionData_size, SteamVR_Input_Source.GetHandle(inputSource));

            if (err != EVRInputError.None)
            {
                Debug.LogError("GetAnalogActionData error (" + fullPath + "): " + err.ToString() + " handle: " + handle.ToString());
            }

            active[inputSource]       = tempActionData.bActive;
            activeOrigin[inputSource] = tempActionData.activeOrigin;
            updateTime[inputSource]   = tempActionData.fUpdateTime;
            changed[inputSource]      = false;
            actionData[inputSource]   = tempActionData;

            if (Mathf.Abs(GetAxisDelta(inputSource)) > changeTolerance)
            {
                changed[inputSource]     = true;
                lastChanged[inputSource] = Time.time;

                if (onChange[inputSource] != null)
                {
                    onChange[inputSource].Invoke(this);
                }
            }

            if (onUpdate[inputSource] != null)
            {
                onUpdate[inputSource].Invoke(this);
            }

            if (onActiveChange[inputSource] != null && lastActive[inputSource] != active[inputSource])
            {
                onActiveChange[inputSource].Invoke(this, active[inputSource]);
            }
        }
        /// <summary>
        /// SteamVR_Standalone keeps a log of past poses so you can retrieve old poses or estimated poses in the future by passing in a secondsFromNow value that is negative or positive.
        /// </summary>
        /// <param name="secondsFromNow">The time offset in the future (estimated) or in the past (previously recorded) you want to get data from</param>
        /// <returns>true if we successfully returned a pose</returns>
        public bool GetPoseAtTimeOffset(float secondsFromNow, out Vector3 positionAtTime, out Quaternion rotationAtTime, out Vector3 velocityAtTime, out Vector3 angularVelocityAtTime)
        {
            EVRInputError err = OpenVR.Input.GetPoseActionDataRelativeToNow(handle, universeOrigin, secondsFromNow, ref tempPoseActionData, poseActionData_size, inputSourceHandle);

            if (err != EVRInputError.None)
            {
                Debug.LogError("<b>[SteamVR_Standalone]</b> GetPoseActionData error (" + fullPath + "): " + err.ToString() + " handle: " + handle.ToString()); //todo: this should be an error

                velocityAtTime        = Vector3.zero;
                angularVelocityAtTime = Vector3.zero;
                positionAtTime        = Vector3.zero;
                rotationAtTime        = Quaternion.identity;
                return(false);
            }

            velocityAtTime        = GetUnityCoordinateVelocity(tempPoseActionData.pose.vVelocity);
            angularVelocityAtTime = GetUnityCoordinateAngularVelocity(tempPoseActionData.pose.vAngularVelocity);
            positionAtTime        = tempPoseActionData.pose.mDeviceToAbsoluteTracking.GetPosition();
            rotationAtTime        = tempPoseActionData.pose.mDeviceToAbsoluteTracking.GetRotation();

            return(true);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Trigger the haptics at a certain time for a certain length
        /// </summary>
        /// <param name="secondsFromNow">How long from the current time to execute the action (in seconds - can be 0)</param>
        /// <param name="durationSeconds">How long the haptic action should last (in seconds)</param>
        /// <param name="frequency">How often the haptic motor should bounce (0 - 320 in hz. The lower end being more useful)</param>
        /// <param name="amplitude">How intense the haptic action should be (0 - 1)</param>
        /// <param name="inputSource">The device you would like to execute the haptic action. Any if the action is not device specific.</param>
        public void Execute(float secondsFromNow, float durationSeconds, float frequency, float amplitude)
        {
            if (SteamVR_Input.isStartupFrame)
            {
                return;
            }

            timeLastExecuted = Time.realtimeSinceStartup;

            EVRInputError err = OpenVR.Input.TriggerHapticVibrationAction(handle, secondsFromNow, durationSeconds, frequency, amplitude, inputSourceHandle);

            //Debug.Log(string.Format("[{5}: haptic] secondsFromNow({0}), durationSeconds({1}), frequency({2}), amplitude({3}), inputSource({4})", secondsFromNow, durationSeconds, frequency, amplitude, inputSource, this.GetShortName()));

            if (err != EVRInputError.None)
            {
                Debug.LogError("<b>[SteamVR_Standalone]</b> TriggerHapticVibrationAction (" + fullPath + ") error: " + err.ToString() + " handle: " + handle.ToString());
            }

            if (onExecute != null)
            {
                onExecute.Invoke(vibrationAction, inputSource, secondsFromNow, durationSeconds, frequency, amplitude);
            }
        }
Exemplo n.º 4
0
        public static void Initialize()
        {
            List <SteamVR_Input_Sources> allSourcesList = new List <SteamVR_Input_Sources>();

            string[] enumNames = System.Enum.GetNames(enumType);
            inputSourceHandlesBySource =
                new Dictionary <SteamVR_Input_Sources, ulong>(new SteamVR_Input_Sources_Comparer());
            inputSourceSourcesByHandle = new Dictionary <ulong, SteamVR_Input_Sources>();

            for (int enumIndex = 0; enumIndex < enumNames.Length; enumIndex++)
            {
                string path = GetPath(enumNames[enumIndex]);

                ulong         handle = 0;
                EVRInputError err    = OpenVR.Input.GetInputSourceHandle(path, ref handle);

                if (err != EVRInputError.None)
                {
                    Debug.LogError("<b>[SteamVR]</b> GetInputSourceHandle (" + path + ") error: " + err.ToString());
                }

                if (enumNames[enumIndex] == SteamVR_Input_Sources.Any.ToString()) //todo: temporary hack
                {
                    inputSourceHandlesBySource.Add((SteamVR_Input_Sources)enumIndex, 0);
                    inputSourceSourcesByHandle.Add(0, (SteamVR_Input_Sources)enumIndex);
                }
                else
                {
                    inputSourceHandlesBySource.Add((SteamVR_Input_Sources)enumIndex, handle);
                    inputSourceSourcesByHandle.Add(handle, (SteamVR_Input_Sources)enumIndex);
                }

                allSourcesList.Add((SteamVR_Input_Sources)enumIndex);
            }

            allSources = allSourcesList.ToArray();
        }
Exemplo n.º 5
0
        /// <summary><strong>[Should not be called by user code]</strong>
        /// Updates the data for this action and this input source. Sends related events.
        /// </summary>
        public virtual void UpdateValue(bool skipStateAndEventUpdates)
        {
            lastChanged         = changed;
            lastPoseActionData  = poseActionData;
            lastLocalPosition   = localPosition;
            lastLocalRotation   = localRotation;
            lastVelocity        = velocity;
            lastAngularVelocity = angularVelocity;

            EVRInputError err = OpenVR.Input.GetPoseActionData(handle, universeOrigin, predictedSecondsFromNow, ref poseActionData, poseActionData_size, inputSourceHandle);

            if (err != EVRInputError.None)
            {
                if (err == EVRInputError.InvalidHandle && Time.realtimeSinceStartup < 5)
                {
                    //ignore. This is probably just steamvr input starting up.
                    //todo: get this fixed
                }
                else
                {
                    Debug.LogError("<b>[SteamVR]</b> GetPoseActionData error (" + fullPath + "): " + err.ToString() + " Handle: " + handle.ToString() + ". Input source: " + inputSource.ToString());
                }
            }

            SetCacheVariables();
            changed = GetChanged();

            if (changed)
            {
                changedTime = updateTime + predictedSecondsFromNow;
            }

            if (skipStateAndEventUpdates == false)
            {
                CheckAndSendEvents();
            }
        }
 internal OpenVRInputException(string message, EVRInputError error) : base(message)
 {
     Error = error;
 }
Exemplo n.º 7
0
        private bool TryGetDeviceIndexFromOrigin(CVRInput vrInput, ulong origin, out OriginData originData, out EVRInputError error)
        {
            if (!m_originDataCache.TryGetValue(origin, out originData))
            {
                var originInfo = default(InputOriginInfo_t);
                error = vrInput.GetOriginTrackedDeviceInfo(origin, ref originInfo, m_originInfoSize);
                if (error != EVRInputError.None)
                {
                    originData = new OriginData()
                    {
                        devicePath  = OpenVR.k_ulInvalidInputValueHandle,
                        deviceIndex = OpenVR.k_unTrackedDeviceIndexInvalid,
                    };
                    return(false);
                }
                else
                {
                    originData = new OriginData()
                    {
                        devicePath  = originInfo.devicePath,
                        deviceIndex = originInfo.trackedDeviceIndex,
                    };

                    s_devicePathHandles[originInfo.trackedDeviceIndex] = originInfo.devicePath;
                    //Debug.Log("Set device path " + originInfo.trackedDeviceIndex + " to " + originInfo.devicePath);
                    m_originDataCache.Add(origin, originData);
                    return(true);
                }
            }
            else
            {
                error = EVRInputError.None;
                return(true);
            }
        }
Exemplo n.º 8
0
        private static void Worker()
        {
            Thread.CurrentThread.IsBackground = true;
            while (true)
            {
                // Getting events
                var vrEvents = new List <VREvent_t>();
                var vrEvent  = new VREvent_t();
                try
                {
                    while (OpenVR.System.PollNextEvent(ref vrEvent, Utils.SizeOf(vrEvent)))
                    {
                        vrEvents.Add(vrEvent);
                    }
                }
                catch (Exception e)
                {
                    Utils.PrintWarning($"Could not get evemt: {e.Message}");
                }

                // Priting events
                foreach (var e in vrEvents)
                {
                    var pid = e.data.process.pid;
                    if ((EVREventType)vrEvent.eventType != EVREventType.VREvent_None)
                    {
                        var name    = Enum.GetName(typeof(EVREventType), e.eventType);
                        var message = $"[{pid}] {name}";
                        if (pid == 0)
                        {
                            Utils.PrintVerbose(message);
                        }
                        else if (name.ToLower().Contains("fail"))
                        {
                            Utils.PrintWarning(message);
                        }
                        else if (name.ToLower().Contains("error"))
                        {
                            Utils.PrintError(message);
                        }
                        else if (name.ToLower().Contains("success"))
                        {
                            Utils.PrintInfo(message);
                        }
                        else
                        {
                            Utils.Print(message);
                        }
                    }
                }

                // Update action set
                // Seems I need the action set when updating the state of actions.
                var actionSet = new VRActiveActionSet_t();
                actionSet.ulActionSet = mActionSetHandle;
                var actionSetArr = new VRActiveActionSet_t[1] {
                    actionSet
                };

                // But I cannot get the size of an array so I supply the one for the set inside the array.
                // No really sure what I am actually supposed to do here (or above).
                var errorUAS = OpenVR.Input.UpdateActionState(actionSetArr, Utils.SizeOf(actionSet));
                if (errorUAS != EVRInputError.None)
                {
                    Utils.PrintError($"UpdateActionState Error: {Enum.GetName(typeof(EVRInputError), errorUAS)}");
                }

                // Get input actions
                var roles = new ETrackedControllerRole[] { ETrackedControllerRole.LeftHand, ETrackedControllerRole.RightHand };
                foreach (var role in roles)
                {
                    // Get device to restrict to, appears mandatory, makes sense for shared actions.
                    uint index = OpenVR.System.GetTrackedDeviceIndexForControllerRole(role);

                    // Load action data
                    var action = new InputDigitalActionData_t(); // I assume this is used for boolean inputs.
                    var size   = Utils.SizeOf(action);
                    var error  = OpenVR.Input.GetDigitalActionData(mActionHandle, ref action, size, index);

                    // Result
                    if (error != mLastError)
                    {
                        mLastError = error;
                        Utils.PrintError($"DigitalActionDataError: {Enum.GetName(typeof(EVRInputError), error)}");
                    }

                    Debug.WriteLine(action.bActive + " " + action.bChanged);
                    if (action.bChanged)
                    {
                        Utils.PrintInfo($"Action state changed to: {action.bState}");
                    }
                }

                // Restrict rate
                Thread.Sleep(1000 / 30);
            }
        }
        public override void UpdateValue(SteamVR_Input_Sources inputSource, bool skipStateAndEventUpdates)
        {
            if (skipStateAndEventUpdates == false)
            {
                base.ResetLastStates(inputSource);
            }

            base.UpdateValue(inputSource, true);
            bool poseChanged = base.changed[inputSource];

            int inputSourceInt = (int)inputSource;

            if (skipStateAndEventUpdates == false)
            {
                changed[inputSource] = false;

                for (int boneIndex = 0; boneIndex < numBones; boneIndex++)
                {
                    lastBonePositions[inputSourceInt][boneIndex] = bonePositions[inputSourceInt][boneIndex];
                    lastBoneRotations[inputSourceInt][boneIndex] = boneRotations[inputSourceInt][boneIndex];
                }
            }

            EVRInputError err = OpenVR.Input.GetSkeletalActionData(handle, ref tempSkeletonActionData, skeletonActionData_size, SteamVR_Input_Source.GetHandle(inputSource));

            if (err != EVRInputError.None)
            {
                // Debug.LogError("GetSkeletalActionData error (" + fullPath + "): " + err.ToString() + " handle: " + handle.ToString());
                active[inputSource] = false;
                return;
            }

            active[inputSource]       = active[inputSource] && tempSkeletonActionData.bActive; //anding from the pose active state
            activeOrigin[inputSource] = tempSkeletonActionData.activeOrigin;

            if (active[inputSource])
            {
                err = OpenVR.Input.GetSkeletalBoneData(handle, skeletalTransformSpace[inputSource], rangeOfMotion[inputSource], tempBoneTransforms, SteamVR_Input_Source.GetHandle(inputSource));
                if (err != EVRInputError.None)
                {
                    Debug.LogError("GetSkeletalBoneData error (" + fullPath + "): " + err.ToString() + " handle: " + handle.ToString());
                }

                for (int boneIndex = 0; boneIndex < tempBoneTransforms.Length; boneIndex++)
                {
                    // SteamVR's coordinate system is right handed, and Unity's is left handed.  The FBX data has its
                    // X axis flipped when Unity imports it, so here we need to flip the X axis as well
                    bonePositions[inputSourceInt][boneIndex].x = -tempBoneTransforms[boneIndex].position.v0;
                    bonePositions[inputSourceInt][boneIndex].y = tempBoneTransforms[boneIndex].position.v1;
                    bonePositions[inputSourceInt][boneIndex].z = tempBoneTransforms[boneIndex].position.v2;

                    boneRotations[inputSourceInt][boneIndex].x = tempBoneTransforms[boneIndex].orientation.x;
                    boneRotations[inputSourceInt][boneIndex].y = -tempBoneTransforms[boneIndex].orientation.y;
                    boneRotations[inputSourceInt][boneIndex].z = -tempBoneTransforms[boneIndex].orientation.z;
                    boneRotations[inputSourceInt][boneIndex].w = tempBoneTransforms[boneIndex].orientation.w;
                }

                // Now that we're in the same handedness as Unity, rotate the root bone around the Y axis
                // so that forward is facing down +Z
                Quaternion qFixUpRot = Quaternion.AngleAxis(Mathf.PI * Mathf.Rad2Deg, Vector3.up);

                boneRotations[inputSourceInt][0] = qFixUpRot * boneRotations[inputSourceInt][0];
            }

            changed[inputSource] = changed[inputSource] || poseChanged;

            if (skipStateAndEventUpdates == false)
            {
                for (int boneIndex = 0; boneIndex < tempBoneTransforms.Length; boneIndex++)
                {
                    if (Vector3.Distance(lastBonePositions[inputSourceInt][boneIndex], bonePositions[inputSourceInt][boneIndex]) > changeTolerance)
                    {
                        changed[inputSource] |= true;
                        break;
                    }

                    if (Mathf.Abs(Quaternion.Angle(lastBoneRotations[inputSourceInt][boneIndex], boneRotations[inputSourceInt][boneIndex])) > changeTolerance)
                    {
                        changed[inputSource] |= true;
                        break;
                    }
                }

                base.CheckAndSendEvents(inputSource);
            }

            if (changed[inputSource])
            {
                lastChanged[inputSource] = Time.time;
            }

            if (skipStateAndEventUpdates == false)
            {
                lastRecordedActive[inputSource]         = active[inputSource];
                lastRecordedPoseActionData[inputSource] = poseActionData[inputSource];
            }
        }
        /// <summary><strong>[Should not be called by user code]</strong>
        /// Updates the data for this action and this input source. Sends related events.
        /// </summary>
        public override void UpdateValue()
        {
            lastActionData = actionData;
            lastActive     = active;
            lastAxis       = axis;
            lastDelta      = delta;

            EVRInputError err = OpenVR.Input.GetAnalogActionData(handle, ref actionData, actionData_size,
                                                                 SteamVR_Input_Source.GetHandle(inputSource));

            if (err != EVRInputError.None)
            {
                Debug.LogError("<b>[SteamVR]</b> GetAnalogActionData error (" + fullPath + "): " + err.ToString() +
                               " handle: " + handle.ToString());
            }

            updateTime = Time.realtimeSinceStartup;
            axis       = new Vector3(actionData.x, actionData.y, actionData.z);
            delta      = new Vector3(actionData.deltaX, actionData.deltaY, actionData.deltaZ);

            changed = false;

            if (active)
            {
                if (delta.magnitude > changeTolerance)
                {
                    changed     = true;
                    changedTime =
                        Time.realtimeSinceStartup +
                        actionData
                        .fUpdateTime;     //fUpdateTime is the time from the time the action was called that the action changed

                    if (onChange != null)
                    {
                        onChange.Invoke(vector3Action, inputSource, axis, delta);
                    }
                }

                if (axis != Vector3.zero)
                {
                    if (onAxis != null)
                    {
                        onAxis.Invoke(vector3Action, inputSource, axis, delta);
                    }
                }

                if (onUpdate != null)
                {
                    onUpdate.Invoke(vector3Action, inputSource, axis, delta);
                }
            }


            if (onActiveBindingChange != null && lastActiveBinding != activeBinding)
            {
                onActiveBindingChange.Invoke(vector3Action, inputSource, activeBinding);
            }

            if (onActiveChange != null && lastActive != active)
            {
                onActiveChange.Invoke(vector3Action, inputSource, activeBinding);
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Checks if it can connect to OpenVR.
        /// </summary>
        /// <returns></returns>
        private bool AttemptOpenVRConnection(ref CVRSystem system)
        {
            system = null;

            EVRInitError eie = new EVRInitError();

            try
            {
                system = OpenVR.Init(ref eie, EVRApplicationType.VRApplication_Background);
            }
            catch (Exception ex)
            {
                system = null;
                //MessageBox.Show("Err 1: " + ex.Message);
            }

            if (eie == EVRInitError.Init_NoServerForBackgroundApp)
            {
                system = null;
                return(true);
            }
            if (system == null)
            {
                return(false);
            }

            this._useLegacyInput = true;

            EVRApplicationError appError = OpenVR.Applications.AddApplicationManifest(Path.GetFullPath("./manifest/app.vrmanifest"), false);

            if (appError != EVRApplicationError.None)
            {
                return(true); //Will use legacy input
            }

            EVRInputError ioError = OpenVR.Input.SetActionManifestPath(Path.GetFullPath("./manifest/actions.json"));

            if (ioError != EVRInputError.None)
            {
                return(true); //Will use legacy input
            }

            if (!LoadAction("/actions/default/in/reset_viewport", ref this.actionResetViewport))
            {
                return(true); //Will use legacy input
            }
            if (!LoadAction("/actions/default/in/reset_viewport_leftgrip", ref this.actionResetViewportLeftGrip))
            {
                return(true); //Will use legacy input
            }
            if (!LoadAction("/actions/default/in/reset_viewport_rightgrip", ref this.actionResetViewportRightGrip))
            {
                return(true); //Will use legacy input
            }

            if (OpenVR.Input.GetActionSetHandle("/actions/default", ref this.actionHandle) != EVRInputError.None)
            {
                return(true);             //Will use legacy input
            }
            this._useLegacyInput = false; //Actions loaded successfully, we can use the modern input.

            return(true);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Loads an action from the VR manifest.
        /// </summary>
        /// <param name="actionName"></param>
        /// <param name="handle"></param>
        /// <returns></returns>
        private bool LoadAction(string actionName, ref ulong handle)
        {
            EVRInputError ioError = OpenVR.Input.GetActionHandle(actionName, ref handle);

            return(ioError == EVRInputError.None);
        }