/// <summary>
    /// Attach the Overlay to [device] at [scale] size with offset [offset], and base position [point].
    /// [point] isn't used for HMD or World, and can be ignored.
    /// </summary>
    /// <param name="device"></param>
    /// <param name="scale"></param>
    /// <param name="offset"></param>
    /// <param name="point"></param>
    public void AttachTo(MountDevice device, float scale, Vector3 offset, MountLocation point = MountLocation.Center)
    {
        // Update Overlay Anchor position
        GetOverlayPosition();

        // Update cached values
        _anchorDevice = device;
        AnchorDevice  = device;
        _anchorPoint  = point;
        AnchorPoint   = point;
        _anchorOffset = offset;
        AnchorOffset  = offset;
        Scale         = scale;

        // Attach Overlay
        switch (device)
        {
        case MountDevice.Screen:
            _anchor = OpenVR.k_unTrackedDeviceIndexInvalid;
            OverlayReference.transform.localPosition = -offset;
            OverlayReference.transform.localRotation = Quaternion.identity;
            break;

        case MountDevice.World:
            _anchor = OpenVR.k_unTrackedDeviceIndexInvalid;
            OverlayReference.transform.localPosition = -offset;
            OverlayReference.transform.localRotation = Quaternion.identity;
            break;

        case MountDevice.LeftController:
            _anchor = HOTK_TrackedDeviceManager.Instance.LeftIndex;
            AttachToController(point, offset);
            break;

        case MountDevice.RightController:
            _anchor = HOTK_TrackedDeviceManager.Instance.RightIndex;
            AttachToController(point, offset);
            break;

        default:
            throw new ArgumentOutOfRangeException("device", device, null);
        }
    }
    /// <summary>
    /// Update the Overlay's Position and Rotation, relative to the selected controller, attaching it to [point] with offset [offset]
    /// </summary>
    /// <param name="point"></param>
    /// <param name="offset"></param>
    private void AttachToController(MountLocation point, Vector3 offset)
    {
        float dx = offset.x, dy = offset.y, dz = offset.z;

        // Offset our position based on the Attachment Point
        switch (point)
        {
        case MountLocation.Center:
            break;

        case MountLocation.FlatAbove:
            dz += 0.05f;
            break;

        case MountLocation.FlatBelow:
            dz -= 0.18f;
            break;

        case MountLocation.FlatBelowFlipped:
            dz += 0.18f;
            break;

        case MountLocation.Above:
            dz -= 0.01f;
            break;

        case MountLocation.AboveFlipped:
            dz += 0.01f;
            break;

        case MountLocation.Below:
            dz += 0.1f;
            break;

        case MountLocation.BelowFlipped:
            dz -= 0.1f;
            break;

        case MountLocation.Up:
            dy += 0.5f;
            break;

        case MountLocation.Down:
            dy -= 0.5f;
            break;

        case MountLocation.Left:
            dx -= 0.5f;
            break;

        case MountLocation.Right:
            dx += 0.5f;
            break;

        default:
            throw new ArgumentOutOfRangeException("point", point, null);
        }

        Vector3 pos;
        var     rot = Quaternion.identity;

        // Apply position and rotation to Overlay anchor
        // Some Axis are flipped here to reorient the offset
        switch (point)
        {
        case MountLocation.FlatAbove:
        case MountLocation.FlatBelow:
            pos = new Vector3(dx, dy, dz);
            break;

        case MountLocation.FlatBelowFlipped:
            pos = new Vector3(dx, -dy, -dz);
            rot = Quaternion.AngleAxis(180f, new Vector3(1f, 0f, 0f));
            break;

        case MountLocation.Center:
        case MountLocation.Above:
        case MountLocation.Below:
            pos = new Vector3(dx, -dz, dy);
            rot = Quaternion.AngleAxis(90f, new Vector3(1f, 0f, 0f));
            break;

        case MountLocation.Up:
        case MountLocation.Down:
        case MountLocation.Left:
        case MountLocation.Right:
            pos = new Vector3(dx, -dz, dy);
            rot = Quaternion.AngleAxis(90f, new Vector3(1f, 0f, 0f));
            break;

        case MountLocation.AboveFlipped:
        case MountLocation.BelowFlipped:
            pos = new Vector3(-dx, dz, dy);
            rot = Quaternion.AngleAxis(90f, new Vector3(1f, 0f, 0f)) * Quaternion.AngleAxis(180f, new Vector3(0f, 1f, 0f));
            break;

        default:
            throw new ArgumentOutOfRangeException("point", point, null);
        }
        OverlayReference.transform.localPosition = pos;
        _anchorRotation = rot;
        var changed = false;

        CheckOverlayRotationChanged(ref changed, true); // Force rotational update
    }
 /// <summary>
 /// Attach the Overlay to [device] at [scale], and base position [point].
 /// [point] isn't used for HMD or World, and can be ignored.
 /// </summary>
 /// <param name="device"></param>
 /// <param name="scale"></param>
 /// <param name="point"></param>
 public void AttachTo(MountDevice device, float scale, MountLocation point = MountLocation.Center)
 {
     AttachTo(device, scale, Vector3.zero, point);
 }