protected override void OnUpdateFrame(FrameEventArgs e)
        {
            if (Board.Marbles.Count == 0)
            {
                Board.NewGame();
            }

            var kbState = KeyboardState;

            if (kbState[Key.Escape])
            {
                Stop();
                return;
            }

            foreach (var marble in Board.Marbles)
            {
                if (marble.RenderObject == null)
                {
                    if (marble.Color == MarbleColor.BombJoker)
                    {
                        marble.RenderObject = CreateBompComponent();
                        marble.RenderObject.TranslationMatrix = BoardTranslationMatrix;
                        marble.RenderObject.RelativeScale     = new Vector3(MarbleScale);
                        marble.RenderObject.RelativeRotation  = new Vector3(-0.15f, 0.15f, 0f).ToQuaternion();
                        marble.RenderObject.Material.AddParameter("joker", marble.Color == MarbleColor.ColorJoker ? 1 : 0);
                        marble.RenderObject.Material.AddParameter("color2", GetMaterialColorShader(marble.Color2));
                    }
                    else
                    {
                        marble.RenderObject = new SphereComponent()
                        {
                            TranslationMatrix = BoardTranslationMatrix,
                            //TranslationTransform = Transform.CreateScale(1, -1, 1),
                            Material      = GetMaterial(marble),
                            RelativeScale = new Vector3(MarbleScale),
                        };
                        marble.RenderObject.Material.AddParameter("joker", marble.Color == MarbleColor.ColorJoker ? 1 : 0);
                        marble.RenderObject.Material.AddParameter("color2", GetMaterialColorShader(marble.Color2));
                    }
                }

                SceneComponent parent = null;
                if (marble.OnBoard)
                {
                    parent = BoardComponent;
                }
                else
                {
                    if (Board.PreviewMode == MarblePreview.Board)
                    {
                        parent = NextMarbleBoardComponent;
                    }
                    else if (Board.PreviewMode == MarblePreview.Side)
                    {
                        parent = NextMarbleComponent;
                    }
                }

                if (parent != null && marble.RenderObject.Parent != parent)
                {
                    marble.RenderObject.Detach();
                    parent.AddComponent(marble.RenderObject);
                }

                var ro = marble.RenderObject;
                if (marble.State == MarbleState.Adding || marble.State == MarbleState.PreAdding)
                {
                    if (marble.OnBoard)
                    {
                        ro.RelativeScale = new Vector3(CreateTween.ScaledPosition);
                    }
                    else if (Board.PreviewMode == MarblePreview.Board)
                    {
                        ro.RelativeScale = new Vector3(CreateTween.ScaledPosition * 0.35f);
                    }
                }
                else
                {
                    if (marble.OnBoard)
                    {
                        ro.RelativeScale = new Vector3(CreateTween.ScaleFunc(1));
                    }
                    else if (Board.PreviewMode == MarblePreview.Board)
                    {
                        ro.RelativeScale = new Vector3(CreateTween.ScaleFunc(1) * 0.35f);
                    }
                }
                if (marble.State == MarbleState.Removing || marble.State == MarbleState.Exploding)
                {
                    ro.RelativeScale = new Vector3(RemoveTween.ScaledPosition);
                }
                if (marble == SelectedMarble && CurrentPath != null && MoveTween.Enabled)
                {
                    var result = GetPathPosition(marble);
                    ro.RelativeTranslation = result.Position;
                    if (marble.Color != MarbleColor.BombJoker)
                    {
                        ro.RelativeRotation = result.Rotate;
                    }
                }
                else
                {
                    ro.RelativeTranslation = GetMarblePos(marble);
                    if (marble.Color != MarbleColor.BombJoker)
                    {
                        ro.RelativeRotation = Quaternion.Identity;
                    }
                }
            }

            BoardActor.GetComponent <SceneComponent>("MarbleSelector").RelativeRotation    = Quaternion.FromEulerAngles(0, 0, SelectorTween.ScaledPosition);
            SceneContext.GetActor("UI").GetComponent <UILabelComponent>("TotalScore").Text = Board.TotalScore.ToString();
            SceneContext.GetActor("UI").GetComponent <UILabelComponent>("LastScore").Text  = Board.LastMoveScore.ToString();

            if (CurrentMouseWorldPositionIsValid)
            {
                var cursor = BoardActor.GetComponent <SceneComponent>("GroundCursor");
                cursor.RelativeTranslation = new Vector3(CurrentMouseWorldPosition.X, CurrentMouseWorldPosition.Y, cursor.RelativeTranslation.Z);
            }

            // Test Rotation:
            //Board.Marbles.Last().RenderObject.RelativeRotation = Quaternion.FromEulerAngles(0.2f, 0.5f, 0.7f);
        }
        protected override void SetupScene()
        {
            Board = new MarbleBoard
            {
                OnMatch      = OnMatch,
                OnNewMarbles = OnNewMarbles,
            };

            //RenderContext.WorldPositionMatrix = Matrix4.CreateScale(1, -1, 1);
            //RenderContext.PrimaryRenderPipeline = RenderContext.GetPipeline<ForwardRenderPipeline>();
            DefaultKeyBindings = false;

            SceneContext.AddActor(BoardActor = new Actor(BoardComponent = new SceneComponent()
            {
                //RelativeRotation = new Vector3(0, 0, 0.02f).ToQuaternion(),
                RelativeTranslation = new Vector3(0, 0, 0.05f),
            }));

            BoardComponent.AddComponent(NextMarbleComponent = new SceneComponent()
            {
                RelativeTranslation = new Vector3(10, -3, 0),
                RelativeScale       = new Vector3(0.5f),
            });

            BoardComponent.AddComponent(NextMarbleBoardComponent = new SceneComponent()
            {
                RelativeTranslation = new Vector3(0, 0, -0.2f),
                // RelativeScale = new Vector3(0.5f),
                // TranslationMatrix = Matrix4.CreateScale(2),
                // IsAbsoluteRotation = true,
                // IsAbsoluteScale = true,
                // IsAbsoluteTranslation = true,
            });

            var camSize = new Vector2(9 * RenderContext.ScreenAspectRatio, 9);

            RenderContext.Camera = new OrthographicCamera(new Vector3(4.5f + ((camSize.X - camSize.Y) / 2f) - 0.5f, -4.5f + 0.5f, 25))
            {
                Size      = camSize,
                NearPlane = 1f,
                FarPlane  = 100.0f,
                Facing    = (float)Math.PI / 2,
                Pitch     = -((float)(Math.PI / 2) - 0.00001f),
            };

            SceneContext.AddActor(new Actor(new CubeComponent()
            {
                Name     = "Ground",
                Material = new Material
                {
                    Color     = new Vector4(0.4f, 0.6f, 0.6f, 1),
                    Shininess = 1.0f,
                },
                RelativeScale       = new Vector3(50, 50, 1),
                RelativeTranslation = new Vector3(0f, 0f, -0.5f),
            }));

            BoardComponent.AddComponent(new CubeComponent()
            {
                Name     = "Board",
                Material = new Material
                {
                    Color     = new Vector4(0.4f, 0.6f, 0.6f, 1) * 1.1f,
                    Shininess = 1.0f,
                },
                RelativeScale       = new Vector3(Board.Width, Board.Height, 1),
                RelativeTranslation = new Vector3((Board.Width / 2f) - 0.5f, (Board.Height / 2f) - 0.5f, -0.5f),
                TranslationMatrix   = BoardTranslationMatrix,
            });

            BoardComponent.AddComponent(new GridPlaneComponent(9, false)
            {
                Name = "Grid",
                RelativeTranslation = new Vector3(-0.5f, -0.5f + 9, 0.01f),
                TranslationMatrix   = BoardTranslationMatrix,
            });
            SceneContext.AddActor(new Actor(new CrossLineComponent(10, true)
            {
                Name = "CenterCross",
                RelativeTranslation = new Vector3(0f, 0f, 0.02f),
                RelativeScale       = new Vector3(1.0f),
            }));

            var alchemyCircleOptions = new Generators.AlchemyCircle.AlchemyCircleOptions
            {
                Seed      = 1919654508,
                Size      = 256,
                Thickness = 4,
            };
            var decalMaterial = new Material()
            {
                DiffuseTexture   = Texture.CreateFromFile(AssetManager.GetAssetsPath("Textures/AlchemyCircle/.png", alchemyCircleOptions)),
                Color            = new Vector4(57f / 255f, 1, 20f / 255f, 1),
                Ambient          = 0.3f,
                Shininess        = 32.0f,
                SpecularStrength = 0.5f,
                CastShadow       = false,
                PipelineType     = PipelineType.Forward,
                UseTransparency  = true,
            };

            BoardComponent.AddComponent(new QuadComponent()
            {
                Material            = decalMaterial,
                Name                = "GroundCursor",
                RelativeTranslation = new Vector3(0, 1, 0.051f),
                RelativeScale       = new Vector3(2f, 2f, 0.1f),
                DrawPriority        = 101,
            });

            BoardComponent.AddComponent(new QuadComponent()
            {
                Name              = "MarbleSelector",
                Material          = decalMaterial,
                TranslationMatrix = BoardTranslationMatrix,
                //Material = material,
                RelativeTranslation = new Vector3(0, 1, 0.05f),
                RelativeScale       = new Vector3(2f, 2f, 0.1f),
                Visible             = false,
                DrawPriority        = 100,
            });

            SceneContext.AddActor(new Actor(new PointLightComponent()
            {
                RelativeTranslation = new Vector3(0, 2, 3.5f),
                Name = "MovingLight",
                //Enabled = false,
            }));

            SceneContext.AddActor(new Actor(new PointLightComponent()
            {
                RelativeTranslation = new Vector3(2f, 0.5f, 4.25f),
                Name = "StaticLight",
            }));

            var flowContainer = new UIFlowContainer()
            {
                Name = "UI",
                DefaultChildSizes = new Vector2(0, 50),
                ExtraChildMargin  = new UIAnchors(10, 10, 10, 0),
                Location          = new Vector2(1000, 0),
                Size = new Vector2(200, 0),
            };

            SceneContext.AddActor(new Actor(flowContainer));

            // flowContainer.AddComponent(new UIMarbles()
            // {
            //     Name = "UI",
            // });

            flowContainer.AddComponent(new UILabelComponent()
            {
                Name  = "LastScore",
                Color = Color.White,
            });
            flowContainer.AddComponent(new UILabelComponent()
            {
                Name  = "TotalScore",
                Color = Color.White,
            });

            SceneContext.AddActor(new Actor(new StatsComponent()
            {
                Name = "Stats",
            }));

            UIButton bt;

            flowContainer.AddComponent(bt = new UIButton()
            {
                Name           = "Exit",
                Text           = "Exit",
                Color          = Color.White,
                BackColor      = new Color(new Rgba32(0, 0, 0, 0.5f)),
                BackColorHover = new Color(new Rgba32(0, 0, 0, 0.8f)),
                BorderColor    = new Color(new Rgba32(0, 0, 0, 0.8f)),
                // Location = new Vector2(620, 200),
                // Size = new Vector2(100, 100),
            });
            bt.Click += (e) =>
            {
                Stop();
            };

            SelectorTween = new Tween1
            {
                Duration  = TimeSpan.FromSeconds(10),
                ScaleFunc = ScaleFuncs.Linear(MathF.PI * 2),
                Repeat    = true,
            };
            SelectorTween.Start();

            RemoveTween = new Tween1
            {
                Duration  = TimeSpan.FromSeconds(0.75),
                ScaleFunc = ScaleFuncs.LinearReverse(MarbleScale),
            };
            RemoveTween.TweenComplete += OnAnimFinshed_MarbleRemoved;

            CreateTween = new Tween1
            {
                Duration  = TimeSpan.FromSeconds(0.75),
                ScaleFunc = ScaleFuncs.Linear(MarbleScale),
            };
            CreateTween.TweenComplete += OnAnimationFinished_MarbleCreated;

            MoveTween = new Tween1()
            {
                ScaleFunc = ScaleFuncs.Power10EaseInOut,
            };
            MoveTween.TweenComplete += OnAnimFinished_MarbleMoved;
        }