Example #1
0
        /// <summary>
        /// Updates the HMD.
        /// </summary>
        private void UpdateHMD()
        {
            CVRSystem hmd = Hmd;

            if (renderPoses.Length > 0)
            {
                ETrackingResult result = renderPoses[0].eTrackingResult;
                VRInitializing = result == ETrackingResult.Uninitialized;
                VRCalibrating  = result == ETrackingResult.Calibrating_InProgress || result == ETrackingResult.Calibrating_OutOfRange;
                VROutOfRange   = result == ETrackingResult.Running_OutOfRange || result == ETrackingResult.Calibrating_OutOfRange;

                if (result == ETrackingResult.Running_OK)
                {
                    // Get poses for each eye (left, right, center)

                    renderPoses[0].ToMatrix(out Matrix mCenter);
                    mCenter.ToVRPose(out VRPose center);
                    EyesProperties[2].Pose = center;

                    for (int i = 0; i < 2; i++)
                    {
                        VREye        eye     = EyesProperties[i];
                        VREyeTexture texture = eye.Texture;
                        hmd.GetProjectionMatrix((EVREye)i, texture.NearPlane, texture.FarPlane).ToMatrix(out Matrix projection);
                        projection.Invert();
                        eye.Projection = projection;

                        hmd.GetEyeToHeadTransform((EVREye)i).ToMatrix(out Matrix mOffset);
                        mOffset *= mCenter;
                        mOffset.ToVRPose(out VRPose pose);
                        eye.Pose = pose;
                    }
                }
            }
        }
        public override void Evaluate(int SpreadMax, CVRSystem system)
        {
            FTexSizeOut[0] = OpenVRManager.RecommendedRenderTargetSize;

            if (OpenVRManager.RenderPoses == null)
            {
                return;
            }

            //camera properties
            var projL = system.GetProjectionMatrix(EVREye.Eye_Left, FNearPlane[0], FFarPlane[0]);
            var projR = system.GetProjectionMatrix(EVREye.Eye_Right, FNearPlane[0], FFarPlane[0]);

            FProjectionOut.SliceCount = 2;
            FProjectionOut[0]         = projL.ToProjectionMatrix();
            FProjectionOut[1]         = projR.ToProjectionMatrix();

            var eyeL = system.GetEyeToHeadTransform(EVREye.Eye_Left).ToEyeMatrix();
            var eyeR = system.GetEyeToHeadTransform(EVREye.Eye_Right).ToEyeMatrix();

            FEyeToHeadOut.SliceCount = 2;
            FEyeToHeadOut[0]         = eyeL;
            FEyeToHeadOut[1]         = eyeR;

            //view
            FViewOut.SliceCount = 2;
            FViewOut[0]         = Matrix.Invert(eyeL * OpenVRManager.RenderPoses[0].mDeviceToAbsoluteTracking.ToMatrix());
            FViewOut[1]         = Matrix.Invert(eyeR * OpenVRManager.RenderPoses[0].mDeviceToAbsoluteTracking.ToMatrix());

            //hidden pixels mesh
            var meshLeft  = system.GetHiddenAreaMesh(EVREye.Eye_Left, EHiddenAreaMeshType.k_eHiddenAreaMesh_Standard);
            var meshRight = system.GetHiddenAreaMesh(EVREye.Eye_Right, EHiddenAreaMeshType.k_eHiddenAreaMesh_Standard);

            if (meshLeft.unTriangleCount > 0 && meshRight.unTriangleCount > 0)
            {
                GetMeshData(meshLeft, FVerticesLeftOut);
                GetMeshData(meshRight, FVerticesRightOut);
            }
            else
            {
                FVerticesLeftOut.SliceCount  = 0;
                FVerticesRightOut.SliceCount = 0;
            }

            FHMDPoseOut[0] = OpenVRManager.GamePoses[0].mDeviceToAbsoluteTracking.ToMatrix();
        }
Example #3
0
        private OpenVRScene(float nearClip, float farClip, CVRSystem hmd, int leftIndex, int rightIndex)
        {
            // set up the hmd
            this.hmd = hmd;

            NearClip = nearClip;
            FarClip  = farClip;

            leftEyeProj              = hmd.GetProjectionMatrix(EVREye.Eye_Left, nearClip, farClip, EGraphicsAPIConvention.API_OpenGL).ToGLMatrix4();
            rightEyeProj             = hmd.GetProjectionMatrix(EVREye.Eye_Right, nearClip, farClip, EGraphicsAPIConvention.API_OpenGL).ToGLMatrix4();
            leftEyeView              = hmd.GetEyeToHeadTransform(EVREye.Eye_Left).ToGLMatrix4().Inverted();
            rightEyeView             = hmd.GetEyeToHeadTransform(EVREye.Eye_Right).ToGLMatrix4().Inverted();
            leftHandControllerIndex  = leftIndex;
            rightHandControllerIndex = rightIndex;

            OpenVRInput = new OpenVRInputObservable(hmd);
        }
Example #4
0
        /// <summary>
        /// Gets the eye view point (boolean to specify left or right).
        /// </summary>
        /// <param name="lefteye">Left or right.</param>
        /// <returns>The eye view point matrix.</returns>
        public Matrix4 Eye(bool lefteye)
        {
            HmdMatrix34_t temp = VR.GetEyeToHeadTransform(lefteye ? EVREye.Eye_Left : EVREye.Eye_Right);
            Matrix4       eye  = new Matrix4(temp.m0, temp.m1, temp.m2, temp.m3, temp.m4, temp.m5, temp.m6, temp.m7, temp.m8, temp.m9, temp.m10, temp.m11, 0, 0, 0, 1);

            eye.Transpose();
            eye = eye.ClearTranslation() * Matrix4.CreateTranslation(eye.ExtractTranslation() * VRScale);
            return(headMat * eye);
        }
Example #5
0
        public override void Evaluate(int SpreadMax, CVRSystem system)
        {
            if (IsInit || FInit[0])
            {
                FTexSizeOut[0] = OpenVRManager.RecommendedRenderTargetSize;

                var projL = system.GetProjectionMatrix(EVREye.Eye_Left, 0.05f, 100, EGraphicsAPIConvention.API_DirectX);
                var projR = system.GetProjectionMatrix(EVREye.Eye_Right, 0.05f, 100, EGraphicsAPIConvention.API_DirectX);
                FProjectionOut.SliceCount = 2;
                FProjectionOut[0]         = projL.ToProjectionMatrix();
                FProjectionOut[1]         = projR.ToProjectionMatrix();

                EyeL = system.GetEyeToHeadTransform(EVREye.Eye_Left).ToEyeMatrix();
                EyeR = system.GetEyeToHeadTransform(EVREye.Eye_Right).ToEyeMatrix();
                FEyeToHeadOut.SliceCount = 2;
                FEyeToHeadOut[0]         = EyeL;
                FEyeToHeadOut[1]         = EyeR;
                IsInit = false;

                var meshLeft  = system.GetHiddenAreaMesh(EVREye.Eye_Left);
                var meshRight = system.GetHiddenAreaMesh(EVREye.Eye_Right);

                //hidden pixels mesh
                if (meshLeft.unTriangleCount > 0 && meshRight.unTriangleCount > 0)
                {
                    GetMeshData(meshLeft, FVerticesLeftOut);
                    GetMeshData(meshRight, FVerticesRightOut);
                }
                else
                {
                    FVerticesLeftOut.SliceCount  = 0;
                    FVerticesRightOut.SliceCount = 0;
                }
            }

            //view
            FViewOut.SliceCount = 2;
            FViewOut[0]         = Matrix.Invert(EyeL * OpenVRManager.RenderPoses[0].mDeviceToAbsoluteTracking.ToMatrix());
            FViewOut[1]         = Matrix.Invert(EyeR * OpenVRManager.RenderPoses[0].mDeviceToAbsoluteTracking.ToMatrix());
            FHMDPoseOut[0]      = OpenVRManager.GamePoses[0].mDeviceToAbsoluteTracking.ToMatrix();
        }
Example #6
0
        public override void Initialize(GraphicsDevice gd)
        {
            _gd = gd;

            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);

            _leftEyeFB  = CreateFramebuffer(eyeWidth, eyeHeight);
            _rightEyeFB = CreateFramebuffer(eyeWidth, eyeHeight);

            Matrix4x4 eyeToHeadLeft = ToSysMatrix(_vrSystem.GetEyeToHeadTransform(EVREye.Eye_Left));

            Matrix4x4.Invert(eyeToHeadLeft, out _headToEyeLeft);

            Matrix4x4 eyeToHeadRight = ToSysMatrix(_vrSystem.GetEyeToHeadTransform(EVREye.Eye_Right));

            Matrix4x4.Invert(eyeToHeadRight, out _headToEyeRight);

            _projLeft  = ToSysMatrix(_vrSystem.GetProjectionMatrix(EVREye.Eye_Left, 0.1f, 1000f));
            _projRight = ToSysMatrix(_vrSystem.GetProjectionMatrix(EVREye.Eye_Right, 0.1f, 1000f));
        }
Example #7
0
        internal static void Enable()
        {
            var initError = EVRInitError.None;

            System = OpenVR.Init(ref initError);

            if (initError != EVRInitError.None)
            {
                return;
            }

            Compositor = OpenVR.Compositor;

            Compositor.CompositorBringToFront();
            Compositor.FadeGrid(5.0f, false);

            var count = OpenVR.k_unMaxTrackedDeviceCount;

            CurrentPoses = new TrackedDevicePose_t[count];
            NextPoses    = new TrackedDevicePose_t[count];

            Controllers                    = new List <uint>();
            ControllerModels               = new RenderModel_t[count];
            ControllerTextures             = new RenderModel_TextureMap_t[count];
            ControllerTextureViews         = new ShaderResourceView[count];
            ControllerVertexBuffers        = new SharpDX.Direct3D11.Buffer[count];
            ControllerIndexBuffers         = new SharpDX.Direct3D11.Buffer[count];
            ControllerVertexBufferBindings = new VertexBufferBinding[count];
            ControllerEmitters             = new Emitter[count];
            ControllerVoices               = new SourceVoice[count];

            for (uint device = 0; device < count; device++)
            {
                var deviceClass = System.GetTrackedDeviceClass(device);

                switch (deviceClass)
                {
                case ETrackedDeviceClass.HMD:
                    Headset = device;
                    break;

                case ETrackedDeviceClass.Controller:
                    Controllers.Add(device);
                    break;
                }
            }

            uint width  = 0;
            uint height = 0;

            System.GetRecommendedRenderTargetSize(ref width, ref height);

            headsetSize = new Size((int)width, (int)height);
            windowSize  = new Size(960, 540);

            var leftEyeProjection  = Convert(System.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f));
            var rightEyeProjection = Convert(System.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f));

            var leftEyeView  = Convert(System.GetEyeToHeadTransform(EVREye.Eye_Left));
            var rightEyeView = Convert(System.GetEyeToHeadTransform(EVREye.Eye_Right));

            foreach (var controller in Controllers)
            {
                var modelName     = new StringBuilder(255, 255);
                var propertyError = ETrackedPropertyError.TrackedProp_Success;

                var length = System.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError);

                if (propertyError == ETrackedPropertyError.TrackedProp_Success)
                {
                    var modelName2 = modelName.ToString();

                    while (true)
                    {
                        var pointer    = IntPtr.Zero;
                        var modelError = EVRRenderModelError.None;

                        modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer);

                        if (modelError == EVRRenderModelError.Loading)
                        {
                            continue;
                        }

                        if (modelError == EVRRenderModelError.None)
                        {
                            var renderModel = global::System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer);

                            ControllerModels[controller] = renderModel;
                            break;
                        }
                    }

                    while (true)
                    {
                        var pointer      = IntPtr.Zero;
                        var textureError = EVRRenderModelError.None;

                        textureError = OpenVR.RenderModels.LoadTexture_Async(ControllerModels[controller].diffuseTextureId, ref pointer);

                        if (textureError == EVRRenderModelError.Loading)
                        {
                            continue;
                        }

                        if (textureError == EVRRenderModelError.None)
                        {
                            var texture = global::System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer);

                            ControllerTextures[controller] = texture;
                            break;
                        }
                    }
                }
            }

            int adapterIndex = 0;

            System.GetDXGIOutputInfo(ref adapterIndex);

            Thread = new Thread(Run);
            Thread.Start();
        }
