Exemplo n.º 1
0
        private static bool CompositorReadyCheck()
        {
            var isCompositorReady = false;

            UnityFuncs.IsCompositorReady(ref isCompositorReady);
            return(isCompositorReady);
        }
Exemplo n.º 2
0
        internal static void UnregisterInterface(FoveInterface xface)
        {
            var unregisteredMatch = m_sUnregisteredInterfaces.FirstOrDefault(i => i.xface == xface);

            if (unregisteredMatch != null)
            {
                m_sUnregisteredInterfaces.Remove(unregisteredMatch);
            }

            var layerIds = m_sInterfaceStacks.Keys.ToList();

            foreach (var layerId in layerIds)
            {
                var interfaces      = m_sInterfaceStacks[layerId];
                var registeredMatch = interfaces.FirstOrDefault(i => i.xface == xface);
                if (registeredMatch != null)
                {
                    interfaces.Remove(registeredMatch);
                }

                if (interfaces.Count == 0)
                {
                    UnityFuncs.DeleteLayer(layerId);
                    m_sInterfaceStacks.Remove(layerId);
                }
            }
        }
Exemplo n.º 3
0
        private static void RegisterHelper(InterfaceInfo reg)
        {
            var layerId = UnityFuncs.GetLayerForCreateInfo(reg.info);

            if (!m_sInterfaceStacks.ContainsKey(layerId))
            {
                m_sInterfaceStacks.Add(layerId, new List <InterfaceInfo>());
            }

            var theStack = m_sInterfaceStacks[layerId];

            if (theStack.Contains(reg))
            {
                return;
            }

            int idx = theStack.Count;

            for (int i = 0; i < theStack.Count; ++i)
            {
                if (theStack[i].xface.Camera.depth > reg.xface.Camera.depth)
                {
                    idx = i;
                    break;
                }
            }

            theStack.Insert(idx, reg);
        }
Exemplo n.º 4
0
        private EyeTextures GetEyeTextures(int layerId)
        {
            EyeTextures result;

            Vec2i dims = new Vec2i(1, 1);

            UnityFuncs.GetIdealLayerDimensions(layerId, ref dims);

            dims.x = (int)(dims.x * renderScale);
            dims.y = (int)(dims.y * renderScale);

            if (eyeTextures.ContainsKey(layerId))
            {
                result = eyeTextures[layerId];

                if (dims.x != result.left.width || dims.y != result.left.height)
                {
                    result = MakeNewEyeTextures(layerId, dims);
                }
            }
            else
            {
                result = MakeNewEyeTextures(layerId, dims);
            }

            return(result);
        }
Exemplo n.º 5
0
        void Awake()
        {
            worldScale  = FoveSettings.WorldScale;
            renderScale = FoveSettings.RenderScale;

            headset.GazeCastPolicy = FoveSettings.GazeCastPolicy;

            UnityFuncs.ResetNativeState();
            screenBlitMaterial = new Material(Shader.Find("Fove/EyeShader"));

            if (FoveSettings.AutomaticObjectRegistration)
            {
                GazableObject.CreateFromSceneColliders();
            }
        }
Exemplo n.º 6
0
        /*******************************************************************************\
        * MonoBehaviour / instance methods                                            *
        \*******************************************************************************/
        private FoveManager()
        {
            if (sInstance != null)
            {
                Debug.LogError("Found an existing instance");
            }

            var logSinkDelegatePtr = Marshal.GetFunctionPointerForDelegate(logSinkDelegate);

            UnityFuncs.SetLogSinkFunction(logSinkDelegatePtr);

            headset = new Headset(currentCapabilities);

            submitNativeFunc          = UnityFuncs.GetSubmitFunctionPtr();
            wfrpNativeFunc            = UnityFuncs.GetWfrpFunctionPtr();
            updateMirrorTexNativeFunc = UnityFuncs.GetUpdateMirrorTexPtrFunctionPtr();
        }
Exemplo n.º 7
0
        private void UpdateCapabilities()
        {
            var newCapabilities = ComputeInterfacesCapabilities() | enforcedCapabilities;

            if (currentCapabilities != newCapabilities)
            {
                var removedCaps = currentCapabilities & ~newCapabilities;
                if (removedCaps != ClientCapabilities.None)
                {
                    UnityFuncs.UnregisterCapabilities(removedCaps);
                    Headset.UnregisterCapabilities(removedCaps);
                }

                var addedCaps = newCapabilities & ~currentCapabilities;
                if (addedCaps != ClientCapabilities.None)
                {
                    UnityFuncs.RegisterCapabilities(addedCaps);
                    Headset.RegisterCapabilities(addedCaps);
                }

                currentCapabilities = newCapabilities;
            }
        }
