-
Notifications
You must be signed in to change notification settings - Fork 80
ViveRole
ViveRole is a mapping system that relate between logic roles and tracking devices. That means application can indicate tracking device by logic role 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
-
- Tracker0 ~ 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);
}
}
}
}
There are some restriction for bindings in each role set.
Before v1.6.4:
- Both mapping (role \<=\> device index) binding (role \<=\> device serial number) are one-on-one relation
- When a device serial number is binding to a role, it means that role is always mapping to the specific device
- If the bound device is disconnected, the bound role will not mapping to any device index (returns invalid index).
You can create custom role in an instant by adding **ViveRoleEnumAttribute** to your enum type. For example:
using HTC.UnityPlugin.Vive;
[ViveRoleEnum((int)MyEquipRole.None)]// must indicate a initial/null state as a invalid role
public enum MyEquipRole
{
None,
MainWeapon,
SecondaryWeapon,
Shield,
...
}
You can customize auto-mapping logic by implementing **ViveRoleHandler\** and call **ViveRole.AssignMapHandler()** to enable 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()
{
// must assign the handler to enable auto-mapping
ViveRole.AssignMapHandler(handler);
}
public bool TryGetEquipPosition(MyEquipRole role, out Vector3 pos)
{
pos = VivePose.GetPoseEx(role).pos;
return VivePose.IsValidEx(role);
}
}