Example #8
0
        void Update()
        {
            //increase prediction
            if (Input.GetKeyDown(KeyCode.KeypadPlus))
            {
                predict += 0.01f;
                log("predict interval set to: " + predict);
            }

            //decrease prediction
            if (Input.GetKeyDown(KeyCode.KeypadMinus))
            {
                predict -= 0.01f;
                log("predict interval set to: " + predict);
            }

            //If Hmd is initialised and key is pressed -> reset position
            if (Input.GetKeyDown(KeyCode.Keypad0) && HmdOn)
            {
                vrSystem.ResetSeatedZeroPose();
                log("Seated pose reset!");
            }

            //If Hmd is not initialised and key is pressed -> initialise everything
            if (Input.GetKeyDown(KeyCode.Keypad0) && !HmdOn)
            {
                //get Active Vessel
                activeVessel = FlightGlobals.ActiveVessel;

                HmdOn = true;

                //setup OpenVR
                setup();

                uint renderTextureWidth  = 0;
                uint renderTextureHeight = 0;
                vrSystem.GetRecommendedRenderTargetSize(ref renderTextureWidth, ref renderTextureHeight);

                HmdMatrix34_t vrLeftEyeTransform  = vrSystem.GetEyeToHeadTransform(EVREye.Eye_Left);
                HmdMatrix34_t vrRightEyeTransform = vrSystem.GetEyeToHeadTransform(EVREye.Eye_Right);

                //eyeDiference = (int)(Camera.main.WorldToScreenPoint(new Utils.RigidTransform(vrLeftEyeTransform).pos) - Camera.main.WorldToScreenPoint(new Utils.RigidTransform(vrRightEyeTransform).pos)).magnitude;

                // skyTexture = new RenderTexture((int)(renderTextureWidth + eyeDiference), (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32);
                // skyTexture.Create();

                hmdLeftEyeRenderTexture = new RenderTexture((int)renderTextureWidth, (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32);
                hmdLeftEyeRenderTexture.Create();

                hmdRightEyeRenderTexture = new RenderTexture((int)renderTextureWidth, (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32);
                hmdRightEyeRenderTexture.Create();

                setupCameras();

                //add on vesselchange callback
                GameEvents.onVesselChange.Add(onVesselChange);
            }
            if (HmdOn)
            {
                if (!CameraManager.Instance.currentCameraMode.Equals(activeCameraMode))
                {
                    if (CameraManager.Instance.currentCameraMode.Equals(CameraManager.CameraMode.Flight) || CameraManager.Instance.currentCameraMode.Equals(CameraManager.CameraMode.External))
                    {
                        //   Camera.main.enabled = true;
                        setRenderTexturesTo(null, null);

                        O_SclaledSpace.enabled = true;
                        O_Galaxy.enabled       = true;
                        O_Near.enabled         = true;
                        O_Far.enabled          = true;
                        //O_Interior.enabled = false;
                    }
                    else
                    {
                        setRenderTexturesTo(null, null);
                        O_SclaledSpace.enabled = false;
                        O_Galaxy.enabled       = false;
                        O_Near.enabled         = false;
                        O_Far.enabled          = false;
                        O_Interior.enabled     = false;
                    }
                }



                if (CameraManager.Instance.currentCameraMode.Equals(CameraManager.CameraMode.IVA))
                {
                    leftStars.Render();
                    leftSky.Render();
                    camLeft_Far.Render();
                    camLeft_Near.Render();
                    camLeft_Interior.Render();

                    rightStars.Render();
                    rightSky.Render();
                    camRight_Far.Render();
                    camRight_Near.Render();
                    camRight_Interior.Render();
                }
                //if someone knows how to fix the other cameras corectly please tell me!
                else if (CameraManager.Instance.currentCameraMode.Equals(CameraManager.CameraMode.Map))
                {
                    O_Galaxy.Render();
                    O_SclaledSpace.Render();
                }
                else
                {
                    O_Galaxy.Render();
                    O_SclaledSpace.Render();
                    O_Far.Render();
                    O_Near.Render();
                }
            }
        }
Example #9
0
        /// <summary>
        /// Overrides the Update method, called every frame.
        /// </summary>
        void LateUpdate()
        {
            try
            {
                // do nothing unless we are in IVA
                hmdIsAllowed = (CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.IVA);

                // start HMD using the Y key
                if (Input.GetKeyDown(KeyCode.Y) && hmdIsAllowed)
                {
                    if (!hmdIsInitialized)
                    {
                        log("Initializing HMD...");
                        try
                        {
                            bool retVal = InitHMD();
                            if (retVal)
                            {
                                log("HMD initialized.");
                            }
                        }
                        catch (Exception e)
                        {
                            err(e.Message);
                        }
                    }
                    else
                    {
                        ResetInitialHmdPosition();
                    }
                }

                // perform regular updates if HMD is initialized
                if (hmdIsAllowed && hmdIsInitialized)
                {
                    EVRCompositorError vrCompositorError = EVRCompositorError.None;

                    // get latest HMD pose
                    //--------------------------------------------------------------
                    vrSystem.GetDeviceToAbsoluteTrackingPose(ETrackingUniverseOrigin.TrackingUniverseSeated, 0.0f, vrDevicePoses);
                    HmdMatrix34_t vrLeftEyeTransform  = vrSystem.GetEyeToHeadTransform(EVREye.Eye_Left);
                    HmdMatrix34_t vrRightEyeTransform = vrSystem.GetEyeToHeadTransform(EVREye.Eye_Right);
                    vrCompositorError = vrCompositor.WaitGetPoses(vrRenderPoses, vrGamePoses);

                    if (vrCompositorError != EVRCompositorError.None)
                    {
                        warn("WaitGetPoses failed: " + (int)vrCompositorError);
                        return;
                    }

                    // convert SteamVR poses to Unity coordinates
                    var hmdTransform         = new SteamVR_Utils.RigidTransform(vrDevicePoses[OpenVR.k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking);
                    var hmdLeftEyeTransform  = new SteamVR_Utils.RigidTransform(vrLeftEyeTransform);
                    var hmdRightEyeTransform = new SteamVR_Utils.RigidTransform(vrRightEyeTransform);
                    var ctrlPoseLeft         = new SteamVR_Utils.RigidTransform(vrDevicePoses[ctrlIndexLeft].mDeviceToAbsoluteTracking);
                    var ctrlPoseRight        = new SteamVR_Utils.RigidTransform(vrDevicePoses[ctrlIndexRight].mDeviceToAbsoluteTracking);



                    // Render the LEFT eye
                    //--------------------------------------------------------------
                    // rotate camera according to the HMD orientation
                    InternalCamera.Instance.transform.localRotation = hmdTransform.rot;

                    // translate the camera to match the position of the left eye, from origin
                    InternalCamera.Instance.transform.localPosition = new Vector3(0f, 0f, 0f);
                    InternalCamera.Instance.transform.Translate(hmdLeftEyeTransform.pos);

                    // translate the camera to match the position of the HMD
                    InternalCamera.Instance.transform.localPosition += hmdTransform.pos;

                    // move the FlightCamera to match the position of the InternalCamera (so the outside world moves accordingly)
                    FlightCamera.fetch.transform.position = InternalSpace.InternalToWorld(InternalCamera.Instance.transform.position);
                    FlightCamera.fetch.transform.rotation = InternalSpace.InternalToWorld(InternalCamera.Instance.transform.rotation);

                    // render the set of cameras
                    foreach (CameraProperties camStruct in camerasToRender)
                    {
                        // set projection matrix
                        camStruct.camera.projectionMatrix = camStruct.hmdLeftProjMatrix;

                        // set texture to render to
                        camStruct.camera.targetTexture = hmdLeftEyeRenderTexture;

                        // render camera
                        camStruct.camera.Render();
                    }


                    // Render the RIGHT eye (see previous comments)
                    //--------------------------------------------------------------
                    InternalCamera.Instance.transform.localRotation = hmdTransform.rot;
                    InternalCamera.Instance.transform.localPosition = new Vector3(0f, 0f, 0f);
                    InternalCamera.Instance.transform.Translate(hmdRightEyeTransform.pos);
                    InternalCamera.Instance.transform.localPosition += hmdTransform.pos;
                    FlightCamera.fetch.transform.position            = InternalSpace.InternalToWorld(InternalCamera.Instance.transform.position);
                    FlightCamera.fetch.transform.rotation            = InternalSpace.InternalToWorld(InternalCamera.Instance.transform.rotation);

                    foreach (CameraProperties camStruct in camerasToRender)
                    {
                        camStruct.camera.projectionMatrix = camStruct.hmdRightProjMatrix;
                        camStruct.camera.targetTexture    = hmdRightEyeRenderTexture;
                        camStruct.camera.Render();
                    }

                    try
                    {
                        // Set camera position to an HMD-centered position (for regular screen rendering)
                        //--------------------------------------------------------------
                        if (renderToScreen)
                        {
                            foreach (CameraProperties camStruct in camerasToRender)
                            {
                                camStruct.camera.targetTexture    = null;
                                camStruct.camera.projectionMatrix = camStruct.originalProjMatrix;
                            }
                            InternalCamera.Instance.transform.localRotation = hmdTransform.rot;
                            InternalCamera.Instance.transform.localPosition = hmdTransform.pos;
                            FlightCamera.fetch.transform.position           = InternalSpace.InternalToWorld(InternalCamera.Instance.transform.position);
                            FlightCamera.fetch.transform.rotation           = InternalSpace.InternalToWorld(InternalCamera.Instance.transform.rotation);
                        }


                        // Submit frames to HMD
                        //--------------------------------------------------------------
                        vrCompositorError = vrCompositor.Submit(EVREye.Eye_Left, ref hmdLeftEyeTexture, ref hmdTextureBounds, EVRSubmitFlags.Submit_Default);
                        if (vrCompositorError != EVRCompositorError.None)
                        {
                            warn("Submit (Eye_Left) failed: " + (int)vrCompositorError);
                        }

                        vrCompositorError = vrCompositor.Submit(EVREye.Eye_Right, ref hmdRightEyeTexture, ref hmdTextureBounds, EVRSubmitFlags.Submit_Default);
                        if (vrCompositorError != EVRCompositorError.None)
                        {
                            warn("Submit (Eye_Right) failed: " + (int)vrCompositorError);
                        }

                        vrCompositor.PostPresentHandoff();

                        //  GL.Flush();
                    } catch (Exception e)
                    {
                        err("Exception! " + e.ToString());
                    }

                    // disable highlighting of parts due to mouse
                    // TODO: there needs to be a better way to do this. this affects the Part permanently
                    Part hoveredPart = Mouse.HoveredPart;
                    if (hoveredPart != null)
                    {
                        hoveredPart.HighlightActive  = false;
                        hoveredPart.highlightColor.a = 0f;// = new Color(0f, 0f, 0f, 0f);
                        //Debug.Log("[KerbalVR] hovered part: " + hoveredPart.name);
                    }


                    // DEBUG
                    if (Input.GetKeyDown(KeyCode.O))
                    {
                        log("POSITION hmdTransform : " + hmdTransform.pos.x + ", " + hmdTransform.pos.y + ", " + hmdTransform.pos.z);
                        log("POSITION hmdLTransform : " + hmdLeftEyeTransform.pos.x + ", " + hmdLeftEyeTransform.pos.y + ", " + hmdLeftEyeTransform.pos.z);
                        log("POSITION hmdRTransform : " + hmdRightEyeTransform.pos.x + ", " + hmdRightEyeTransform.pos.y + ", " + hmdRightEyeTransform.pos.z);
                        log("POSITION ctrlPoseRight : " + ctrlPoseRight.pos.x + ", " + ctrlPoseRight.pos.y + ", " + ctrlPoseRight.pos.z);

                        log("POSITION InternalCamera.Instance.transform.abs : " + InternalCamera.Instance.transform.position.x + ", " + InternalCamera.Instance.transform.position.y + ", " + InternalCamera.Instance.transform.position.z);
                        log("POSITION InternalCamera.Instance.transform.rel : " + InternalCamera.Instance.transform.localPosition.x + ", " + InternalCamera.Instance.transform.localPosition.y + ", " + InternalCamera.Instance.transform.localPosition.z);

                        foreach (Camera c in Camera.allCameras)
                        {
                            log("Camera: " + c.name + ", cullingMask = " + c.cullingMask);
                        }
                    }
                }

                // if we are exiting VR, restore the cameras
                if (!hmdIsAllowed && hmdIsAllowed_prev)
                {
                    foreach (CameraProperties camStruct in camerasToRender)
                    {
                        camStruct.camera.projectionMatrix = camStruct.originalProjMatrix;
                        camStruct.camera.targetTexture    = null;
                    }
                }

                hmdIsAllowed_prev = hmdIsAllowed;
            }
            catch (Exception e)
            {
                err(e.ToString());
            }
        }
Example #10
0
        /*void LateUpdate()
         * {
         *  if (HmdOn)
         *  {
         *      foreach (int id in leftCameras)
         *      {
         *
         *          //Left camera position:##########################################################
         *          Camera.allCameras[id].transform.localRotation = hmdTransform.rot;
         *
         *          // translate the camera to match the position of the left eye, from origin
         *          Camera.allCameras[id].transform.localPosition = new Vector3(0f, 0f, 0f);
         *          Camera.allCameras[id].transform.Translate(hmdLeftEyeTransform.pos);
         *
         *          // translate the camera to match the position of the HMD
         *          Camera.allCameras[id].transform.localPosition += hmdTransform.pos;
         *
         *      }
         *  }
         * }*/



        void Update()
        {
            if (Input.GetKeyDown(KeyCode.KeypadPlus))
            {
                predict += 0.01f;
                log("predict interval set to: " + predict);
            }
            if (Input.GetKeyDown(KeyCode.KeypadMinus))
            {
                predict -= 0.01f;
                log("predict interval set to: " + predict);
            }

            /*     if (Input.GetKeyDown(KeyCode.Keypad5))
             *   {
             *       log("cameras:");
             *       foreach (Camera c in Camera.allCameras)
             *       {
             *           log("    " + c.name);
             *       }
             *   }*/

            if (Input.GetKeyDown(KeyCode.Keypad0) && HmdOn)
            {
                vrSystem.ResetSeatedZeroPose();
                log("Seated pose reset!");
            }

            if (Input.GetKeyDown(KeyCode.KeypadMultiply))
            {
                camLeft_Near.cullingMask  = camLeft_Near.cullingMask << 1;
                camRight_Near.cullingMask = camLeft_Near.cullingMask;
                log(Convert.ToString(camLeft_Near.cullingMask, 2));
                if (camLeft_Near.cullingMask == 0)
                {
                    camLeft_Near.cullingMask  = 1;
                    camRight_Near.cullingMask = 1;
                }
            }


            if (Input.GetKeyDown(KeyCode.KeypadDivide))
            {
                camLeft_Near.cullingMask  = camLeft_Near.cullingMask >> 1;
                camRight_Near.cullingMask = camLeft_Near.cullingMask;
                log(Convert.ToString(camLeft_Near.cullingMask, 2));
                if (camLeft_Near.cullingMask == 0)
                {
                    camLeft_Near.cullingMask  = 1;
                    camRight_Near.cullingMask = 1;
                }
            }
            if (Input.GetKeyDown(KeyCode.Keypad2))
            {
                log("          ScaledSpace rot = " + ScaledSpace.Instance.transform.rotation.eulerAngles.ToString());
                log("    GalaxyCubeControl rot = " + GalaxyCubeControl.Instance.transform.rotation.eulerAngles.ToString());
                log("GalaxyCubeControl tgt rot = " + GalaxyCubeControl.Instance.tgt.transform.rotation.eulerAngles.ToString());
                log("  GalaxyCameraControl rot = " + GalaxyCameraControl.Instance.transform.rotation.eulerAngles.ToString());
                log("         ScaledCamera rot = " + ScaledCamera.Instance.transform.rotation.eulerAngles.ToString());
            }

            if (HmdOn)
            {
                if (Input.GetKeyDown(KeyCode.Keypad1))
                {
                    log("L:" + Convert.ToString(camLeft_Near.cullingMask, 2));
                    log("R:" + Convert.ToString(camRight_Near.cullingMask, 2));
                }


                int tmp = 0;
                if (Input.GetKey(KeyCode.LeftShift))
                {
                    tmp = 10;
                }
                else if (Input.GetKey(KeyCode.RightShift))
                {
                    tmp = 20;
                }
                else if (Input.GetKey(KeyCode.RightControl))
                {
                    tmp = 30;
                }

                if (Input.GetKeyDown(KeyCode.Alpha0))
                {
                    camLeft_Near.cullingMask ^= (1 << 0 + tmp);
                }
                if (Input.GetKeyDown(KeyCode.Alpha1))
                {
                    camLeft_Near.cullingMask ^= (1 << 1 + tmp);
                }
                if (Input.GetKeyDown(KeyCode.Alpha2))
                {
                    camLeft_Near.cullingMask ^= (1 << 2 + tmp);
                }
                if (Input.GetKeyDown(KeyCode.Alpha3))
                {
                    camLeft_Near.cullingMask ^= (1 << 3 + tmp);
                }
                if (Input.GetKeyDown(KeyCode.Alpha4))
                {
                    camLeft_Near.cullingMask ^= (1 << 4 + tmp);
                }
                if (Input.GetKeyDown(KeyCode.Alpha5))
                {
                    camLeft_Near.cullingMask ^= (1 << 5 + tmp);
                }
                if (Input.GetKeyDown(KeyCode.Alpha6))
                {
                    camLeft_Near.cullingMask ^= (1 << 6 + tmp);
                }
                if (Input.GetKeyDown(KeyCode.Alpha7))
                {
                    camLeft_Near.cullingMask ^= (1 << 7 + tmp);
                }
                if (Input.GetKeyDown(KeyCode.Alpha8))
                {
                    camLeft_Near.cullingMask ^= (1 << 8 + tmp);
                }
                if (Input.GetKeyDown(KeyCode.Alpha9))
                {
                    camLeft_Near.cullingMask ^= (1 << 9 + tmp);
                }
                camRight_Near.cullingMask = camLeft_Near.cullingMask;

                if (Input.GetKeyDown(KeyCode.Keypad7))
                {
                    if (camRight_Near.transparencySortMode == TransparencySortMode.Default)
                    {
                        camRight_Near.transparencySortMode = TransparencySortMode.Orthographic;
                        camLeft_Near.transparencySortMode  = TransparencySortMode.Orthographic;
                    }
                    if (camRight_Near.transparencySortMode == TransparencySortMode.Orthographic)
                    {
                        camRight_Near.transparencySortMode = TransparencySortMode.Perspective;
                        camLeft_Near.transparencySortMode  = TransparencySortMode.Perspective;
                    }
                    if (camRight_Near.transparencySortMode == TransparencySortMode.Perspective)
                    {
                        camRight_Near.transparencySortMode = TransparencySortMode.Default;
                        camLeft_Near.transparencySortMode  = TransparencySortMode.Default;
                    }
                }
                if (Input.GetKeyDown(KeyCode.Keypad8))
                {
                    if (camRight_Near.opaqueSortMode == UnityEngine.Rendering.OpaqueSortMode.Default)
                    {
                        camRight_Near.opaqueSortMode = UnityEngine.Rendering.OpaqueSortMode.FrontToBack;
                        camLeft_Near.opaqueSortMode  = UnityEngine.Rendering.OpaqueSortMode.FrontToBack;
                    }
                    if (camRight_Near.opaqueSortMode == UnityEngine.Rendering.OpaqueSortMode.FrontToBack)
                    {
                        camRight_Near.opaqueSortMode = UnityEngine.Rendering.OpaqueSortMode.NoDistanceSort;
                        camLeft_Near.opaqueSortMode  = UnityEngine.Rendering.OpaqueSortMode.NoDistanceSort;
                    }
                    if (camRight_Near.opaqueSortMode == UnityEngine.Rendering.OpaqueSortMode.NoDistanceSort)
                    {
                        camRight_Near.opaqueSortMode = UnityEngine.Rendering.OpaqueSortMode.Default;
                        camLeft_Near.opaqueSortMode  = UnityEngine.Rendering.OpaqueSortMode.Default;
                    }
                }
            }
            if (Input.GetKeyDown(KeyCode.Keypad0) && !HmdOn)
            {
                activeVessel = FlightGlobals.ActiveVessel;

                var goArray = FindObjectsOfType <GameObject>();

                /*GameObject tmp = new GameObject();
                 * tmp.transform.position = activeVessel.transform.position;
                 * tmp.transform.SetParent(activeVessel.transform);
                 * for (var i = 0; i < goArray.Length; i++)
                 * {
                 *  if (goArray[i].layer == 16 | goArray[i].layer == 20)
                 *  {
                 *      log(goArray[i].name);
                 *      //Vector3 tmp = goArray[i].transform.position;
                 *
                 *
                 *      goArray[i].transform.SetParent(tmp.transform);
                 *      interiorModelList.Add(goArray[i]);
                 *  }
                 * }
                 * tmp.transform.rotation = activeVessel.transform.rotation;
                 */
                HmdOn = true;
                log("TEST!!!!!!!!!!!!!!!!!!");
                log(ScaledSpace.Instance.transform.rotation.eulerAngles.ToString());
                //setup OpenVR
                setup();


                int    mask = 0;
                Camera pit  = Camera.main;


                uint renderTextureWidth  = 0;
                uint renderTextureHeight = 0;
                vrSystem.GetRecommendedRenderTargetSize(ref renderTextureWidth, ref renderTextureHeight);

                HmdMatrix34_t vrLeftEyeTransform  = vrSystem.GetEyeToHeadTransform(EVREye.Eye_Left);
                HmdMatrix34_t vrRightEyeTransform = vrSystem.GetEyeToHeadTransform(EVREye.Eye_Right);



                int widthDiference = (int)(Camera.main.WorldToScreenPoint(new Utils.RigidTransform(vrLeftEyeTransform).pos) - Camera.main.WorldToScreenPoint(new Utils.RigidTransform(vrRightEyeTransform).pos)).magnitude;
                widthDiference = 100; //TODO calculate corectly
                skyTexture     = new RenderTexture((int)(renderTextureWidth + widthDiference), (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32);
                skyTexture.Create();

                hmdLeftEyeRenderTexture = new RenderTexture((int)renderTextureWidth, (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32);
                hmdLeftEyeRenderTexture.Create();

                hmdRightEyeRenderTexture = new RenderTexture((int)renderTextureWidth, (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32);
                hmdRightEyeRenderTexture.Create();

                float max = 0;

                float[] distances = new float[32];

                foreach (string cameraName in cameraNamesToRender)
                {
                    foreach (Camera camera in Camera.allCameras)
                    {
                        if (cameraName.Equals(camera.name))
                        {
                            switch (camera.name)
                            {
                            case "GalaxyCamera":
                                O_Galaxy = camera;
                                break;

                            case "Camera ScaledSpace":
                                O_SclaledSpace = camera;
                                break;

                            case "Camera 01":
                                O_Far = camera;
                                break;

                            case "Camera 00":
                                O_Near = camera;
                                break;

                            default:
                                break;
                            }


                            mask |= camera.cullingMask;

                            max = Math.Max(camera.farClipPlane, max);
                            string bitMask = Convert.ToString(camera.cullingMask, 2);
                            for (int i = 0; i < distances.Length; i++)
                            {
                                distances[i] = Math.Max(distances[i], Math.Max(camera.layerCullDistances[i], camera.farClipPlane));
                            }

                            camera.gameObject.AddOrGetComponent <posTracker>();

                            log("Camera:");
                            log("  Name:  " + camera.name);
                            log("  mask:  " + Convert.ToString(camera.cullingMask, 2));
                            log("  depth: " + camera.depth);
                            log("");

                            if (cameraName.Equals("InternalCamera"))
                            {
                                pit          = camera;
                                camLeft_Near = camera;
                                //camRight = camera;
                                leftCameras.Add(camera);
                                O_Interior = camera;
                            }
                            if (cameraName.Equals("GalaxyCamera"))
                            {
                                O_Galaxy = camera;
                            }

                            if (cameraName.Equals("Camera ScaledSpace"))
                            {
                                //  sky = camera;
                                O_SclaledSpace = camera;
                                log("sky cam rot = " + camera.transform.rotation.eulerAngles.ToString());
                            }
                        }
                    }
                }

                //   camRight_Interior = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation);
                //   camLeft_Interior = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation);

                camRight_Near = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation);
                camLeft_Near  = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation);

                camRight_Far = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation);
                camLeft_Far  = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation);

                leftSky  = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation);
                rightSky = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation);

                leftStars  = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation);
                rightStars = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation);

                leftSky.CopyFrom(O_SclaledSpace);
                rightSky.CopyFrom(O_SclaledSpace);

                leftSky.transform.SetParent(activeVessel.transform);
                rightSky.transform.SetParent(activeVessel.transform);

                leftStars.CopyFrom(O_Galaxy);
                rightStars.CopyFrom(O_Galaxy);

                leftStars.transform.SetParent(activeVessel.transform);
                rightStars.transform.SetParent(activeVessel.transform);

                camRight_Near.CopyFrom(O_Near);
                camLeft_Near.CopyFrom(O_Near);

                camRight_Near.transform.SetParent(activeVessel.transform);
                camLeft_Near.transform.SetParent(activeVessel.transform);

                //     camLeft_Interior.CopyFrom(O_Interior);
                //     camRight_Interior.CopyFrom(O_Interior);

                //    camLeft_Interior.transform.SetParent(activeVessel.transform);
                //    camRight_Interior.transform.SetParent(activeVessel.transform);

                camRight_Far.CopyFrom(O_Far);
                camLeft_Far.CopyFrom(O_Far);

                camRight_Far.transform.SetParent(activeVessel.transform);
                camLeft_Far.transform.SetParent(activeVessel.transform);
                // stars.clearFlags = CameraClearFlags.Depth;
                // stars.cullingMask = (1 << 18);
                //sky.cullingMask = (1 << 9);
                leftStars.targetTexture  = hmdLeftEyeRenderTexture;
                rightStars.targetTexture = hmdRightEyeRenderTexture;
                //
                leftSky.targetTexture  = hmdLeftEyeRenderTexture;
                rightSky.targetTexture = hmdRightEyeRenderTexture;

                //skyCopySlave = rightSky.gameObject.AddComponent<copySlave>();
                // skyCopySlave.leftTarget = hmdLeftEyeRenderTexture;
                // skyCopySlave.rightTarget = hmdRightEyeRenderTexture;
                //skyCopySlave.difrence = widthDiference;

                camLeft_Near.targetTexture  = hmdLeftEyeRenderTexture;
                camRight_Near.targetTexture = hmdRightEyeRenderTexture;

                //   camLeft_Interior.targetTexture = hmdLeftEyeRenderTexture;
                //   camRight_Interior.targetTexture = hmdRightEyeRenderTexture;


                camLeft_Far.targetTexture  = hmdLeftEyeRenderTexture;
                camRight_Far.targetTexture = hmdRightEyeRenderTexture;

                leftStars.depth    += 4;
                leftSky.depth      += 4;
                camLeft_Near.depth += 4;
                camLeft_Far.depth  += 4;
                // camLeft_Interior.depth += 4;
                // camRight_Interior.depth += 4;
                //rightSky.depth = -5;
                //  camRight.targetTexture = sky.targetTexture;
                //  camLeft.targetTexture = sky.targetTexture;

                //   camera.targetTexture = hmdLeftEyeRenderTexture;
                //     camRight.cullingMask = (1 << 0) | (1 << 4) | (1 << 10) | (1 << 15) | (1 << 16) | (1 << 20) | (1 << 23);
                //    camLeft.cullingMask = (1 << 0) | (1 << 4) | (1 << 10) | (1 << 15) | (1 << 16) | (1 << 20) | (1 << 23);

                // 0: ship exterior
                //15: ground
                //16: ship interior

                //TODO change to |=
                //camRight_Near.cullingMask = 1 << 20 | (1 << 16);
                //camLeft_Near.cullingMask = 1 << 20 | (1 << 16);



                //  camLeft.clearFlags = CameraClearFlags.Depth;
                //  camRight.clearFlags = CameraClearFlags.Depth;

                // camLeft_Near.layerCullDistances = distances;
                // camRight_Near.layerCullDistances = distances;


                //  camLeft.depthTextureMode = DepthTextureMode.Depth;
                //  camRight.depthTextureMode = DepthTextureMode.Depth;
                //camRight.transparencySortMode = TransparencySortMode.Perspective;
                //create left slave
                leftSlave = camLeft_Near.gameObject.AddOrGetComponent <RenderSlave>();
                //leftSlave = sky.gameObject.AddOrGetComponent<RenderSlave>();
                leftSlave.left = true;
                // camLeft.cullingMask = (1 << 0) | (1 << 4) | (1 << 9) | (1 << 10) | (1 << 15) | (1 << 16) | (1 << 18) | (1 << 20) | (1 << 23);
                //camLeft.cullingMask = (1 << 9) | (1 << 15) | (1 << 16) | (1 << 20) | (1 << 32);
                //camLeft.cullingMask = 0;
                //  camLeft.ResetCullingMatrix();
                //camLeft_Near.useOcclusionCulling = true;
                //camLeft_Near.nearClipPlane = 0.01f;
                //camLeft_Near.farClipPlane = max;

                //create right slave
                rightSlave      = camRight_Near.gameObject.AddOrGetComponent <RenderSlave>();
                rightSlave.left = false;
                // camRight.cullingMask = (1 << 0) | (1 << 4) | (1 << 9) | (1 << 10) | (1 << 15) | (1 << 16) | (1 << 18) | (1 << 20) | (1 << 23);
                //   camRight.cullingMask = (1 << 9) | (1 << 15) | (1 << 16) | (1 << 20) | (1 << 32);
                //  camRight.cullingMask = 0;
                //camRight.ResetCullingMatrix();
                // camRight_Near.useOcclusionCulling = true;
                //
                // camRight_Near.nearClipPlane = 0.01f;
                // camRight_Near.farClipPlane = max;
                //set camera projections:


                //TODO rewrite
                HmdMatrix44_t projLeft  = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, camLeft_Near.nearClipPlane, camLeft_Near.farClipPlane);
                HmdMatrix44_t projRight = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, camRight_Near.nearClipPlane, camRight_Near.farClipPlane);

                camLeft_Near.projectionMatrix  = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft);
                camRight_Near.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projRight);

                // HmdMatrix44_t projLeft2 = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, camLeft_Interior.nearClipPlane, camLeft_Interior.farClipPlane);
                // HmdMatrix44_t projRight2 = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, camRight_Interior.nearClipPlane, camRight_Interior.farClipPlane);
                //
                // camLeft_Interior.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft2);
                // camRight_Interior.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projRight2);

                HmdMatrix44_t projLeft3  = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, camLeft_Far.nearClipPlane, camLeft_Far.farClipPlane);
                HmdMatrix44_t projRight3 = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, camRight_Far.nearClipPlane, camRight_Far.farClipPlane);

                camLeft_Far.projectionMatrix  = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft3);
                camRight_Far.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projRight3);

                HmdMatrix44_t projLeft4  = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, leftSky.nearClipPlane, leftSky.farClipPlane);
                HmdMatrix44_t projRight4 = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, rightSky.nearClipPlane, rightSky.farClipPlane);

                leftSky.projectionMatrix  = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft4);
                rightSky.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projRight4);

                HmdMatrix44_t projLeft5  = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, leftStars.nearClipPlane, leftStars.farClipPlane);
                HmdMatrix44_t projRight5 = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, rightStars.nearClipPlane, rightStars.farClipPlane);

                leftStars.projectionMatrix  = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft5);
                rightStars.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projRight5);

                // camLeft_Interior.depth = 0;
                // camLeft_Interior.clearFlags = CameraClearFlags.Skybox;
                //    camLeft_Near.depth = 0;
                //    camLeft_Near.clearFlags = CameraClearFlags.Nothing;
                //    camLeft_Far.depth = -1;
                //    camLeft_Far.clearFlags = CameraClearFlags.Nothing;
                //    leftSky.depth = -2;
                //    leftSky.clearFlags = CameraClearFlags.Nothing;
                //    leftStars.depth = -3;
                //    leftStars.clearFlags = CameraClearFlags.Skybox;
                //   //
                //   // camRight_Interior.depth = 5;
                //   // camRight_Interior.clearFlags = CameraClearFlags.Skybox;
                //    camRight_Near.depth =0;
                //    camRight_Near.clearFlags = CameraClearFlags.Nothing;
                //    camRight_Far.depth = -1;
                //    camRight_Far.clearFlags = CameraClearFlags.Nothing;
                //    rightSky.depth = -2;
                //    rightSky.clearFlags = CameraClearFlags.Nothing;
                //    rightStars.depth = -3;
                //    rightStars.clearFlags = CameraClearFlags.Skybox;


                //activate slaves
                posTracker.HmdOn = true;
                leftSlave.HmdOn  = true;
                rightSlave.HmdOn = true;
            }
        }