Exemplo n.º 8
0
        private bool UpdateHmdDataInternal()
        {
            var isHmdConnectedChanged = false;

            // First chech and update the HMD connection status
            // If the HMD happens to be disconnected we trigger the associated event and abort the update process
            // If the HMD status changed to connected, we delay the trigger of the associated event after the update of other data
            {
                var isHmdConnected = Headset.IsHardwareConnected();
                if (isHmdConnected.error == ErrorCode.Hardware_Disconnected) // this returns an error whereas it is was we are querying, so we just ignore it...
                {
                    isHmdConnected.error = ErrorCode.None;
                }

                if (isHmdConnected != wasHardwareConnected)
                {
                    isHmdConnectedChanged = true;
                    wasHardwareConnected  = isHmdConnected;
                    if (!isHmdConnected)
                    {
                        // trigger the hmd disconnected event before returning
                        var handler = HardwareDisconnected;
                        if (handler != null)
                        {
                            handler.Invoke();
                        }

                        return(false); // abort the update and mark it as failure
                    }
                }
            }

            // Fetch the new eye tracking data from the service
            var fetchResult = Headset.FetchEyeTrackingData();

            if (fetchResult.error == ErrorCode.Connect_NotConnected)
            {
                return(false);
            }

            // Fetch the new pose data from the service
            fetchResult = Headset.FetchPoseData();
            if (fetchResult.error == ErrorCode.Connect_NotConnected)
            {
                return(false);
            }

            // HMD pose
            // It is taken from the UnityFunction native plugin to be sure to return
            // the same pose as the one used to perform the rendering
            hmdPose          = UnityFuncs.GetLastPose();
            headPosition     = hmdPose.position.ToVector3() * worldScale;
            standingPosition = hmdPose.standingPosition.ToVector3() * worldScale;
            headRotation     = hmdPose.orientation.ToQuaternion();

            // Update the eyes & position textures
            TryUpdateTexture(Headset.GetEyesImage, ref eyesImage, ref eyesTexture);
            TryUpdateTexture(Headset.GetPositionImage, ref positionImage, ref positionTexture);

            // update the mirror texture native pointer if is exists
            // we need this update because of the rolling buffer
            if (mirrorTexture.value != null)
            {
                int    dummy;
                IntPtr texPtr;
                GetMirrorTexturePtr(out texPtr, out dummy, out dummy);
                mirrorTexture.value.UpdateExternalTexture(texPtr);
            }

            // Call user custom data update callbacks
            var addInUpdateCallback = AddInUpdate;

            if (addInUpdateCallback != null)
            {
                addInUpdateCallback();
            }

            // Trigger the event callbacks now that have updated all the HMD data
            if (isHmdConnectedChanged)
            {
                if (!wasHardwareConnected)
                {
                    throw new Exception("Internal error: Unexpected hmd connection status");
                }

                var handler = HardwareConnected;
                if (handler != null)
                {
                    handler.Invoke();
                }
            }

            var hwdReady = IsHardwareReady();

            if (hwdReady.IsValid && wasHardwareReady != hwdReady)
            {
                wasHardwareReady = hwdReady;
                var handler = hwdReady ? HardwareIsReady : null;
                if (handler != null)
                {
                    handler.Invoke();
                }
            }

            var isCalibrating = IsEyeTrackingCalibrating();

            if (isCalibrating.IsValid && isCalibrating != wasCalibrating)
            {
                if (wasCalibrating)
                {
                    var handler = EyeTrackingCalibrationStarted;
                    if (handler != null)
                    {
                        handler.Invoke();
                    }
                }
                else
                {
                    var handler = EyeTrackingCalibrationEnded;
                    if (handler != null)
                    {
                        handler.Invoke(GetEyeTrackingCalibrationState());
                    }
                }
                wasCalibrating = isCalibrating;
            }

            var userAttention = IsUserShiftingAttention();

            if (userAttention.IsValid && wasShiftingAttention != userAttention)
            {
                wasShiftingAttention = userAttention;
                var handler = IsUserShiftingAttentionChanged;
                if (handler != null)
                {
                    handler.Invoke(wasShiftingAttention);
                }
            }

            UpdateEyeState(Eye.Left);
            UpdateEyeState(Eye.Right);

            var userPresent = IsUserPresent();

            if (userPresent.IsValid && wasUserPresent != userPresent)
            {
                wasUserPresent = userPresent;
                var handler = UserPresenceChanged;
                if (handler != null)
                {
                    handler.Invoke(wasUserPresent);
                }
            }

            var adjusmentGuiVisible = IsHmdAdjustmentGuiVisible();

            if (adjusmentGuiVisible.IsValid && wasHmdAdjustmentVisible != adjusmentGuiVisible)
            {
                wasHmdAdjustmentVisible = adjusmentGuiVisible;
                var handler = HmdAdjustmentGuiVisibilityChanged;
                if (handler != null)
                {
                    handler.Invoke(wasHmdAdjustmentVisible);
                }
            }

            return(true);
        }
