public static int GetDeviceIndex(DeviceRelation relation,
TrackedDeviceClass deviceClass = TrackedDeviceClass.Controller,
int relativeTo = (int)OpenVR.k_unTrackedDeviceIndex_Hmd)
{
var invXform = ((uint)relativeTo < OpenVR.k_unMaxTrackedDeviceCount) ?
Input(relativeTo).transform.GetInverse() : SteamVR_Utils.RigidTransform.identity;
var vr = SteamVR.instance;
var result = -1;
var best = -float.MaxValue;
for (int i = 0; i < OpenVR.k_unMaxTrackedDeviceCount; i++)
{
if (i == relativeTo || vr.hmd.GetTrackedDeviceClass((uint)i) != deviceClass)
continue;
var device = Input(i);
if (!device.connected)
continue;
if (relation == DeviceRelation.First)
return i;
float score;
var pos = invXform * device.transform.pos;
if (relation == DeviceRelation.FarthestRight)
{
score = pos.x;
}
else if (relation == DeviceRelation.FarthestLeft)
{
score = -pos.x;
}
else
{
var dir = new Vector3(pos.x, 0.0f, pos.z).normalized;
var dot = Vector3.Dot(dir, Vector3.forward);
var cross = Vector3.Cross(dir, Vector3.forward);
if (relation == DeviceRelation.Leftmost)
{
score = (cross.y > 0.0f) ? 2.0f - dot : dot;
}
else
{
score = (cross.y < 0.0f) ? 2.0f - dot : dot;
}
}
if (score > best)
{
result = i;
best = score;
}
}
return result;
}