public static void SetupTracking() { OculusTracking._hmd.SetEnabledCaps(OVR.HmdCaps.ovrHmdCap_Writable_Mask); OculusTracking._hmd.ConfigureTracking(OVR.TrackingCaps.ovrTrackingCap_Orientation | OVR.TrackingCaps.ovrTrackingCap_MagYawCorrection | OVR.TrackingCaps.ovrTrackingCap_Position, OVR.TrackingCaps.None); OculusTracking.EyeViewport[] eyeViewportArray = new OculusTracking.EyeViewport[2]; OVR.FovPort[] fovPortArray = new OVR.FovPort[2]; for (int index = 0; index < 2; ++index) { OVR.EyeType eyeType = (OVR.EyeType)index; OculusTracking.EyeViewport eyeViewport = new OculusTracking.EyeViewport(); eyeViewport.FieldOFView = OculusTracking._hmd.DefaultEyeFov[index]; eyeViewport.ViewportSize = OculusTracking._hmd.GetFovTextureSize(eyeType, OculusTracking._hmd.DefaultEyeFov[index], 1f); eyeViewport.RenderDescription = OculusTracking._hmd.GetRenderDesc(eyeType, OculusTracking._hmd.DefaultEyeFov[index]); eyeViewport.HmdToEyeViewOffset = eyeViewport.RenderDescription.HmdToEyeViewOffset; fovPortArray[index] = eyeViewport.FieldOFView; eyeViewportArray[index] = eyeViewport; } OVR.Vector3f[] vector3fArray = new OVR.Vector3f[2] { eyeViewportArray[0].HmdToEyeViewOffset, eyeViewportArray[1].HmdToEyeViewOffset }; double[] numArray1 = new double[2] { Math.Atan((double)fovPortArray[0].LeftTan), Math.Atan((double)fovPortArray[1].LeftTan) }; double[] numArray2 = new double[2] { Math.Atan((double)fovPortArray[0].RightTan), Math.Atan((double)fovPortArray[1].RightTan) }; OculusTracking._startPos = new Point3d(0.0, 0.0, 0.0); OculusTracking._startDir = Transform.Rotation(new Vector3d(0.0, 1.0, 0.0), new Vector3d(0.0, 1.0, 0.0), new Point3d(0.0, 0.0, 0.0)); OculusTracking._hmdToEyeViewOffsets = vector3fArray; OculusTracking._fovL = numArray1; OculusTracking._fovR = numArray2; }
/// <summary> /// Convert an ovrVector3f to Wave Vector3. /// </summary> /// <param name="ovrVector3f">ovrVector3f to convert to a SharpDX Vector3.</param> /// <returns>SharpDX Vector3, based on the ovrVector3f.</returns> public static Vector3 ToVector3(this OVR.Vector3f ovrVector3f) { return(new Vector3(ovrVector3f.X, ovrVector3f.Y, ovrVector3f.Z)); }
/// <summary> /// Convert an ovrVector3f to Wave Vector3. /// </summary> /// <param name="ovrVector3f">ovrVector3f to convert to a SharpDX Vector3.</param> /// <param name="vector3">Wave Vector3, based on the ovrVector3f.</param> public static void ToVector3(this OVR.Vector3f ovrVector3f, out Vector3 vector3) { vector3.X = ovrVector3f.X; vector3.Y = ovrVector3f.Y; vector3.Z = ovrVector3f.Z; }
protected override void OnRenderFrame(FrameEventArgs e) { base.OnRenderFrame(e); startTime += (float)e.Time; // Get eye poses, feeding in correct IPD offset OVR.Vector3f[] ViewOffset = new OVR.Vector3f[] { EyeRenderDesc[0].HmdToEyeViewOffset, EyeRenderDesc[1].HmdToEyeViewOffset }; double ftiming = hmd.GetPredictedDisplayTime(0); // Keeping sensorSampleTime as close to ovr_GetTrackingState as possible - fed into the layer double sensorSampleTime = wrap.GetTimeInSeconds(); OVR.TrackingState hmdState = hmd.GetTrackingState(ftiming); OVR.Posef[] eyePoses = new OVR.Posef[2]; wrap.CalcEyePoses(hmdState.HeadPose.ThePose, ViewOffset, ref eyePoses); Matrix4 worldCube = Matrix4.CreateScale(5) * Matrix4.CreateRotationX(startTime) * Matrix4.CreateRotationY(startTime) * Matrix4.CreateRotationZ(startTime) * Matrix4.CreateTranslation(new Vector3(0, 0, 10)); if (isVisible) { for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++) { layerFov.RenderPose[eyeIndex] = eyePoses[eyeIndex]; // Increment to use next texture, just before writing eyeRenderTexture[eyeIndex].TextureSet.CurrentIndex = (eyeRenderTexture[eyeIndex].TextureSet.CurrentIndex + 1) % eyeRenderTexture[eyeIndex].TextureSet.TextureCount; GL.Viewport(0, 0, eyeRenderTexture[eyeIndex].Width, eyeRenderTexture[eyeIndex].Height); // Set and Clear Rendertarget eyeRenderTexture[eyeIndex].Bind(eyeDepthBuffer[eyeIndex].TexId); GL.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit); // Setup Viewmatrix Quaternion rotationQuaternion = layerFov.RenderPose[eyeIndex].Orientation.ToTK(); Matrix4 rotationMatrix = Matrix4.CreateFromQuaternion(rotationQuaternion); // I M P O R T A N T !!!! Play with this scaleMatrix to tweek HMD's Pitch, Yaw and Roll behavior. It depends on your coordinate system. //Convert to X=right, Y=up, Z=in //S = [1, 1, -1]; //viewMat = viewMat * S * R * S; Matrix4 scaleMatrix = Matrix4.CreateScale(-1f, 1f, -1f); rotationMatrix = scaleMatrix * rotationMatrix * scaleMatrix; Vector3 lookUp = Vector3.Transform(Vector3.UnitY, rotationMatrix); Vector3 lookAt = Vector3.Transform(Vector3.UnitZ, rotationMatrix); Vector3 viewPosition = playerPos + layerFov.RenderPose[eyeIndex].Position.ToTK(); Matrix4 view = Matrix4.LookAt(viewPosition, viewPosition + lookAt, lookUp); Matrix4 proj = OVR.ovrMatrix4f_Projection(hmd.DefaultEyeFov[eyeIndex], 0.1f, 1000.0f, OVR.ProjectionModifier.RightHanded).ToTK(); proj.Transpose(); // OpenTK has Row Major Order and transposes matrices on the way to the shaders, thats why matrix multiplication is reverse order. RenderScene(view * proj, worldCube); // Unbind bound shared textures eyeRenderTexture[eyeIndex].UnBind(); } } // Do distortion rendering, Present and flush/sync OVR.ViewScaleDesc viewScale = new OVR.ViewScaleDesc() { HmdToEyeViewOffset = new OVR.Vector3f[] { ViewOffset[0], ViewOffset[1] }, HmdSpaceToWorldScaleInMeters = 1.0f }; for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++) { // Update layer layerFov.ColorTexture[eyeIndex] = eyeRenderTexture[eyeIndex].TextureSet.SwapTextureSetPtr; layerFov.Viewport[eyeIndex].Position = new OVR.Vector2i(0, 0); layerFov.Viewport[eyeIndex].Size = new OVR.Sizei(eyeRenderTexture[eyeIndex].Width, eyeRenderTexture[eyeIndex].Height); layerFov.Fov[eyeIndex] = hmd.DefaultEyeFov[eyeIndex]; layerFov.RenderPose[eyeIndex] = eyePoses[eyeIndex]; layerFov.SensorSampleTime = sensorSampleTime; } OVR.ovrResult result = hmd.SubmitFrame(0, layers); isVisible = (result == OVR.ovrResult.Success); // Copy mirror data from mirror texture provided by OVR to backbuffer of the desktop window. GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, mirrorFbo); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, 0); int w = mirrorTex.Texture.Header.TextureSize.Width; int h = mirrorTex.Texture.Header.TextureSize.Height; GL.BlitFramebuffer( 0, h, w, 0, 0, 0, w, h, ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Nearest); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, 0); this.SwapBuffers(); }