Ejemplo n.º 1
0
        // Update is called once per frame
        private void Update()
        {
            try
            {
                Performance.Enter("SM.Update");

                if (!NodeLock.TryLockEdit(30))      // 30 msek allow latency of other pending editor
                {
                    Message.Send(ID, MessageLevel.DEBUG, "Lock contention detected! NodeLock::TryLockEdit() FRAME LOST");

                    // We failed to refresh scene in reasonable time but we still need to issue updates;

                    Performance.Enter("SM.Update.PreTraverse");
                    if (SceneManagerCamera != null)
                    {
                        SceneManagerCamera.PreTraverse();
                    }
                    OnPreTraverse?.Invoke();
                    Performance.Leave();

                    return;
                }

                try // We are now locked in edit
                {
                    Performance.Enter("SM.ProcessPendingUpdates");
                    ProcessPendingUpdates();
                }
                finally
                {
                    Performance.Leave();

                    NodeLock.UnLock();
                }

                // Notify about we are starting to traverse -----------------------

                Performance.Enter("SM.Update.PreTraverse");
                if (SceneManagerCamera != null)
                {
                    SceneManagerCamera.PreTraverse();
                }
                OnPreTraverse?.Invoke();
                Performance.Leave();

                // Check if camera present ---------------------------------------

                if (SceneManagerCamera == null)
                {
                    return;
                }


                // ---------------------------------------------------------------

                var UnityCamera = SceneManagerCamera.Camera;

                if (UnityCamera == null)
                {
                    return;
                }

                if (!NodeLock.TryLockRender(30))    // 30 millisek latency allowed
                {
                    Message.Send(ID, MessageLevel.DEBUG, "Lock contention detected! NodeLock::TryLockRender() FRAME LOST");
                    return;
                }

                try // We are now locked in read
                {
                    // Transfer camera parameters

                    PerspCamera perspCamera = _native_camera as PerspCamera;

                    if (perspCamera != null)
                    {
                        perspCamera.VerticalFOV   = UnityCamera.fieldOfView;
                        perspCamera.HorizontalFOV = 2 * Mathf.Atan(Mathf.Tan(UnityCamera.fieldOfView * Mathf.Deg2Rad / 2) * UnityCamera.aspect) * Mathf.Rad2Deg;;
                        perspCamera.NearClipPlane = UnityCamera.nearClipPlane;
                        perspCamera.FarClipPlane  = UnityCamera.farClipPlane;
                    }

                    Matrix4x4 unity_camera_transform = UnityCamera.transform.worldToLocalMatrix;

                    _native_camera.Transform = unity_camera_transform.ToZFlippedMatrix4();

                    _native_camera.Position = SceneManagerCamera.GlobalPosition;

                    _native_camera.Render(_native_context, 1000, 1000, 1000, _native_traverse_action);

#if DEBUG_CAMERA
                    _native_camera.DebugRefresh();
#endif
                }
                finally
                {
                    NodeLock.UnLock();
                }

                UpdateNodeInternals();

                // -------------------------------------------------------------
            }
            finally
            {
                // Notify about we are ready in traverse -----------------------

                Performance.Enter("SM.Update.PostTraverse");
                if (SceneManagerCamera != null)
                {
                    SceneManagerCamera.PostTraverse();
                }
                OnPostTraverse?.Invoke();
                Performance.Leave();

                // Leave Scm update -------------------------------------------
                Performance.Leave();
            }
        }