private void OpenInfoBar(object sender, RoutedEventArgs e)
        {
            if (_infoViewer == null)
            {
                _infoViewer         = new InfoViewer();
                _infoViewer.Loaded += (_s, _e) =>
                {
                    AddInfo("信息面板已激活");
                };
                _infoViewer.Closed += (_s, _e) =>
                {
                    AddInfo("关闭信息面板");
                    _infoViewer = null;
                };

                _infoViewer.Show();
            }

            try
            {
                _infoViewer.Activate();
            }
            catch
            {
            }
        }
示例#2
0
        private void Form1_Shown(object sender, EventArgs e)
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

            var model = ModelFiles.GetAfricanHeadModel();

            //var model = ModelFiles.GetDiabloModel();

            sw.Stop();

            var renderer = new ModelRenderer(new ShadowShaderRenderer(model, pictureBox1));

            //var renderer = new ModelRenderer(new NoToneShaderRenderer(model, pictureBox1));
            //var renderer = new ModelRenderer(new ToonShaderRenderer(model, pictureBox1));
            //var renderer = new ModelRenderer(new NormalMapShaderRenderer(model, pictureBox1));
            renderer.Render();

            InfoViewer.ShowDiagnosticInfo
                ($"Loading Time: {sw.Elapsed.TotalMilliseconds:f2} ms", new PointF(10, 10), Graphics.FromImage(pictureBox1.Image));

            InfoViewer.ShowDiagnosticInfo
                ($"Triangles Count: {model.FacesV.Count}", new PointF(10, 50), Graphics.FromImage(pictureBox1.Image));

            InfoViewer.ShowDiagnosticInfo
                ($"Resolution: {pictureBox1.Width} X {pictureBox1.Height}", new PointF(10, 70), Graphics.FromImage(pictureBox1.Image));
        }
