1,199 changes: 609 additions & 590 deletions Assets/SteamVR/Input/Editor/SteamVR_Input_EditorWindow.cs

Large diffs are not rendered by default.

1,880 changes: 986 additions & 894 deletions Assets/SteamVR/Input/Editor/SteamVR_Input_Generator.cs

Large diffs are not rendered by default.

169 changes: 169 additions & 0 deletions Assets/SteamVR/Input/Editor/SteamVR_Input_LiveWindow.cs
@@ -0,0 +1,169 @@
using UnityEditor;
using UnityEngine;

using System.CodeDom;
using Microsoft.CSharp;
using System.IO;
using System.CodeDom.Compiler;

using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.Linq.Expressions;
using System;
using UnityEditorInternal;

namespace Valve.VR
{
public class SteamVR_Input_LiveWindow : EditorWindow
{
private GUIStyle labelStyle;

[MenuItem("Window/SteamVR Input Live View")]
public static void ShowWindow()
{
GetWindow<SteamVR_Input_LiveWindow>(false, "SteamVR Input Live View", true);
}

private void OnInspectorUpdate()
{
Repaint();
}

private Vector2 scrollPosition;

private void OnGUI()
{
if (labelStyle == null)
{
labelStyle = new GUIStyle(EditorStyles.textField);
labelStyle.normal.background = Texture2D.whiteTexture;
}

scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);

Color defaultColor = GUI.backgroundColor;

SteamVR_ActionSet[] actionSets = SteamVR_Input.actionSets;
if (actionSets == null)
actionSets = SteamVR_Input_References.instance.actionSetObjects;

SteamVR_Input_Sources[] sources = SteamVR_Input_Source.GetUpdateSources();
for (int sourceIndex = 0; sourceIndex < sources.Length; sourceIndex++)
{
SteamVR_Input_Sources source = sources[sourceIndex];
EditorGUILayout.LabelField(source.ToString());

for (int actionSetIndex = 0; actionSetIndex < actionSets.Length; actionSetIndex++)
{
SteamVR_ActionSet set = actionSets[actionSetIndex];
string activeText = set.IsActive() ? "Active" : "Inactive";
float setLastChanged = set.GetTimeLastChanged();

if (setLastChanged != -1)
{
float timeSinceLastChanged = Time.time - setLastChanged;
if (timeSinceLastChanged < 1)
{
Color setColor = Color.Lerp(Color.green, defaultColor, timeSinceLastChanged);
GUI.backgroundColor = setColor;
}
}

EditorGUILayout.LabelField(set.GetShortName(), activeText, labelStyle);
GUI.backgroundColor = defaultColor;

EditorGUI.indentLevel++;

for (int actionIndex = 0; actionIndex < set.allActions.Length; actionIndex++)
{
SteamVR_Action action = set.allActions[actionIndex];

if (action.actionSet == null || action.actionSet.IsActive() == false)
{
EditorGUILayout.LabelField(action.GetShortName(), "-", labelStyle);
continue;
}

float actionLastChanged = action.GetTimeLastChanged(source);

string actionText = "";

float timeSinceLastChanged = -1;

if (actionLastChanged != -1)
{
timeSinceLastChanged = Time.time - actionLastChanged;

if (timeSinceLastChanged < 1)
{
Color setColor = Color.Lerp(Color.green, defaultColor, timeSinceLastChanged);
GUI.backgroundColor = setColor;
}
}


if (action is SteamVR_Action_Boolean)
{
SteamVR_Action_Boolean actionBoolean = (SteamVR_Action_Boolean)action;
actionText = actionBoolean.GetState(source).ToString();
}
else if (action is SteamVR_Action_Single)
{
SteamVR_Action_Single actionSingle = (SteamVR_Action_Single)action;
actionText = actionSingle.GetAxis(source).ToString("0.0000");
}
else if (action is SteamVR_Action_Vector2)
{
SteamVR_Action_Vector2 actionVector2 = (SteamVR_Action_Vector2)action;
actionText = string.Format("({0:0.0000}, {1:0.0000})", actionVector2.GetAxis(source).x, actionVector2.GetAxis(source).y);
}
else if (action is SteamVR_Action_Vector3)
{
SteamVR_Action_Vector3 actionVector3 = (SteamVR_Action_Vector3)action;
Vector3 axis = actionVector3.GetAxis(source);
actionText = string.Format("({0:0.0000}, {1:0.0000}, {2:0.0000})", axis.x, axis.y, axis.z);
}
else if (action is SteamVR_Action_Pose)
{
SteamVR_Action_Pose actionPose = (SteamVR_Action_Pose)action;
Vector3 position = actionPose.GetLocalPosition(source);
Quaternion rotation = actionPose.GetLocalRotation(source);
actionText = string.Format("({0:0.0000}, {1:0.0000}, {2:0.0000}) : ({3:0.0000}, {4:0.0000}, {5:0.0000}, {6:0.0000})",
position.x, position.y, position.z,
rotation.x, rotation.y, rotation.z, rotation.w);
}
else if (action is SteamVR_Action_Skeleton)
{
SteamVR_Action_Skeleton actionSkeleton = (SteamVR_Action_Skeleton)action;
Vector3 position = actionSkeleton.GetLocalPosition(source);
Quaternion rotation = actionSkeleton.GetLocalRotation(source);
actionText = string.Format("({0:0.0000}, {1:0.0000}, {2:0.0000}) : ({3:0.0000}, {4:0.0000}, {5:0.0000}, {6:0.0000})",
position.x, position.y, position.z,
rotation.x, rotation.y, rotation.z, rotation.w);
}
else if (action is SteamVR_Action_Vibration)
{
//SteamVR_Input_Action_Vibration actionVibration = (SteamVR_Input_Action_Vibration)action;

if (timeSinceLastChanged == -1)
actionText = "never used";

actionText = string.Format("{0:0} seconds since last used", timeSinceLastChanged);
}

EditorGUILayout.LabelField(action.GetShortName(), actionText, labelStyle);
GUI.backgroundColor = defaultColor;
}

EditorGUILayout.Space();
}


EditorGUI.indentLevel--;
}

EditorGUILayout.EndScrollView();
}
}
}
File renamed without changes.
119 changes: 61 additions & 58 deletions Assets/SteamVR/Input/Editor/SteamVR_Input_PostProcessBuild.cs
Expand Up @@ -4,90 +4,93 @@
using UnityEditor.Callbacks;
using System.IO;

