public void SetAttachment(AttachmentType attachmentType, Vector3 position, Vector3 rotation, string attachmentKey = null) { if (!_ingame) { throw new Exception("Cannot set attachment for dashboard overlay"); } _attachmentType = attachmentType; _position = position; _rotation = rotation; if (attachmentType == AttachmentType.Absolute) { HmdMatrix34_t matrix = GetMatrixFromPositionAndRotation(position, rotation); SteamVR_WebKit.OverlayManager.SetOverlayTransformAbsolute(_handle, ETrackingUniverseOrigin.TrackingUniverseStanding, ref matrix); _sentAttachmentSuccess = true; } else if (attachmentType == AttachmentType.Hmd) { SetDeviceAttachment((uint)0, position, rotation); _sentAttachmentSuccess = true; } else if (attachmentType == AttachmentType.Overlay) { ulong attachmentHandle = 0; if (attachmentType == AttachmentType.Overlay && attachmentKey == null) { attachmentKey = _attachedTo; } if (_attachedTo != attachmentKey) { SteamVR_WebKit.OverlayManager.FindOverlay(attachmentKey, ref attachmentHandle); _attachedToHandle = attachmentHandle; } if (_attachedToHandle != 0) { HmdMatrix34_t matrix = GetMatrixFromPositionAndRotation(position, rotation); EVROverlayError err = SteamVR_WebKit.OverlayManager.SetOverlayTransformOverlayRelative(_handle, _attachedToHandle, ref matrix); if (err != EVROverlayError.None) { SteamVR_WebKit.Log("Failed to attach " + Key + " to Overlay " + attachmentKey + " failed: " + err.ToString()); } _sentAttachmentSuccess = true; } else { SteamVR_WebKit.Log("Attempted to attach to " + attachmentKey + " but it could not be found."); } } else if (attachmentType == AttachmentType.AbsoluteRelative) { ulong attachmentHandle = 0; if (attachmentType == AttachmentType.Overlay && attachmentKey == null) { attachmentKey = _attachedTo; } if (_attachedTo != attachmentKey) { SteamVR_WebKit.OverlayManager.FindOverlay(attachmentKey, ref attachmentHandle); _attachedToHandle = attachmentHandle; } if (_attachedToHandle != 0) { HmdMatrix34_t matrix = GetMatrixFromPositionAndRotation(position, rotation); HmdMatrix34_t parentMatrix = new HmdMatrix34_t(); uint parentWidth = 0, parentHeight = 0; SteamVR_WebKit.OverlayManager.GetOverlayTextureSize(_attachedToHandle, ref parentWidth, ref parentHeight); EVROverlayError err = SteamVR_WebKit.OverlayManager.GetTransformForOverlayCoordinates(_attachedToHandle, ETrackingUniverseOrigin.TrackingUniverseStanding, new HmdVector2_t() { v0 = parentWidth / 2, v1 = parentHeight / 2 }, ref parentMatrix); if (err != EVROverlayError.None) { SteamVR_WebKit.Log("Failed to retrieve overlay position for " + _attachedTo); return; } HmdMatrix34_t resultMatrix = TransformUtils.OpenTKMatrixToOpenVRMatrix(TransformUtils.OpenVRMatrixToOpenTKMatrix(parentMatrix) * TransformUtils.OpenVRMatrixToOpenTKMatrix(matrix)); err = SteamVR_WebKit.OverlayManager.SetOverlayTransformAbsolute(_handle, ETrackingUniverseOrigin.TrackingUniverseStanding, ref resultMatrix); if (err != EVROverlayError.None) { SteamVR_WebKit.Log("Failed to attach " + Key + " to Overlay " + attachmentKey + " failed: " + err.ToString()); } _sentAttachmentSuccess = true; } else { SteamVR_WebKit.Log("Attempted to attach to " + attachmentKey + " but it could not be found."); } } else { SetDeviceAttachment(SteamVR_WebKit.OVRSystem.GetTrackedDeviceIndexForControllerRole(attachmentType == AttachmentType.LeftController ? ETrackedControllerRole.LeftHand : ETrackedControllerRole.RightHand), position, rotation); if (!_controllerListenersSetup) { SteamVR_Event.Listen("TrackedDeviceRoleChanged", HandleDeviceRoleChanged); SteamVR_Event.Listen("device_connected", HandleDeviceConnected); _controllerListenersSetup = true; } else { _sentAttachmentSuccess = true; } } }