示例#3
0
        /// <summary>
        /// Создает элемент управления для отображения ограничений заданного агрегата
        /// </summary>
        public TemplateDatailLimitationsMaxResourcesControl()
        {
            AutoSize              = true;
            AutoSizeMode          = AutoSizeMode.GrowAndShrink;
            maxResourcesInfo      = new InfoViewer(5);
            notifyWhenRemainsInfo = new InfoViewer(5);
            labelRemark           = new Label();
            //
            // maxResourcesInfo
            //
            maxResourcesInfo.LifeLengthViewers[0].ShowHeaders = true;
            maxResourcesInfo.Location        = new Point(0, 0);
            maxResourcesInfo.LabelTitle.Text = "Max resources";
            maxResourcesInfo.LeftHeaderWidth = 150;
            maxResourcesInfo.LifeLengthViewers[0].LeftHeader = "Since new";
            maxResourcesInfo.LifeLengthViewers[1].LeftHeader = "Since overhaul";
            maxResourcesInfo.LifeLengthViewers[2].LeftHeader = "Since inspection";
            maxResourcesInfo.LifeLengthViewers[3].LeftHeader = "Since shop visit";
            maxResourcesInfo.LifeLengthViewers[4].LeftHeader = "Since hot section " + "\r\n" + " inspection";
            maxResourcesInfo.LifeLengthViewers[4].Visible    = false;
            maxResourcesInfo.FirstLifelengthViewerLostFocusByShiftTabClicked = true;
            maxResourcesInfo.ShowMinutes = false;
            maxResourcesInfo.ReadOnly    = false;
            maxResourcesInfo.LastLifelengthViewerTabClicked       += maxResourcesInfo_LastLifelengthViewerTabClicked;
            maxResourcesInfo.FirstLifelengthViewerShiftTabClicked += maxResourcesInfo_FirstLifelengthViewerShiftTabClicked;
            maxResourcesInfo.LifelengthViewerLostFocus            += maxResourcesInfo_LifelengthViewerLostFocus;
            //
            // notifyWhenRemainsInfo
            //
            notifyWhenRemainsInfo.LifeLengthViewers[0].ShowHeaders = true;
            notifyWhenRemainsInfo.Location        = new Point(maxResourcesInfo.Right + 100, 0);
            notifyWhenRemainsInfo.LabelTitle.Text = "Notify when remains";
            notifyWhenRemainsInfo.LeftHeaderWidth = 150;
            notifyWhenRemainsInfo.LifeLengthViewers[0].LeftHeader           = "Since new";
            notifyWhenRemainsInfo.LifeLengthViewers[1].LeftHeader           = "Since overhaul";
            notifyWhenRemainsInfo.LifeLengthViewers[2].LeftHeader           = "Since inspection";
            notifyWhenRemainsInfo.LifeLengthViewers[3].LeftHeader           = "Since shop visit";
            notifyWhenRemainsInfo.LifeLengthViewers[4].LeftHeader           = "Since hot section " + "\r\n" + " inspection";
            notifyWhenRemainsInfo.LifeLengthViewers[4].Visible              = false;
            notifyWhenRemainsInfo.LastLifelengthViewerLostFocusByTabClicked = true;
            notifyWhenRemainsInfo.ShowMinutes = false;
            notifyWhenRemainsInfo.ReadOnly    = false;
            notifyWhenRemainsInfo.LastLifelengthViewerTabClicked       += notifyWhenRemainsInfo_LastLifelengthViewerTabClicked;
            notifyWhenRemainsInfo.FirstLifelengthViewerShiftTabClicked += notifyWhenRemainsInfo_FirstLifelengthViewerShiftTabClicked;
            //
            // labelRemark
            //
            labelRemark.AutoSize  = true;
            labelRemark.Font      = Css.OrdinaryText.Fonts.RegularFont;
            labelRemark.ForeColor = Css.OrdinaryText.Colors.ForeColor;
            labelRemark.Text      = "Use double click to set applicability of the field";

            Controls.Add(maxResourcesInfo);
            Controls.Add(notifyWhenRemainsInfo);
            Controls.Add(labelRemark);

            labelRemark.Location = new Point(0, maxResourcesInfo.Bottom + 20);
        }
        /// <summary>
        /// Создает элемент управления для задания ограничений <see cref="MaintenanceDirective"/>
        /// </summary>
        /// <param name="directive">Директива</param>
        public MaintenanceStatusLimitationsControl(MaintenanceDirective directive)
        {
            this.directive         = directive;
            infoViewerMaxResource  = new InfoViewer(directive.Limitations.Length);
            infoViewerNotification = new InfoViewer(directive.Limitations.Length);
            for (int i = 0; i < directive.Limitations.Length; i++)
            {
                CheckBox checkBox = new CheckBox();
                checkBox.Font            = Css.OrdinaryText.Fonts.RegularFont;
                checkBox.ForeColor       = Css.OrdinaryText.Colors.ForeColor;
                checkBox.Location        = new Point(LEFT_MARGIN, TOP_MARGIN + i * checkBoxSize.Height);
                checkBox.Size            = checkBoxSize;
                checkBox.CheckedChanged += MaintenanceStatusLimitationsControl_CheckedChanged;
                checkBoxs.Add(checkBox);
            }
            //
            // infoViewerMaxResource
            //
            infoViewerMaxResource.Location = new Point(LEFT_MARGIN + checkBoxSize.Width, 0);
            infoViewerMaxResource.LifeLengthViewers[0].ShowHeaders = true;
            infoViewerMaxResource.LeftHeaderWidth = 0;
            infoViewerMaxResource.LabelTitle.Text = "Maintenance Intervals";
            infoViewerMaxResource.FirstLifelengthViewerLostFocusByShiftTabClicked = true;
            infoViewerMaxResource.ShowMinutes = false;
            infoViewerMaxResource.LastLifelengthViewerTabClicked       += maxResourcesInfo_LastLifelengthViewerTabClicked;
            infoViewerMaxResource.FirstLifelengthViewerShiftTabClicked += maxResourcesInfo_FirstLifelengthViewerShiftTabClicked;
            //
            // infoViewerNotification
            //
            infoViewerNotification.Location = new Point(infoViewerMaxResource.Right + WIDTH_INTERVAL, 0);
            infoViewerNotification.LifeLengthViewers[0].ShowHeaders = true;
            infoViewerNotification.LeftHeaderWidth = 0;
            infoViewerNotification.LabelTitle.Text = "Notification";
            infoViewerNotification.LastLifelengthViewerLostFocusByTabClicked = true;
            infoViewerNotification.ShowMinutes = false;
            infoViewerNotification.LastLifelengthViewerTabClicked       += notifyWhenRemainsInfo_LastLifelengthViewerTabClicked;
            infoViewerNotification.FirstLifelengthViewerShiftTabClicked += notifyWhenRemainsInfo_FirstLifelengthViewerShiftTabClicked;
            //
            // linkEditSubChecks
            //
            linkEditSubChecks.AutoSize = true;
            Css.SimpleLink.Adjust(linkEditSubChecks);
            linkEditSubChecks.Text                = "Edit Subchecks";
            linkEditSubChecks.Location            = new Point(LEFT_MARGIN_FOR_LINK, infoViewerMaxResource.Bottom + HEIGHT_INTERVAL);
            linkEditSubChecks.DisplayerRequested += linkEditSubChecks_DisplayerRequested;

            BackColor = Css.CommonAppearance.Colors.BackColor;
            AutoSize  = true;
            Controls.AddRange(checkBoxs.ToArray());
            Controls.Add(infoViewerMaxResource);
            Controls.Add(infoViewerNotification);
            Controls.Add(linkEditSubChecks);
        }