Example #11
0
    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);
    }
Example #12
0
        public void InitRendering(UI ui)
        {
            lock (_drawLock)
            {
                if (ui == null)
                {
                    return;
                }
                _ui          = ui;
                ResizeRedraw = true;

                var initError = EVRInitError.None;

                system = OpenVR.Init(ref initError);

                if (initError != EVRInitError.None)
                {
                    throw new Exception("Not Available");
                }

                compositor = OpenVR.Compositor;

                compositor.CompositorBringToFront();
                compositor.FadeGrid(5.0f, false);

                count = OpenVR.k_unMaxTrackedDeviceCount;

                currentPoses = new TrackedDevicePose_t[count];
                nextPoses    = new TrackedDevicePose_t[count];

                controllers                    = new List <uint>();
                controllerModels               = new RenderModel_t[count];
                controllerTextures             = new RenderModel_TextureMap_t[count];
                controllerTextureViews         = new ShaderResourceView[count];
                controllerVertexBuffers        = new SharpDX.Direct3D11.Buffer[count];
                controllerIndexBuffers         = new SharpDX.Direct3D11.Buffer[count];
                controllerVertexBufferBindings = new VertexBufferBinding[count];

                for (uint device = 0; device < count; device++)
                {
                    var deviceClass = system.GetTrackedDeviceClass(device);

                    switch (deviceClass)
                    {
                    case ETrackedDeviceClass.HMD:
                        headset = device;
                        break;

                    case ETrackedDeviceClass.Controller:
                        controllers.Add(device);
                        break;
                    }
                }

                uint width  = 0;
                uint height = 0;

                system.GetRecommendedRenderTargetSize(ref width, ref height);

                headsetSize = new Size((int)width, (int)height);
                windowSize  = new Size(UI.GameWidth, UI.GameHeight);

                leftEyeProjection  = Convert(system.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f));
                rightEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f));

                leftEyeView  = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Left));
                rightEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Right));

                foreach (var controller in controllers)
                {
                    var modelName     = new StringBuilder(255, 255);
                    var propertyError = ETrackedPropertyError.TrackedProp_Success;

                    var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError);

                    if (propertyError == ETrackedPropertyError.TrackedProp_Success)
                    {
                        var modelName2 = modelName.ToString();

                        while (true)
                        {
                            var pointer    = IntPtr.Zero;
                            var modelError = EVRRenderModelError.None;

                            modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer);

                            if (modelError == EVRRenderModelError.Loading)
                            {
                                continue;
                            }

                            if (modelError == EVRRenderModelError.None)
                            {
                                var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer);

                                controllerModels[controller] = renderModel;
                                break;
                            }
                        }

                        while (true)
                        {
                            var pointer      = IntPtr.Zero;
                            var textureError = EVRRenderModelError.None;

                            textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer);

                            if (textureError == EVRRenderModelError.Loading)
                            {
                                continue;
                            }

                            if (textureError == EVRRenderModelError.None)
                            {
                                var texture = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer);

                                controllerTextures[controller] = texture;
                                break;
                            }
                        }
                    }
                }

                int adapterIndex = 0;

                system.GetDXGIOutputInfo(ref adapterIndex);

                using (var factory = new SharpDX.DXGI.Factory4())
                {
                    var adapter = factory.GetAdapter(adapterIndex);

                    var swapChainDescription = new SwapChainDescription
                    {
                        BufferCount     = 1,
                        Flags           = SwapChainFlags.None,
                        IsWindowed      = true,
                        ModeDescription = new ModeDescription
                        {
                            Format      = Format.B8G8R8A8_UNorm,
                            Width       = windowSize.Width,
                            Height      = windowSize.Height,
                            RefreshRate = new Rational(60, 1)
                        },
                        OutputHandle      = this.Handle,
                        SampleDescription = new SampleDescription(1, 0),
                        SwapEffect        = SwapEffect.Discard,
                        Usage             = Usage.RenderTargetOutput
                    };

                    SharpDX.Direct3D11.Device.CreateWithSwapChain(adapter, DeviceCreationFlags.None, swapChainDescription, out device, out swapChain);

                    factory.MakeWindowAssociation(this.Handle, WindowAssociationFlags.None);

                    context = device.ImmediateContext;

                    using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0))
                        backBufferView = new RenderTargetView(device, backBuffer);

                    var depthBufferDescription = new Texture2DDescription
                    {
                        Format            = Format.D16_UNorm,
                        ArraySize         = 1,
                        MipLevels         = 1,
                        Width             = windowSize.Width,
                        Height            = windowSize.Height,
                        SampleDescription = new SampleDescription(1, 0),
                        Usage             = ResourceUsage.Default,
                        BindFlags         = BindFlags.DepthStencil,
                        CpuAccessFlags    = CpuAccessFlags.None,
                        OptionFlags       = ResourceOptionFlags.None
                    };

                    using (var depthBuffer = new Texture2D(device, depthBufferDescription))
                        depthStencilView = new DepthStencilView(device, depthBuffer);

                    // Create Eye Textures
                    var eyeTextureDescription = new Texture2DDescription
                    {
                        ArraySize         = 1,
                        BindFlags         = BindFlags.RenderTarget,
                        CpuAccessFlags    = CpuAccessFlags.None,
                        Format            = Format.B8G8R8A8_UNorm,
                        Width             = headsetSize.Width,
                        Height            = headsetSize.Height,
                        MipLevels         = 1,
                        OptionFlags       = ResourceOptionFlags.None,
                        SampleDescription = new SampleDescription(1, 0),
                        Usage             = ResourceUsage.Default
                    };

                    leftEyeTexture  = new Texture2D(device, eyeTextureDescription);
                    rightEyeTexture = new Texture2D(device, eyeTextureDescription);

                    leftEyeTextureView  = new RenderTargetView(device, leftEyeTexture);
                    rightEyeTextureView = new RenderTargetView(device, rightEyeTexture);

                    // Create Eye Depth Buffer
                    eyeTextureDescription.BindFlags = BindFlags.DepthStencil;
                    eyeTextureDescription.Format    = Format.D32_Float;

                    eyeDepth     = new Texture2D(device, eyeTextureDescription);
                    eyeDepthView = new DepthStencilView(device, eyeDepth);

                    Shapes.Cube.Load(device);
                    Shapes.Sphere.Load(device);
                    Shaders.Normal.Load(device);
                    Shaders.NormalTexture.Load(device);

                    // Load Controller Models
                    foreach (var controller in controllers)
                    {
                        var model = controllerModels[controller];

                        controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription
                        {
                            BindFlags   = BindFlags.VertexBuffer,
                            SizeInBytes = (int)model.unVertexCount * 32
                        });

                        controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0);

                        controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription
                        {
                            BindFlags   = BindFlags.IndexBuffer,
                            SizeInBytes = (int)model.unTriangleCount * 3 * 2
                        });

                        var texture = controllerTextures[controller];

                        using (var texture2d = new Texture2D(device, new Texture2DDescription
                        {
                            ArraySize = 1,
                            BindFlags = BindFlags.ShaderResource,
                            Format = Format.R8G8B8A8_UNorm,
                            Width = texture.unWidth,
                            Height = texture.unHeight,
                            MipLevels = 1,
                            SampleDescription = new SampleDescription(1, 0)
                        }, new DataRectangle(texture.rubTextureMapData, texture.unWidth * 4)))
                            controllerTextureViews[controller] = new ShaderResourceView(device, texture2d);
                    }

                    shaderParameterBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf <Shaders.Parameters>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);

                    var rasterizerStateDescription = RasterizerStateDescription.Default();
                    //rasterizerStateDescription.FillMode = FillMode.Wireframe;
                    rasterizerStateDescription.IsFrontCounterClockwise = true;
                    //rasterizerStateDescription.CullMode = CullMode.None;

                    rasterizerState = new RasterizerState(device, rasterizerStateDescription);

                    var blendStateDescription = BlendStateDescription.Default();

                    blendStateDescription.RenderTarget[0].BlendOperation   = BlendOperation.Add;
                    blendStateDescription.RenderTarget[0].SourceBlend      = BlendOption.SourceAlpha;
                    blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha;

                    blendStateDescription.RenderTarget[0].IsBlendEnabled = false;

                    blendState = new BlendState(device, blendStateDescription);

                    var depthStateDescription = DepthStencilStateDescription.Default();

                    depthStateDescription.DepthComparison  = Comparison.LessEqual;
                    depthStateDescription.IsDepthEnabled   = true;
                    depthStateDescription.IsStencilEnabled = false;

                    depthStencilState = new DepthStencilState(device, depthStateDescription);

                    var samplerStateDescription = SamplerStateDescription.Default();

                    samplerStateDescription.Filter   = Filter.MinMagMipLinear;
                    samplerStateDescription.AddressU = TextureAddressMode.Wrap;
                    samplerStateDescription.AddressV = TextureAddressMode.Wrap;

                    samplerState = new SamplerState(device, samplerStateDescription);

                    startTime = DateTime.Now;
                    frame     = 0;
                    //windowSize = ClientSize;

                    backgroundColor = new RawColor4(0.1f, 0.1f, 0.1f, 1);

                    head = Matrix.Identity;

                    _ui.ready = true;
                }
            }
        }
