Last active
September 21, 2021 16:18
-
-
Save sh-akira/1f3fdb2dad46b71cd215d2a045897bd3 to your computer and use it in GitHub Desktop.
SteamVR Plugin 2.xでVIVEトラッカーの役割設定からトラッカー位置を取得するサンプル(肘と膝を含む)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"actions": [ | |
{ | |
"name": "/actions/default/in/Pose", | |
"type": "pose" | |
}, | |
{ | |
"name": "/actions/default/in/SkeletonLeftHand", | |
"type": "skeleton", | |
"skeleton": "/skeleton/hand/left" | |
}, | |
{ | |
"name": "/actions/default/in/SkeletonRightHand", | |
"type": "skeleton", | |
"skeleton": "/skeleton/hand/right" | |
}, | |
{ | |
"name": "/actions/default/in/SelectButton", | |
"type": "boolean" | |
}, | |
{ | |
"name": "/actions/default/in/CancelButton", | |
"type": "boolean" | |
}, | |
{ | |
"name": "/actions/default/in/StickButton", | |
"type": "boolean" | |
}, | |
{ | |
"name": "/actions/default/in/MenuButton", | |
"type": "boolean" | |
}, | |
{ | |
"name": "/actions/default/in/TriggerButton", | |
"type": "boolean" | |
}, | |
{ | |
"name": "/actions/default/in/GripButton", | |
"type": "boolean" | |
}, | |
{ | |
"name": "/actions/default/in/StickAxis", | |
"type": "vector2" | |
}, | |
{ | |
"name": "/actions/default/out/Haptic", | |
"type": "vibration" | |
} | |
], | |
"action_sets": [ | |
{ | |
"name": "/actions/default", | |
"usage": "single" | |
} | |
], | |
"default_bindings": [ | |
{ | |
"controller_type": "vive_controller", | |
"binding_url": "bindings_vive_controller.json" | |
}, | |
{ | |
"controller_type": "oculus_touch", | |
"binding_url": "bindings_oculus_touch.json" | |
}, | |
{ | |
"controller_type": "knuckles", | |
"binding_url": "bindings_knuckles.json" | |
}, | |
{ | |
"controller_type": "holographic_controller", | |
"binding_url": "bindings_holographic_controller.json" | |
}, | |
{ | |
"controller_type": "vive_cosmos_controller", | |
"binding_url": "bindings_vive_cosmos_controller.json" | |
}, | |
{ | |
"controller_type": "vive_cosmos", | |
"binding_url": "binding_vive_cosmos.json" | |
}, | |
{ | |
"controller_type": "vive", | |
"binding_url": "binding_vive.json" | |
}, | |
{ | |
"controller_type": "indexhmd", | |
"binding_url": "binding_index_hmd.json" | |
}, | |
{ | |
"controller_type": "vive_pro", | |
"binding_url": "binding_vive_pro.json" | |
}, | |
{ | |
"controller_type": "rift", | |
"binding_url": "binding_rift.json" | |
}, | |
{ | |
"controller_type": "holographic_hmd", | |
"binding_url": "binding_holographic_hmd.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_camera", | |
"binding_url": "binding_vive_tracker_camera.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_chest", | |
"binding_url": "binding_vive_tracker_chest.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_head", | |
"binding_url": "binding_vive_tracker_head.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_left_elbow", | |
"binding_url": "binding_vive_tracker_left_elbow.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_left_foot", | |
"binding_url": "binding_vive_tracker_left_foot.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_left_hand", | |
"binding_url": "binding_vive_tracker_left_hand.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_left_knee", | |
"binding_url": "binding_vive_tracker_left_knee.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_left_shoulder", | |
"binding_url": "binding_vive_tracker_left_shoulder.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_right_elbow", | |
"binding_url": "binding_vive_tracker_right_elbow.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_right_foot", | |
"binding_url": "binding_vive_tracker_right_foot.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_right_hand", | |
"binding_url": "binding_vive_tracker_right_hand.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_right_knee", | |
"binding_url": "binding_vive_tracker_right_knee.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_right_shoulder", | |
"binding_url": "binding_vive_tracker_right_shoulder.json" | |
}, | |
{ | |
"controller_type": "vive_tracker_waist", | |
"binding_url": "binding_vive_tracker_waist.json" | |
} | |
], | |
"localization": [ | |
{ | |
"language_tag": "en_US", | |
"/actions/default/in/Pose": "Pose", | |
"/actions/default/in/SkeletonLeftHand": "Skeleton (Left)", | |
"/actions/default/in/SkeletonRightHand": "Skeleton (Right)", | |
"/actions/default/out/Haptic": "Haptic" | |
} | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alias_info" : {}, | |
"bindings" : { | |
"/actions/default" : { | |
"poses" : [ | |
{ | |
"output" : "/actions/default/in/pose", | |
"path" : "/user/chest/pose/raw" | |
} | |
] | |
} | |
}, | |
"controller_type" : "vive_tracker_chest", | |
"description" : "", | |
"name" : "Chest", | |
"options" : {}, | |
"simulated_actions" : [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alias_info" : {}, | |
"bindings" : { | |
"/actions/default" : { | |
"poses" : [ | |
{ | |
"output" : "/actions/default/in/pose", | |
"path" : "/user/head/pose/raw" | |
} | |
] | |
} | |
}, | |
"controller_type" : "vive_tracker_head", | |
"description" : "", | |
"name" : "Head", | |
"options" : {}, | |
"simulated_actions" : [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alias_info" : {}, | |
"bindings" : { | |
"/actions/default" : { | |
"poses" : [ | |
{ | |
"output" : "/actions/default/in/pose", | |
"path" : "/user/elbow/left/pose/raw" | |
} | |
] | |
} | |
}, | |
"controller_type" : "vive_tracker_left_elbow", | |
"description" : "", | |
"name" : "LeftElbow", | |
"options" : {}, | |
"simulated_actions" : [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alias_info" : {}, | |
"bindings" : { | |
"/actions/default" : { | |
"poses" : [ | |
{ | |
"output" : "/actions/default/in/pose", | |
"path" : "/user/foot/left/pose/raw" | |
} | |
] | |
} | |
}, | |
"controller_type" : "vive_tracker_left_foot", | |
"description" : "", | |
"name" : "LeftFoot", | |
"options" : {}, | |
"simulated_actions" : [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alias_info" : {}, | |
"bindings" : { | |
"/actions/default" : { | |
"poses" : [ | |
{ | |
"output" : "/actions/default/in/pose", | |
"path" : "/user/hand/left/pose/raw" | |
} | |
] | |
} | |
}, | |
"controller_type" : "vive_tracker_left_hand", | |
"description" : "", | |
"name" : "LeftHand", | |
"options" : {}, | |
"simulated_actions" : [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alias_info" : {}, | |
"bindings" : { | |
"/actions/default" : { | |
"poses" : [ | |
{ | |
"output" : "/actions/default/in/pose", | |
"path" : "/user/knee/left/pose/raw" | |
} | |
] | |
} | |
}, | |
"controller_type" : "vive_tracker_left_knee", | |
"description" : "", | |
"name" : "LeftKnee", | |
"options" : {}, | |
"simulated_actions" : [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alias_info" : {}, | |
"bindings" : { | |
"/actions/default" : { | |
"poses" : [ | |
{ | |
"output" : "/actions/default/in/pose", | |
"path" : "/user/shoulder/left/pose/raw" | |
} | |
] | |
} | |
}, | |
"controller_type" : "vive_tracker_left_shoulder", | |
"description" : "", | |
"name" : "LeftShoulder", | |
"options" : {}, | |
"simulated_actions" : [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alias_info" : {}, | |
"bindings" : { | |
"/actions/default" : { | |
"poses" : [ | |
{ | |
"output" : "/actions/default/in/pose", | |
"path" : "/user/elbow/right/pose/raw" | |
} | |
] | |
} | |
}, | |
"controller_type" : "vive_tracker_right_elbow", | |
"description" : "", | |
"name" : "RightElbow", | |
"options" : {}, | |
"simulated_actions" : [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alias_info" : {}, | |
"bindings" : { | |
"/actions/default" : { | |
"poses" : [ | |
{ | |
"output" : "/actions/default/in/pose", | |
"path" : "/user/foot/right/pose/raw" | |
} | |
] | |
} | |
}, | |
"controller_type" : "vive_tracker_right_foot", | |
"description" : "", | |
"name" : "RightFoot", | |
"options" : {}, | |
"simulated_actions" : [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alias_info" : {}, | |
"bindings" : { | |
"/actions/default" : { | |
"poses" : [ | |
{ | |
"output" : "/actions/default/in/pose", | |
"path" : "/user/hand/right/pose/raw" | |
} | |
] | |
} | |
}, | |
"controller_type" : "vive_tracker_right_hand", | |
"description" : "", | |
"name" : "RightHand", | |
"options" : {}, | |
"simulated_actions" : [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alias_info" : {}, | |
"bindings" : { | |
"/actions/default" : { | |
"poses" : [ | |
{ | |
"output" : "/actions/default/in/pose", | |
"path" : "/user/knee/right/pose/raw" | |
} | |
] | |
} | |
}, | |
"controller_type" : "vive_tracker_right_knee", | |
"description" : "", | |
"name" : "RightKnee", | |
"options" : {}, | |
"simulated_actions" : [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alias_info" : {}, | |
"bindings" : { | |
"/actions/default" : { | |
"poses" : [ | |
{ | |
"output" : "/actions/default/in/pose", | |
"path" : "/user/shoulder/right/pose/raw" | |
} | |
] | |
} | |
}, | |
"controller_type" : "vive_tracker_right_shoulder", | |
"description" : "", | |
"name" : "RightShoulder", | |
"options" : {}, | |
"simulated_actions" : [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"alias_info" : {}, | |
"bindings" : { | |
"/actions/default" : { | |
"poses" : [ | |
{ | |
"output" : "/actions/default/in/pose", | |
"path" : "/user/waist/pose/raw" | |
} | |
] | |
} | |
}, | |
"controller_type" : "vive_tracker_waist", | |
"description" : "", | |
"name" : "Waist", | |
"options" : {}, | |
"simulated_actions" : [] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SteamVR 2.x Tracker Role Pose Example | |
// MIT License | |
// Copyright (c) 2021 sh_akira | |
using System; | |
using System.Runtime.InteropServices; | |
using UnityEngine; | |
using Valve.VR; | |
namespace akr.Avatar.Tracking | |
{ | |
public class SteamVRTracker : MonoBehaviour | |
{ | |
//外部からTransformを指定されたときはそちらをそのまま使用する。無い場合は自動で作成して割り当てる | |
public TrackerTarget[] TrackerTargets = new TrackerTarget[] | |
{ | |
new TrackerTarget { TrackerPosition = TrackerPositions.Head }, | |
new TrackerTarget { TrackerPosition = TrackerPositions.LeftHand }, | |
new TrackerTarget { TrackerPosition = TrackerPositions.RightHand }, | |
new TrackerTarget { TrackerPosition = TrackerPositions.Waist }, | |
new TrackerTarget { TrackerPosition = TrackerPositions.LeftFoot }, | |
new TrackerTarget { TrackerPosition = TrackerPositions.RightFoot }, | |
new TrackerTarget { TrackerPosition = TrackerPositions.LeftElbow }, | |
new TrackerTarget { TrackerPosition = TrackerPositions.RightElbow }, | |
new TrackerTarget { TrackerPosition = TrackerPositions.LeftKnee }, | |
new TrackerTarget { TrackerPosition = TrackerPositions.RightKnee }, | |
}; | |
// "/actions/default/in/Pose" | |
public SteamVR_Action_Pose PoseAction = SteamVR_Input.GetAction<SteamVR_Action_Pose>("Pose"); | |
private static float framesAhead = 2; | |
private ETrackingUniverseOrigin universeOrigin = ETrackingUniverseOrigin.TrackingUniverseRawAndUncalibrated; | |
private uint poseActionData_size = 0; | |
private ulong actionHandle = 0; | |
// enum TrackerPositionsとstring InputSourcePathとの対応表 | |
private readonly string[] TrackerPositionsToPath = new string[] | |
{ | |
"/unrestricted", | |
OpenVR.k_pchPathUserHandLeft, | |
OpenVR.k_pchPathUserHandRight, | |
OpenVR.k_pchPathUserFootLeft, | |
OpenVR.k_pchPathUserFootRight, | |
OpenVR.k_pchPathUserShoulderLeft, | |
OpenVR.k_pchPathUserShoulderRight, | |
OpenVR.k_pchPathUserWaist, | |
OpenVR.k_pchPathUserChest, | |
OpenVR.k_pchPathUserHead, | |
OpenVR.k_pchPathUserGamepad, | |
OpenVR.k_pchPathUserCamera, | |
OpenVR.k_pchPathUserKeyboard, | |
OpenVR.k_pchPathUserTreadmill, | |
OpenVR.k_pchPathUserElbowLeft, | |
OpenVR.k_pchPathUserElbowRight, | |
OpenVR.k_pchPathUserKneeLeft, | |
OpenVR.k_pchPathUserKneeRight, | |
OpenVR.k_pchPathUserStylus, | |
}; | |
/// <summary> | |
/// ActionのフルパスからHandle取得 | |
/// </summary> | |
/// <param name="fullPath"></param> | |
/// <returns></returns> | |
private ulong GetActionHandle(string fullPath) | |
{ | |
ulong newHandle = 0; | |
EVRInputError err = OpenVR.Input.GetActionHandle(fullPath.ToLowerInvariant(), ref newHandle); | |
if (err != EVRInputError.None) | |
Debug.LogError("GetActionHandle (" + fullPath.ToLowerInvariant() + ") error: " + err.ToString()); | |
return newHandle; | |
} | |
/// <summary> | |
/// 指定したTrackerPositionsのInputSourceHandleを取得 | |
/// </summary> | |
/// <param name="trackerPosition"></param> | |
/// <returns></returns> | |
private ulong GetTrackerInputSourceHandle(TrackerPositions trackerPosition) | |
=> GetTrackerInputSourceHandle(TrackerPositionsToPath[(int)trackerPosition]); | |
/// <summary> | |
/// 指定したInputSourcePathのInputSourceHandleを取得 | |
/// </summary> | |
/// <param name="path"></param> | |
/// <returns></returns> | |
private ulong GetTrackerInputSourceHandle(string path) | |
{ | |
ulong handle = 0; | |
EVRInputError err = OpenVR.Input.GetInputSourceHandle(path, ref handle); | |
if (err != EVRInputError.None) | |
Debug.LogError("GetInputSourceHandle (" + path + ") error: " + err.ToString()); | |
return handle; | |
} | |
/// <summary> | |
/// 指定したInputSourceHandleからトラッカーのPoseを取得 | |
/// </summary> | |
/// <param name="inputSourceHandle"></param> | |
/// <returns></returns> | |
private InputPoseActionData_t GetPoseByHandle(ulong inputSourceHandle) | |
{ | |
var poseActionData = new InputPoseActionData_t(); | |
EVRInputError err = OpenVR.Input.GetPoseActionDataRelativeToNow(actionHandle, universeOrigin, framesAhead * (Time.timeScale / SteamVR.instance.hmd_DisplayFrequency), ref poseActionData, poseActionData_size, inputSourceHandle); | |
if (err != EVRInputError.None) | |
{ | |
Debug.LogError("GetPoseActionDataRelativeToNow error: " + err.ToString() + " ActionHandle: " + actionHandle.ToString() + ". Input source: " + inputSourceHandle.ToString()); | |
} | |
return poseActionData; | |
} | |
private void Awake() | |
{ | |
universeOrigin = SteamVR_Settings.instance.trackingSpace; | |
poseActionData_size = (uint)Marshal.SizeOf(typeof(InputPoseActionData_t)); | |
} | |
private void Start() | |
{ | |
actionHandle = GetActionHandle(PoseAction.fullPath); | |
foreach(var trackerTarget in TrackerTargets) | |
{ | |
if (trackerTarget.TargetTransform == null) | |
{ | |
var newTarget = new GameObject(trackerTarget.TrackerPosition.ToString()); | |
newTarget.transform.SetParent(transform, false); | |
trackerTarget.TargetTransform = newTarget.transform; | |
} | |
trackerTarget.InputSourceHandle = GetTrackerInputSourceHandle(trackerTarget.TrackerPosition); | |
} | |
} | |
private void Update() | |
{ | |
foreach (var trackerTarget in TrackerTargets) | |
{ | |
var poseActionData = GetPoseByHandle(trackerTarget.InputSourceHandle); | |
if (poseActionData.bActive) | |
{ | |
trackerTarget.TargetTransform.localPosition = poseActionData.pose.mDeviceToAbsoluteTracking.GetPosition(); | |
trackerTarget.TargetTransform.localRotation = poseActionData.pose.mDeviceToAbsoluteTracking.GetRotation(); | |
} | |
} | |
} | |
} | |
[Serializable] | |
public class TrackerTarget | |
{ | |
public TrackerPositions TrackerPosition; | |
public Transform TargetTransform; | |
[NonSerialized] | |
public ulong InputSourceHandle; | |
} | |
/// <summary> | |
/// SteamVRで割り当て可能なトラッカー位置(拡張SteamVR_Input_Sources) | |
/// </summary> | |
public enum TrackerPositions | |
{ | |
Any, | |
LeftHand, | |
RightHand, | |
LeftFoot, | |
RightFoot, | |
LeftShoulder, | |
RightShoulder, | |
Waist, | |
Chest, | |
Head, | |
Gameoad, | |
Camera, | |
Keyboard, | |
Treadmill, | |
LeftElbow, | |
RightElbow, | |
LeftKnee, | |
RightKnee, | |
Stylus, | |
} | |
} |
SteamVRの設定にはLeft KneeやRight Elbow設定が可能にもかかわらず、SteamVR Pluginに定義が存在しない為、拡張SteamVR_Input_Sourcesを自前で持っています。SteamVR Pluginには定義がないが、OpenVRの定義には存在しているので直接k_pchPathUserKneeLeft等を使用しています。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
最低限InのActionにPoseが追加されている必要があります。