示例#5
0
        /// <summary>
        /// Создает элемент управления для отображения ограничений заданного агрегата
        /// </summary>
        public TemplateDatailLimitationsMaxResourcesControl()
        {
            AutoSize              = true;
            AutoSizeMode          = AutoSizeMode.GrowAndShrink;
            maxResourcesInfo      = new InfoViewer();
            notifyWhenRemainsInfo = new InfoViewer();
            labelRemark           = new Label();
            //
            // maxResourcesInfo
            //
            maxResourcesInfo.LifelengthViewer1.ShowHeaders = true;
            maxResourcesInfo.Location        = new Point(0, 0);
            maxResourcesInfo.LabelTitle.Text = "Max resources";
            maxResourcesInfo.LeftHeaderWidth = 150;
            maxResourcesInfo.LifelengthViewer1.LeftHeader = "Since new";
            maxResourcesInfo.LifelengthViewer2.LeftHeader = "Since overhaul";
            maxResourcesInfo.LifelengthViewer3.LeftHeader = "Since inspection";
            maxResourcesInfo.LifelengthViewer4.LeftHeader = "Since shop visit";
            maxResourcesInfo.LifelengthViewer5.LeftHeader = "Since hot section " + "\r\n" + " inspection";
            maxResourcesInfo.ReadOnly = false;
            //
            // notifyWhenRemainsInfo
            //
            notifyWhenRemainsInfo.LifelengthViewer1.ShowHeaders = true;
            notifyWhenRemainsInfo.Location        = new Point(maxResourcesInfo.Right + 100, 0);
            notifyWhenRemainsInfo.LabelTitle.Text = "Notify when remains";
            notifyWhenRemainsInfo.LeftHeaderWidth = 150;
            notifyWhenRemainsInfo.LifelengthViewer1.LeftHeader = "Since new";
            notifyWhenRemainsInfo.LifelengthViewer2.LeftHeader = "Since overhaul";
            notifyWhenRemainsInfo.LifelengthViewer3.LeftHeader = "Since inspection";
            notifyWhenRemainsInfo.LifelengthViewer4.LeftHeader = "Since shop visit";
            notifyWhenRemainsInfo.LifelengthViewer5.LeftHeader = "Since hot section " + "\r\n" + " inspection";
            notifyWhenRemainsInfo.ReadOnly = false;
            //
            // labelRemark
            //
            labelRemark.AutoSize  = true;
            labelRemark.Font      = Css.OrdinaryText.Fonts.RegularFont;
            labelRemark.ForeColor = Css.OrdinaryText.Colors.ForeColor;
            labelRemark.Text      = "Use double click to set applicability of the field";

            Controls.Add(maxResourcesInfo);
            Controls.Add(notifyWhenRemainsInfo);
            Controls.Add(labelRemark);

            labelRemark.Location = new Point(0, maxResourcesInfo.Bottom + 20);
        }