Example #13
0
        public override Matrix GetViewMatrix(int eye, Matrix playerPose)
        {
            var matrixEyePos = _hmd.GetEyeToHeadTransform((EVREye)eye).ToXNA();

            return(matrixEyePos * Matrix.Invert(_hmdPose));
        }
Example #14
0
    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);
    }
Example #15
0
        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();
                                                                    }
                                                                }
        }
Example #16
0
 // instead of Model * View * Projection the model is Model * View * Eye * Projection
 private Matrix GetEyeView(EVREye eye) => Matrix.Invert(Matrix.Transpose(ToMonogameMatrix(_vrSystem.GetEyeToHeadTransform(eye))));
        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);
        }
Example #18
0
        static void Main()
        {
            var initError = EVRInitError.None;

            system = OpenVR.Init(ref initError);

            if (initError != EVRInitError.None)
            {
                return;
            }

            compositor = OpenVR.Compositor;

            compositor.CompositorBringToFront();
            compositor.FadeGrid(5.0f, false);

            count = OpenVR.k_unMaxTrackedDeviceCount;

            currentPoses = new TrackedDevicePose_t[count];
            nextPoses    = new TrackedDevicePose_t[count];

            controllers                    = new List <uint>();
            controllerModels               = new RenderModel_t[count];
            controllerTextures             = new RenderModel_TextureMap_t[count];
            controllerTextureViews         = new ShaderResourceView[count];
            controllerVertexBuffers        = new SharpDX.Direct3D11.Buffer[count];
            controllerIndexBuffers         = new SharpDX.Direct3D11.Buffer[count];
            controllerVertexBufferBindings = new VertexBufferBinding[count];
            controllerEmitters             = new Emitter[count];
            controllerVoices               = new SourceVoice[count];

            for (uint device = 0; device < count; device++)
            {
                var deviceClass = system.GetTrackedDeviceClass(device);

                switch (deviceClass)
                {
                case ETrackedDeviceClass.HMD:
                    headset = device;
                    break;

                case ETrackedDeviceClass.Controller:
                    controllers.Add(device);
                    break;
                }
            }

            uint width  = 0;
            uint height = 0;

            system.GetRecommendedRenderTargetSize(ref width, ref height);

            headsetSize = new Size((int)width, (int)height);
            windowSize  = new Size(960, 540);

            var leftEyeProjection  = Convert(system.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f));
            var rightEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f));

            var leftEyeView  = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Left));
            var rightEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Right));

            foreach (var controller in controllers)
            {
                var modelName     = new StringBuilder(255, 255);
                var propertyError = ETrackedPropertyError.TrackedProp_Success;

                var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError);

                if (propertyError == ETrackedPropertyError.TrackedProp_Success)
                {
                    var modelName2 = modelName.ToString();

                    while (true)
                    {
                        var pointer    = IntPtr.Zero;
                        var modelError = EVRRenderModelError.None;

                        modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer);

                        if (modelError == EVRRenderModelError.Loading)
                        {
                            continue;
                        }

                        if (modelError == EVRRenderModelError.None)
                        {
                            var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer);

                            controllerModels[controller] = renderModel;
                            break;
                        }
                    }

                    while (true)
                    {
                        var pointer      = IntPtr.Zero;
                        var textureError = EVRRenderModelError.None;

                        textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer);

                        if (textureError == EVRRenderModelError.Loading)
                        {
                            continue;
                        }

                        if (textureError == EVRRenderModelError.None)
                        {
                            var texture = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer);

                            controllerTextures[controller] = texture;
                            break;
                        }
                    }
                }
            }

            int adapterIndex = 0;

            system.GetDXGIOutputInfo(ref adapterIndex);

            using (var form = new Form())
                using (var factory = new Factory4())
                {
                    form.ClientSize = windowSize;

                    var adapter = factory.GetAdapter(adapterIndex);

                    var swapChainDescription = new SwapChainDescription
                    {
                        BufferCount     = 1,
                        Flags           = SwapChainFlags.None,
                        IsWindowed      = true,
                        ModeDescription = new ModeDescription
                        {
                            Format      = Format.B8G8R8A8_UNorm,
                            Width       = form.ClientSize.Width,
                            Height      = form.ClientSize.Height,
                            RefreshRate = new Rational(60, 1)
                        },
                        OutputHandle      = form.Handle,
                        SampleDescription = new SampleDescription(1, 0),
                        SwapEffect        = SwapEffect.Discard,
                        Usage             = Usage.RenderTargetOutput
                    };

                    SharpDX.Direct3D11.Device.CreateWithSwapChain(adapter, DeviceCreationFlags.None, swapChainDescription, out device, out swapChain);

                    factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.None);

                    context = device.ImmediateContext;

                    using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0))
                        backBufferView = new RenderTargetView(device, backBuffer);

                    var depthBufferDescription = new Texture2DDescription
                    {
                        Format            = Format.D16_UNorm,
                        ArraySize         = 1,
                        MipLevels         = 1,
                        Width             = form.ClientSize.Width,
                        Height            = form.ClientSize.Height,
                        SampleDescription = new SampleDescription(1, 0),
                        Usage             = ResourceUsage.Default,
                        BindFlags         = BindFlags.DepthStencil,
                        CpuAccessFlags    = CpuAccessFlags.None,
                        OptionFlags       = ResourceOptionFlags.None
                    };

                    using (var depthBuffer = new Texture2D(device, depthBufferDescription))
                        depthStencilView = new DepthStencilView(device, depthBuffer);

                    // Create Eye Textures
                    var eyeTextureDescription = new Texture2DDescription
                    {
                        ArraySize         = 1,
                        BindFlags         = BindFlags.RenderTarget,
                        CpuAccessFlags    = CpuAccessFlags.None,
                        Format            = Format.B8G8R8A8_UNorm,
                        Width             = headsetSize.Width,
                        Height            = headsetSize.Height,
                        MipLevels         = 1,
                        OptionFlags       = ResourceOptionFlags.None,
                        SampleDescription = new SampleDescription(1, 0),
                        Usage             = ResourceUsage.Default
                    };

                    var leftEyeTexture  = new Texture2D(device, eyeTextureDescription);
                    var rightEyeTexture = new Texture2D(device, eyeTextureDescription);

                    var leftEyeTextureView  = new RenderTargetView(device, leftEyeTexture);
                    var rightEyeTextureView = new RenderTargetView(device, rightEyeTexture);

                    // Create Eye Depth Buffer
                    eyeTextureDescription.BindFlags = BindFlags.DepthStencil;
                    eyeTextureDescription.Format    = Format.D32_Float;

                    var eyeDepth     = new Texture2D(device, eyeTextureDescription);
                    var eyeDepthView = new DepthStencilView(device, eyeDepth);

                    Shapes.Cube.Load(device);
                    Shapes.Sphere.Load(device);
                    Shaders.Load(device);

                    // Load Controller Models
                    foreach (var controller in controllers)
                    {
                        var model = controllerModels[controller];

                        controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription
                        {
                            BindFlags   = BindFlags.VertexBuffer,
                            SizeInBytes = (int)model.unVertexCount * 32
                        });

                        controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0);

                        controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription
                        {
                            BindFlags   = BindFlags.IndexBuffer,
                            SizeInBytes = (int)model.unTriangleCount * 3 * 2
                        });

                        var texture = controllerTextures[controller];

                        using (var texture2d = new Texture2D(device, new Texture2DDescription
                        {
                            ArraySize = 1,
                            BindFlags = BindFlags.ShaderResource,
                            Format = Format.R8G8B8A8_UNorm,
                            Width = texture.unWidth,
                            Height = texture.unHeight,
                            MipLevels = 1,
                            SampleDescription = new SampleDescription(1, 0)
                        }, new DataRectangle(texture.rubTextureMapData, texture.unWidth * 4)))
                            controllerTextureViews[controller] = new ShaderResourceView(device, texture2d);
                    }

                    var controllerVertexShaderByteCode = SharpDX.D3DCompiler.ShaderBytecode.Compile(Properties.Resources.NormalTextureShader, "VS", "vs_5_0");
                    controllerVertexShader = new VertexShader(device, controllerVertexShaderByteCode);
                    controllerPixelShader  = new PixelShader(device, SharpDX.D3DCompiler.ShaderBytecode.Compile(Properties.Resources.NormalTextureShader, "PS", "ps_5_0"));

                    var controllerLayout = new InputLayout(device, SharpDX.D3DCompiler.ShaderSignature.GetInputSignature(controllerVertexShaderByteCode), new InputElement[]
                    {
                        new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                        new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0),
                        new InputElement("TEXCOORD", 0, Format.R32G32_Float, 24, 0)
                    });

                    worldViewProjectionBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf <Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);

                    var rasterizerStateDescription = RasterizerStateDescription.Default();
                    //rasterizerStateDescription.FillMode = FillMode.Wireframe;
                    rasterizerStateDescription.IsFrontCounterClockwise = true;
                    //rasterizerStateDescription.CullMode = CullMode.None;

                    rasterizerState = new RasterizerState(device, rasterizerStateDescription);

                    var blendStateDescription = BlendStateDescription.Default();

                    blendStateDescription.RenderTarget[0].BlendOperation   = BlendOperation.Add;
                    blendStateDescription.RenderTarget[0].SourceBlend      = BlendOption.SourceAlpha;
                    blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha;

                    blendStateDescription.RenderTarget[0].IsBlendEnabled = false;

                    blendState = new BlendState(device, blendStateDescription);

                    var depthStateDescription = DepthStencilStateDescription.Default();

                    depthStateDescription.DepthComparison  = Comparison.LessEqual;
                    depthStateDescription.IsDepthEnabled   = true;
                    depthStateDescription.IsStencilEnabled = false;

                    depthStencilState = new DepthStencilState(device, depthStateDescription);

                    var samplerStateDescription = SamplerStateDescription.Default();

                    samplerStateDescription.Filter   = Filter.MinMagMipLinear;
                    samplerStateDescription.AddressU = TextureAddressMode.Wrap;
                    samplerStateDescription.AddressV = TextureAddressMode.Wrap;

                    samplerState = new SamplerState(device, samplerStateDescription);

                    startTime  = DateTime.Now;
                    frame      = 0;
                    windowSize = form.ClientSize;

                    backgroundColor = new RawColor4(0.1f, 0.1f, 0.1f, 1);

                    var vrEvent   = new VREvent_t();
                    var eventSize = (uint)Utilities.SizeOf <VREvent_t>();

                    head = Matrix.Identity;

                    // Initialize Audio
                    audio = new XAudio2();
                    var voice = new MasteringVoice(audio);
                    audio3d = new X3DAudio(Speakers.Stereo);

                    foreach (var controller in controllers)
                    {
                        controllerEmitters[controller] = new Emitter
                        {
                            ChannelCount        = 1,
                            CurveDistanceScaler = 0.15f,
                            OrientFront         = Vector3.ForwardLH,
                            OrientTop           = Vector3.Up,
                            Position            = new Vector3(0, 0, 1000),
                            //Velocity = Vector3.Zero
                        };
                    }

                    listener = new Listener
                    {
                        OrientFront = Vector3.ForwardLH,
                        OrientTop   = Vector3.Up,
                        Position    = new Vector3(0, 0, 1000)
                    };

                    var audioFormat = new WaveFormat(44100, 32, 1);
                    //var audioSource = new SourceVoice(audio, audioFormat);
                    var audioBufferSize = audioFormat.ConvertLatencyToByteSize(1000);
                    var audioStream     = new DataStream(audioBufferSize, true, true);
                    var audioSamples    = audioBufferSize / audioFormat.BlockAlign;

                    var random = new Random();

                    for (var sample = 0; sample < audioSamples; sample++)
                    {
                        audioStream.Write((float)random.NextFloat(-1, 1));
                    }

                    audioStream.Position = 0;

                    var audioBuffer = new AudioBuffer
                    {
                        Stream     = audioStream,
                        AudioBytes = audioBufferSize,
                        LoopCount  = 255
                    };

                    var audioSettings = new DspSettings(1, 2);

                    foreach (var controller in controllers)
                    {
                        var audioSource = new SourceVoice(audio, audioFormat);

                        audioSource.SubmitSourceBuffer(audioBuffer, null);

                        audio3d.Calculate(listener, controllerEmitters[controller], CalculateFlags.Matrix, audioSettings);

                        audioSource.SetOutputMatrix(1, 2, audioSettings.MatrixCoefficients);

                        audioSource.Start();

                        controllerVoices[controller] = audioSource;
                    }

                    RenderLoop.Run(form, () =>
                    {
                        while (system.PollNextEvent(ref vrEvent, eventSize))
                        {
                            switch ((EVREventType)vrEvent.eventType)
                            {
                            case EVREventType.VREvent_TrackedDeviceActivated:
                                var controller = vrEvent.trackedDeviceIndex;

                                controllers.Add(controller);

                                var modelName     = new StringBuilder(255, 255);
                                var propertyError = ETrackedPropertyError.TrackedProp_Success;

                                var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError);

                                if (propertyError == ETrackedPropertyError.TrackedProp_Success)
                                {
                                    var modelName2 = modelName.ToString();

                                    while (true)
                                    {
                                        var pointer    = IntPtr.Zero;
                                        var modelError = EVRRenderModelError.None;

                                        modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer);

                                        if (modelError == EVRRenderModelError.Loading)
                                        {
                                            continue;
                                        }

                                        if (modelError == EVRRenderModelError.None)
                                        {
                                            var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer);

                                            controllerModels[controller] = renderModel;

                                            // Load Controller Model
                                            var model = controllerModels[controller];

                                            controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription
                                            {
                                                BindFlags   = BindFlags.VertexBuffer,
                                                SizeInBytes = (int)model.unVertexCount * 32
                                            });

                                            controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0);

                                            controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription
                                            {
                                                BindFlags   = BindFlags.IndexBuffer,
                                                SizeInBytes = (int)model.unTriangleCount * 3 * 2
                                            });

                                            break;
                                        }
                                    }

                                    while (true)
                                    {
                                        var pointer      = IntPtr.Zero;
                                        var textureError = EVRRenderModelError.None;

                                        textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer);

                                        if (textureError == EVRRenderModelError.Loading)
                                        {
                                            continue;
                                        }

                                        if (textureError == EVRRenderModelError.None)
                                        {
                                            var textureMap = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer);

                                            controllerTextures[controller] = textureMap;

                                            using (var texture2d = new Texture2D(device, new Texture2DDescription
                                            {
                                                ArraySize = 1,
                                                BindFlags = BindFlags.ShaderResource,
                                                Format = Format.R8G8B8A8_UNorm,
                                                Width = textureMap.unWidth,
                                                Height = textureMap.unHeight,
                                                MipLevels = 1,
                                                SampleDescription = new SampleDescription(1, 0)
                                            }, new DataRectangle(textureMap.rubTextureMapData, textureMap.unWidth * 4)))
                                                controllerTextureViews[controller] = new ShaderResourceView(device, texture2d);

                                            break;
                                        }
                                    }

                                    controllerEmitters[controller] = new Emitter
                                    {
                                        ChannelCount        = 1,
                                        CurveDistanceScaler = 0.15f,
                                        OrientFront         = Vector3.ForwardLH,
                                        OrientTop           = Vector3.Up,
                                        Position            = new Vector3(0, 0, 1000),
                                        //Velocity = Vector3.Zero
                                    };

                                    var audioSource = new SourceVoice(audio, audioFormat);

                                    audioSource.SubmitSourceBuffer(audioBuffer, null);

                                    audio3d.Calculate(listener, controllerEmitters[controller], CalculateFlags.Matrix, audioSettings);

                                    audioSource.SetOutputMatrix(1, 2, audioSettings.MatrixCoefficients);

                                    audioSource.Start();

                                    controllerVoices[controller] = audioSource;
                                }
                                break;

                            case EVREventType.VREvent_TrackedDeviceDeactivated:
                                controllers.RemoveAll(c => c == vrEvent.trackedDeviceIndex);
                                break;

                            default:
                                System.Diagnostics.Debug.WriteLine((EVREventType)vrEvent.eventType);
                                break;
                            }
                        }

                        if (form.ClientSize != windowSize)
                        {
                            Utilities.Dispose(ref backBufferView);

                            if (form.ClientSize.Width != 0 && form.ClientSize.Height != 0)
                            {
                                swapChain.ResizeBuffers(1, form.ClientSize.Width, form.ClientSize.Height, Format.B8G8R8A8_UNorm, SwapChainFlags.None);

                                using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0))
                                    backBufferView = new RenderTargetView(device, backBuffer);
                            }

                            windowSize = form.ClientSize;
                        }

                        // Update Device Tracking
                        compositor.WaitGetPoses(currentPoses, nextPoses);

                        if (currentPoses[headset].bPoseIsValid)
                        {
                            Convert(ref currentPoses[headset].mDeviceToAbsoluteTracking, ref head);

                            // Update Audio Listener
                            listener.Position    = head.TranslationVector * new Vector3(1, 1, -1);
                            listener.OrientFront = head.Forward * new Vector3(1, 1, -1);
                            listener.OrientTop   = head.Up * new Vector3(1, 1, -1);
                        }

                        foreach (var controller in controllers)
                        {
                            var controllerMatrix = Matrix.Identity;

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref controllerMatrix);

                            var position = controllerMatrix.TranslationVector * new Vector3(1, 1, -1);

                            controllerEmitters[controller].Position = position;

                            audio3d.Calculate(listener, controllerEmitters[controller], CalculateFlags.Matrix, audioSettings);

                            controllerVoices[controller].SetOutputMatrix(1, 2, audioSettings.MatrixCoefficients);
                        }

                        // Render Left Eye
                        context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height);
                        context.OutputMerger.SetTargets(eyeDepthView, leftEyeTextureView);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.ClearRenderTargetView(leftEyeTextureView, backgroundColor);
                        context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0);

                        Shaders.Apply(context);

                        context.Rasterizer.State = rasterizerState;

                        context.OutputMerger.SetBlendState(blendState);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.PixelShader.SetSampler(0, samplerState);

                        var ratio = (float)headsetSize.Width / (float)headsetSize.Height;

                        var projection = leftEyeProjection;
                        var view       = Matrix.Invert(leftEyeView * head);
                        var world      = Matrix.Scaling(0.5f) * Matrix.Translation(0, 1.0f, 0);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                        //Shapes.Cube.Begin(context);
                        //Shapes.Cube.Draw(context);

                        Shapes.Sphere.Begin(context);
                        Shapes.Sphere.Draw(context);

                        // Draw Controllers
                        context.InputAssembler.InputLayout       = controllerLayout;
                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

                        context.VertexShader.Set(controllerVertexShader);
                        context.PixelShader.Set(controllerPixelShader);
                        context.GeometryShader.Set(null);
                        context.DomainShader.Set(null);
                        context.HullShader.Set(null);

                        context.PixelShader.SetSampler(0, samplerState);

                        foreach (var controller in controllers)
                        {
                            context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]);
                            context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0);

                            context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]);

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world);

                            worldViewProjection = world * view * projection;

                            context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                            context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                            context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0);
                        }

                        var texture = new Texture_t
                        {
                            eType       = ETextureType.DirectX,
                            eColorSpace = EColorSpace.Gamma,
                            handle      = leftEyeTextureView.Resource.NativePointer
                        };

                        var bounds = new VRTextureBounds_t
                        {
                            uMin = 0.0f,
                            uMax = 1.0f,
                            vMin = 0.0f,
                            vMax = 1.0f,
                        };

                        var submitError = compositor.Submit(EVREye.Eye_Left, ref texture, ref bounds, EVRSubmitFlags.Submit_Default);

                        if (submitError != EVRCompositorError.None)
                        {
                            System.Diagnostics.Debug.WriteLine(submitError);
                        }

                        // Render Right Eye
                        context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height);
                        context.OutputMerger.SetTargets(eyeDepthView, rightEyeTextureView);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.ClearRenderTargetView(rightEyeTextureView, backgroundColor);
                        context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0);

                        Shaders.Apply(context);

                        context.Rasterizer.State = rasterizerState;

                        context.OutputMerger.SetBlendState(blendState);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.PixelShader.SetSampler(0, samplerState);

                        projection = rightEyeProjection;
                        view       = Matrix.Invert(rightEyeView * head);
                        world      = Matrix.Scaling(0.5f) * Matrix.Translation(0, 1.0f, 0);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                        //Shapes.Cube.Begin(context);
                        //Shapes.Cube.Draw(context);

                        Shapes.Sphere.Begin(context);
                        Shapes.Sphere.Draw(context);

                        // Draw Controllers
                        context.InputAssembler.InputLayout       = controllerLayout;
                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

                        context.VertexShader.Set(controllerVertexShader);
                        context.PixelShader.Set(controllerPixelShader);
                        context.GeometryShader.Set(null);
                        context.DomainShader.Set(null);
                        context.HullShader.Set(null);

                        context.PixelShader.SetSampler(0, samplerState);

                        foreach (var controller in controllers)
                        {
                            context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]);
                            context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0);

                            context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]);

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world);

                            worldViewProjection = world * view * projection;

                            context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                            context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                            context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0);
                        }

                        texture.handle = rightEyeTextureView.Resource.NativePointer;

                        submitError = compositor.Submit(EVREye.Eye_Right, ref texture, ref bounds, EVRSubmitFlags.Submit_Default);

                        if (submitError != EVRCompositorError.None)
                        {
                            System.Diagnostics.Debug.WriteLine(submitError);
                        }

                        // Render Window
                        context.Rasterizer.SetViewport(0, 0, windowSize.Width, windowSize.Height);

                        context.OutputMerger.SetTargets(depthStencilView, backBufferView);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.ClearRenderTargetView(backBufferView, backgroundColor);
                        context.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0);

                        Shaders.Apply(context);

                        context.Rasterizer.State = rasterizerState;

                        context.OutputMerger.SetBlendState(blendState);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.PixelShader.SetSampler(0, samplerState);

                        ratio = (float)form.ClientSize.Width / (float)form.ClientSize.Height;

                        projection = Matrix.PerspectiveFovRH(3.14F / 3.0F, ratio, 0.01f, 1000);
                        view       = Matrix.Invert(head);
                        world      = Matrix.Scaling(0.5f) * Matrix.Translation(0, 1.0f, 0);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                        //Shapes.Cube.Begin(context);
                        //Shapes.Cube.Draw(context);

                        Shapes.Sphere.Begin(context);
                        Shapes.Sphere.Draw(context);

                        // Draw Controllers
                        context.InputAssembler.InputLayout       = controllerLayout;
                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

                        context.VertexShader.Set(controllerVertexShader);
                        context.PixelShader.Set(controllerPixelShader);
                        context.GeometryShader.Set(null);
                        context.DomainShader.Set(null);
                        context.HullShader.Set(null);

                        context.PixelShader.SetSampler(0, samplerState);

                        foreach (var controller in controllers)
                        {
                            context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]);
                            context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0);

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world);

                            worldViewProjection = world * view * projection;

                            context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                            context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                            context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0);
                        }

                        // Show Backbuffer
                        swapChain.Present(0, PresentFlags.None);
                    });

                    audio.Dispose();
                }
        }