Exemplo n.º 9
0
        private IEnumerator FoveUpdateCoroutine()
        {
            if (FoveSettings.ShouldForceCalibration)
            {
                StartEyeTrackingCalibration(new CalibrationOptions {
                    lazy = true
                });
            }

            var endOfFrameWait = new WaitForEndOfFrame();

            while (Application.isPlaying)
            {
                // update the headset capabilities if changed
                UpdateCapabilities();

                if (!UpdateHmdDataInternal()) // hmd got disconnected
                {
                    break;
                }

                // Don't do any rendering code (below) if the compositor isn't ready
                if (!CompositorReadyCheck())
                {
                    yield return(endOfFrameWait);

                    continue;
                }

                // On first run and in case any new FoveInterfaces have been created
                if (m_sUnregisteredInterfaces.Count > 0)
                {
                    foreach (var reg in m_sUnregisteredInterfaces)
                    {
                        RegisterHelper(reg);
                    }
                    m_sUnregisteredInterfaces.Clear();
                }

                // Render all cameras, one eye at a time
                RenderTexture oldCurrent = RenderTexture.active;
                foreach (var list in m_sInterfaceStacks)
                {
                    if (list.Value.Count == 0)
                    {
                        continue;
                    }

                    int layerId = list.Key;
                    var eyeTx   = GetEyeTextures(layerId);

                    UnityFuncs.SetPoseForSubmit(layerId, hmdPose);

                    if (eyeTx.areNew)
                    {
                        var texPtrLeft  = eyeTx.left.GetNativeTexturePtr();
                        var texPtrRight = eyeTx.right.GetNativeTexturePtr();

                        // texture native ptr get valid only after first flush
                        if (texPtrLeft != IntPtr.Zero && texPtrRight != IntPtr.Zero)
                        {
                            UnityFuncs.SetLeftEyeTexture(layerId, texPtrLeft);
                            UnityFuncs.SetRightEyeTexture(layerId, texPtrRight);
                            eyeTx.areNew = false;
                        }
                        else
                        {
                            // force the creation of the new render targets
                            Graphics.SetRenderTarget(eyeTx.left);
                            Graphics.SetRenderTarget(eyeTx.right);
                            GL.Flush();
                            break;
                        }
                    }

                    Graphics.SetRenderTarget(eyeTx.left);
                    GL.Clear(true, true, Color.clear);
                    Graphics.SetRenderTarget(eyeTx.right);
                    GL.Clear(true, true, Color.clear);

                    foreach (var interfaceInfo in list.Value)
                    {
                        interfaceInfo.xface.RenderEye(Eye.Left, eyeTx.left);
                        interfaceInfo.xface.RenderEye(Eye.Right, eyeTx.right);
                    }

                    GL.Flush();
                    GL.IssuePluginEvent(submitNativeFunc, layerId);

                    isBackendInitialized = true; // Submit implicitly initializes the backend

                    if (!FoveSettings.CustomDesktopView)
                    {
                        // this code works only because we only have one single layer (base) allowed for the moment
                        // TODO: Adapt this code as soon as we allow several layers
                        RenderTexture.active = oldCurrent;
                        screenBlitMaterial.SetTexture("_TexLeft", eyeTx.left);
                        screenBlitMaterial.SetTexture("_TexRight", eyeTx.right);
                        Graphics.Blit(null, screenBlitMaterial);
                    }
                }
                GL.Flush();

                if (!isBackendInitialized && isMirrorRequested)
                {
                    InitBackendExplicit();
                    isBackendInitialized = true;
                }

                // Wait for render pose
                GL.IssuePluginEvent(updateMirrorTexNativeFunc, 0);
                GL.IssuePluginEvent(wfrpNativeFunc, 0);

                yield return(endOfFrameWait);
            }

            StartCoroutine(CheckForHeadsetCoroutine());
        }
Exemplo n.º 10
0
 private void OnDestroy()
 {
     headset.Dispose();
     UnityFuncs.DestroyNativeResources();
 }