private Matrix GetProjection(EVREye eye) { // Dunno why _vrSystem.GetProjectionMatrix doesn't work. Maybe different semantics of the matrix? float left = 0, right = 0, top = 0, bottom = 0; var near = 0.5f; var far = 20.0f; _vrSystem.GetProjectionRaw(eye, ref left, ref right, ref top, ref bottom); left *= near; right *= near; top *= near; bottom *= near; return(Matrix.CreatePerspectiveOffCenter(left, right, bottom, top, near, far)); }
private SteamVR(System.IntPtr pHmd, System.IntPtr pCompositor, System.IntPtr pOverlay) { hmd = new CVRSystem(pHmd); Debug.Log("Connected to " + hmd_TrackingSystemName + ":" + hmd_SerialNumber); compositor = new CVRCompositor(pCompositor); overlay = new CVROverlay(pOverlay); var capacity = compositor.GetLastError(null, 0); if (capacity > 1) { var result = new System.Text.StringBuilder((int)capacity); compositor.GetLastError(result, capacity); Debug.Log("Compositor - " + result); } // Hook up the render thread event. var error = HmdError.None; SetUnityRenderCallback(OpenVR.GetGenericInterface(IVRHmdDistortPresent_Version, ref error)); // Setup render values uint w = 0, h = 0; hmd.GetRecommendedRenderTargetSize(ref w, ref h); sceneWidth = (float)w; sceneHeight = (float)h; float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; hmd.GetProjectionRaw(Hmd_Eye.Eye_Left, ref l_left, ref l_right, ref l_top, ref l_bottom); float r_left = 0.0f, r_right = 0.0f, r_top = 0.0f, r_bottom = 0.0f; hmd.GetProjectionRaw(Hmd_Eye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom); tanHalfFov = new Vector2( Mathf.Max(-l_left, l_right, -r_left, r_right), Mathf.Max(-l_top, l_bottom, -r_top, r_bottom)); textureBounds = new VRTextureBounds_t[2]; textureBounds[0].uMin = 0.5f + 0.5f * l_left / tanHalfFov.x; textureBounds[0].uMax = 0.5f + 0.5f * l_right / tanHalfFov.x; textureBounds[0].vMin = 0.5f - 0.5f * l_bottom / tanHalfFov.y; textureBounds[0].vMax = 0.5f - 0.5f * l_top / tanHalfFov.y; textureBounds[1].uMin = 0.5f + 0.5f * r_left / tanHalfFov.x; textureBounds[1].uMax = 0.5f + 0.5f * r_right / tanHalfFov.x; textureBounds[1].vMin = 0.5f - 0.5f * r_bottom / tanHalfFov.y; textureBounds[1].vMax = 0.5f - 0.5f * r_top / tanHalfFov.y; // Grow the recommended size to account for the overlapping fov sceneWidth = sceneWidth / Mathf.Max(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin); sceneHeight = sceneHeight / Mathf.Max(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin); aspect = tanHalfFov.x / tanHalfFov.y; fieldOfView = 2.0f * Mathf.Atan(tanHalfFov.y) * Mathf.Rad2Deg; eyes = new SteamVR_Utils.RigidTransform[] { new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(Hmd_Eye.Eye_Left)), new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(Hmd_Eye.Eye_Right)) }; if (SystemInfo.graphicsDeviceVersion.StartsWith("OpenGL")) { graphicsAPI = GraphicsAPIConvention.API_OpenGL; } else { graphicsAPI = GraphicsAPIConvention.API_DirectX; } SteamVR_Utils.Event.Listen("initializing", OnInitializing); SteamVR_Utils.Event.Listen("calibrating", OnCalibrating); SteamVR_Utils.Event.Listen("out_of_range", OnOutOfRange); SteamVR_Utils.Event.Listen("device_connected", OnDeviceConnected); SteamVR_Utils.Event.Listen("new_poses", OnNewPoses); }
private void setup() { //init VR System and check for errors var error = EVRInitError.None; vrSystem = OpenVR.Init(ref error, EVRApplicationType.VRApplication_Scene); if ((int)error != (int)EVRInitError.None) { log("KerbalVrPlugin started."); } else { err(error.ToString()); } //rendervalues ######################################################### // Setup render values uint w = 0, h = 0; vrSystem.GetRecommendedRenderTargetSize(ref w, ref h); float sceneWidth = (float)w; float sceneHeight = (float)h; float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; vrSystem.GetProjectionRaw(EVREye.Eye_Left, ref l_left, ref l_right, ref l_top, ref l_bottom); float r_left = 0.0f, r_right = 0.0f, r_top = 0.0f, r_bottom = 0.0f; vrSystem.GetProjectionRaw(EVREye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom); Vector2 tanHalfFov = new Vector2(Mathf.Max(-l_left, l_right, -r_left, r_right), Mathf.Max(-l_top, l_bottom, -r_top, r_bottom)); //Setup rendertextures hmdLeftEyeTexture = new Texture_t(); hmdLeftEyeTexture.eColorSpace = EColorSpace.Auto; hmdRightEyeTexture = new Texture_t(); hmdRightEyeTexture.eColorSpace = EColorSpace.Auto; //select Texture Type depending on RenderAPI (Currently only DirectX11 is tested) switch (SystemInfo.graphicsDeviceType) { case UnityEngine.Rendering.GraphicsDeviceType.OpenGL2: log("OpenGL2"); hmdLeftEyeTexture.eType = ETextureType.OpenGL; hmdRightEyeTexture.eType = ETextureType.OpenGL; break; case UnityEngine.Rendering.GraphicsDeviceType.OpenGLCore: log("OpenCore"); hmdLeftEyeTexture.eType = ETextureType.OpenGL; hmdRightEyeTexture.eType = ETextureType.OpenGL; break; case UnityEngine.Rendering.GraphicsDeviceType.OpenGLES2: log("OpenGLES2"); hmdLeftEyeTexture.eType = ETextureType.OpenGL; hmdRightEyeTexture.eType = ETextureType.OpenGL; break; case UnityEngine.Rendering.GraphicsDeviceType.OpenGLES3: log("OpenGLES3"); hmdLeftEyeTexture.eType = ETextureType.OpenGL; hmdRightEyeTexture.eType = ETextureType.OpenGL; break; case UnityEngine.Rendering.GraphicsDeviceType.Direct3D9: log("Direct3D9"); warn("DirectX 9 mode not Supported! There be Dragons!"); hmdLeftEyeTexture.eType = ETextureType.DirectX; hmdRightEyeTexture.eType = ETextureType.DirectX; break; case UnityEngine.Rendering.GraphicsDeviceType.Direct3D11: log("Direct3D11"); hmdLeftEyeTexture.eType = ETextureType.DirectX; hmdRightEyeTexture.eType = ETextureType.DirectX; break; case UnityEngine.Rendering.GraphicsDeviceType.Direct3D12: log("Direct3D12"); warn("DirectX 12 mode not implemented! There be Dragons!"); hmdLeftEyeTexture.eType = ETextureType.DirectX12; hmdRightEyeTexture.eType = ETextureType.DirectX12; break; default: throw (new Exception(SystemInfo.graphicsDeviceType.ToString() + " not supported")); } vrCompositor = OpenVR.Compositor; if (!vrCompositor.CanRenderScene()) { err("can not render scene"); } }
public override void Initialize() { StringBuilder sb = new StringBuilder(512); ETrackedPropertyError error = ETrackedPropertyError.TrackedProp_Success; uint ret = _vrSystem.GetStringTrackedDeviceProperty( OVR.k_unTrackedDeviceIndex_Hmd, ETrackedDeviceProperty.Prop_TrackingSystemName_String, sb, 512u, ref error); if (error != ETrackedPropertyError.TrackedProp_Success) { _deviceName = "<Unknown OpenVR Device>"; } else { _deviceName = sb.ToString(); } uint eyeWidth = 0; uint eyeHeight = 0; _vrSystem.GetRecommendedRenderTargetSize(ref eyeWidth, ref eyeHeight); _leftEyeGT = GPUDevice.CreateTexture(); var descLeftEye = GPUTextureDescription.New2D((int)eyeWidth, (int)eyeHeight, 1, PixelFormat.R8G8B8A8_UNorm, msaaLevel: _options.EyeRenderTargetSampleCount); _leftEyeGT.Init(ref descLeftEye); _rightEyeGT = GPUDevice.CreateTexture(); var descRightEye = GPUTextureDescription.New2D((int)eyeWidth, (int)eyeHeight, 1, PixelFormat.R8G8B8A8_UNorm, msaaLevel: _options.EyeRenderTargetSampleCount); _rightEyeGT.Init(ref descRightEye); Matrix eyeToHeadLeft = ToSysMatrix(_vrSystem.GetEyeToHeadTransform(EVREye.Eye_Left)); Matrix.Invert(ref eyeToHeadLeft, out _headToEyeLeft); Matrix eyeToHeadRight = ToSysMatrix(_vrSystem.GetEyeToHeadTransform(EVREye.Eye_Right)); Matrix.Invert(ref eyeToHeadRight, out _headToEyeRight); // Default RH matrices /*_projLeft = ToSysMatrix(_vrSystem.GetProjectionMatrix(EVREye.Eye_Left, 0.1f, 10000f)); * _projRight = ToSysMatrix(_vrSystem.GetProjectionMatrix(EVREye.Eye_Right, 0.1f, 10000f));*/ // Build LH projection matrices (https://github.com/ValveSoftware/openvr/wiki/IVRSystem::GetProjectionRaw) float pLeft = 0; float pRight = 0; float pTop = 0; float pBottom = 0; // Default values float zNear = 0.1f; float zFar = 20000f; _vrSystem.GetProjectionRaw(EVREye.Eye_Left, ref pLeft, ref pRight, ref pTop, ref pBottom); _projLeft = Matrix.PerspectiveOffCenter(pLeft * zNear, pRight * zNear, pBottom * zNear * -1f, pTop * zNear * -1f, zNear, zFar); _vrSystem.GetProjectionRaw(EVREye.Eye_Right, ref pLeft, ref pRight, ref pTop, ref pBottom); _projRight = Matrix.PerspectiveOffCenter(pLeft * zNear, pRight * zNear, pBottom * zNear * -1f, pTop * zNear * -1f, zNear, zFar); }
protected override void Render() { EnsureDllsLoaded(); Lock = true; EVRInitError initError = EVRInitError.None; Valve.VR.OpenVR.Init(ref initError); if (initError != EVRInitError.None) { throw new Exception("OpenVR init error " + initError + ": " + Valve.VR.OpenVR.GetStringForHmdError(initError)); } CVRSystem hmd = Valve.VR.OpenVR.System; CVRCompositor compositor = Valve.VR.OpenVR.Compositor; uint targetWidth = 0, targetHeight = 0; hmd.GetRecommendedRenderTargetSize(ref targetWidth, ref targetHeight); float sceneWidth = (float)targetWidth; float sceneHeight = (float)targetHeight; float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; hmd.GetProjectionRaw(EVREye.Eye_Left, ref l_left, ref l_right, ref l_top, ref l_bottom); float r_left = 0.0f, r_right = 0.0f, r_top = 0.0f, r_bottom = 0.0f; hmd.GetProjectionRaw(EVREye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom); Vector2 tanHalfFov = new Vector2( Math.Max(Math.Max(-l_left, l_right), Math.Max(-r_left, r_right)), Math.Max(Math.Max(-l_top, l_bottom), Math.Max(-r_top, r_bottom)) ); VRTextureBounds_t[] textureBounds = new VRTextureBounds_t[2]; textureBounds[0].uMin = 0.5f + 0.5f * l_left / tanHalfFov.X; textureBounds[0].uMax = 0.5f + 0.5f * l_right / tanHalfFov.X; textureBounds[0].vMin = 0.5f - 0.5f * l_bottom / tanHalfFov.Y; textureBounds[0].vMax = 0.5f - 0.5f * l_top / tanHalfFov.Y; textureBounds[1].uMin = 0.5f + 0.5f * r_left / tanHalfFov.X; textureBounds[1].uMax = 0.5f + 0.5f * r_right / tanHalfFov.X; textureBounds[1].vMin = 0.5f - 0.5f * r_bottom / tanHalfFov.Y; textureBounds[1].vMax = 0.5f - 0.5f * r_top / tanHalfFov.Y; float aspect = tanHalfFov.X / tanHalfFov.Y; float lookFov = (float)(2.0f * Math.Atan(tanHalfFov.Y) * 180 / Math.PI); Texture2DDescription eyeTextureDescription = new Texture2DDescription() { Format = Format.R8G8B8A8_UNorm_SRgb, ArraySize = 1, MipLevels = 1, Width = (int)targetWidth, Height = (int)targetHeight, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; Texture2DDescription eyeDepthTextureDescription = new Texture2DDescription() { Format = Format.D32_Float_S8X24_UInt, ArraySize = 1, MipLevels = 1, Width = (int)targetWidth, Height = (int)targetHeight, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; ///// CUBE //var cubeEffect = new SharpDX.Toolkit.Graphics.BasicEffect(_gd) //{ // //PreferPerPixelLighting = false, // //TextureEnabled = false, // LightingEnabled = true, // //DiffuseColor = new Vector4(0.5f,0.5f,0.5f,1f), // Sampler = _gd.SamplerStates.AnisotropicClamp //}; //cubeEffect.EnableDefaultLighting(); //var cube = SharpDX.Toolkit.Graphics.GeometricPrimitive.Teapot.New(_gd, 1, 8, false); ///// END using (_device = new Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport, new FeatureLevel[] { FeatureLevel.Level_10_0 })) using (DeviceContext context = _device.ImmediateContext) using (_gd = SharpDX.Toolkit.Graphics.GraphicsDevice.New(_device)) //using (SharpDX.Toolkit.Graphics.GeometricPrimitive primitive = GraphicTools.CreateGeometry(_projection, _gd, false)) using (customEffectL = GetCustomEffect(_gd)) using (customEffectR = GetCustomEffect(_gd)) using (Texture2D leftEye = new Texture2D(_device, eyeTextureDescription)) using (RenderTargetView leftEyeView = new RenderTargetView(_device, leftEye)) using (Texture2D leftEyeDepth = new Texture2D(_device, eyeDepthTextureDescription)) using (DepthStencilView leftEyeDepthView = new DepthStencilView(_device, leftEyeDepth)) using (Texture2D rightEye = new Texture2D(_device, eyeTextureDescription)) using (RenderTargetView rightEyeView = new RenderTargetView(_device, rightEye)) using (Texture2D rightEyeDepth = new Texture2D(_device, eyeDepthTextureDescription)) using (DepthStencilView rightEyeDepthView = new DepthStencilView(_device, rightEyeDepth)) using (vrui = new VRUI(_device, _gd)) { //primitive = GraphicTools.CreateGeometry(Projection, _gd, false); Stopwatch stopwatch = new Stopwatch(); Texture_t leftEyeTex = new Texture_t() { eColorSpace = EColorSpace.Gamma, eType = EGraphicsAPIConvention.API_DirectX, handle = leftEye.NativePointer }; Texture_t rightEyeTex = new Texture_t() { eColorSpace = EColorSpace.Gamma, eType = EGraphicsAPIConvention.API_DirectX, handle = rightEye.NativePointer }; TrackedDevicePose_t[] renderPoseArray = new TrackedDevicePose_t[16]; TrackedDevicePose_t[] gamePoseArray = new TrackedDevicePose_t[16]; TrackedDevicePose_t pose = new TrackedDevicePose_t(); try { // Start with default background SetDefaultScene(); while (!abort) { UpdateContentIfRequested(); float deltaTime = (float)stopwatch.Elapsed.TotalSeconds; stopwatch.Restart(); compositor.WaitGetPoses(renderPoseArray, gamePoseArray); if (renderPoseArray[Valve.VR.OpenVR.k_unTrackedDeviceIndex_Hmd].bPoseIsValid) { pose = gamePoseArray[Valve.VR.OpenVR.k_unTrackedDeviceIndex_Hmd]; } foreach (EVREye eye in new EVREye[] { EVREye.Eye_Left, EVREye.Eye_Right }) { DepthStencilView currentEyeDepthView = (eye == EVREye.Eye_Left) ? leftEyeDepthView : rightEyeDepthView; RenderTargetView currentEyeView = (eye == EVREye.Eye_Left) ? leftEyeView : rightEyeView; // Setup targets and viewport for rendering context.OutputMerger.SetTargets(currentEyeDepthView, currentEyeView); context.ClearDepthStencilView(currentEyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0); context.ClearRenderTargetView(currentEyeView, Color.Black); context.Rasterizer.SetViewport(new Viewport(0, 0, (int)targetWidth, (int)targetHeight, 0.0f, 1.0f)); Quaternion lookRotation; // = pose.mDeviceToAbsoluteTracking.GetRotation(); Vector3 lookPosition; // = pose.mDeviceToAbsoluteTracking.GetPosition(); Vector3 scale; Matrix eyePose = hmd.GetEyeToHeadTransform(eye).RebuildTRSMatrix() * pose.mDeviceToAbsoluteTracking.RebuildTRSMatrix(); eyePose.Decompose(out scale, out lookRotation, out lookPosition); Matrix rotationMatrix = Matrix.RotationQuaternion(lookRotation); Vector3 lookUp = Vector3.Transform(Vector3.Up, rotationMatrix).ToVector3(); Vector3 lookAt = Vector3.Transform(Vector3.ForwardRH, rotationMatrix).ToVector3(); //Console.WriteLine($"OpenVR {eye} up: {lookUp:00.00} at: {lookAt:00.00} position:{lookPosition:00.00}"); Matrix viewMatrix = Matrix.LookAtRH(lookPosition, lookPosition + lookAt, lookUp); Matrix pm1 = Matrix.PerspectiveFovLH(lookFov * ((float)Math.PI / 180f), aspect, 0.001f, 100.0f); //Matrix pm2 = hmd.GetProjectionMatrix(eye, 0.001f, 100f, EGraphicsAPIConvention.API_DirectX).ToProjMatrix(); Matrix projectionMatrix = pm1; Matrix worldMatrix = Matrix.Translation(lookPosition); if (Logic.Instance.settings.OpenVRReverse) { worldMatrix = Matrix.RotationY(180) * worldMatrix; } Matrix MVP = worldMatrix * viewMatrix * projectionMatrix; customEffectL.Parameters["WorldViewProj"].SetValue(MVP); customEffectR.Parameters["WorldViewProj"].SetValue(MVP); lock (localCritical) { if (eye == EVREye.Eye_Left) { primitive?.Draw(customEffectL); } if (eye == EVREye.Eye_Right) { primitive?.Draw(customEffectR); } } if (eye == EVREye.Eye_Left) { Vector3 fixedLookPosition = Vector3.Transform(lookPosition, MVP).ToVector3(); Vector3 fixedLookAt = Vector3.Transform(lookPosition + Vector3.ForwardLH, MVP).ToVector3() - fixedLookPosition; Vector3 fixedLookUp = Vector3.Transform(lookPosition + Vector3.Up, MVP).ToVector3() - fixedLookPosition; fixedLookAt.Normalize(); fixedLookUp.Normalize(); Quaternion fixedLookRotation = Quaternion.LookAtRH(Vector3.Zero, fixedLookAt, fixedLookUp); //fixedLookRotation.X *= -1; //fixedLookRotation.Y *= -1; fixedLookRotation.Z *= -1; //if(eye == EVREye.Eye_Left) // fixedLookRotation.Invert(); //Mirror effect of rotation along z axis by flipping x and y elements of the quaternion. //http://stackoverflow.com/a/32482386/785171 //float t = fixedLookRotation.X; //fixedLookRotation.X = fixedLookRotation.Y; //fixedLookRotation.Y = t; //fixedLookRotation = new Quaternion(1, 0, 0, 0) * fixedLookRotation; //fixedLookRotation = new Quaternion(0, 0, 1, 0) * fixedLookRotation; LoggerManager.Publish("openvr.forward", fixedLookAt); LoggerManager.Publish("openvr.up", fixedLookUp); // TODO: normalize ProvideLook?.Invoke(fixedLookPosition, fixedLookRotation, lookFov); } // reset UI position every frame if it is not visible if (vrui.isUIHidden) { vrui.SetWorldPosition(viewMatrix.Forward, lookPosition, false); } vrui.Draw(Media, currentTime, Duration); vrui.Render(deltaTime, viewMatrix, projectionMatrix, lookPosition, ShouldShowVRUI); //// controllers: //cubeEffect.View = viewMatrix; //cubeEffect.Projection = projectionMatrix; //for (uint controller = 1 /*skip hmd*/; controller < Valve.VR.OpenVR.k_unMaxTrackedDeviceCount; controller++) //{ // VRControllerState_t controllerState = default(VRControllerState_t); // //var controllerPose = renderPoseArray[controller]; // //if (hmd.GetControllerState(controller, ref controllerState)) { // Vector3 pos = renderPoseArray[controller].mDeviceToAbsoluteTracking.GetPosition(); // Quaternion rot = renderPoseArray[controller].mDeviceToAbsoluteTracking.GetRotation(); // rot = rot * new Quaternion(0, 1, 0, 0); // float s = controllerState.ulButtonPressed > 0 ? 0.5f : 0.1f; // cubeEffect.World = Matrix.Scaling(s) * Matrix.RotationQuaternion(rot) * Matrix.Translation(pos); // cube.Draw(cubeEffect); // //} //} } // RENDER TO HMD EVRCompositorError errorLeft = compositor.Submit( EVREye.Eye_Left, ref leftEyeTex, ref textureBounds[0], EVRSubmitFlags.Submit_Default ); EVRCompositorError errorRight = compositor.Submit( EVREye.Eye_Right, ref rightEyeTex, ref textureBounds[1], EVRSubmitFlags.Submit_Default ); if (errorLeft != EVRCompositorError.None) { throw new HeadsetError("VR Compositor failure (left): " + errorLeft); } if (errorRight != EVRCompositorError.None) { throw new HeadsetError("VR Compositor failure (right): " + errorRight); } } ; } finally { Valve.VR.OpenVR.Shutdown(); primitive?.Dispose(); context.ClearState(); context.Flush(); } } }
private SteamVR(System.IntPtr pHmd, System.IntPtr pCompositor, System.IntPtr pOverlay) { hmd = new CVRSystem(pHmd); Debug.Log("Connected to " + hmd_TrackingSystemName + ":" + hmd_SerialNumber); compositor = new CVRCompositor(pCompositor); overlay = new CVROverlay(pOverlay); // Setup render values uint w = 0, h = 0; hmd.GetRecommendedRenderTargetSize(ref w, ref h); sceneWidth = (float)w; sceneHeight = (float)h; float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; hmd.GetProjectionRaw(EVREye.Eye_Left, ref l_left, ref l_right, ref l_top, ref l_bottom); float r_left = 0.0f, r_right = 0.0f, r_top = 0.0f, r_bottom = 0.0f; hmd.GetProjectionRaw(EVREye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom); tanHalfFov = new Vector2( Mathf.Max(-l_left, l_right, -r_left, r_right), Mathf.Max(-l_top, l_bottom, -r_top, r_bottom)); textureBounds = new VRTextureBounds_t[2]; textureBounds[0].uMin = 0.5f + 0.5f * l_left / tanHalfFov.x; textureBounds[0].uMax = 0.5f + 0.5f * l_right / tanHalfFov.x; textureBounds[0].vMin = 0.5f - 0.5f * l_bottom / tanHalfFov.y; textureBounds[0].vMax = 0.5f - 0.5f * l_top / tanHalfFov.y; textureBounds[1].uMin = 0.5f + 0.5f * r_left / tanHalfFov.x; textureBounds[1].uMax = 0.5f + 0.5f * r_right / tanHalfFov.x; textureBounds[1].vMin = 0.5f - 0.5f * r_bottom / tanHalfFov.y; textureBounds[1].vMax = 0.5f - 0.5f * r_top / tanHalfFov.y; Unity.SetSubmitParams(textureBounds[0], textureBounds[1], EVRSubmitFlags.Submit_Default); // Grow the recommended size to account for the overlapping fov sceneWidth = sceneWidth / Mathf.Max(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin); sceneHeight = sceneHeight / Mathf.Max(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin); aspect = tanHalfFov.x / tanHalfFov.y; fieldOfView = 2.0f * Mathf.Atan(tanHalfFov.y) * Mathf.Rad2Deg; eyes = new SteamVR_Utils.RigidTransform[] { new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(EVREye.Eye_Left)), new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(EVREye.Eye_Right)) }; if (SystemInfo.graphicsDeviceVersion.StartsWith("OpenGL")) { graphicsAPI = EGraphicsAPIConvention.API_OpenGL; } else { graphicsAPI = EGraphicsAPIConvention.API_DirectX; } SteamVR_Utils.Event.Listen("initializing", OnInitializing); SteamVR_Utils.Event.Listen("calibrating", OnCalibrating); SteamVR_Utils.Event.Listen("out_of_range", OnOutOfRange); SteamVR_Utils.Event.Listen("device_connected", OnDeviceConnected); SteamVR_Utils.Event.Listen("new_poses", OnNewPoses); }
private SteamVR(System.IntPtr pHmd, System.IntPtr pCompositor, System.IntPtr pOverlay) { hmd = new CVRSystem(pHmd); Debug.Log("Connected to " + hmd_TrackingSystemName + ":" + hmd_SerialNumber); compositor = new CVRCompositor(pCompositor); overlay = new CVROverlay(pOverlay); var device = new UnityGraphicsDevice(); GetUnityGraphicsDevice(ref device); switch (device.type) { case GfxDeviceRenderer.kGfxRendererD3D11: compositor.SetGraphicsDevice(Compositor_DeviceType.D3D11, device.ptr); break; case GfxDeviceRenderer.kGfxRendererOpenGL: compositor.SetGraphicsDevice(Compositor_DeviceType.OpenGL, device.ptr); break; default: throw new System.Exception("Unsupported device type."); } var capacity = compositor.GetLastError(null, 0); if (capacity > 1) { var result = new System.Text.StringBuilder((int)capacity); compositor.GetLastError(result, capacity); Debug.Log("Compositor - " + result); } // Register for a callback if our graphics device goes away, so we can properly clean up. var resetDelegate = new UnityResetDelegate(SteamVR.SafeDispose); callbackHandle = GCHandle.Alloc(resetDelegate); SetUnityResetCallback(Marshal.GetFunctionPointerForDelegate(resetDelegate)); // Hook up the render thread present event just in case we wind up needing to use this. var error = HmdError.None; SetUnityRenderCallback(OpenVR.GetGenericInterface(IVRHmdDistortPresent_Version, ref error)); // Setup render values uint w = 0, h = 0; hmd.GetRecommendedRenderTargetSize(ref w, ref h); sceneWidth = (float)w; sceneHeight = (float)h; float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; hmd.GetProjectionRaw(Hmd_Eye.Eye_Left, ref l_left, ref l_right, ref l_top, ref l_bottom); float r_left = 0.0f, r_right = 0.0f, r_top = 0.0f, r_bottom = 0.0f; hmd.GetProjectionRaw(Hmd_Eye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom); tanHalfFov = new Vector2( Mathf.Max(-l_left, l_right, -r_left, r_right), Mathf.Max(-l_top, l_bottom, -r_top, r_bottom)); textureBounds = new VRTextureBounds_t[2]; textureBounds[0].uMin = 0.5f + 0.5f * l_left / tanHalfFov.x; textureBounds[0].uMax = 0.5f + 0.5f * l_right / tanHalfFov.x; textureBounds[0].vMin = 0.5f - 0.5f * l_bottom / tanHalfFov.y; textureBounds[0].vMax = 0.5f - 0.5f * l_top / tanHalfFov.y; textureBounds[1].uMin = 0.5f + 0.5f * r_left / tanHalfFov.x; textureBounds[1].uMax = 0.5f + 0.5f * r_right / tanHalfFov.x; textureBounds[1].vMin = 0.5f - 0.5f * r_bottom / tanHalfFov.y; textureBounds[1].vMax = 0.5f - 0.5f * r_top / tanHalfFov.y; // Grow the recommended size to account for the overlapping fov sceneWidth = sceneWidth / Mathf.Max(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin); sceneHeight = sceneHeight / Mathf.Max(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin); aspect = tanHalfFov.x / tanHalfFov.y; fieldOfView = 2.0f * Mathf.Atan(tanHalfFov.y) * Mathf.Rad2Deg; eyes = new SteamVR_Utils.RigidTransform[] { new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(Hmd_Eye.Eye_Left)), new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(Hmd_Eye.Eye_Right)) }; SteamVR_Utils.Event.Listen("initializing", OnInitializing); SteamVR_Utils.Event.Listen("calibrating", OnCalibrating); SteamVR_Utils.Event.Listen("out_of_range", OnOutOfRange); SteamVR_Utils.Event.Listen("device_connected", OnDeviceConnected); SteamVR_Utils.Event.Listen("new_poses", OnNewPoses); }