Example #19
0
        /// <summary>
        /// Overrides the Update method, called every frame.
        /// </summary>
        void Update()
        {
            // do nothing unless we are in IVA
            hmdIsAllowed = (CameraManager.Instance.currentCameraMode == CameraManager.CameraMode.IVA);

            // start HMD using the Y key
            if (Input.GetKeyDown(KeyCode.Y) && hmdIsAllowed)
            {
                if (!hmdIsInitialized)
                {
                    Debug.Log("[KerbalVR] Initializing HMD...");
                    bool retVal = InitHMD();
                    if (retVal)
                    {
                        Debug.Log("[KerbalVR] HMD initialized.");
                    }
                }
                else
                {
                    ResetInitialHmdPosition();
                }
            }

            // perform regular updates if HMD is initialized
            if (hmdIsAllowed && hmdIsInitialized)
            {
                EVRCompositorError vrCompositorError = EVRCompositorError.None;

                // get latest HMD pose
                //--------------------------------------------------------------
                vrSystem.GetDeviceToAbsoluteTrackingPose(ETrackingUniverseOrigin.TrackingUniverseSeated, 0.0f, vrDevicePoses);
                HmdMatrix34_t vrLeftEyeTransform  = vrSystem.GetEyeToHeadTransform(EVREye.Eye_Left);
                HmdMatrix34_t vrRightEyeTransform = vrSystem.GetEyeToHeadTransform(EVREye.Eye_Right);
                vrCompositorError = vrCompositor.WaitGetPoses(vrRenderPoses, vrGamePoses);

                if (vrCompositorError != EVRCompositorError.None)
                {
                    Debug.Log("[KerbalVR] WaitGetPoses failed: " + (int)vrCompositorError);
                    return;
                }

                // convert SteamVR poses to Unity coordinates
                var hmdTransform         = new SteamVR_Utils.RigidTransform(vrDevicePoses[OpenVR.k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking);
                var hmdLeftEyeTransform  = new SteamVR_Utils.RigidTransform(vrLeftEyeTransform);
                var hmdRightEyeTransform = new SteamVR_Utils.RigidTransform(vrRightEyeTransform);
                var ctrlPoseLeft         = new SteamVR_Utils.RigidTransform(vrDevicePoses[ctrlIndexLeft].mDeviceToAbsoluteTracking);
                var ctrlPoseRight        = new SteamVR_Utils.RigidTransform(vrDevicePoses[ctrlIndexRight].mDeviceToAbsoluteTracking);



                // Render the LEFT eye
                //--------------------------------------------------------------
                // rotate camera according to the HMD orientation
                InternalCamera.Instance.transform.localRotation = hmdTransform.rot;

                // translate the camera to match the position of the left eye, from origin
                InternalCamera.Instance.transform.localPosition = new Vector3(0f, 0f, 0f);
                InternalCamera.Instance.transform.Translate(hmdLeftEyeTransform.pos);

                // translate the camera to match the position of the HMD
                InternalCamera.Instance.transform.localPosition += hmdTransform.pos;

                // move the FlightCamera to match the position of the InternalCamera (so the outside world moves accordingly)
                FlightCamera.fetch.transform.position = InternalSpace.InternalToWorld(InternalCamera.Instance.transform.position);
                FlightCamera.fetch.transform.rotation = InternalSpace.InternalToWorld(InternalCamera.Instance.transform.rotation);

                // render the set of cameras
                foreach (CameraProperties camStruct in camerasToRender)
                {
                    // set projection matrix
                    camStruct.camera.projectionMatrix = camStruct.hmdLeftProjMatrix;

                    // set texture to render to
                    camStruct.camera.targetTexture = hmdLeftEyeRenderTexture;
                    RenderTexture.active           = hmdLeftEyeRenderTexture;

                    // render camera
                    camStruct.camera.Render();
                }


                // Render the RIGHT eye (see previous comments)
                //--------------------------------------------------------------
                InternalCamera.Instance.transform.localRotation = hmdTransform.rot;
                InternalCamera.Instance.transform.localPosition = new Vector3(0f, 0f, 0f);
                InternalCamera.Instance.transform.Translate(hmdRightEyeTransform.pos);
                InternalCamera.Instance.transform.localPosition += hmdTransform.pos;
                FlightCamera.fetch.transform.position            = InternalSpace.InternalToWorld(InternalCamera.Instance.transform.position);
                FlightCamera.fetch.transform.rotation            = InternalSpace.InternalToWorld(InternalCamera.Instance.transform.rotation);

                foreach (CameraProperties camStruct in camerasToRender)
                {
                    camStruct.camera.projectionMatrix = camStruct.hmdRightProjMatrix;
                    camStruct.camera.targetTexture    = hmdRightEyeRenderTexture;
                    RenderTexture.active = hmdRightEyeRenderTexture;
                    camStruct.camera.Render();
                }

                var origTex = uiCamera.targetTexture;
                uiCamera.targetTexture = uiTexture;
                RenderTexture.active   = uiTexture;
                uiCamera.Render();
                uiCamera.targetTexture = origTex;
                RenderTexture.active   = null;


                // Set camera position to an HMD-centered position (for regular screen rendering)
                //--------------------------------------------------------------
                if (renderToScreen)
                {
                    foreach (CameraProperties camStruct in camerasToRender)
                    {
                        camStruct.camera.targetTexture    = null;
                        RenderTexture.active              = null;
                        camStruct.camera.projectionMatrix = camStruct.originalProjMatrix;
                    }
                    InternalCamera.Instance.transform.localRotation = hmdTransform.rot;
                    InternalCamera.Instance.transform.localPosition = hmdTransform.pos;
                    FlightCamera.fetch.transform.position           = InternalSpace.InternalToWorld(InternalCamera.Instance.transform.position);
                    FlightCamera.fetch.transform.rotation           = InternalSpace.InternalToWorld(InternalCamera.Instance.transform.rotation);
                }



                // Set position of the hand controller props
                //--------------------------------------------------------------

                if (propLeftHand != null)
                {
                    propLeftHand.transform.position = InternalCamera.Instance.transform.parent.position;
                    propLeftHand.transform.rotation = InternalCamera.Instance.transform.parent.rotation;
                    propLeftHand.transform.Translate(ctrlPoseLeft.pos);
                    propLeftHand.transform.rotation *= ctrlPoseLeft.rot;
                    propLeftHandRenderer.enabled     = vrDevicePoses[ctrlIndexLeft].bDeviceIsConnected;

                    uiScreen.transform.position = InternalSpace.InternalToWorld(propLeftHand.transform.position);
                    uiScreen.transform.rotation = InternalSpace.InternalToWorld(propLeftHand.transform.rotation);
                    uiScreen.transform.Rotate(90f, 0f, 0f);
                }

                if (propRightHand != null)
                {
                    propRightHand.transform.position = InternalCamera.Instance.transform.parent.position;
                    propRightHand.transform.rotation = InternalCamera.Instance.transform.parent.rotation;
                    propRightHand.transform.Translate(ctrlPoseRight.pos);
                    propRightHand.transform.rotation *= ctrlPoseRight.rot;
                    propRightHandRenderer.enabled     = vrDevicePoses[ctrlIndexRight].bDeviceIsConnected;

                    InternalProp closestProp        = null;
                    float        closestDistanceSqr = 10000f;
                    foreach (InternalProp prop in activeVesselInternalProps)
                    {
                        if (!prop.name.Equals(propRightHand.name))
                        {
                            Vector3 directionToTarget   = prop.transform.position - gloveCollider.transform.position;
                            float   distanceToTargetSqr = directionToTarget.sqrMagnitude;
                            if (distanceToTargetSqr < closestDistanceSqr)
                            {
                                closestDistanceSqr = distanceToTargetSqr;
                                closestProp        = prop;
                            }
                        }
                    }
                }



                /*
                 * if (closestProp != null && closestDistanceSqr < 0.005f)
                 * {
                 *  Debug.Log("[KerbalVR] closest prop: " + closestProp + ", " + closestDistanceSqr + " m2");
                 *  foreach (InternalModule mod in closestProp.internalModules)
                 *  {
                 *      Debug.Log("[KerbalVR] module: " + mod.name);
                 *  }
                 * }
                 */

                // Submit frames to HMD
                //--------------------------------------------------------------
                vrCompositorError = vrCompositor.Submit(EVREye.Eye_Left, ref hmdLeftEyeTexture, ref hmdTextureBounds, EVRSubmitFlags.Submit_Default);
                if (vrCompositorError != EVRCompositorError.None)
                {
                    Debug.Log("[KerbalVR] Submit (Eye_Left) failed: " + (int)vrCompositorError);
                }


                vrCompositorError = vrCompositor.Submit(EVREye.Eye_Right, ref hmdRightEyeTexture, ref hmdTextureBounds, EVRSubmitFlags.Submit_Default);
                if (vrCompositorError != EVRCompositorError.None)
                {
                    Debug.Log("[KerbalVR] Submit (Eye_Right) failed: " + (int)vrCompositorError);
                }

                // disable highlighting of parts due to mouse
                // TODO: there needs to be a better way to do this. this affects the Part permanently
                Part hoveredPart = Mouse.HoveredPart;
                if (hoveredPart != null)
                {
                    hoveredPart.HighlightActive  = false;
                    hoveredPart.highlightColor.a = 0f;// = new Color(0f, 0f, 0f, 0f);
                    //Debug.Log("[KerbalVR] hovered part: " + hoveredPart.name);
                }


                // DEBUG
                if (Input.GetKeyDown(KeyCode.O))
                {
                    Debug.Log("[KerbalVR] POSITION hmdTransform : " + hmdTransform.pos.x + ", " + hmdTransform.pos.y + ", " + hmdTransform.pos.z);
                    Debug.Log("[KerbalVR] POSITION hmdLTransform : " + hmdLeftEyeTransform.pos.x + ", " + hmdLeftEyeTransform.pos.y + ", " + hmdLeftEyeTransform.pos.z);
                    Debug.Log("[KerbalVR] POSITION hmdRTransform : " + hmdRightEyeTransform.pos.x + ", " + hmdRightEyeTransform.pos.y + ", " + hmdRightEyeTransform.pos.z);
                    Debug.Log("[KerbalVR] POSITION ctrlPoseRight : " + ctrlPoseRight.pos.x + ", " + ctrlPoseRight.pos.y + ", " + ctrlPoseRight.pos.z);

                    Debug.Log("[KerbalVR] POSITION InternalCamera.Instance.transform.abs : " + InternalCamera.Instance.transform.position.x + ", " + InternalCamera.Instance.transform.position.y + ", " + InternalCamera.Instance.transform.position.z);
                    Debug.Log("[KerbalVR] POSITION InternalCamera.Instance.transform.rel : " + InternalCamera.Instance.transform.localPosition.x + ", " + InternalCamera.Instance.transform.localPosition.y + ", " + InternalCamera.Instance.transform.localPosition.z);
                    //Debug.Log("[KerbalVR] POSITION myprop.transform : " + testProp.transform.position.x + ", " + testProp.transform.position.y + ", " + testProp.transform.position.z);

                    uiScreen.layer = (uiScreen.layer == 31) ? 0 : uiScreen.layer + 1;
                    Debug.Log("[KerbalVR] prop layer = " + propLeftHand.gameObject.layer + ", screen obj layer = " + uiScreen.layer);

                    foreach (Camera c in Camera.allCameras)
                    {
                        Debug.Log("[KerbalVR] Camera: " + c.name + ", cullingMask = " + c.cullingMask);
                    }
                }
            }

            // if we are exiting VR, restore the cameras
            if (!hmdIsAllowed && hmdIsAllowed_prev)
            {
                foreach (CameraProperties camStruct in camerasToRender)
                {
                    camStruct.camera.projectionMatrix = camStruct.originalProjMatrix;
                    camStruct.camera.targetTexture    = null;
                    RenderTexture.active = null;
                }
            }

            hmdIsAllowed_prev = hmdIsAllowed;
        }
Example #20
0
        public override Matrix GetViewMatrix(int eye, Matrix parent)
        {
            var matrixEyePos = m_System.GetEyeToHeadTransform((EVREye)eye).ToXNA();

            return(Matrix.Invert(parent) * (m_HMDPose * matrixEyePos));
        }
Example #21
0
        static void Main()
        {
            var initError = EVRInitError.None;

            system = OpenVR.Init(ref initError);

            if (initError != EVRInitError.None)
            {
                return;
            }

            compositor = OpenVR.Compositor;

            compositor.CompositorBringToFront();
            compositor.FadeGrid(5.0f, false);

            count = OpenVR.k_unMaxTrackedDeviceCount;

            currentPoses = new TrackedDevicePose_t[count];
            nextPoses    = new TrackedDevicePose_t[count];

            controllers                    = new List <uint>();
            controllerModels               = new RenderModel_t[count];
            controllerTextures             = new RenderModel_TextureMap_t[count];
            controllerTextureViews         = new ShaderResourceView[count];
            controllerVertexBuffers        = new SharpDX.Direct3D11.Buffer[count];
            controllerIndexBuffers         = new SharpDX.Direct3D11.Buffer[count];
            controllerVertexBufferBindings = new VertexBufferBinding[count];

            for (uint device = 0; device < count; device++)
            {
                var deviceClass = system.GetTrackedDeviceClass(device);

                switch (deviceClass)
                {
                case ETrackedDeviceClass.HMD:
                    headset = device;
                    break;

                case ETrackedDeviceClass.Controller:
                    controllers.Add(device);
                    break;
                }
            }

            uint width  = 0;
            uint height = 0;

            system.GetRecommendedRenderTargetSize(ref width, ref height);

            headsetSize = new Size((int)width, (int)height);
            windowSize  = new Size(960, 540);

            var leftEyeProjection  = Convert(system.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f));
            var rightEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f));

            var leftEyeView  = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Left));
            var rightEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Right));

            foreach (var controller in controllers)
            {
                var modelName     = new StringBuilder(255, 255);
                var propertyError = ETrackedPropertyError.TrackedProp_Success;

                var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError);

                if (propertyError == ETrackedPropertyError.TrackedProp_Success)
                {
                    var modelName2 = modelName.ToString();

                    while (true)
                    {
                        var pointer    = IntPtr.Zero;
                        var modelError = EVRRenderModelError.None;

                        modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer);

                        if (modelError == EVRRenderModelError.Loading)
                        {
                            continue;
                        }

                        if (modelError == EVRRenderModelError.None)
                        {
                            var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer);

                            controllerModels[controller] = renderModel;
                            break;
                        }
                    }

                    while (true)
                    {
                        var pointer      = IntPtr.Zero;
                        var textureError = EVRRenderModelError.None;

                        textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer);

                        if (textureError == EVRRenderModelError.Loading)
                        {
                            continue;
                        }

                        if (textureError == EVRRenderModelError.None)
                        {
                            var texture = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer);

                            controllerTextures[controller] = texture;
                            break;
                        }
                    }
                }
            }

            int adapterIndex = 0;

            system.GetDXGIOutputInfo(ref adapterIndex);

            using (var form = new Form())
                using (var factory = new Factory4())
                {
                    form.ClientSize = windowSize;

                    var adapter = factory.GetAdapter(adapterIndex);

                    var swapChainDescription = new SwapChainDescription
                    {
                        BufferCount     = 1,
                        Flags           = SwapChainFlags.None,
                        IsWindowed      = true,
                        ModeDescription = new ModeDescription
                        {
                            Format      = Format.B8G8R8A8_UNorm,
                            Width       = form.ClientSize.Width,
                            Height      = form.ClientSize.Height,
                            RefreshRate = new Rational(60, 1)
                        },
                        OutputHandle      = form.Handle,
                        SampleDescription = new SampleDescription(1, 0),
                        SwapEffect        = SwapEffect.Discard,
                        Usage             = Usage.RenderTargetOutput
                    };

                    SharpDX.Direct3D11.Device.CreateWithSwapChain(adapter, DeviceCreationFlags.None, swapChainDescription, out device, out swapChain);

                    factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.None);

                    context = device.ImmediateContext;

                    using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0))
                        backBufferView = new RenderTargetView(device, backBuffer);

                    var depthBufferDescription = new Texture2DDescription
                    {
                        Format            = Format.D16_UNorm,
                        ArraySize         = 1,
                        MipLevels         = 1,
                        Width             = form.ClientSize.Width,
                        Height            = form.ClientSize.Height,
                        SampleDescription = new SampleDescription(1, 0),
                        Usage             = ResourceUsage.Default,
                        BindFlags         = BindFlags.DepthStencil,
                        CpuAccessFlags    = CpuAccessFlags.None,
                        OptionFlags       = ResourceOptionFlags.None
                    };

                    using (var depthBuffer = new Texture2D(device, depthBufferDescription))
                        depthStencilView = new DepthStencilView(device, depthBuffer);

                    // Create Eye Textures
                    var eyeTextureDescription = new Texture2DDescription
                    {
                        ArraySize         = 1,
                        BindFlags         = BindFlags.RenderTarget,
                        CpuAccessFlags    = CpuAccessFlags.None,
                        Format            = Format.B8G8R8A8_UNorm,
                        Width             = headsetSize.Width,
                        Height            = headsetSize.Height,
                        MipLevels         = 1,
                        OptionFlags       = ResourceOptionFlags.None,
                        SampleDescription = new SampleDescription(1, 0),
                        Usage             = ResourceUsage.Default
                    };

                    var leftEyeTexture  = new Texture2D(device, eyeTextureDescription);
                    var rightEyeTexture = new Texture2D(device, eyeTextureDescription);

                    var leftEyeTextureView  = new RenderTargetView(device, leftEyeTexture);
                    var rightEyeTextureView = new RenderTargetView(device, rightEyeTexture);

                    // Create Eye Depth Buffer
                    eyeTextureDescription.BindFlags = BindFlags.DepthStencil;
                    eyeTextureDescription.Format    = Format.D32_Float;

                    var eyeDepth     = new Texture2D(device, eyeTextureDescription);
                    var eyeDepthView = new DepthStencilView(device, eyeDepth);

                    Shapes.Cube.Load(device);
                    Shapes.Sphere.Load(device);
                    Shaders.Position.Load(device);
                    Shaders.Normal.Load(device);
                    Shaders.NormalTexture.Load(device);

                    // Load Controller Models
                    foreach (var controller in controllers)
                    {
                        var model = controllerModels[controller];

                        controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription
                        {
                            BindFlags   = BindFlags.VertexBuffer,
                            SizeInBytes = (int)model.unVertexCount * 32
                        });

                        controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0);

                        controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription
                        {
                            BindFlags   = BindFlags.IndexBuffer,
                            SizeInBytes = (int)model.unTriangleCount * 3 * 2
                        });

                        var texture = controllerTextures[controller];

                        using (var texture2d = new Texture2D(device, new Texture2DDescription
                        {
                            ArraySize = 1,
                            BindFlags = BindFlags.ShaderResource,
                            Format = Format.R8G8B8A8_UNorm,
                            Width = texture.unWidth,
                            Height = texture.unHeight,
                            MipLevels = 1,
                            SampleDescription = new SampleDescription(1, 0)
                        }, new DataRectangle(texture.rubTextureMapData, texture.unWidth * 4)))
                            controllerTextureViews[controller] = new ShaderResourceView(device, texture2d);
                    }

                    worldViewProjectionBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf <Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);

                    var rasterizerStateDescription = RasterizerStateDescription.Default();
                    //rasterizerStateDescription.FillMode = FillMode.Wireframe;
                    rasterizerStateDescription.IsFrontCounterClockwise = true;
                    //rasterizerStateDescription.CullMode = CullMode.None;

                    rasterizerState = new RasterizerState(device, rasterizerStateDescription);

                    var blendStateDescription = BlendStateDescription.Default();

                    blendStateDescription.RenderTarget[0].BlendOperation   = BlendOperation.Add;
                    blendStateDescription.RenderTarget[0].SourceBlend      = BlendOption.SourceAlpha;
                    blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha;

                    blendStateDescription.RenderTarget[0].IsBlendEnabled = false;

                    blendState = new BlendState(device, blendStateDescription);

                    var depthStateDescription = DepthStencilStateDescription.Default();

                    depthStateDescription.DepthComparison  = Comparison.LessEqual;
                    depthStateDescription.IsDepthEnabled   = true;
                    depthStateDescription.IsStencilEnabled = false;

                    depthStencilState = new DepthStencilState(device, depthStateDescription);

                    var samplerStateDescription = SamplerStateDescription.Default();

                    samplerStateDescription.Filter   = Filter.MinMagMipLinear;
                    samplerStateDescription.AddressU = TextureAddressMode.Wrap;
                    samplerStateDescription.AddressV = TextureAddressMode.Wrap;

                    samplerState = new SamplerState(device, samplerStateDescription);

                    startTime  = DateTime.Now;
                    frame      = 0;
                    windowSize = form.ClientSize;

                    backgroundColor = new RawColor4(0.1f, 0.1f, 0.1f, 1);

                    var vrEvent   = new VREvent_t();
                    var eventSize = (uint)Utilities.SizeOf <VREvent_t>();

                    head = Matrix.Identity;

                    // Initialize Audio
                    var audioSamples = 1024;

                    var audioDevices = DirectSoundCapture.GetDevices();

                    //var audioCapture = new DirectSoundCapture(devices.OrderByDescending(d => d.Description.Contains("Mic")).First().DriverGuid);
                    var audioCapture = new DirectSoundCapture(audioDevices.OrderByDescending(d => d.Description.Contains("Mix")).First().DriverGuid);

                    var audioFormat = new WaveFormat();
                    var audioLength = audioFormat.ConvertLatencyToByteSize(24);

                    var audioData     = new byte[audioLength];
                    var audioPosition = 0;

                    var leftWaveForm  = new float[1024 * 8];
                    var rightWaveForm = new float[1024 * 8];

                    for (var sample = 0; sample < 1024; sample++)
                    {
                        leftWaveForm[(sample * 8) + 0]  = -1.0f + ((float)sample / 512.0f);
                        rightWaveForm[(sample * 8) + 0] = -1.0f + ((float)sample / 512.0f);
                    }

                    var audioBuffer = new CaptureBuffer(audioCapture, new CaptureBufferDescription
                    {
                        BufferBytes = audioLength,
                        Format      = audioFormat
                    });

                    audioBuffer.Start(true);

                    var waveFormBufferDescription = new BufferDescription
                    {
                        BindFlags      = BindFlags.VertexBuffer,
                        SizeInBytes    = leftWaveForm.Length * sizeof(float),
                        CpuAccessFlags = CpuAccessFlags.Write,
                        Usage          = ResourceUsage.Dynamic
                    };

                    var leftWaveFormVertexBuffer  = SharpDX.Direct3D11.Buffer.Create(device, leftWaveForm, waveFormBufferDescription);
                    var rightWaveFormVertexBuffer = SharpDX.Direct3D11.Buffer.Create(device, rightWaveForm, waveFormBufferDescription);

                    var leftWaveFormVertexBufferBinding  = new VertexBufferBinding(leftWaveFormVertexBuffer, 8 * sizeof(float), 0);
                    var rightWaveFormVertexBufferBinding = new VertexBufferBinding(rightWaveFormVertexBuffer, 8 * sizeof(float), 0);

                    RenderLoop.Run(form, () =>
                    {
                        if (audioBuffer.CurrentCapturePosition != audioBuffer.CurrentRealPosition)
                        {
                            audioBuffer.Read(audioData, 0, audioData.Length, 0, LockFlags.None);

                            for (var sample = 0; sample < 1024; sample++)
                            {
                                leftWaveForm[(sample * 8) + 1]  = -BitConverter.ToInt16(audioData, sample * 4) / (float)short.MinValue;
                                rightWaveForm[(sample * 8) + 1] = -BitConverter.ToInt16(audioData, (sample * 4) + 2) / (float)short.MinValue;
                            }

                            DataStream stream;

                            context.MapSubresource(leftWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream);

                            stream.WriteRange(leftWaveForm);

                            context.UnmapSubresource(leftWaveFormVertexBuffer, 0);

                            stream.Dispose();

                            context.MapSubresource(rightWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream);

                            stream.WriteRange(rightWaveForm);

                            context.UnmapSubresource(rightWaveFormVertexBuffer, 0);

                            stream.Dispose();
                        }

                        audioPosition += 8;

                        if (audioPosition >= leftWaveForm.Length)
                        {
                            audioPosition = 0;
                        }

                        while (system.PollNextEvent(ref vrEvent, eventSize))
                        {
                            switch ((EVREventType)vrEvent.eventType)
                            {
                            case EVREventType.VREvent_TrackedDeviceActivated:
                                var controller = vrEvent.trackedDeviceIndex;

                                controllers.Add(controller);

                                var modelName     = new StringBuilder(255, 255);
                                var propertyError = ETrackedPropertyError.TrackedProp_Success;

                                var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError);

                                if (propertyError == ETrackedPropertyError.TrackedProp_Success)
                                {
                                    var modelName2 = modelName.ToString();

                                    while (true)
                                    {
                                        var pointer    = IntPtr.Zero;
                                        var modelError = EVRRenderModelError.None;

                                        modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer);

                                        if (modelError == EVRRenderModelError.Loading)
                                        {
                                            continue;
                                        }

                                        if (modelError == EVRRenderModelError.None)
                                        {
                                            var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer);

                                            controllerModels[controller] = renderModel;

                                            // Load Controller Model
                                            var model = controllerModels[controller];

                                            controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription
                                            {
                                                BindFlags   = BindFlags.VertexBuffer,
                                                SizeInBytes = (int)model.unVertexCount * 32
                                            });

                                            controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0);

                                            controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription
                                            {
                                                BindFlags   = BindFlags.IndexBuffer,
                                                SizeInBytes = (int)model.unTriangleCount * 3 * 2
                                            });

                                            break;
                                        }
                                    }

                                    while (true)
                                    {
                                        var pointer      = IntPtr.Zero;
                                        var textureError = EVRRenderModelError.None;

                                        textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer);

                                        if (textureError == EVRRenderModelError.Loading)
                                        {
                                            continue;
                                        }

                                        if (textureError == EVRRenderModelError.None)
                                        {
                                            var textureMap = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer);

                                            controllerTextures[controller] = textureMap;

                                            using (var texture2d = new Texture2D(device, new Texture2DDescription
                                            {
                                                ArraySize = 1,
                                                BindFlags = BindFlags.ShaderResource,
                                                Format = Format.R8G8B8A8_UNorm,
                                                Width = textureMap.unWidth,
                                                Height = textureMap.unHeight,
                                                MipLevels = 1,
                                                SampleDescription = new SampleDescription(1, 0)
                                            }, new DataRectangle(textureMap.rubTextureMapData, textureMap.unWidth * 4)))
                                                controllerTextureViews[controller] = new ShaderResourceView(device, texture2d);

                                            break;
                                        }
                                    }
                                }
                                break;

                            case EVREventType.VREvent_TrackedDeviceDeactivated:
                                controllers.RemoveAll(c => c == vrEvent.trackedDeviceIndex);
                                break;

                            default:
                                System.Diagnostics.Debug.WriteLine((EVREventType)vrEvent.eventType);
                                break;
                            }
                        }

                        if (form.ClientSize != windowSize)
                        {
                            Utilities.Dispose(ref backBufferView);

                            if (form.ClientSize.Width != 0 && form.ClientSize.Height != 0)
                            {
                                swapChain.ResizeBuffers(1, form.ClientSize.Width, form.ClientSize.Height, Format.B8G8R8A8_UNorm, SwapChainFlags.None);

                                using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0))
                                    backBufferView = new RenderTargetView(device, backBuffer);
                            }

                            windowSize = form.ClientSize;
                        }

                        // Update Device Tracking
                        compositor.WaitGetPoses(currentPoses, nextPoses);

                        if (currentPoses[headset].bPoseIsValid)
                        {
                            Convert(ref currentPoses[headset].mDeviceToAbsoluteTracking, ref head);
                        }

                        foreach (var controller in controllers)
                        {
                            var controllerMatrix = Matrix.Identity;

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref controllerMatrix);
                        }

                        // Render Left Eye
                        context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height);
                        context.OutputMerger.SetTargets(eyeDepthView, leftEyeTextureView);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.ClearRenderTargetView(leftEyeTextureView, backgroundColor);
                        context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0);

                        Shaders.Normal.Apply(context);

                        context.Rasterizer.State = rasterizerState;

                        context.OutputMerger.SetBlendState(blendState);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.PixelShader.SetSampler(0, samplerState);

                        var ratio = (float)headsetSize.Width / (float)headsetSize.Height;

                        var projection = leftEyeProjection;
                        var view       = Matrix.Invert(leftEyeView * head);
                        var world      = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                        //Shapes.Cube.Begin(context);
                        //Shapes.Cube.Draw(context);

                        Shapes.Sphere.Begin(context);
                        Shapes.Sphere.Draw(context);

                        // Draw Controllers
                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

                        Shaders.NormalTexture.Apply(context);

                        context.PixelShader.SetSampler(0, samplerState);

                        foreach (var controller in controllers)
                        {
                            context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]);
                            context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0);

                            context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]);

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world);

                            world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world;

                            worldViewProjection = world * view * projection;

                            context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                            context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                            context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0);
                        }

                        // Draw Waveforms
                        Shaders.Position.Apply(context);

                        world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip;

                        context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding);

                        context.Draw(1024, 0);

                        world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding);

                        context.Draw(1024, 0);

                        // Present Left Eye
                        var texture = new Texture_t
                        {
                            eType       = ETextureType.DirectX,
                            eColorSpace = EColorSpace.Gamma,
                            handle      = leftEyeTextureView.Resource.NativePointer
                        };

                        var bounds = new VRTextureBounds_t
                        {
                            uMin = 0.0f,
                            uMax = 1.0f,
                            vMin = 0.0f,
                            vMax = 1.0f,
                        };

                        var submitError = compositor.Submit(EVREye.Eye_Left, ref texture, ref bounds, EVRSubmitFlags.Submit_Default);

                        if (submitError != EVRCompositorError.None)
                        {
                            System.Diagnostics.Debug.WriteLine(submitError);
                        }

                        // Render Right Eye
                        context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height);
                        context.OutputMerger.SetTargets(eyeDepthView, rightEyeTextureView);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.ClearRenderTargetView(rightEyeTextureView, backgroundColor);
                        context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0);

                        Shaders.Normal.Apply(context);

                        context.Rasterizer.State = rasterizerState;

                        context.OutputMerger.SetBlendState(blendState);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.PixelShader.SetSampler(0, samplerState);

                        projection = rightEyeProjection;
                        view       = Matrix.Invert(rightEyeView * head);
                        world      = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                        //Shapes.Cube.Begin(context);
                        //Shapes.Cube.Draw(context);

                        Shapes.Sphere.Begin(context);
                        Shapes.Sphere.Draw(context);

                        // Draw Controllers
                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

                        Shaders.NormalTexture.Apply(context);

                        context.PixelShader.SetSampler(0, samplerState);

                        foreach (var controller in controllers)
                        {
                            context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]);
                            context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0);

                            context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]);

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world);

                            world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world;

                            worldViewProjection = world * view * projection;

                            context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                            context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                            context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0);
                        }

                        // Draw Waveforms
                        Shaders.Position.Apply(context);

                        world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip;

                        context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding);

                        context.Draw(1024, 0);

                        world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding);

                        context.Draw(1024, 0);

                        // Present Right Eye
                        texture.handle = rightEyeTextureView.Resource.NativePointer;

                        submitError = compositor.Submit(EVREye.Eye_Right, ref texture, ref bounds, EVRSubmitFlags.Submit_Default);

                        if (submitError != EVRCompositorError.None)
                        {
                            System.Diagnostics.Debug.WriteLine(submitError);
                        }

                        // Render Window
                        context.Rasterizer.SetViewport(0, 0, windowSize.Width, windowSize.Height);

                        context.OutputMerger.SetTargets(depthStencilView, backBufferView);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.ClearRenderTargetView(backBufferView, backgroundColor);
                        context.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0);

                        Shaders.Normal.Apply(context);

                        context.Rasterizer.State = rasterizerState;

                        context.OutputMerger.SetBlendState(blendState);
                        context.OutputMerger.SetDepthStencilState(depthStencilState);

                        context.PixelShader.SetSampler(0, samplerState);

                        ratio = (float)form.ClientSize.Width / (float)form.ClientSize.Height;

                        projection = Matrix.PerspectiveFovRH(3.14f / 3.0f, ratio, 0.01f, 1000);
                        view       = Matrix.Invert(head);
                        world      = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                        //Shapes.Cube.Begin(context);
                        //Shapes.Cube.Draw(context);

                        Shapes.Sphere.Begin(context);
                        Shapes.Sphere.Draw(context);

                        // Draw Controllers
                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

                        Shaders.NormalTexture.Apply(context);

                        context.PixelShader.SetSampler(0, samplerState);

                        foreach (var controller in controllers)
                        {
                            context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]);
                            context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0);

                            Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world);

                            world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world;

                            worldViewProjection = world * view * projection;

                            context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                            context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer);

                            context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0);
                        }

                        // Draw Waveforms
                        Shaders.Position.Apply(context);

                        world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip;

                        context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding);

                        context.Draw(1024, 0);

                        world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1);

                        worldViewProjection = world * view * projection;

                        context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer);

                        context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding);

                        context.Draw(1024, 0);

                        // Show Backbuffer
                        swapChain.Present(0, PresentFlags.None);
                    });
                }
        }
    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);
    }