示例#6
0
        /// <summary>
        /// Создает элемент управления для задания ограничений <see cref="TemplateMaintenanceDirective"/>
        /// </summary>
        /// <param name="currentMaintenanceDirective">Maintenance Directive</param>
        public TemplateMaintenanceLimitationsControl(TemplateMaintenanceDirective currentMaintenanceDirective)
        {
            this.currentMaintenanceDirective = currentMaintenanceDirective;
            infoViewerMaxResource            = new InfoViewer(currentMaintenanceDirective.Limitations.Length);
            infoViewerNotification           = new InfoViewer(currentMaintenanceDirective.Limitations.Length);
            for (int i = 0; i < currentMaintenanceDirective.Limitations.Length; i++)
            {
                CheckBox checkBox = new CheckBox();
                checkBox.Font            = Css.OrdinaryText.Fonts.RegularFont;
                checkBox.ForeColor       = Css.OrdinaryText.Colors.ForeColor;
                checkBox.Location        = new Point(LEFT_MARGIN, TOP_MARGIN + i * checkBoxSize.Height);
                checkBox.Size            = checkBoxSize;
                checkBox.CheckedChanged += MaintenanceStatusLimitationsControl_CheckedChanged;
                checkBoxs.Add(checkBox);
            }
            //
            // infoViewerMaxResource
            //
            infoViewerMaxResource.Location = new Point(LEFT_MARGIN + checkBoxSize.Width, 0);
            infoViewerMaxResource.LifeLengthViewers[0].ShowHeaders = true;
            infoViewerMaxResource.ShowMinutes     = false;
            infoViewerMaxResource.LeftHeaderWidth = 0;
            infoViewerMaxResource.LabelTitle.Text = "Maintenance Intervals";
            infoViewerMaxResource.FirstLifelengthViewerLostFocusByShiftTabClicked = true;
            infoViewerMaxResource.LastLifelengthViewerTabClicked       += maxResourcesInfo_LastLifelengthViewerTabClicked;
            infoViewerMaxResource.FirstLifelengthViewerShiftTabClicked += maxResourcesInfo_FirstLifelengthViewerShiftTabClicked;
            //
            // infoViewerNotification
            //
            infoViewerNotification.Location = new Point(infoViewerMaxResource.Right + WIDTH_INTERVAL, 0);
            infoViewerNotification.LifeLengthViewers[0].ShowHeaders = true;
            infoViewerNotification.ShowMinutes     = false;
            infoViewerNotification.LeftHeaderWidth = 0;
            infoViewerNotification.LabelTitle.Text = "Notification";
            infoViewerNotification.LastLifelengthViewerLostFocusByTabClicked = true;
            infoViewerNotification.LastLifelengthViewerTabClicked           += notifyWhenRemainsInfo_LastLifelengthViewerTabClicked;
            infoViewerNotification.FirstLifelengthViewerShiftTabClicked     += notifyWhenRemainsInfo_FirstLifelengthViewerShiftTabClicked;

            BackColor = Css.CommonAppearance.Colors.BackColor;
            AutoSize  = true;
            Controls.AddRange(checkBoxs.ToArray());
            Controls.Add(infoViewerMaxResource);
            Controls.Add(infoViewerNotification);
        }
