//======= Copyright (c) Valve Corporation, All rights reserved. ===============
using UnityEngine;
using System.Collections;
using System;
using Valve.VR;
using System.Runtime.InteropServices;
using System.Collections.Generic;
namespace Valve.VR
{
[Serializable]
///
/// Pose actions represent a position, rotation, and velocities inside the tracked space.
/// SteamVR keeps a log of past poses so you can retrieve old poses with GetPoseAtTimeOffset or GetVelocitiesAtTimeOffset.
/// You can also pass in times in the future to these methods for SteamVR's best prediction of where the pose will be at that time.
///
public class SteamVR_Action_Pose : SteamVR_Action_Pose_Base, SteamVR_Action_Pose_Source>, ISerializationCallbackReceiver
{
public delegate void ActiveChangeHandler(SteamVR_Action_Pose fromAction, SteamVR_Input_Sources fromSource, bool active);
public delegate void ChangeHandler(SteamVR_Action_Pose fromAction, SteamVR_Input_Sources fromSource);
public delegate void UpdateHandler(SteamVR_Action_Pose fromAction, SteamVR_Input_Sources fromSource);
public delegate void TrackingChangeHandler(SteamVR_Action_Pose fromAction, SteamVR_Input_Sources fromSource, ETrackingResult trackingState);
public delegate void ValidPoseChangeHandler(SteamVR_Action_Pose fromAction, SteamVR_Input_Sources fromSource, bool validPose);
public delegate void DeviceConnectedChangeHandler(SteamVR_Action_Pose fromAction, SteamVR_Input_Sources fromSource, bool deviceConnected);
/// [Shortcut to: SteamVR_Input_Sources.Any] Event fires when the active state (ActionSet active and binding active) changes
public event ActiveChangeHandler onActiveChange
{ add { sourceMap[SteamVR_Input_Sources.Any].onActiveChange += value; } remove { sourceMap[SteamVR_Input_Sources.Any].onActiveChange -= value; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] Event fires when the active state of the binding changes
public event ActiveChangeHandler onActiveBindingChange
{ add { sourceMap[SteamVR_Input_Sources.Any].onActiveBindingChange += value; } remove { sourceMap[SteamVR_Input_Sources.Any].onActiveBindingChange -= value; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] Event fires when the orientation of the pose changes more than the changeTolerance
public event ChangeHandler onChange
{ add { sourceMap[SteamVR_Input_Sources.Any].onChange += value; } remove { sourceMap[SteamVR_Input_Sources.Any].onChange -= value; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] Event fires when the action is updated
public event UpdateHandler onUpdate
{ add { sourceMap[SteamVR_Input_Sources.Any].onUpdate += value; } remove { sourceMap[SteamVR_Input_Sources.Any].onUpdate -= value; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] Event fires when the state of the tracking has changed
public event TrackingChangeHandler onTrackingChanged
{ add { sourceMap[SteamVR_Input_Sources.Any].onTrackingChanged += value; } remove { sourceMap[SteamVR_Input_Sources.Any].onTrackingChanged -= value; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] Event fires when the validity of the pose has changed
public event ValidPoseChangeHandler onValidPoseChanged
{ add { sourceMap[SteamVR_Input_Sources.Any].onValidPoseChanged += value; } remove { sourceMap[SteamVR_Input_Sources.Any].onValidPoseChanged -= value; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] Event fires when the device bound to this pose is connected or disconnected
public event DeviceConnectedChangeHandler onDeviceConnectedChanged
{ add { sourceMap[SteamVR_Input_Sources.Any].onDeviceConnectedChanged += value; } remove { sourceMap[SteamVR_Input_Sources.Any].onDeviceConnectedChanged -= value; } }
/// Fires an event when a device is connected or disconnected.
/// The device you would like to add an event to. Any if the action is not device specific.
/// The method you would like to be called when a device is connected. Should take a SteamVR_Action_Pose as a param
public void AddOnDeviceConnectedChanged(SteamVR_Input_Sources inputSource, DeviceConnectedChangeHandler functionToCall)
{
sourceMap[inputSource].onDeviceConnectedChanged += functionToCall;
}
/// Stops executing the function setup by the corresponding AddListener
/// The device you would like to remove an event from. Any if the action is not device specific.
/// The method you would like to stop calling when a device is connected. Should take a SteamVR_Action_Pose as a param
public void RemoveOnDeviceConnectedChanged(SteamVR_Input_Sources inputSource, DeviceConnectedChangeHandler functionToStopCalling)
{
sourceMap[inputSource].onDeviceConnectedChanged -= functionToStopCalling;
}
/// Fires an event when the tracking of the device has changed
/// The device you would like to add an event to. Any if the action is not device specific.
/// The method you would like to be called when tracking has changed. Should take a SteamVR_Action_Pose as a param
public void AddOnTrackingChanged(SteamVR_Input_Sources inputSource, TrackingChangeHandler functionToCall)
{
sourceMap[inputSource].onTrackingChanged += functionToCall;
}
/// Stops executing the function setup by the corresponding AddListener
/// The device you would like to remove an event from. Any if the action is not device specific.
/// The method you would like to stop calling when tracking has changed. Should take a SteamVR_Action_Pose as a param
public void RemoveOnTrackingChanged(SteamVR_Input_Sources inputSource, TrackingChangeHandler functionToStopCalling)
{
sourceMap[inputSource].onTrackingChanged -= functionToStopCalling;
}
/// Fires an event when the device now has a valid pose or no longer has a valid pose
/// The device you would like to add an event to. Any if the action is not device specific.
/// The method you would like to be called when the pose has become valid or invalid. Should take a SteamVR_Action_Pose as a param
public void AddOnValidPoseChanged(SteamVR_Input_Sources inputSource, ValidPoseChangeHandler functionToCall)
{
sourceMap[inputSource].onValidPoseChanged += functionToCall;
}
/// Stops executing the function setup by the corresponding AddListener
/// The device you would like to remove an event from. Any if the action is not device specific.
/// The method you would like to stop calling when the pose has become valid or invalid. Should take a SteamVR_Action_Pose as a param
public void RemoveOnValidPoseChanged(SteamVR_Input_Sources inputSource, ValidPoseChangeHandler functionToStopCalling)
{
sourceMap[inputSource].onValidPoseChanged -= functionToStopCalling;
}
/// Executes a function when this action's bound state changes
/// The device you would like to get data from. Any if the action is not device specific.
public void AddOnActiveChangeListener(SteamVR_Input_Sources inputSource, ActiveChangeHandler functionToCall)
{
sourceMap[inputSource].onActiveChange += functionToCall;
}
/// Stops executing the function setup by the corresponding AddListener
/// The local function that you've setup to receive update events
/// The device you would like to get data from. Any if the action is not device specific.
public void RemoveOnActiveChangeListener(SteamVR_Input_Sources inputSource, ActiveChangeHandler functionToStopCalling)
{
sourceMap[inputSource].onActiveChange -= functionToStopCalling;
}
/// Executes a function when the state of this action (with the specified inputSource) changes
/// A local function that receives the boolean action who's state has changed, the corresponding input source, and the new value
/// The device you would like to get data from. Any if the action is not device specific.
public void AddOnChangeListener(SteamVR_Input_Sources inputSource, ChangeHandler functionToCall)
{
sourceMap[inputSource].onChange += functionToCall;
}
/// Stops executing the function setup by the corresponding AddListener
/// The local function that you've setup to receive on change events
/// The device you would like to get data from. Any if the action is not device specific.
public void RemoveOnChangeListener(SteamVR_Input_Sources inputSource, ChangeHandler functionToStopCalling)
{
sourceMap[inputSource].onChange -= functionToStopCalling;
}
/// Executes a function when the state of this action (with the specified inputSource) is updated.
/// A local function that receives the boolean action who's state has changed, the corresponding input source, and the new value
/// The device you would like to get data from. Any if the action is not device specific.
public void AddOnUpdateListener(SteamVR_Input_Sources inputSource, UpdateHandler functionToCall)
{
sourceMap[inputSource].onUpdate += functionToCall;
}
/// Stops executing the function setup by the corresponding AddListener
/// The local function that you've setup to receive update events
/// The device you would like to get data from. Any if the action is not device specific.
public void RemoveOnUpdateListener(SteamVR_Input_Sources inputSource, UpdateHandler functionToStopCalling)
{
sourceMap[inputSource].onUpdate -= functionToStopCalling;
}
void ISerializationCallbackReceiver.OnBeforeSerialize() { }
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
InitAfterDeserialize();
}
///
/// Sets all pose and skeleton actions to use the specified universe origin.
///
public static void SetTrackingUniverseOrigin(ETrackingUniverseOrigin newOrigin)
{
SetUniverseOrigin(newOrigin);
OpenVR.Compositor.SetTrackingSpace(newOrigin);
}
}
[Serializable]
///
/// The base pose action (pose and skeleton inherit from this)
///
public abstract class SteamVR_Action_Pose_Base : SteamVR_Action_In, ISteamVR_Action_Pose
where SourceMap : SteamVR_Action_Pose_Source_Map, new()
where SourceElement : SteamVR_Action_Pose_Source, new()
{
///
/// Sets all pose (and skeleton) actions to use the specified universe origin.
///
protected static void SetUniverseOrigin(ETrackingUniverseOrigin newOrigin)
{
for (int actionIndex = 0; actionIndex < SteamVR_Input.actionsPose.Length; actionIndex++)
{
SteamVR_Input.actionsPose[actionIndex].sourceMap.SetTrackingUniverseOrigin(newOrigin);
}
for (int actionIndex = 0; actionIndex < SteamVR_Input.actionsSkeleton.Length; actionIndex++)
{
SteamVR_Input.actionsSkeleton[actionIndex].sourceMap.SetTrackingUniverseOrigin(newOrigin);
}
}
/// [Shortcut to: SteamVR_Input_Sources.Any] The local position of this action relative to the universe origin
public Vector3 localPosition { get { return sourceMap[SteamVR_Input_Sources.Any].localPosition; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] The local rotation of this action relative to the universe origin
public Quaternion localRotation { get { return sourceMap[SteamVR_Input_Sources.Any].localRotation; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] The state of the tracking system that is used to create pose data (position, rotation, etc)
public ETrackingResult trackingState { get { return sourceMap[SteamVR_Input_Sources.Any].trackingState; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] The local velocity of this pose relative to the universe origin
public Vector3 velocity { get { return sourceMap[SteamVR_Input_Sources.Any].velocity; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] The local angular velocity of this pose relative to the universe origin
public Vector3 angularVelocity { get { return sourceMap[SteamVR_Input_Sources.Any].angularVelocity; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] True if the pose retrieved for this action and input source is valid (good data from the tracking source)
public bool poseIsValid { get { return sourceMap[SteamVR_Input_Sources.Any].poseIsValid; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] True if the device bound to this action and input source is connected
public bool deviceIsConnected { get { return sourceMap[SteamVR_Input_Sources.Any].deviceIsConnected; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] The local position for this pose during the previous update
public Vector3 lastLocalPosition { get { return sourceMap[SteamVR_Input_Sources.Any].lastLocalPosition; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] The local rotation for this pose during the previous update
public Quaternion lastLocalRotation { get { return sourceMap[SteamVR_Input_Sources.Any].lastLocalRotation; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] The tracking state for this pose during the previous update
public ETrackingResult lastTrackingState { get { return sourceMap[SteamVR_Input_Sources.Any].lastTrackingState; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] The velocity for this pose during the previous update
public Vector3 lastVelocity { get { return sourceMap[SteamVR_Input_Sources.Any].lastVelocity; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] The angular velocity for this pose during the previous update
public Vector3 lastAngularVelocity { get { return sourceMap[SteamVR_Input_Sources.Any].lastAngularVelocity; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] True if the pose was valid during the previous update
public bool lastPoseIsValid { get { return sourceMap[SteamVR_Input_Sources.Any].lastPoseIsValid; } }
/// [Shortcut to: SteamVR_Input_Sources.Any] True if the device bound to this action was connected during the previous update
public bool lastDeviceIsConnected { get { return sourceMap[SteamVR_Input_Sources.Any].lastDeviceIsConnected; } }
public SteamVR_Action_Pose_Base() { }
///
/// [Should not be called by user code]
/// Updates the data for all the input sources the system has detected need to be updated.
///
public virtual void UpdateValues(bool skipStateAndEventUpdates)
{
sourceMap.UpdateValues(skipStateAndEventUpdates);
}
///
/// SteamVR 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.
///
/// The device you would like to get data from. Any if the action is not device specific.
/// The time offset in the future (estimated) or in the past (previously recorded) you want to get data from
/// true if the call succeeded
public bool GetVelocitiesAtTimeOffset(SteamVR_Input_Sources inputSource, float secondsFromNow, out Vector3 velocity, out Vector3 angularVelocity)
{
return sourceMap[inputSource].GetVelocitiesAtTimeOffset(secondsFromNow, out velocity, out angularVelocity);
}
///
/// SteamVR 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.
///
/// The device you would like to get data from. Any if the action is not device specific.
/// The time offset in the future (estimated) or in the past (previously recorded) you want to get data from
/// true if the call succeeded
public bool GetPoseAtTimeOffset(SteamVR_Input_Sources inputSource, float secondsFromNow, out Vector3 localPosition, out Quaternion localRotation, out Vector3 velocity, out Vector3 angularVelocity)
{
return sourceMap[inputSource].GetPoseAtTimeOffset(secondsFromNow, out localPosition, out localRotation, out velocity, out angularVelocity);
}
///
/// Update a transform's local position and local roation to match the pose from the most recent update
///
/// The device you would like to get data from. Any if the action is not device specific.
/// The transform of the object to be updated
public virtual void UpdateTransform(SteamVR_Input_Sources inputSource, Transform transformToUpdate)
{
sourceMap[inputSource].UpdateTransform(transformToUpdate);
}
/// The local position of this action relative to the universe origin
/// The device you would like to get data from. Any if the action is not device specific.
public Vector3 GetLocalPosition(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].localPosition;
}
/// The local rotation of this action relative to the universe origin
/// The device you would like to get data from. Any if the action is not device specific.
public Quaternion GetLocalRotation(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].localRotation;
}
/// The local velocity of this pose relative to the universe origin
/// The device you would like to get data from. Any if the action is not device specific.
public Vector3 GetVelocity(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].velocity;
}
/// The local angular velocity of this pose relative to the universe origin
/// The device you would like to get data from. Any if the action is not device specific.
public Vector3 GetAngularVelocity(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].angularVelocity;
}
/// True if the device bound to this action and input source is connected
/// The device you would like to get data from. Any if the action is not device specific.
public bool GetDeviceIsConnected(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].deviceIsConnected;
}
/// True if the pose retrieved for this action and input source is valid (good data from the tracking source)
/// The device you would like to get data from. Any if the action is not device specific.
public bool GetPoseIsValid(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].poseIsValid;
}
/// The state of the tracking system that is used to create pose data (position, rotation, etc)
/// The device you would like to get data from. Any if the action is not device specific.
public ETrackingResult GetTrackingResult(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].trackingState;
}
/// The local position for this pose during the previous update
/// The device you would like to get data from. Any if the action is not device specific.
public Vector3 GetLastLocalPosition(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].lastLocalPosition;
}
/// The local rotation for this pose during the previous update
/// The device you would like to get data from. Any if the action is not device specific.
public Quaternion GetLastLocalRotation(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].lastLocalRotation;
}
/// The velocity for this pose during the previous update
/// The device you would like to get data from. Any if the action is not device specific.
public Vector3 GetLastVelocity(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].lastVelocity;
}
/// The angular velocity for this pose during the previous update
/// The device you would like to get data from. Any if the action is not device specific.
public Vector3 GetLastAngularVelocity(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].lastAngularVelocity;
}
/// True if the device bound to this action was connected during the previous update
/// The device you would like to get data from. Any if the action is not device specific.
public bool GetLastDeviceIsConnected(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].lastDeviceIsConnected;
}
/// True if the pose was valid during the previous update
/// The device you would like to get data from. Any if the action is not device specific.
public bool GetLastPoseIsValid(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].lastPoseIsValid;
}
/// The tracking state for this pose during the previous update
/// The device you would like to get data from. Any if the action is not device specific.
public ETrackingResult GetLastTrackingResult(SteamVR_Input_Sources inputSource)
{
return sourceMap[inputSource].lastTrackingState;
}
}
///
/// Boolean actions are either true or false. There is an onStateUp and onStateDown event for the rising and falling edge.
///
public class SteamVR_Action_Pose_Source_Map