using System; using System.Runtime.InteropServices; using UnityEngine; using Valve.VR; public class SteamVR_Overlay : MonoBehaviour { public static SteamVR_Overlay instance { get; private set; } public static string key { get { return "unity:" + Application.companyName + "." + Application.productName; } } private void OnEnable() { CVROverlay overlay = OpenVR.Overlay; if (overlay != null) { EVROverlayError evroverlayError = overlay.CreateOverlay(SteamVR_Overlay.key, base.gameObject.name, ref this.handle); if (evroverlayError != EVROverlayError.None) { Debug.Log(overlay.GetOverlayErrorNameFromEnum(evroverlayError)); base.enabled = false; return; } } SteamVR_Overlay.instance = this; } private void OnDisable() { if (this.handle != 0UL) { CVROverlay overlay = OpenVR.Overlay; if (overlay != null) { overlay.DestroyOverlay(this.handle); } this.handle = 0UL; } SteamVR_Overlay.instance = null; } public void UpdateOverlay() { CVROverlay overlay = OpenVR.Overlay; if (overlay == null) { return; } if (this.texture != null) { EVROverlayError evroverlayError = overlay.ShowOverlay(this.handle); if ((evroverlayError == EVROverlayError.InvalidHandle || evroverlayError == EVROverlayError.UnknownOverlay) && overlay.FindOverlay(SteamVR_Overlay.key, ref this.handle) != EVROverlayError.None) { return; } Texture_t texture_t = default(Texture_t); texture_t.handle = this.texture.GetNativeTexturePtr(); texture_t.eType = SteamVR.instance.graphicsAPI; texture_t.eColorSpace = EColorSpace.Auto; overlay.SetOverlayTexture(this.handle, ref texture_t); overlay.SetOverlayAlpha(this.handle, this.alpha); overlay.SetOverlayWidthInMeters(this.handle, this.scale); overlay.SetOverlayAutoCurveDistanceRangeInMeters(this.handle, this.curvedRange.x, this.curvedRange.y); VRTextureBounds_t vrtextureBounds_t = default(VRTextureBounds_t); vrtextureBounds_t.uMin = this.uvOffset.x * this.uvOffset.z; vrtextureBounds_t.vMin = (1f + this.uvOffset.y) * this.uvOffset.w; vrtextureBounds_t.uMax = (1f + this.uvOffset.x) * this.uvOffset.z; vrtextureBounds_t.vMax = this.uvOffset.y * this.uvOffset.w; overlay.SetOverlayTextureBounds(this.handle, ref vrtextureBounds_t); HmdVector2_t hmdVector2_t = default(HmdVector2_t); hmdVector2_t.v0 = this.mouseScale.x; hmdVector2_t.v1 = this.mouseScale.y; overlay.SetOverlayMouseScale(this.handle, ref hmdVector2_t); SteamVR_Camera steamVR_Camera = SteamVR_Render.Top(); if (steamVR_Camera != null && steamVR_Camera.origin != null) { SteamVR_Utils.RigidTransform rigidTransform = new SteamVR_Utils.RigidTransform(steamVR_Camera.origin, base.transform); rigidTransform.pos.x = rigidTransform.pos.x / steamVR_Camera.origin.localScale.x; rigidTransform.pos.y = rigidTransform.pos.y / steamVR_Camera.origin.localScale.y; rigidTransform.pos.z = rigidTransform.pos.z / steamVR_Camera.origin.localScale.z; rigidTransform.pos.z = rigidTransform.pos.z + this.distance; HmdMatrix34_t hmdMatrix34_t = rigidTransform.ToHmdMatrix34(); overlay.SetOverlayTransformAbsolute(this.handle, SteamVR_Render.instance.trackingSpace, ref hmdMatrix34_t); } overlay.SetOverlayInputMethod(this.handle, this.inputMethod); if (this.curved || this.antialias) { this.highquality = true; } if (this.highquality) { overlay.SetHighQualityOverlay(this.handle); overlay.SetOverlayFlag(this.handle, VROverlayFlags.Curved, this.curved); overlay.SetOverlayFlag(this.handle, VROverlayFlags.RGSS4X, this.antialias); } else if (overlay.GetHighQualityOverlay() == this.handle) { overlay.SetHighQualityOverlay(0UL); } } else { overlay.HideOverlay(this.handle); } } public bool PollNextEvent(ref VREvent_t pEvent) { CVROverlay overlay = OpenVR.Overlay; if (overlay == null) { return false; } uint uncbVREvent = (uint)Marshal.SizeOf(typeof(VREvent_t)); return overlay.PollNextOverlayEvent(this.handle, ref pEvent, uncbVREvent); } public bool ComputeIntersection(Vector3 source, Vector3 direction, ref SteamVR_Overlay.IntersectionResults results) { CVROverlay overlay = OpenVR.Overlay; if (overlay == null) { return false; } VROverlayIntersectionParams_t vroverlayIntersectionParams_t = default(VROverlayIntersectionParams_t); vroverlayIntersectionParams_t.eOrigin = SteamVR_Render.instance.trackingSpace; vroverlayIntersectionParams_t.vSource.v0 = source.x; vroverlayIntersectionParams_t.vSource.v1 = source.y; vroverlayIntersectionParams_t.vSource.v2 = -source.z; vroverlayIntersectionParams_t.vDirection.v0 = direction.x; vroverlayIntersectionParams_t.vDirection.v1 = direction.y; vroverlayIntersectionParams_t.vDirection.v2 = -direction.z; VROverlayIntersectionResults_t vroverlayIntersectionResults_t = default(VROverlayIntersectionResults_t); if (!overlay.ComputeOverlayIntersection(this.handle, ref vroverlayIntersectionParams_t, ref vroverlayIntersectionResults_t)) { return false; } results.point = new Vector3(vroverlayIntersectionResults_t.vPoint.v0, vroverlayIntersectionResults_t.vPoint.v1, -vroverlayIntersectionResults_t.vPoint.v2); results.normal = new Vector3(vroverlayIntersectionResults_t.vNormal.v0, vroverlayIntersectionResults_t.vNormal.v1, -vroverlayIntersectionResults_t.vNormal.v2); results.UVs = new Vector2(vroverlayIntersectionResults_t.vUVs.v0, vroverlayIntersectionResults_t.vUVs.v1); results.distance = vroverlayIntersectionResults_t.fDistance; return true; } public Texture texture; public bool curved = true; public bool antialias = true; public bool highquality = true; public float scale = 3f; public float distance = 1.25f; public float alpha = 1f; public Vector4 uvOffset = new Vector4(0f, 0f, 1f, 1f); public Vector2 mouseScale = new Vector2(1f, 1f); public Vector2 curvedRange = new Vector2(1f, 2f); public VROverlayInputMethod inputMethod; private ulong handle; public struct IntersectionResults { public Vector3 point; public Vector3 normal; public Vector2 UVs; public float distance; } }