示例#7
0
        public void Render()
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

            DirectBitmap bitmap = new DirectBitmap(width, height);

            for (int i = 0; i < z_buffer.Length; i++)
            {
                z_buffer[i] = -float.MaxValue;
            }

            Rasterizer rasterizer = new Rasterizer();

            //// start of picture render by normal map shader ////
            var nm_shader = new NormalMappingShader(model, ViewPort, Projection, ModelView, light_dir);

            nm_shader.uniform_m   = Projection * ModelView;
            nm_shader.uniform_mit = (Projection * ModelView).Inverse().Transpose();

            for (int i = 0; i < model.FacesV.Count; i++)
            {
                Vector4[] screen_coords = new Vector4[3];
                for (int j = 0; j < model.FacesV[i].Length; j++)
                {
                    screen_coords[j] = nm_shader.Vertex(i, j);
                }

                rasterizer.Triangle(screen_coords, nm_shader, bitmap, pictureBox, z_buffer);
            }
            //// end of picture render by normal map shader ////

            sw.Stop();

            bitmap.Bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);

            InfoViewer.ShowDiagnosticInfo
                ($"Render Time: {sw.Elapsed.TotalMilliseconds:f2} ms", new PointF(10, 30), Graphics.FromImage(bitmap.Bitmap));

            // output final render
            pictureBox.Image = bitmap.Bitmap;
        }
示例#8
0
        private void InitializeComponents()
        {
            complianceDataInfo = new InfoViewer(4);
            //
            // labelIntrodactionDate
            //
            labelIntrodactionDate.AutoSize = true;
            Css.OrdinaryText.Adjust(labelIntrodactionDate);
            labelIntrodactionDate.Location = new Point(MARGIN + 7, MARGIN);
            labelIntrodactionDate.Text     = "Introdaction Date";
            //
            // dateTimePicker
            //
            dateTimePicker.Location      = new Point(MARGIN + 186, MARGIN);
            dateTimePicker.Width         = 180;
            dateTimePicker.Format        = DateTimePickerFormat.Custom;
            dateTimePicker.CustomFormat  = "dd.MM.yyyy";
            dateTimePicker.ValueChanged += dateTimePicker_ValueChanged;
            Css.OrdinaryText.Adjust(dateTimePicker);

            //
            // complianceDataInfo
            //
            complianceDataInfo.LabelTitle.Height = 0;
            complianceDataInfo.LifeLengthViewers[0].ShowHeaders = true;
            complianceDataInfo.LifeLengthViewers[1].Enabled     = false;
            complianceDataInfo.Location        = new Point(MARGIN, dateTimePicker.Bottom + 2 * MARGIN);
            complianceDataInfo.LeftHeaderWidth = 180;
            complianceDataInfo.LifeLengthViewers[0].LeftHeader = "Perfomance s/i.d";
            complianceDataInfo.LifeLengthViewers[1].LeftHeader = "Compliance Deadline";
            complianceDataInfo.LifeLengthViewers[2].LeftHeader = "Frequency";
            complianceDataInfo.LifeLengthViewers[3].LeftHeader = "Notify";
            complianceDataInfo.ReadOnly    = false;
            complianceDataInfo.ShowMinutes = false;

            BackColor = Css.CommonAppearance.Colors.BackColor;
            Controls.Add(labelIntrodactionDate);
            Controls.Add(dateTimePicker);
            Controls.Add(complianceDataInfo);
            Size = new Size(complianceDataInfo.Width + MARGIN, complianceDataInfo.Height + 4 * MARGIN + dateTimePicker.Height);
        }
