-
Notifications
You must be signed in to change notification settings - Fork 81
ViveRole
ViveRole is a mapping system that relate between logic roles and tracking devices. That means application can indicate tracking device by semantic role name instead of device index.
Now there are 4 built-in role sets, each role set has their own default mapping logic:
- DeviceRole
-
- Device0 ~ Device15
- role that mapping to all 16 devices, ordered exactly same as device index.
-
- HandRole
-
- RightHand
- Mapping to the controller on the right hand side.
- LeftHand
- Mapping to the controller on the left hand side.
- ExternalCamera
- Mapping to the 3rd found controller. If 3rd controller not available, then mapping to the first found generic tracker. It is also the default tracking target of ExternalCameraHook.
- Controller4 ~ 15
- Mapping to the rest of nth found controllers.
-
- TrackerRole
-
- Tracker1 ~ Tracker15
- Mapping to the nth found generic trackers.
-
- BodyRole
- Head
- RightHand
- LeftHand
- RightFoot
- LeftFoot
- Hip
ViveRole defines the logic roles using enum type. Most of the API in Vive Input Utility use the role enum to indicate tracking device.
For example:
using HTC.UnityPlugin.Vive;
using UnityEngine;
public class ExampleClass : MonoBehaviour
{
private void Update()
{
// common functions that use role to indicate device
uint exCamDeviceIndex = ViveRole.GetDeviceIndexEx(HandRole.ExternalCamera);
bool rightPadTouched = ViveInput.GetPressEx(HandRole.RightHand, ControllerButton.PadTouch);
float leftTriggerValue = ViveInput.GetAxisEx(HandRole.LeftHand, ControllerAxis.Trigger);
Vector3 tracker1Position = VivePose.GetPoseEx(TrackerRole.Tracker1).pos;
Quaternion headRotation = VivePose.GetPoseEx(BodyRole.Head).rot;
}
}
This example shows how it works with the role enum:
using HTC.UnityPlugin.Vive;
using UnityEngine;
public class ExampleClass : MonoBehaviour
{
// set default value as HandRole.RightHand
public ViveRoleProperty viveRole = ViveRoleProperty.New(HandRole.RightHand);
private void Update()
{
uint deviceIndex = viveRole.GetDeviceIndex();
float triggerValue = ViveInput.GetAxis(viveRole, ControllerAxis.Trigger);
transform.localPosition = VivePose.GetPose(viveRole).pos;
transform.localRotation = VivePose.GetPose(viveRole).rot;
// switch hands when menu button pressed
if (ViveInput.GetPressDown(viveRole, ControllerButton.Menu))
{
if (viveRole.IsRole(HandRole.RightHand))
{
viveRole.SetEx(HandRole.LeftHand);
}
else
{
viveRole.SetEx(HandRole.RightHand);
}
}
}
}
You can create custom role by adding ViveRoleEnumAttribute to your enum type. For example:
using HTC.UnityPlugin.Vive;
[ViveRoleEnum((int)MyEquipRole.None)]// must specify invalid role value as default role value
public enum MyEquipRole
{
None,
MainWeapon,
SecondaryWeapon,
Shield,
...
}
You can customize auto-mapping logic by implementing ViveRoleHandler<EnumType> and call ViveRole.AssignMapHandler() to apply it. For Example:
using UnityEngine;
using HTC.UnityPlugin.Vive;
public class MyEquipRoleHandler : ViveRole.MapHandler<MyEquipRole>
{
// called when handler is assigned
public override void OnInitialize() { RemapAll(); }
// called when device connected or disconnected
public override void OnConnectedDeviceChanged(uint deviceIndex, ETrackedDeviceClass deviceClass, string deviceSN, bool connected) { RemapAll(); }
// called when binding changed (Ex. when ViveRole.GetMap<MyEquipRole>().BindRole called)
public override void OnBindingChanged(MyEquipRole role, string deviceSN, bool bound) { RemapAll(); }
// called when OpenVR TrackedDeviceRoleChanged event emitted
public override void OnTrackedDeviceRoleChanged() { RemapAll(); }
public void RemapAll()
{
// some auto mapping algorithm...
// call protected function here to map/unmap relations
// this.UnmappingAll() to unmap all relations
// this.MappingRole(MyEquipRole role, uint deviceIndex) to map the role to the device
}
}
public class MyEquipRoleManager : MonoBehaviour
{
public readonly MyEquipRoleHandler handler = new MyEquipRoleHandler();
public void Awake()
{
// assign the handler to apply the auto-mapping logic
ViveRole.AssignMapHandler(handler);
}
public bool TryGetEquipPosition(MyEquipRole role, out Vector3 pos)
{
pos = VivePose.GetPoseEx(role).pos;
return VivePose.IsValidEx(role);
}
}
Binding feature allows overriding auto-mapping result. When a device serial number is bound to a role, the device with certain SN will force map to that role when it is connected. This can be performed in either Embedded Binding UI or bind manually in scripts.
// Bind "LHT-XXXXXXXXX" to BodyRole.LeftFoot
ViveRole.GetMap<BodyRole>().BindDeviceToRole("LHT-XXXXXXXXX", BodyRole.LeftFoot);