public class SteamVR_Input_PostProcessBuild
namespace Valve.VR
{
[PostProcessBuildAttribute(1)]
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
public class SteamVR_Input_PostProcessBuild
{
SteamVR_Input.InitializeFile();

FileInfo fileInfo = new FileInfo(pathToBuiltProject);
string buildPath = fileInfo.Directory.FullName;

string[] files = SteamVR_Input.actionFile.GetFilesToCopy();
[PostProcessBuildAttribute(1)]
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
{
SteamVR_Input.InitializeFile();

bool overwrite = EditorPrefs.GetBool(SteamVR_Input_Generator.steamVRInputOverwriteBuildKey);
FileInfo fileInfo = new FileInfo(pathToBuiltProject);
string buildPath = fileInfo.Directory.FullName;

foreach (string file in files)
{
FileInfo bindingInfo = new FileInfo(file);
string newFilePath = Path.Combine(buildPath, bindingInfo.Name);
string[] files = SteamVR_Input.actionFile.GetFilesToCopy();

bool exists = false;
if (File.Exists(newFilePath))
exists = true;
bool overwrite = EditorPrefs.GetBool(SteamVR_Input_Generator.steamVRInputOverwriteBuildKey);

if (exists)
foreach (string file in files)
{
if (overwrite)
{
FileInfo existingFile = new FileInfo(newFilePath);
existingFile.IsReadOnly = false;
existingFile.Delete();
FileInfo bindingInfo = new FileInfo(file);
string newFilePath = Path.Combine(buildPath, bindingInfo.Name);

File.Copy(file, newFilePath);
bool exists = false;
if (File.Exists(newFilePath))
exists = true;

UpdateAppKey(newFilePath, fileInfo.Name);

Debug.Log("[SteamVR] Copied (overwrote) SteamVR Input file at build path: " + newFilePath);
if (exists)
{
if (overwrite)
{
FileInfo existingFile = new FileInfo(newFilePath);
existingFile.IsReadOnly = false;
existingFile.Delete();

File.Copy(file, newFilePath);

UpdateAppKey(newFilePath, fileInfo.Name);

Debug.Log("[SteamVR] Copied (overwrote) SteamVR Input file at build path: " + newFilePath);
}
else
{
Debug.Log("[SteamVR] Skipped writing existing file at build path: " + newFilePath);
}
}
else
{
Debug.Log("[SteamVR] Skipped writing existing file at build path: " + newFilePath);
File.Copy(file, newFilePath);
UpdateAppKey(newFilePath, fileInfo.Name);

Debug.Log("[SteamVR] Copied SteamVR Input file to build folder: " + newFilePath);
}
}
else
{
File.Copy(file, newFilePath);
UpdateAppKey(newFilePath, fileInfo.Name);

Debug.Log("[SteamVR] Copied SteamVR Input file to build folder: " + newFilePath);
}

}
}

private static void UpdateAppKey(string newFilePath, string executableName)
{
if (File.Exists(newFilePath))
private static void UpdateAppKey(string newFilePath, string executableName)
{
string jsonText = System.IO.File.ReadAllText(newFilePath);

string findString = "\"app_key\" : \"";
int stringStart = jsonText.IndexOf(findString);

if (stringStart == -1)
if (File.Exists(newFilePath))
{
findString = findString.Replace(" ", "");
stringStart = jsonText.IndexOf(findString);
string jsonText = System.IO.File.ReadAllText(newFilePath);

string findString = "\"app_key\" : \"";
int stringStart = jsonText.IndexOf(findString);

if (stringStart == -1)
return; //no app key
}
{
findString = findString.Replace(" ", "");
stringStart = jsonText.IndexOf(findString);

stringStart += findString.Length;
int stringEnd = jsonText.IndexOf("\"", stringStart);
if (stringStart == -1)
return; //no app key
}

int stringLength = stringEnd - stringStart;
stringStart += findString.Length;
int stringEnd = jsonText.IndexOf("\"", stringStart);

string appKey = jsonText.Substring(stringStart, stringLength);
int stringLength = stringEnd - stringStart;

if (string.Equals(appKey, SteamVR_Settings.instance.appKey, System.StringComparison.CurrentCultureIgnoreCase) == false)
{
jsonText = jsonText.Replace(appKey, SteamVR_Settings.instance.appKey);
string appKey = jsonText.Substring(stringStart, stringLength);

File.WriteAllText(newFilePath, jsonText);
if (string.Equals(appKey, SteamVR_Settings.instance.appKey, System.StringComparison.CurrentCultureIgnoreCase) == false)
{
jsonText = jsonText.Replace(appKey, SteamVR_Settings.instance.appKey);

File.WriteAllText(newFilePath, jsonText);
}
}
}
}
}
}
60 changes: 44 additions & 16 deletions Assets/SteamVR/Input/ExampleJSON/actions.json
@@ -1,13 +1,5 @@
{
"actions": [
{
"name": "/actions/default/in/Move",
"type": "vector2"
},
{
"name": "/actions/default/in/Use",
"type": "boolean"
},
{
"name": "/actions/default/in/InteractUI",
"type": "boolean"
Expand Down Expand Up @@ -38,15 +30,52 @@
"type": "skeleton",
"skeleton": "/skeleton/hand/right"
},
{
"name": "/actions/default/in/Squeeze",
"type": "vector1",
"requirement": "optional"
},
{
"name": "/actions/default/out/Haptic",
"type": "vibration"
},
{
"name": "/actions/platformer/in/Move",
"type": "vector2"
},
{
"name": "/actions/platformer/in/Jump",
"type": "boolean"
},
{
"name": "/actions/buggy/in/Steering",
"type": "vector2"
},
{
"name": "/actions/buggy/in/Throttle",
"type": "vector1"
},
{
"name": "/actions/buggy/in/Brake",
"type": "boolean"
},
{
"name": "/actions/buggy/in/Reset",
"type": "boolean"
}
],
"action_sets": [
{
"name": "/actions/default",
"usage": "single"
},
{
"name": "/actions/platformer",
"usage": "single"
},
{
"name": "/actions/buggy",
"usage": "single"
}
],
"default_bindings": [
Expand All @@ -66,21 +95,20 @@
"localization": [
{
"language_tag": "en_US",
"/actions/default/in/Move": "Move",
"/actions/default/in/Use": "Use",
"/actions/default/in/InteractUI": "Interact With UI",
"/actions/default/in/Teleport": "Teleport",
"/actions/default/in/GrabPinch": "Grab Pinch",
"/actions/default/in/GrabGrip": "Grab Grip",
"/actions/default/in/PoseLeftHand": "Pose (Left)",
"/actions/default/in/PoseRightHand": "Pose (Right)",
"/actions/default/in/SkeletonLeftHand": "Skeleton (Left)",
"/actions/default/in/SkeletonRightHand": "Skeleton (Right)",
"/actions/default/out/HapticLeftHand": "Haptic",
"/actions/default/out/HapticRightHand": "Haptic (Right)",
"/actions/default/in/Plant": "Plant",
"/actions/default/in/Pose": "Pose",
"/actions/default/out/Haptic": "Haptic"
"/actions/default/out/Haptic": "Haptic",
"/actions/buggybuddy/in/Steering": "Steering",
"/actions/buggybuddy/in/Throttle": "Throttle",
"/actions/buggybuddy/in/Brake": "Brake",
"/actions/buggybuddy/in/Reset": "Reset",
"/actions/platformer/in/Move": "Move",
"/actions/platformer/in/Jump": "Jump"
}
]
}
135 changes: 135 additions & 0 deletions Assets/SteamVR/Input/ExampleJSON/bindings_knuckles.json
@@ -1,5 +1,82 @@
{
"app_key" : "application.generated.unity.steamvr.exe",
"bindings" : {
"/actions/buggy" : {
"sources" : [
{
"inputs" : {
"position" : {
"output" : "/actions/buggy/in/steering"
}
},
"mode" : "joystick",
"path" : "/user/hand/left/input/thumbstick"
},
{
"inputs" : {
"position" : {
"output" : "/actions/buggy/in/steering"
}
},
"mode" : "joystick",
"path" : "/user/hand/right/input/thumbstick"
},
{
"inputs" : {
"pull" : {
"output" : "/actions/buggy/in/throttle"
}
},
"mode" : "trigger",
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"pull" : {
"output" : "/actions/buggy/in/throttle"
}
},
"mode" : "trigger",
"path" : "/user/hand/right/input/trigger"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/brake"
}
},
"mode" : "button",
"path" : "/user/hand/left/input/a"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/brake"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/a"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/reset"
}
},
"mode" : "button",
"path" : "/user/hand/left/input/b"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/reset"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/b"
}
]
},
"/actions/default" : {
"chords" : [],
"haptics" : [
Expand Down Expand Up @@ -60,6 +137,24 @@
"mode" : "trackpad",
"path" : "/user/hand/left/input/trackpad"
},
{
"inputs" : {
"force" : {
"output" : "/actions/default/in/squeeze"
}
},
"mode" : "force_sensor",
"path" : "/user/hand/left/input/grip"
},
{
"inputs" : {
"force" : {
"output" : "/actions/default/in/squeeze"
}
},
"mode" : "force_sensor",
"path" : "/user/hand/right/input/grip"
},
{
"inputs" : {
"click" : {
Expand Down Expand Up @@ -158,6 +253,46 @@
"path" : "/user/hand/right/input/pinch"
}
]
},
"/actions/platformer" : {
"sources" : [
{
"inputs" : {
"position" : {
"output" : "/actions/platformer/in/move"
}
},
"mode" : "joystick",
"path" : "/user/hand/left/input/thumbstick"
},
{
"inputs" : {
"position" : {
"output" : "/actions/platformer/in/move"
}
},
"mode" : "joystick",
"path" : "/user/hand/right/input/thumbstick"
},
{
"inputs" : {
"click" : {
"output" : "/actions/platformer/in/jump"
}
},
"mode" : "button",
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"click" : {
"output" : "/actions/platformer/in/jump"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/trigger"
}
]
}
},
"controller_type" : "knuckles",
Expand Down
199 changes: 152 additions & 47 deletions Assets/SteamVR/Input/ExampleJSON/bindings_oculus_touch.json
@@ -1,5 +1,100 @@
{
"app_key" : "application.generated.unity.steamvr.exe",
"bindings" : {
"/actions/buggy" : {
"sources" : [
{
"inputs" : {
"pull" : {
"output" : "/actions/buggy/in/throttle"
}
},
"mode" : "trigger",
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"pull" : {
"output" : "/actions/buggy/in/throttle"
}
},
"mode" : "trigger",
"path" : "/user/hand/right/input/trigger"
},
{
"inputs" : {
"position" : {
"output" : "/actions/buggy/in/steering"
}
},
"mode" : "joystick",
"path" : "/user/hand/left/input/joystick"
},
{
"inputs" : {
"position" : {
"output" : "/actions/buggy/in/steering"
}
},
"mode" : "joystick",
"path" : "/user/hand/right/input/joystick"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/brake"
}
},
"mode" : "button",
"path" : "/user/hand/left/input/x"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/brake"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/x"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/reset"
}
},
"mode" : "button",
"path" : "/user/hand/left/input/y"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/reset"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/y"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/brake"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/a"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/reset"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/b"
}
]
},
"/actions/default" : {
"chords" : [],
"haptics" : [
Expand Down Expand Up @@ -36,7 +131,7 @@
{
"inputs" : {
"click" : {
"output" : "/actions/default/in/use"
"output" : "/actions/default/in/interactui"
}
},
"mode" : "button",
Expand All @@ -45,30 +140,12 @@
{
"inputs" : {
"click" : {
"output" : "/actions/default/in/interactui"
"output" : "/actions/default/in/teleport"
}
},
"mode" : "button",
"path" : "/user/hand/left/input/trigger"
},
{
"inputs": {
"position": {
"output": "/actions/default/in/move"
}
},
"mode": "joystick",
"path": "/user/hand/left/input/joystick"
},
{
"inputs": {
"click": {
"output": "/actions/default/in/teleport"
}
"path" : "/user/hand/left/input/joystick"
},
"mode": "button",
"path": "/user/hand/left/input/joystick"
},
{
"inputs" : {
"click" : {
Expand All @@ -77,8 +154,8 @@
},
"mode" : "button",
"parameters" : {
"click_activate_threshold" : "0.05",
"click_deactivate_threshold" : "0",
"click_activate_threshold" : "0.8",
"click_deactivate_threshold" : "0.7",
"force_input" : "force"
},
"path" : "/user/hand/left/input/grip"
Expand All @@ -91,21 +168,12 @@
},
"mode" : "button",
"parameters" : {
"click_activate_threshold" : "0.1",
"click_deactivate_threshold" : "0.05",
"click_activate_threshold" : "0.8",
"click_deactivate_threshold" : "0.7",
"force_input" : "value"
},
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"click" : {
"output" : "/actions/default/in/use"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/trigger"
},
{
"inputs" : {
"click" : {
Expand All @@ -123,20 +191,11 @@
},
"mode" : "button",
"parameters" : {
"click_activate_threshold" : "0.1",
"click_deactivate_threshold" : "0.05"
"click_activate_threshold" : "0.8",
"click_deactivate_threshold" : "0.7"
},
"path" : "/user/hand/right/input/trigger"
},
{
"inputs": {
"position": {
"output": "/actions/default/in/move"
}
},
"mode": "joystick",
"path": "/user/hand/right/input/joystick"
},
{
"inputs" : {
"click" : {
Expand All @@ -154,11 +213,57 @@
},
"mode" : "button",
"parameters" : {
"click_activate_threshold" : "0.05",
"click_deactivate_threshold" : "0",
"click_activate_threshold" : "0.8",
"click_deactivate_threshold" : "0.7",
"force_input" : "force"
},
"path" : "/user/hand/right/input/grip"
},
{
"inputs" : {
"pull" : {
"output" : "/actions/default/in/squeeze"
}
},
"mode" : "trigger",
"path" : "/user/hand/left/input/grip"
},
{
"inputs" : {
"pull" : {
"output" : "/actions/default/in/squeeze"
}
},
"mode" : "trigger",
"path" : "/user/hand/right/input/grip"
}
]
},
"/actions/platformer" : {
"sources" : [
{
"inputs" : {
"click" : {
"output" : "/actions/platformer/in/jump"
},
"position" : {
"output" : "/actions/platformer/in/move"
}
},
"mode" : "joystick",
"path" : "/user/hand/left/input/joystick"
},
{
"inputs" : {
"click" : {
"output" : "/actions/platformer/in/jump"
},
"position" : {
"output" : "/actions/platformer/in/move"
}
},
"mode" : "joystick",
"path" : "/user/hand/right/input/joystick"
}
]
}
Expand Down
163 changes: 125 additions & 38 deletions Assets/SteamVR/Input/ExampleJSON/bindings_vive_controller.json
@@ -1,5 +1,70 @@
{
"app_key" : "application.generated.unity.steamvr.exe",
"bindings" : {
"/actions/buggy" : {
"sources" : [
{
"inputs" : {
"pull" : {
"output" : "/actions/buggy/in/throttle"
}
},
"mode" : "trigger",
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"pull" : {
"output" : "/actions/buggy/in/throttle"
}
},
"mode" : "trigger",
"path" : "/user/hand/right/input/trigger"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/brake"
},
"position" : {
"output" : "/actions/buggy/in/steering"
}
},
"mode" : "trackpad",
"path" : "/user/hand/left/input/trackpad"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/brake"
},
"position" : {
"output" : "/actions/buggy/in/steering"
}
},
"mode" : "trackpad",
"path" : "/user/hand/right/input/trackpad"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/reset"
}
},
"mode" : "button",
"path" : "/user/hand/left/input/application_menu"
},
{
"inputs" : {
"click" : {
"output" : "/actions/buggy/in/reset"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/application_menu"
}
]
},
"/actions/default" : {
"chords" : [],
"haptics" : [
Expand Down Expand Up @@ -33,15 +98,6 @@
}
],
"sources" : [
{
"inputs" : {
"click" : {
"output" : "/actions/default/in/use"
}
},
"mode" : "button",
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"click" : {
Expand All @@ -51,15 +107,6 @@
"mode" : "button",
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"position" : {
"output" : "/actions/default/in/move"
}
},
"mode" : "trackpad",
"path" : "/user/hand/left/input/trackpad"
},
{
"inputs" : {
"click" : {
Expand Down Expand Up @@ -91,16 +138,16 @@
},
"mode" : "button",
"parameters" : {
"click_activate_threshold" : "0.1",
"click_deactivate_threshold" : "0.05",
"click_activate_threshold" : "0.75",
"click_deactivate_threshold" : "0.7",
"force_input" : "value"
},
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"click" : {
"output" : "/actions/default/in/use"
"output" : "/actions/default/in/interactui"
}
},
"mode" : "button",
Expand All @@ -109,56 +156,96 @@
{
"inputs" : {
"click" : {
"output" : "/actions/default/in/interactui"
"output" : "/actions/default/in/grabpinch"
}
},
"mode" : "button",
"parameters" : {
"click_activate_threshold" : "0.75",
"click_deactivate_threshold" : "0.7"
},
"path" : "/user/hand/right/input/trigger"
},
{
"inputs" : {
"click" : {
"output" : "/actions/default/in/grabpinch"
"output" : "/actions/default/in/teleport"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/trackpad"
},
{
"inputs" : {
"click" : {
"output" : "/actions/default/in/grabgrip"
}
},
"mode" : "button",
"parameters" : {
"click_activate_threshold" : "0.1",
"click_deactivate_threshold" : "0.05"
"click_activate_threshold" : "0.05",
"click_deactivate_threshold" : "0",
"force_input" : "force"
},
"path" : "/user/hand/right/input/trigger"
"path" : "/user/hand/right/input/grip"
},
{
"inputs" : {
"position" : {
"output" : "/actions/default/in/move"
"pull" : {
"output" : "/actions/default/in/squeeze"
}
},
"mode" : "trackpad",
"path" : "/user/hand/right/input/trackpad"
"mode" : "trigger",
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"pull" : {
"output" : "/actions/default/in/squeeze"
}
},
"mode" : "trigger",
"path" : "/user/hand/right/input/trigger"
}
]
},
"/actions/platformer" : {
"sources" : [
{
"inputs" : {
"click" : {
"output" : "/actions/default/in/teleport"
"output" : "/actions/platformer/in/jump"
}
},
"mode" : "button",
"path" : "/user/hand/right/input/trackpad"
"path" : "/user/hand/left/input/trigger"
},
{
"inputs" : {
"click" : {
"output" : "/actions/default/in/grabgrip"
"output" : "/actions/platformer/in/jump"
}
},
"mode" : "button",
"parameters" : {
"click_activate_threshold" : "0.05",
"click_deactivate_threshold" : "0",
"force_input" : "force"
"path" : "/user/hand/right/input/trigger"
},
{
"inputs" : {
"position" : {
"output" : "/actions/platformer/in/move"
}
},
"path" : "/user/hand/right/input/grip"
"mode" : "trackpad",
"path" : "/user/hand/left/input/trackpad"
},
{
"inputs" : {
"position" : {
"output" : "/actions/platformer/in/move"
}
},
"mode" : "trackpad",
"path" : "/user/hand/right/input/trackpad"
}
]
}
Expand Down
80 changes: 80 additions & 0 deletions Assets/SteamVR/Input/SteamVR_Action.cs
@@ -0,0 +1,80 @@
//======= 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
{
/// <summary>
/// This is the base level action for SteamVR Input. All SteamVR_Action_In and SteamVR_Action_Out inherit from this.
/// Initializes the ulong handle for the action and has helper references.
/// </summary>
public abstract class SteamVR_Action : ScriptableObject
{
public float changeTolerance = 0.000001f;

public string fullPath;

[NonSerialized]
protected ulong handle;

public SteamVR_ActionSet actionSet;

public SteamVR_ActionDirections direction;

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, float> lastChanged = new Dictionary<SteamVR_Input_Sources, float>(new SteamVR_Input_Sources_Comparer());

public float GetTimeLastChanged(SteamVR_Input_Sources inputSource)
{
return lastChanged[inputSource];
}

/// <summary>
/// Initializes the dictionaries used by this action
/// </summary>
public virtual void PreInitialize()
{
SteamVR_Input_Sources[] sources = SteamVR_Input_Source.GetUpdateSources();
for (int sourceIndex = 0; sourceIndex < sources.Length; sourceIndex++)
{
InitializeDictionaries(sources[sourceIndex]);
}
}

/// <summary>
/// Initializes the handle for the action
/// </summary>
public virtual void Initialize()
{
EVRInputError err = OpenVR.Input.GetActionHandle(fullPath.ToLower(), ref handle);

if (err != EVRInputError.None)
Debug.LogError("GetActionHandle (" + fullPath + ") error: " + err.ToString());
//else Debug.Log("handle: " + handle);
}

protected virtual void InitializeDictionaries(SteamVR_Input_Sources source)
{
lastChanged.Add(source, 0);
}

[NonSerialized]
private string cachedShortName;

/// <summary>Gets the last part of the path for this action. Removes action set.</summary>
public string GetShortName()
{
if (cachedShortName == null)
{
cachedShortName = SteamVR_Input_ActionFile.GetShortName(fullPath);
}

return cachedShortName;
}
}
}
13 changes: 13 additions & 0 deletions Assets/SteamVR/Input/SteamVR_ActionDirections.cs
@@ -0,0 +1,13 @@
//======= Copyright (c) Valve Corporation, All rights reserved. ===============

namespace Valve.VR
{
/// <summary>
/// The direction the the action. In actions get input, Out actions send input.
/// </summary>
public enum SteamVR_ActionDirections
{
In,
Out,
}
}
202 changes: 202 additions & 0 deletions Assets/SteamVR/Input/SteamVR_ActionSet.cs
@@ -0,0 +1,202 @@
//======= 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
{
/// <summary>
/// Action sets are logical groupings of actions. Multiple sets can be active at one time.
/// </summary>
public class SteamVR_ActionSet : ScriptableObject
{
[NonSerialized]
protected static VRActiveActionSet_t[] activeActionSets;

[NonSerialized]
protected static List<VRActiveActionSet_t> activeActionSetsList = new List<VRActiveActionSet_t>();

[NonSerialized]
protected VRActiveActionSet_t actionSet = new VRActiveActionSet_t();

/// <summary>All actions within this set (including out actions)</summary>
public SteamVR_Action[] allActions;

/// <summary>All IN actions within this set that are NOT pose or skeleton actions</summary>
public SteamVR_Action_In[] nonVisualInActions;

/// <summary>All pose and skeleton actions within this set</summary>
public SteamVR_Action_In[] visualActions;

/// <summary>All pose actions within this set</summary>
public SteamVR_Action_Pose[] poseActions;

/// <summary>All skeleton actions within this set</summary>
public SteamVR_Action_Skeleton[] skeletonActions;

/// <summary>All out actions within this set</summary>
public SteamVR_Action_Out[] outActionArray;


/// <summary>The full path to this action set (ex: /actions/in/default)</summary>
public string fullPath;
public string usage;

[NonSerialized]
public ulong handle;

[NonSerialized]
protected bool setIsActive = false;

[NonSerialized]
protected float lastChanged = -1;

[NonSerialized]
protected static uint activeActionSetSize;

public void Initialize()
{
EVRInputError err = OpenVR.Input.GetActionSetHandle(fullPath.ToLower(), ref handle);

if (err != EVRInputError.None)
Debug.LogError("GetActionSetHandle (" + fullPath + ") error: " + err.ToString());

activeActionSetSize = (uint)(Marshal.SizeOf(typeof(VRActiveActionSet_t)));
}

/// <summary>
/// Returns whether the set is currently active or not.
/// </summary>
public bool IsActive()
{
return setIsActive;
}

/// <summary>
/// Returns the last time this action set was changed (set to active or inactive)
/// </summary>
/// <returns></returns>
public float GetTimeLastChanged()
{
return lastChanged;
}

/// <summary>
/// Activate this set as a primary action set so its actions can be called
/// </summary>
/// <param name="disableAllOtherActionSets">Disable all other action sets at the same time</param>
public void ActivatePrimary(bool disableAllOtherActionSets = false)
{
if (disableAllOtherActionSets)
DisableAllActionSets();

actionSet.ulActionSet = handle;

if (activeActionSetsList.Contains(actionSet) == false)
activeActionSetsList.Add(actionSet);

setIsActive = true;
lastChanged = Time.time;

UpdateActionSetArray();
}

/// <summary>
/// Activate this set as a secondary action set so its actions can be called
/// </summary>
/// <param name="disableAllOtherActionSets">Disable all other action sets at the same time</param>
public void ActivateSecondary(bool disableAllOtherActionSets = false)
{
if (disableAllOtherActionSets)
DisableAllActionSets();

actionSet.ulSecondaryActionSet = handle;

if (activeActionSetsList.Contains(actionSet) == false)
activeActionSetsList.Add(actionSet);

setIsActive = true;
lastChanged = Time.time;

UpdateActionSetArray();
}

/// <summary>
/// Deactivate the action set so its actions can no longer be called
/// </summary>
public void Deactivate()
{
setIsActive = false;
lastChanged = Time.time;

if (actionSet.ulActionSet == handle)
actionSet.ulActionSet = 0;
if (actionSet.ulSecondaryActionSet == handle)
actionSet.ulActionSet = 0;

if (actionSet.ulActionSet == 0 && actionSet.ulSecondaryActionSet == 0)
{
activeActionSetsList.Remove(actionSet);

UpdateActionSetArray();
}
}

/// <summary>
/// Disable all known action sets.
/// </summary>
public static void DisableAllActionSets()
{
for (int actionSetIndex = 0; actionSetIndex < SteamVR_Input.actionSets.Length; actionSetIndex++)
{
SteamVR_ActionSet set = SteamVR_Input.actionSets[actionSetIndex];
set.Deactivate();
}
}

protected static void UpdateActionSetArray()
{
activeActionSets = activeActionSetsList.ToArray();
}

[NonSerialized]
protected static int lastFrameUpdated;
public static void UpdateActionSetsState(bool force = false)
{
if (force || Time.frameCount != lastFrameUpdated)
{
lastFrameUpdated = Time.frameCount;

if (activeActionSets != null && activeActionSets.Length > 0)
{
EVRInputError err = OpenVR.Input.UpdateActionState(activeActionSets, activeActionSetSize);
if (err != EVRInputError.None)
Debug.LogError("UpdateActionState error: " + err.ToString());
//else Debug.Log("Action sets activated: " + activeActionSets.Length);
}
else
{
//Debug.LogWarning("No sets active");
}
}
}

[NonSerialized]
private string cachedShortName;

/// <summary>Gets the last part of the path for this action. Removes "actions" and direction.</summary>
public string GetShortName()
{
if (cachedShortName == null)
{
cachedShortName = SteamVR_Input_ActionFile.GetShortName(fullPath);
}

return cachedShortName;
}
}
}
126 changes: 126 additions & 0 deletions Assets/SteamVR/Input/SteamVR_Action_Boolean.cs
@@ -0,0 +1,126 @@
//======= 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
{
/// <summary>
/// Boolean actions are either true or false. There is an onStateUp and onStateDown event for the rising and falling edge.
/// </summary>
public class SteamVR_Action_Boolean : SteamVR_Action_In
{
[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, Action<SteamVR_Action_Boolean>> onStateDown = new Dictionary<SteamVR_Input_Sources, Action<SteamVR_Action_Boolean>>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, Action<SteamVR_Action_Boolean>> onStateUp = new Dictionary<SteamVR_Input_Sources, Action<SteamVR_Action_Boolean>>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, InputDigitalActionData_t> actionData = new Dictionary<SteamVR_Input_Sources, InputDigitalActionData_t>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, InputDigitalActionData_t> lastActionData = new Dictionary<SteamVR_Input_Sources, InputDigitalActionData_t>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected InputDigitalActionData_t tempActionData = new InputDigitalActionData_t();

[NonSerialized]
protected uint actionData_size = 0;

public override void Initialize()
{
base.Initialize();
actionData_size = (uint)Marshal.SizeOf(tempActionData);
}

/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
protected override void InitializeDictionaries(SteamVR_Input_Sources source)
{
base.InitializeDictionaries(source);

onStateDown.Add(source, null);
onStateUp.Add(source, null);
actionData.Add(source, new InputDigitalActionData_t());
lastActionData.Add(source, new InputDigitalActionData_t());
}

/// <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];

EVRInputError err = OpenVR.Input.GetDigitalActionData(handle, ref tempActionData, actionData_size, SteamVR_Input_Source.GetHandle(inputSource));
if (err != EVRInputError.None)
Debug.LogError("GetDigitalActionData error (" + fullPath + "): " + err.ToString() + " handle: " + handle.ToString());

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

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


if (onStateDown[inputSource] != null && GetStateDown(inputSource))
onStateDown[inputSource].Invoke(this);

if (onStateUp[inputSource] != null && GetStateUp(inputSource))
onStateUp[inputSource].Invoke(this);

if (onChange[inputSource] != null && GetChanged(inputSource))
onChange[inputSource].Invoke(this);

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

/// <summary>Returns true if the value of the action has been set to true (from false) in the most recent update.</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public bool GetStateDown(SteamVR_Input_Sources inputSource)
{
return actionData[inputSource].bState && actionData[inputSource].bChanged;
}

/// <summary>Returns true if the value of the action has been set to false (from true) in the most recent update.</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public bool GetStateUp(SteamVR_Input_Sources inputSource)
{
return actionData[inputSource].bState == false && actionData[inputSource].bChanged;
}

/// <summary>Returns true if the value of the action is currently true</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public bool GetState(SteamVR_Input_Sources inputSource)
{
return actionData[inputSource].bState;
}

/// <summary>Returns true if the value of the action has been set to true (from false) in the previous update.</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public bool GetLastStateDown(SteamVR_Input_Sources inputSource)
{
return lastActionData[inputSource].bState && lastActionData[inputSource].bChanged;
}

/// <summary>Returns true if the value of the action has been set to false (from true) in the previous update.</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public bool GetLastStateUp(SteamVR_Input_Sources inputSource)
{
return lastActionData[inputSource].bState == false && lastActionData[inputSource].bChanged;
}

/// <summary>Returns true if the value of the action was true in the previous update.</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public bool GetLastState(SteamVR_Input_Sources inputSource)
{
return lastActionData[inputSource].bState;
}
}
}
172 changes: 172 additions & 0 deletions Assets/SteamVR/Input/SteamVR_Action_In.cs
@@ -0,0 +1,172 @@
//======= 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
{
/// <summary>
/// In actions are all input type actions. Boolean, Single, Vector2, Vector3, Skeleton, and Pose.
/// This class fires onChange and onUpdate events.
/// </summary>
public abstract class SteamVR_Action_In : SteamVR_Action
{
[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, float> updateTime = new Dictionary<SteamVR_Input_Sources, float>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, ulong> activeOrigin = new Dictionary<SteamVR_Input_Sources, ulong>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, bool> active = new Dictionary<SteamVR_Input_Sources, bool>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, bool> changed = new Dictionary<SteamVR_Input_Sources, bool>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, Action<SteamVR_Action_In>> onChange = new Dictionary<SteamVR_Input_Sources, Action<SteamVR_Action_In>>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, Action<SteamVR_Action_In>> onUpdate = new Dictionary<SteamVR_Input_Sources, Action<SteamVR_Action_In>>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, InputOriginInfo_t> lastInputOriginInfo = new Dictionary<SteamVR_Input_Sources, InputOriginInfo_t>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, float> lastOriginGetFrame = new Dictionary<SteamVR_Input_Sources, float>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected static uint inputOriginInfo_size = 0;

public abstract void UpdateValue(SteamVR_Input_Sources inputSource);

public override void Initialize()
{
base.Initialize();

if (inputOriginInfo_size == 0)
{
InputOriginInfo_t inputOriginInfo = new InputOriginInfo_t();
inputOriginInfo_size = (uint)Marshal.SizeOf(inputOriginInfo);
}
}

protected override void InitializeDictionaries(SteamVR_Input_Sources source)
{
base.InitializeDictionaries(source);

updateTime.Add(source, -1);
activeOrigin.Add(source, 0);
active.Add(source, false);
changed.Add(source, false);
onChange.Add(source, null);
onUpdate.Add(source, null);
lastInputOriginInfo.Add(source, new InputOriginInfo_t());
lastOriginGetFrame.Add(source, -1);
}

/// <summary>
/// Returns the component name for the part of the controller that is bound to this action.
/// </summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public virtual string GetDeviceComponentName(SteamVR_Input_Sources inputSource)
{
if (GetActive(inputSource))
{
UpdateOriginTrackedDeviceInfo(inputSource);

return lastInputOriginInfo[inputSource].rchRenderModelComponentName;
}

return null;
}

/// <summary>
/// Gets the full device path for the controller this device is bound to.
/// </summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public virtual ulong GetDevicePath(SteamVR_Input_Sources inputSource)
{
if (GetActive(inputSource))
{
UpdateOriginTrackedDeviceInfo(inputSource);

return lastInputOriginInfo[inputSource].devicePath;
}

return 0;
}

/// <summary>
/// Gets the device index for the controller this action is bound to. This can be used for render models or the pose tracking system.
/// </summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public virtual uint GetDeviceIndex(SteamVR_Input_Sources inputSource)
{
if (GetActive(inputSource))
{
UpdateOriginTrackedDeviceInfo(inputSource);

return lastInputOriginInfo[inputSource].trackedDeviceIndex;
}

return 0;
}

/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public virtual bool GetChanged(SteamVR_Input_Sources inputSource)
{
return changed[inputSource];
}

/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public virtual bool GetActive(SteamVR_Input_Sources inputSource)
{
return active[inputSource];
}

/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
protected void UpdateOriginTrackedDeviceInfo(SteamVR_Input_Sources inputSource)
{
if (lastOriginGetFrame[inputSource] != Time.frameCount) //only get once per frame
{
InputOriginInfo_t inputOriginInfo = new InputOriginInfo_t();
EVRInputError err = OpenVR.Input.GetOriginTrackedDeviceInfo(activeOrigin[inputSource], ref inputOriginInfo, inputOriginInfo_size);

if (err != EVRInputError.None)
Debug.LogError("GetOriginTrackedDeviceInfo error (" + fullPath + "): " + err.ToString() + " handle: " + handle.ToString() + " activeOrigin: " + activeOrigin[inputSource].ToString() + " active: " + active[inputSource]);

lastInputOriginInfo[inputSource] = inputOriginInfo;
lastOriginGetFrame[inputSource] = Time.frameCount;
}
}

/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public void AddOnChangeListener(Action<SteamVR_Action_In> action, SteamVR_Input_Sources inputSource)
{
onChange[inputSource] += action;
}

/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public void RemoveOnChangeListener(Action<SteamVR_Action_In> action, SteamVR_Input_Sources inputSource)
{
onChange[inputSource] -= action;
}

/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public void AddOnUpdateListener(Action<SteamVR_Action_In> action, SteamVR_Input_Sources inputSource)
{
onUpdate[inputSource] += action;
}

/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public void RemoveOnUpdateListener(Action<SteamVR_Action_In> action, SteamVR_Input_Sources inputSource)
{
onUpdate[inputSource] -= action;
}
}
}
19 changes: 19 additions & 0 deletions Assets/SteamVR/Input/SteamVR_Action_List.cs
@@ -0,0 +1,19 @@
//======= Copyright (c) Valve Corporation, All rights reserved. ===============

using UnityEngine;
using System.Collections;
using System;
using System.Runtime.InteropServices;

namespace Valve.VR
{
/// <summary>
/// A list of the actions in an action set. Restricted per Action Direction.
/// </summary>
public abstract class SteamVR_Action_List : ScriptableObject
{
public SteamVR_ActionSet actionSet;
public SteamVR_ActionDirections listDirection;
public SteamVR_Action[] actions;
}
}
17 changes: 17 additions & 0 deletions Assets/SteamVR/Input/SteamVR_Action_Out.cs
@@ -0,0 +1,17 @@
//======= Copyright (c) Valve Corporation, All rights reserved. ===============

using UnityEngine;
using System.Collections;
using System;
using Valve.VR;
using System.Runtime.InteropServices;

namespace Valve.VR
{
/// <summary>
/// There is currently only one output type action - vibration. But there may be more in the future.
/// </summary>
public abstract class SteamVR_Action_Out : SteamVR_Action
{
}
}
358 changes: 358 additions & 0 deletions Assets/SteamVR/Input/SteamVR_Action_Pose.cs

Large diffs are not rendered by default.

100 changes: 100 additions & 0 deletions Assets/SteamVR/Input/SteamVR_Action_Single.cs
@@ -0,0 +1,100 @@
//======= 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
{
/// <summary>An analog action with a value generally from 0 to 1. Also provides a delta since the last update.</summary>
public class SteamVR_Action_Single : SteamVR_Action_In
{
[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, InputAnalogActionData_t> actionData = new Dictionary<SteamVR_Input_Sources, InputAnalogActionData_t>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, InputAnalogActionData_t> lastActionData = new Dictionary<SteamVR_Input_Sources, InputAnalogActionData_t>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected InputAnalogActionData_t tempActionData = new InputAnalogActionData_t();

[NonSerialized]
protected uint actionData_size = 0;

public override void Initialize()
{
base.Initialize();
actionData_size = (uint)Marshal.SizeOf(tempActionData);
}

/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
protected override void InitializeDictionaries(SteamVR_Input_Sources source)
{
base.InitializeDictionaries(source);

actionData.Add(source, new InputAnalogActionData_t());
lastActionData.Add(source, new InputAnalogActionData_t());
}

/// <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];

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);
}
}

/// <summary>The analog value</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public float GetAxis(SteamVR_Input_Sources inputSource)
{
return actionData[inputSource].x;
}

/// <summary>The delta from the analog value</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public float GetAxisDelta(SteamVR_Input_Sources inputSource)
{
return actionData[inputSource].deltaX;
}

/// <summary>The previous analog value</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public float GetLastAxis(SteamVR_Input_Sources inputSource)
{
return lastActionData[inputSource].x;
}

/// <summary>The previous delta from the analog value</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public float GetLastAxisDelta(SteamVR_Input_Sources inputSource)
{
return lastActionData[inputSource].deltaX;
}
}
}
226 changes: 226 additions & 0 deletions Assets/SteamVR/Input/SteamVR_Action_Skeleton.cs
@@ -0,0 +1,226 @@
//======= Copyright (c) Valve Corporation, All rights reserved. ===============

using UnityEngine;
using System.Collections;
using System;

using System.Runtime.InteropServices;
using System.Collections.Generic;

namespace Valve.VR
{
/// <summary>
/// Skeleton Actions are our best approximation of where your hands are while holding vr controllers and pressing buttons. We give you 31 bones to help you animate hand models.
/// For more information check out this blog post: https://steamcommunity.com/games/250820/announcements/detail/1690421280625220068
/// </summary>
public class SteamVR_Action_Skeleton : SteamVR_Action_Pose
{
public const int numBones = 31;

[NonSerialized]
protected List<Vector3[]> bonePositions = new List<Vector3[]>();

[NonSerialized]
protected List<Quaternion[]> boneRotations = new List<Quaternion[]>();

[NonSerialized]
protected List<Vector3[]> lastBonePositions = new List<Vector3[]>();

[NonSerialized]
protected List<Quaternion[]> lastBoneRotations = new List<Quaternion[]>();

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, EVRSkeletalMotionRange> rangeOfMotion = new Dictionary<SteamVR_Input_Sources, EVRSkeletalMotionRange>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected VRBoneTransform_t[] tempBoneTransforms = new VRBoneTransform_t[numBones];

[NonSerialized]
protected InputSkeletalActionData_t tempSkeletonActionData = new InputSkeletalActionData_t();

[NonSerialized]
protected uint skeletonActionData_size = 0;

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, EVRSkeletalTransformSpace> skeletalTransformSpace = new Dictionary<SteamVR_Input_Sources, EVRSkeletalTransformSpace>(new SteamVR_Input_Sources_Comparer());

public override void Initialize()
{
base.Initialize();
skeletonActionData_size = (uint)Marshal.SizeOf(tempSkeletonActionData);
}

protected override void InitializeDictionaries(SteamVR_Input_Sources source)
{
base.InitializeDictionaries(source);

bonePositions.Add(new Vector3[numBones]);
boneRotations.Add(new Quaternion[numBones]);
lastBonePositions.Add(new Vector3[numBones]);
lastBoneRotations.Add(new Quaternion[numBones]);
rangeOfMotion.Add(source, EVRSkeletalMotionRange.WithController);
skeletalTransformSpace.Add(source, EVRSkeletalTransformSpace.Parent);
}

public override void UpdateValue(SteamVR_Input_Sources inputSource)
{
UpdateValue(inputSource, false);
}

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.LogWarning("GetSkeletalActionData error (" + fullPath + "): " + err.ToString() + " handle: " + handle.ToString()); //todo: this should be an error
active[inputSource] = false;
return;
}

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;
}

/// <summary>
/// Gets the bone positions in local space
/// </summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public Vector3[] GetBonePositions(SteamVR_Input_Sources inputSource)
{
return bonePositions[(int)inputSource];
}

/// <summary>
/// Gets the bone rotations in local space
/// </summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public Quaternion[] GetBoneRotations(SteamVR_Input_Sources inputSource)
{
return boneRotations[(int)inputSource];
}

/// <summary>
/// Gets the bone positions in local space from the previous update
/// </summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public Vector3[] GetLastBonePositions(SteamVR_Input_Sources inputSource)
{
return lastBonePositions[(int)inputSource];
}

/// <summary>
/// Gets the bone rotations in local space from the previous update
/// </summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public Quaternion[] GetLastBoneRotations(SteamVR_Input_Sources inputSource)
{
return lastBoneRotations[(int)inputSource];
}

/// <summary>
/// Set the range of the motion of the bones in this skeleton. Options are "With Controller" as if your hand is holding your VR controller.
/// Or "Without Controller" as if your hand is empty.
/// </summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public void SetRangeOfMotion(SteamVR_Input_Sources inputSource, EVRSkeletalMotionRange range)
{
rangeOfMotion[inputSource] = range;
}

/// <summary>
/// Sets the space that you'll get bone data back in. Options are relative to the Model, relative to the Parent bone, and Additive.
/// </summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
/// <param name="space">the space that you'll get bone data back in. Options are relative to the Model, relative to the Parent bone, and Additive.</param>
public void SetSkeletalTransformSpace(SteamVR_Input_Sources inputSource, EVRSkeletalTransformSpace space)
{
skeletalTransformSpace[inputSource] = space;
}
}

/// <summary>
/// The change in range of the motion of the bones in the skeleton. Options are "With Controller" as if your hand is holding your VR controller.
/// Or "Without Controller" as if your hand is empty.
/// </summary>
public enum SkeletalMotionRangeChange
{
None = -1,

/// <summary>Estimation of bones in hand while holding a controller</summary>
WithController = 0,

/// <summary>Estimation of bones in hand while hand is empty (allowing full fist)</summary>
WithoutController = 1,
}
}
100 changes: 100 additions & 0 deletions Assets/SteamVR/Input/SteamVR_Action_Vector2.cs
@@ -0,0 +1,100 @@
//======= 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
{
/// <summary>
/// Vector2 actions are useful when you need two analog values from the same device. Radial menu navigation or character controllers are good examples of this.
/// </summary>
public class SteamVR_Action_Vector2 : SteamVR_Action_In
{
[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, InputAnalogActionData_t> actionData = new Dictionary<SteamVR_Input_Sources, InputAnalogActionData_t>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, InputAnalogActionData_t> lastActionData = new Dictionary<SteamVR_Input_Sources, InputAnalogActionData_t>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected InputAnalogActionData_t tempActionData = new InputAnalogActionData_t();

[NonSerialized]
protected uint actionData_size = 0;

public override void Initialize()
{
base.Initialize();
actionData_size = (uint)Marshal.SizeOf(tempActionData);
}

protected override void InitializeDictionaries(SteamVR_Input_Sources source)
{
base.InitializeDictionaries(source);

actionData.Add(source, new InputAnalogActionData_t());
lastActionData.Add(source, new InputAnalogActionData_t());
}

public override void UpdateValue(SteamVR_Input_Sources inputSource)
{
lastActionData[inputSource] = actionData[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 (GetAxisDelta(inputSource).magnitude > changeTolerance)
{
changed[inputSource] = true;
lastChanged[inputSource] = Time.time;

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

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

/// <summary>The two axis value from the latest update</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public Vector2 GetAxis(SteamVR_Input_Sources inputSource)
{
return new Vector2(actionData[inputSource].x, actionData[inputSource].y);
}

/// <summary>The two axis delta of the value from the latest update</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public Vector2 GetAxisDelta(SteamVR_Input_Sources inputSource)
{
return new Vector2(actionData[inputSource].deltaX, actionData[inputSource].deltaY);
}

/// <summary>The two axis value from the previous update</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public Vector2 GetLastAxis(SteamVR_Input_Sources inputSource)
{
return new Vector2(lastActionData[inputSource].x, lastActionData[inputSource].y);
}

/// <summary>The two axis delta of the value from the previous update</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public Vector2 GetLastAxisDelta(SteamVR_Input_Sources inputSource)
{
return new Vector2(lastActionData[inputSource].deltaX, lastActionData[inputSource].deltaY);
}
}
}
100 changes: 100 additions & 0 deletions Assets/SteamVR/Input/SteamVR_Action_Vector3.cs
@@ -0,0 +1,100 @@
//======= 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
{
/// <summary>
/// Vector3 actions are relatively uncommon. If you're looking for an action to get a 3d position from you probably want a Pose action.
/// </summary>
public class SteamVR_Action_Vector3 : SteamVR_Action_In
{
[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, InputAnalogActionData_t> actionData = new Dictionary<SteamVR_Input_Sources, InputAnalogActionData_t>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected Dictionary<SteamVR_Input_Sources, InputAnalogActionData_t> lastActionData = new Dictionary<SteamVR_Input_Sources, InputAnalogActionData_t>(new SteamVR_Input_Sources_Comparer());

[NonSerialized]
protected InputAnalogActionData_t tempActionData = new InputAnalogActionData_t();

[NonSerialized]
protected uint actionData_size = 0;

public override void Initialize()
{
base.Initialize();
actionData_size = (uint)Marshal.SizeOf(tempActionData);
}

protected override void InitializeDictionaries(SteamVR_Input_Sources source)
{
base.InitializeDictionaries(source);

actionData.Add(source, new InputAnalogActionData_t());
lastActionData.Add(source, new InputAnalogActionData_t());
}

public override void UpdateValue(SteamVR_Input_Sources inputSource)
{
lastActionData[inputSource] = actionData[inputSource];

EVRInputError err = OpenVR.Input.GetAnalogActionData(handle, ref tempActionData, actionData_size, SteamVR_Input_Source.GetHandle(inputSource));
if (err != EVRInputError.None)
Debug.LogError("Vector3 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 (GetAxisDelta(inputSource).magnitude > changeTolerance)
{
changed[inputSource] = true;
lastChanged[inputSource] = Time.time;

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

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

/// <summary>The three axis value from the latest update</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public Vector3 GetAxis(SteamVR_Input_Sources inputSource)
{
return new Vector3(actionData[inputSource].x, actionData[inputSource].y, actionData[inputSource].z);
}

/// <summary>The three axis delta of the value from the latest update</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public Vector3 GetAxisDelta(SteamVR_Input_Sources inputSource)
{
return new Vector3(actionData[inputSource].deltaX, actionData[inputSource].deltaY, actionData[inputSource].deltaZ);
}

/// <summary>The three axis value from the previous update</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public Vector3 GetLastAxis(SteamVR_Input_Sources inputSource)
{
return new Vector3(lastActionData[inputSource].x, lastActionData[inputSource].y, lastActionData[inputSource].z);
}

/// <summary>The three axis delta of the value from the previous update</summary>
/// <param name="inputSource">The device you would like to get data from. Any if the action is not device specific.</param>
public Vector3 GetLastAxisDelta(SteamVR_Input_Sources inputSource)
{
return new Vector3(lastActionData[inputSource].deltaX, lastActionData[inputSource].deltaY, lastActionData[inputSource].deltaZ);
}
}
}
36 changes: 36 additions & 0 deletions Assets/SteamVR/Input/SteamVR_Action_Vibration.cs
@@ -0,0 +1,36 @@
//======= Copyright (c) Valve Corporation, All rights reserved. ===============

using UnityEngine;
using System.Collections;
using System;
using Valve.VR;
using System.Runtime.InteropServices;

namespace Valve.VR
{
/// <summary>
/// Vibration actions are used to trigger haptic feedback in vr controllers.
/// </summary>
public class SteamVR_Action_Vibration : SteamVR_Action_Out
{
/// <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, SteamVR_Input_Sources inputSource)
{
lastChanged[inputSource] = Time.time;

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

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

if (err != EVRInputError.None)
Debug.LogError("TriggerHapticVibrationAction (" + fullPath + ") error: " + err.ToString() + " handle: " + handle.ToString());
}
}
}
40 changes: 40 additions & 0 deletions Assets/SteamVR/Input/SteamVR_ActivateActionSetOnLoad.cs
@@ -0,0 +1,40 @@
//======= Copyright (c) Valve Corporation, All rights reserved. ===============

using UnityEngine;
using System.Collections;

namespace Valve.VR
{
/// <summary>
/// Automatically activates an action set on Start() and deactivates the set on OnDestroy(). Optionally deactivating all other sets as well.
/// </summary>
public class SteamVR_ActivateActionSetOnLoad : MonoBehaviour
{
[SteamVR_DefaultActionSet("default")]
public SteamVR_ActionSet actionSet;

public bool disableAllOtherActionSets = false;

public bool activateOnStart = true;
public bool deactivateOnDestroy = true;


private void Start()
{
if (actionSet != null && activateOnStart)
{
//Debug.Log(string.Format("[SteamVR] Activating {0} action set.", actionSet.fullPath));
actionSet.ActivatePrimary(disableAllOtherActionSets);
}
}

private void OnDestroy()
{
if (actionSet != null && deactivateOnDestroy)
{
//Debug.Log(string.Format("[SteamVR] Deactivating {0} action set.", actionSet.fullPath));
actionSet.Deactivate();
}
}
}
}