示例#9
0
        public void Render()
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

            DirectBitmap bitmap = new DirectBitmap(width, height);

            Rasterizer rasterizer = new Rasterizer();

            //// start of picture render by toon shader ////
            var toon_shader = new GouraudShader(model, ViewPort, Projection, ModelView, light_dir);

            for (int i = 0; i < model.FacesV.Count; i++)
            {
                Vector4[] screen_coords = new Vector4[3];
                for (int j = 0; j < model.FacesV[i].Length; j++)
                {
                    screen_coords[j] = toon_shader.Vertex(i, j);
                }

                rasterizer.Triangle(screen_coords, toon_shader, bitmap, pictureBox, z_buffer);
            }
            //// end of picture render by toon shader ////

            sw.Stop();

            model.Texture.Dispose();
            bitmap.Bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);

            InfoViewer.ShowDiagnosticInfo
                ($"Render Time: {sw.Elapsed.TotalMilliseconds:f2} ms", new PointF(10, 30), Graphics.FromImage(bitmap.Bitmap));

            // output final render
            pictureBox.Image = bitmap.Bitmap;
        }
        public void Render()
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

            DirectBitmap bitmap = new DirectBitmap(width, height);

            Rasterizer rasterizer = new Rasterizer();

            //// start of shadow buffer rendering
            Matrix4x4 SB_ModelView  = Matrix4x4Extensions.LookAt(light_dir, center, up);
            Matrix4x4 SB_Projection = Matrix4x4.Identity;
            Matrix4x4 ViewPort      = Matrix4x4Extensions.Viewport(width / 8, height / 8, width * 3 / 4, height * 3 / 4);

            SB_Projection.M43 = 0;

            var shader = new DepthShader(model, ViewPort, SB_Projection, SB_ModelView);

            for (int i = 0; i < model.FacesV.Count; i++)
            {
                Vector4[] screen_coords = new Vector4[3];
                for (int j = 0; j < model.FacesV[i].Length; j++)
                {
                    screen_coords[j] = shader.Vertex(i, j);
                }

                rasterizer.Triangle(screen_coords, shader, bitmap, pictureBox, shadow_buffer, true);
            }
            //// end of shadow buffer rendering

            //// start of picture render by shadow shader ////
            Matrix4x4 M = ViewPort * SB_Projection * SB_ModelView;

            Matrix4x4 ModelView  = Matrix4x4Extensions.LookAt(eye, center, up);
            Matrix4x4 Projection = Matrix4x4.Identity;

            Projection.M43 = -1.0f / (eye - center).Norm();

            var sh_shader = new ShadowShader(model, ViewPort, Projection, ModelView, light_dir, shadow_buffer, width);

            sh_shader.uniform_m        = Projection * ModelView;
            sh_shader.uniform_mit      = sh_shader.uniform_m.Inverse().Transpose();
            sh_shader.uniform_m_shadow = M * (ViewPort * Projection * ModelView).Inverse();

            for (int i = 0; i < model.FacesV.Count; i++)
            {
                Vector4[] screen_coords = new Vector4[3];
                for (int j = 0; j < model.FacesV[i].Length; j++)
                {
                    screen_coords[j] = sh_shader.Vertex(i, j);
                }

                rasterizer.Triangle(screen_coords, sh_shader, bitmap, pictureBox, z_buffer);
            }
            //// end of picture render by shadow shader ////

            sw.Stop();

            model.Texture.Dispose();
            bitmap.Bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);

            InfoViewer.ShowDiagnosticInfo
                ($"Render Time: {sw.Elapsed.TotalMilliseconds:f2} ms", new PointF(10, 30), Graphics.FromImage(bitmap.Bitmap));

            // output final render
            pictureBox.Image = bitmap.Bitmap;
        }
示例#11
0
        public override void Update()
        {
            var deltaSeconds = Stopwatch.Elapsed.TotalSeconds;
            InfoViewer.Log("Client FPS", Math.Round(1f / deltaSeconds, 2).ToString());

            InfoViewer.Log("Roundtrip", _server?.Roundtrip.ToString());
            InfoViewer.Log("Roundtrip Varience", _server?.RoundtripVarience.ToString());

            Stopwatch.Restart();

            NetworkEvent networkEvent = _client.Poll();
            while (networkEvent.Type != NetworkEventType.Nothing)
            {
                switch (networkEvent.Type)
                {
                    case NetworkEventType.Connect:
                        _server = networkEvent.Connection;
                        break;
                    case NetworkEventType.Data:
                        var diff = _messageTimer.Elapsed.TotalMilliseconds;
                        //InfoViewer.Values["Message Time"] = Math.Round(diff, 4).ToString();
                        _messageTimer.Restart();
                        MessageRecieved(networkEvent.Data);
                        break;
                }
                networkEvent.Recycle();
                networkEvent = _client.Poll();
            }

            _imGuiRenderer.Update((float)deltaSeconds, _window.InputSnapshot);
            var imGuiWantsMouse = ImGuiNET.ImGui.GetIO().WantCaptureMouse;

            var cameraEntities = _camerasSet.GetEntities();
            var cameraTransform = cameraEntities.Length > 0 ? cameraEntities[0].Get<Transform>() : new Transform();

            var inputTrackerTransform = Matrix3x2.CreateTranslation(-_window.Width / 2f, -_window.Height / 2f) *
                Matrix3x2.CreateScale(1 / Settings.GRAPHICS_SCALE, -1 / Settings.GRAPHICS_SCALE) *
                Matrix3x2.CreateScale(1 / _zoom) *
                cameraTransform.Matrix;

            _cameraSpaceInputTracker.SetTransform(inputTrackerTransform);
            _cameraSpaceGameInputTracker.SetActive(!imGuiWantsMouse);

            _zoom += _window.InputSnapshot.WheelDelta * 0.1f;

            PreUpdate(deltaSeconds);
            Scene.Update(new LogicUpdate((float)deltaSeconds, _cameraSpaceGameInputTracker));
            PostUpdate(deltaSeconds);

            var serverMessages = new List<object>();

            _editorMenu.Run(new EditorUpdate()
            {
                CameraSpaceInput = _cameraSpaceInputTracker,
                CameraSpaceGameInput = _cameraSpaceGameInputTracker,
                Scene = Scene,
                ServerMessages = serverMessages
            });

            var clientUpdate = new ClientSystemUpdate()
            {
                Messages = serverMessages,
                Input = _cameraSpaceGameInputTracker
            };

            foreach (var system in _clientSystems)
            {
                system.Update(clientUpdate);
            }

            if(_server != null)
            {
                var messages = SerializeMessages(serverMessages);
                _server.Send(messages, 5, true, _messagesSent++);
            }

            cameraEntities = _camerasSet.GetEntities();
            cameraTransform = cameraEntities.Length > 0 ? cameraEntities[0].Get<Transform>() : new Transform();

            var cameraMatrix = cameraTransform.GetCameraMatrix(Settings.GRAPHICS_SCALE) * Matrix4x4.CreateScale(_zoom);

            var vp = _viewport.Viewport;
            _drawDevice.Begin(cameraMatrix * _viewport.GetScalingTransform(), vp);

            Scene.Render(_drawDevice);

            float gridSize = 20;
            var gridCenter = new Vector2((int)Math.Round(cameraTransform.WorldPosition.X / gridSize) * gridSize, (int)Math.Round(cameraTransform.WorldPosition.Y / gridSize) * gridSize);
            for (int x = -2; x <= 2; x++)
            {
                for (int y = -2; y <= 2; y++)
                {
                    SpriteBatchExtensions.DrawCircle(_drawDevice, (gridCenter + new Vector2(x, y) * gridSize) * Settings.GRAPHICS_SCALE, 0.2f * Settings.GRAPHICS_SCALE, 8, RgbaFloat.Red);
                }
            }

            _drawDevice.Draw();

            _imGuiRenderer.Render(_drawDevice.GraphicsDevice, _drawDevice.CommandList);

            _drawDevice.End();

            _window.GraphicsDevice.SwapBuffers(_window.MainSwapchain);
            _window.GraphicsDevice.WaitForIdle();
        }