Пример #1
0
        public void getMousePositionChange(out int xMouseDelta, out int yMouseDelta, out int zMouseDelta)
        {
            // Get mouse position change
            currentMouseState = OpenTK.Input.Mouse.GetState();
            if (currentMouseState != previousMouseState)
            {
                // Mouse state has changed
                if (currentMouseState [OpenTK.Input.MouseButton.Right])                   //Move only when right mouse button pressed
                {
                    xMouseDelta = currentMouseState.X - previousMouseState.X;
                    yMouseDelta = currentMouseState.Y - previousMouseState.Y;
                    zMouseDelta = currentMouseState.Wheel - previousMouseState.Wheel;
                }
                else
                {
                    xMouseDelta = 0;
                    yMouseDelta = 0;
                    zMouseDelta = 0;
                }
            }
            else
            {
                xMouseDelta = 0;
                yMouseDelta = 0;
                zMouseDelta = 0;
            }
            previousMouseState = currentMouseState;

            //int xpos = System.Windows.Forms.Cursor.Position.X;
            //int ypos = System.Windows.Forms.Cursor.Position.X;

            //System.Windows.Forms.Cursor.Position = new Point (glwidget1.Allocation.Width / 2, glwidget1.Allocation.Height / 2);
        }
Пример #2
0
        public void SetMouseState(OpenTK.Input.MouseState m, int x, int y)
        {
            if (m.LeftButton == ButtonState.Pressed)
            {
                if (lastLButtonState)
                {
                    int2 d = zoom * new int2((x - dragStart.x), y - dragStart.y);
                    offset.x = Math.Min(size.x - (int)(screen.width * zoom), Math.Max(0, offsetStart.x - d.x));
                    offset.y = Math.Min(size.y - (int)(screen.height * zoom), Math.Max(0, offsetStart.y - d.y));
                    k_sim.SetArgument(4, offset);
                }
                else
                {
                    dragStart        = new int2(x, y);
                    offsetStart      = new int2(offset.x, offset.y);
                    lastLButtonState = true;
                }
            }
            else
            {
                lastLButtonState = false;
            }

            // Zoom
            scrollValue   += -(m.Wheel - lastMouseWheel);
            lastMouseWheel = m.Wheel;
            scrollValue    = Math.Min(maxScroll, Math.Max(scrollValue, -maxScroll));
            zoom           = 1 + (scrollValue + 1) / (float)maxScroll;

            if (scrollValue != lastScrollValue)
            {
                lastScrollValue = scrollValue;
                resolution      = zoom * resolutionStart;
            }
        }
Пример #3
0
        void UpdateMousePosition()
        {
            currentMouseState = Mouse.GetState();

            if (!Focused)
            {
                return;
            }

            if (currentMouseState != previousMouseState)
            {
                int xdelta = currentMouseState.X - previousMouseState.X;
                int ydelta = currentMouseState.Y - previousMouseState.Y;
                previousMouseState = currentMouseState;

                angleX += rotation_speed * (float)ydelta;
                angleY += rotation_speed * (float)xdelta;


                if (CursorGrabbed)
                {
                    int centerx = this.Bounds.Left + (Bounds.Width / 2);
                    int centery = Bounds.Top + (Bounds.Height / 2);
                    ignoreMouseMoveEvent = true;
                    Mouse.SetPosition(centerx, centery);
                }
            }
        }
Пример #4
0
        void UpdateMousePosition()
        {
            currentMouseState = Mouse.GetState();

            if (!Focused)
            {
                return;
            }

            if (currentMouseState != previousMouseState)
            {
                int xdelta = currentMouseState.X - previousMouseState.X;
                int ydelta = currentMouseState.Y - previousMouseState.Y;

                mouseMoveEventVS(mouseX, mouseY, xdelta, ydelta);


                previousMouseState = currentMouseState;

                if (CursorGrabbed)
                {
                    int centerx = this.Bounds.Left + (Bounds.Width / 2);
                    int centery = this.Bounds.Top + (Bounds.Height / 2);
                    ignoreMouseMoveEvent = true;
                    Mouse.SetPosition(centerx, centery);
                }
            }
        }
Пример #5
0
        public void tポーリング(bool bWindowがアクティブ中)
        {
            for (int i = 0; i < Enum.GetNames(typeof(MouseButton)).Length; i++)
            {
                this.bMousePushDown[i] = false;
                this.bMousePullUp[i]   = false;
            }

            if (bWindowがアクティブ中)
            {
                // this.list入力イベント = new List<STInputEvent>( 32 );
                this.list入力イベント.Clear();                            // #xxxxx 2012.6.11 yyagi; To optimize, I removed new();



                #region [ 入力 ]
                //-----------------------------

                OpenTK.Input.MouseState currentState = OpenTK.Input.Mouse.GetState();
                if (currentState.IsConnected)
                {
                    for (int j = 0; (j < Enum.GetNames(typeof(MouseButton)).Length); j++)
                    {
                        if (this.bMouseState[j] == false && currentState[(MouseButton)j] == true)
                        {
                            var ev = new STInputEvent()
                            {
                                nKey       = j,
                                b押された      = true,
                                b離された      = false,
                                nTimeStamp = CSound管理.rc演奏用タイマ.nシステム時刻,                                 // 演奏用タイマと同じタイマを使うことで、BGMと譜面、入力ずれを防ぐ。
                                nVelocity  = CInput管理.n通常音量,
                            };
                            this.list入力イベント.Add(ev);

                            this.bMouseState[j]    = true;
                            this.bMousePushDown[j] = true;
                        }
                        else if (this.bMouseState[j] == true && currentState[(MouseButton)j] == false)
                        {
                            var ev = new STInputEvent()
                            {
                                nKey       = j,
                                b押された      = false,
                                b離された      = true,
                                nTimeStamp = CSound管理.rc演奏用タイマ.nシステム時刻,                                 // 演奏用タイマと同じタイマを使うことで、BGMと譜面、入力ずれを防ぐ。
                                nVelocity  = CInput管理.n通常音量,
                            };
                            this.list入力イベント.Add(ev);

                            this.bMouseState[j]  = false;
                            this.bMousePullUp[j] = true;
                        }
                    }
                }
                //-----------------------------
                #endregion
            }
        }
Пример #6
0
 private static int GetDrawState(OpenTK.Input.MouseState mouse)
 {
     if (mouse.IsButtonDown(MouseButton.Left))
     {
         return(1);
     }
     else if (mouse.IsButtonDown(MouseButton.Right))
     {
         return(2);
     }
     return(0);
 }
Пример #7
0
        private static void InputTick(object sender, EventArgs e)
        {
            float speed = 0.01f * (float)ControlsWindow.camSpeed;

            OpenTK.Input.MouseState    mouseState    = OpenTK.Input.Mouse.GetState();
            OpenTK.Input.KeyboardState keyboardState = OpenTK.Input.Keyboard.GetState();

            if (keyboardState.IsKeyDown(Key.Up))
            {
                dragY = dragY + speed;
            }

            if (keyboardState.IsKeyDown(Key.Down))
            {
                dragY = dragY - speed;
            }

            if (keyboardState.IsKeyDown(Key.Left))
            {
                angle = angle + speed;
            }

            if (keyboardState.IsKeyDown(Key.Right))
            {
                angle = angle - speed;
            }

            if (keyboardState.IsKeyDown(Key.Z))
            {
                dragZ = dragZ - speed;
            }

            if (keyboardState.IsKeyDown(Key.X))
            {
                dragZ = dragZ + speed;
            }

            if (keyboardState.IsKeyDown(Key.Q))
            {
                angle = angle + 0.5f;
            }

            if (keyboardState.IsKeyDown(Key.E))
            {
                angle = angle - 0.5f;
            }

            //if (mouseInRender)
            //{
            //dragZ = (mouseState.WheelPrecise / speed) - (7.5f); //Startzoom is at -7.5f
            //}
        }
Пример #8
0
        public void Update(Vector2 mousePosInNDC, Inp.MouseState newMouseState, Inp.MouseState oldMouseState, Inp.KeyboardState newKeyboardState, Inp.KeyboardState oldKeyboardState)
        {
            //bool activated = UpdateHotkeys(newKeyboardState, oldKeyboardState);

            if (MouseIsOver(mousePosInNDC))
            {
                if (newMouseState.LeftButton == Inp.ButtonState.Released)
                {
                    ContainingMenu.SelectedButton = this;
                }
                if (MousePressedHereWithoutRelease && newMouseState.LeftButton == Inp.ButtonState.Released)
                {
                    if (BoundBool != null)
                    {
                        BoundBool.Value = !BoundBool.Value;
                    }
                    if (OnActivate != null)
                    {
                        OnActivate(this);
                    }
                }
                if (newMouseState.LeftButton == Inp.ButtonState.Pressed && oldMouseState.LeftButton == Inp.ButtonState.Released)
                {
                    MousePressedHereWithoutRelease = true;
                }
            }
            else if (ContainingMenu.SelectedButton == this)
            {
                ContainingMenu.SelectedButton = null;
            }

            if (newMouseState.LeftButton == Inp.ButtonState.Released)
            {
                MousePressedHereWithoutRelease = false;
            }
            else if (MousePressedHereWithoutRelease && BoundFloat != null)
            {
                BoundFloat.Value = (mousePosInNDC.X - PositionX()) / Width * Main.AspectRatio();
            }

            if (BoundFloat != null)
            {
                if (BoundFloat.Value < 0f)
                {
                    BoundFloat.Value = 0f;
                }
                else if (BoundFloat.Value > 1f)
                {
                    BoundFloat.Value = 1f;
                }
            }
        }
        private Vector2 getUpdatedPosition(OpenTK.Input.MouseState state, OpenTKMouseState lastState)
        {
            Vector2 currentPosition;

            if ((state.Flags & MouseStateFlags.MoveAbsolute) > 0)
            {
                const int raw_input_resolution = 65536;

                if (mapAbsoluteInputToWindow)
                {
                    // map directly to local window
                    currentPosition.X = ((float)((state.X - raw_input_resolution / 2f) * sensitivity.Value) + raw_input_resolution / 2f) / raw_input_resolution * Host.Window.Width;
                    currentPosition.Y = ((float)((state.Y - raw_input_resolution / 2f) * sensitivity.Value) + raw_input_resolution / 2f) / raw_input_resolution
                                        * Host.Window.Height;
                }
                else
                {
                    Rectangle screenRect = (state.Flags & MouseStateFlags.VirtualDesktop) > 0
                        ? Platform.Windows.Native.Input.GetVirtualScreenRect()
                        : new Rectangle(0, 0, DisplayDevice.Default.Width, DisplayDevice.Default.Height);

                    // map to full screen space
                    currentPosition.X = (float)state.X / raw_input_resolution * screenRect.Width + screenRect.X;
                    currentPosition.Y = (float)state.Y / raw_input_resolution * screenRect.Height + screenRect.Y;

                    // find local window coordinates
                    var clientPos = Host.Window.PointToClient(new Point((int)Math.Round(currentPosition.X), (int)Math.Round(currentPosition.Y)));

                    // apply sensitivity from window's centre
                    currentPosition.X = (float)((clientPos.X - Host.Window.Width / 2f) * sensitivity.Value + Host.Window.Width / 2f);
                    currentPosition.Y = (float)((clientPos.Y - Host.Window.Height / 2f) * sensitivity.Value + Host.Window.Height / 2f);
                }
            }
            else
            {
                if (lastState == null)
                {
                    // when we return from being outside of the window, we want to set the new position of our game cursor
                    // to where the OS cursor is, just once.
                    var cursorState = OpenTK.Input.Mouse.GetCursorState();
                    var screenPoint = Host.Window.PointToClient(new Point(cursorState.X, cursorState.Y));
                    currentPosition = new Vector2(screenPoint.X, screenPoint.Y);
                }
                else
                {
                    currentPosition = lastState.Position + new Vector2(state.X - lastState.RawState.X, state.Y - lastState.RawState.Y) * (float)sensitivity.Value;
                }
            }

            return(currentPosition);
        }
Пример #10
0
        public override void CheckMouse()
        {
            base.CheckMouse();

            return; // disable mouse


            OpenTK.Input.MouseState mouseState = OpenTK.Input.Mouse.GetCursorState();

            float mouseStepW = 2 * MathHelper.Pi / GameWindow.Width;

            float mouseStepH = 2 * MathHelper.Pi / GameWindow.Height;

            Quaternion qcu = Quaternion.FromAxisAngle(
                new Vector3(Camera.CameraUVW.Row0),
                (mouseState.Y - oldMouseState.Y) * mouseStepH);

            Quaternion qcv = Quaternion.FromAxisAngle(
                Vector3.UnitY, (mouseState.X - oldMouseState.X) * mouseStepW);

            Camera.Rotate(qcv * qcu);



            if (mouseState.X > GameWindow.Width - 10)
            {
                OpenTK.Input.Mouse.SetPosition(
                    GameWindow.Width / 2, GameWindow.Height / 2);
            }

            if (mouseState.X < 10)
            {
                OpenTK.Input.Mouse.SetPosition(
                    GameWindow.Width, GameWindow.Height / 2);
            }

            if (mouseState.Y > GameWindow.Height - 10)
            {
                OpenTK.Input.Mouse.SetPosition(
                    GameWindow.Width / 2, GameWindow.Height / 2);
            }
            if (mouseState.Y < 10)
            {
                OpenTK.Input.Mouse.SetPosition(
                    GameWindow.Width / 2, GameWindow.Height);
            }

            oldMouseState = OpenTK.Input.Mouse.GetCursorState();
        }
Пример #11
0
        protected OpenTKMouseState(OpenTK.Input.MouseState tkState, bool active, Vector2?mappedPosition)
        {
            WasActive = active;

            // While not focused, let's silently ignore everything but position.
            if (active && tkState.IsAnyButtonDown)
            {
                addIfPressed(tkState.LeftButton, MouseButton.Left);
                addIfPressed(tkState.MiddleButton, MouseButton.Middle);
                addIfPressed(tkState.RightButton, MouseButton.Right);
                addIfPressed(tkState.XButton1, MouseButton.Button1);
                addIfPressed(tkState.XButton2, MouseButton.Button2);
            }

            Wheel    = tkState.Wheel;
            Position = new Vector2(mappedPosition?.X ?? tkState.X, mappedPosition?.Y ?? tkState.Y);
        }
Пример #12
0
        protected OpenTKMouseState(OpenTK.Input.MouseState tkState, bool active, Vector2?mappedPosition)
        {
            WasActive = active;

            RawState = tkState;

            // While not focused, let's silently ignore everything but position.
            if (active && tkState.IsAnyButtonDown)
            {
                addIfPressed(tkState.LeftButton, MouseButton.Left);
                addIfPressed(tkState.MiddleButton, MouseButton.Middle);
                addIfPressed(tkState.RightButton, MouseButton.Right);
                addIfPressed(tkState.XButton1, MouseButton.Button1);
                addIfPressed(tkState.XButton2, MouseButton.Button2);
            }

            Scroll           = new Vector2(-tkState.Scroll.X, tkState.Scroll.Y);
            HasPreciseScroll = tkState.Flags.HasFlag(MouseStateFlags.HasPreciseScroll);
            Position         = new Vector2(mappedPosition?.X ?? tkState.X, mappedPosition?.Y ?? tkState.Y);
        }
Пример #13
0
        private void RenderFrame(RenderInfo renderInfo)
        {
            UpdateMouse();
            GL.Viewport(0, 0, renderInfo.Width, renderInfo.Height);

            _keyboardState = Keyboard.GetState();
            _mouseState    = Mouse.GetState();

            var client = _connectionManager.Client;

            if (client != null)
            {
                client.UpdateState();
                _renderer.Render(client, renderInfo);
            }
            else
            {
                GL.ClearColor(0f, 0f, 0f, 1f);
                GL.Clear(ClearBufferMask.ColorBufferBit);
            }

            _uiRenderer.Render(renderInfo, _wasWindowGrabbed ? MouseMode.Grabbed : MouseMode.Free, _gameControl, GetInputState());
        }
 public UnfocusedMouseState(OpenTK.Input.MouseState tkState, bool active, Vector2?mappedPosition)
     : base(tkState, active, mappedPosition)
 {
 }
Пример #15
0
        public MyGameLevel(int id, string name, GameWindow gameWindow,
                           Vector2 targetPosition,
                           MyPlayer player)
            : base(id, name, gameWindow)
        {
            aspectRatio = (float)GameWindow.Width / GameWindow.Height;

            oldMouseState = OpenTK.Input.Mouse.GetCursorState();

            TargetPosition = targetPosition;

            Camera = new Camera();

            Camera.Position = new Vector3(0, -150, 0);
            Camera.Rotate(new Vector3(Camera.CameraUVW.Row0),
                          MathHelper.PiOver2);

            Camera.Update();

            TextRenderClock =
                new TextRender(150, 100,
                               new Vector2(GameWindow.Width - 160 - 100, 10),
                               FontFamily.Families[19], 52);

            TextRenderClock.BackgroundColor = Color.FromArgb(0, 0, 0, 0);

            TextRenderClock.FontStyle = FontStyle.Bold;

            TextRenderClock.Load(GameWindow.Width, GameWindow.Height);

            DateTimeClock = DateTime.Now;

            PointLight = new PointLight
            {
                Position = new Vector3(-30f, 5f, -30f),
                Color    = new Vector3(0.9f, 0.9f, 0.9f),
                //Intensity = 0.2f
                Intensity = 1
            };

            SpotLight = new SpotLight
            {
                Position = new Vector3(30f, 6f, -30f),
                Color    = new Vector3(0.9f, 0.9f, 0.8f),
                //Intensity = 0.2f,
                Intensity     = 1,
                ConeAngle     = 0.5f,
                ConeDirection = new Vector3(0f, -1f, 0f)
            };

            CubesHaveNormalMap = true;

            Load();

            ballUpdateOldPosition = Shapes3D["sphereEnvCubeMap"].Position;

            SunLightPosition = new Vector3(68, 200, -18);
            //SunLightPosition = -ShadowMap.LightView.Position;

            CurrentState = State.Running;

            FinishCamera = new Camera();
        }
Пример #16
0
 internal void HandleMouseUp(object sender, MouseButtonEventArgs e)
 {
     state = e.Mouse;
     ButtonUp(this, e);
 }
Пример #17
0
        private void RenderFrame(RenderInfo renderInfo)
        {
            UpdateMouse();
            GL.Viewport(0, 0, renderInfo.Width, renderInfo.Height);

            _keyboardState = Keyboard.GetState();
            _mouseState = Mouse.GetState();

            var client = _connectionManager.Client;
            if (client != null)
            {
                client.UpdateState();
                _renderer.Render(client, renderInfo);
            }
            else
            {
                GL.ClearColor(0f, 0f, 0f, 1f);
                GL.Clear(ClearBufferMask.ColorBufferBit);
            }

            _uiRenderer.Render(renderInfo, _wasWindowGrabbed ? MouseMode.Grabbed : MouseMode.Free, _gameControl, GetInputState());
        }
Пример #18
0
    void UpdateMousePosition(UpdateMousePositionArgs args)
    {
        args.mouseCurrentX = System.Windows.Forms.Cursor.Position.X;
        args.mouseCurrentY = System.Windows.Forms.Cursor.Position.Y;
        if (!mousePointerLocked)
        {
            args.mouseCurrentX = args.mouseCurrentX - window.X;
            args.mouseCurrentY = args.mouseCurrentY - window.Y;

            args.mouseCurrentY = args.mouseCurrentY - System.Windows.Forms.SystemInformation.CaptionHeight;

            args.mouseDeltaX = args.mouseCurrentX - mouse_previous.X;
            args.mouseDeltaY = args.mouseCurrentY - mouse_previous.Y;
            mouse_previous.X = args.mouseCurrentX;
            mouse_previous.Y = args.mouseCurrentY;
        }
        if (!window.Focused)
        {
            return;
        }
        if (mousePointerLocked && (!wasMousePointerLocked))
        {
            mouse_previous.X = args.mouseCurrentX;
            mouse_previous.Y = args.mouseCurrentY;
            args.freemousejustdisabled = false;
        }
        wasMousePointerLocked = mousePointerLocked;
        if (mousePointerLocked)
        {
            //There are two versions:

            //a) System.Windows.Forms.Cursor and GameWindow.CursorVisible = true.
            //It works by centering global mouse cursor every frame.
            //*Windows:
            //   *OK.
            //   *On a few YouTube videos mouse cursor is not hiding properly.
            //    That could be just a problem with video recording software.
            //*Ubuntu: Broken, mouse cursor doesn't hide.
            //*Mac: Broken, mouse doesn't move at all.

            //b) OpenTk.Input.Mouse and GameWindow.CursorVisible = false.
            //Uses raw mouse coordinates, movement is not accelerated.
            //*Windows:
            //  *OK.
            //  *Worse than a), because this doesn't use system-wide mouse acceleration.
            //*Ubuntu: Broken, crashes with "libxi" library missing.
            //*Mac: OK.

            if (!IsMac)
            {
                //a)
                int centerx = window.Bounds.Left + (window.Bounds.Width / 2);
                int centery = window.Bounds.Top + (window.Bounds.Height / 2);

                args.mouseDeltaX = args.mouseCurrentX - mouse_previous.X;
                args.mouseDeltaY = args.mouseCurrentY - mouse_previous.Y;

                System.Windows.Forms.Cursor.Position =
                    new Point(centerx, centery);
                mouse_previous = new Point(centerx, centery);
            }
            else
            {
                //b)
                var state = OpenTK.Input.Mouse.GetState();
                float dx = state.X - mouse_previous_state.X;
                float dy = state.Y - mouse_previous_state.Y;
                mouse_previous_state = state;
                //These are raw coordinates, so need to apply acceleration manually.
                float dx2 = (dx * Math.Abs(dx) * MouseAcceleration1);
                float dy2 = (dy * Math.Abs(dy) * MouseAcceleration1);
                dx2 += dx * MouseAcceleration2;
                dy2 += dy * MouseAcceleration2;
                args.mouseDeltaX = dx2;
                args.mouseDeltaY = dy2;
            }
        }
    }
Пример #19
0
 internal void HandleMouseMove(object sender, MouseMoveEventArgs e)
 {
     state = e.Mouse;
     Move(this, e);
 }
Пример #20
0
 internal void HandleMouseWheel(object sender, MouseWheelEventArgs e)
 {
     state = e.Mouse;
     WheelChanged(this, e);
 }
Пример #21
0
        public static bool UpdateAllSlots(int shaderID, int mouseX, int mouseY, ref Inp.KeyboardState newKeyboardState, ref Inp.MouseState newMouseState, ref Inp.MouseState oldMouseState, MarbleSelection marbleSelection, Rectangle clientRectangle, Camera camera, ref Matrix4 projection, ref Matrix4 view, List <Marble> marbles, List <MarbleMove> moves, ref int undoLevel, bool spinningMarbles, bool animateMoves, ref Marble lastMarbleRemovedForWin)
        {
            if (Game.FlashTicksAreAscending)
            {
                Game.FlashTicks++;
                if (Game.FlashTicks > Game.MAX_FLASH_TICKS)
                {
                    Game.FlashTicks            -= 2;
                    Game.FlashTicksAreAscending = false;
                }
            }
            else
            {
                Game.FlashTicks--;
                if (Game.FlashTicks < 0)
                {
                    Game.FlashTicks             = 1;
                    Game.FlashTicksAreAscending = true;
                }
            }
            if (Selected != null)
            {
                SelectionAnimationTick++;
                if (SelectionAnimationTick > MAX_SELECTION_ANIMATION_TICK)
                {
                    SelectionAnimationTick = 0;
                }
            }
            Marble oldSelected = Selected;

            for (int i = 1; i < Game.LIGHT_COUNT; i++)
            {
                Game.SetLightEnabled(shaderID, i, false);
            }

            HighlightedSlot = null;

            if (marbleSelection == MarbleSelection.None || (marbleSelection == MarbleSelection.Mouse && (mouseX < 0 || mouseY < 0 || mouseX > clientRectangle.Width || mouseY > clientRectangle.Height)))
            {
                foreach (Marble m in marbles)
                {
                    m.Update(shaderID, spinningMarbles);
                }
                return(false);
            }

            Marble highlightedMarble     = null;
            float  closestMarbleDistance = float.MaxValue;
            float  distance = float.NaN;
            //Vector2 mousePosNDC = MousePositionInNDC();
            //float rotY = (float)Math.Atan(-mousePosNDC.Y * Math.Tan(VerticalFieldOfView / 2f));
            //float rotX = -(float)Math.Atan(mousePosNDC.X * Math.Tan(HorizontalFieldOfView(VerticalFieldOfView) / 2f));
            //float rot = (float)Math.Atan(mousePosNDC.Length * (float)Math.Tan(VerticalFieldOfView / 2f));
            //float rotY = (float)Math.Atan(-mousePosNDC.Y * (float)Math.Tan(VerticalFieldOfView / 2f));
            //float rotX = -(float)Math.Atan(mousePosNDC.X * (float)Math.Tan(HorizontalFieldOfView(VerticalFieldOfView) / 2f));
            //Matrix4 xRotation = Matrix4.CreateFromAxisAngle(CameraUp(), rotX);
            //Vector3 ray = Vector3.Transform(CameraForward(), xRotation);
            //ray = Vector3.Transform(ray, Matrix4.CreateFromAxisAngle(CameraRight(), rotY));
            //Vector3 ray = Vector3.TransformPerspective(CameraForward(), Matrix4.CreateFromAxisAngle(CameraUp(), rotX) * Matrix4.CreateFromAxisAngle(CameraRight(), rotY));

            Vector3 ray;

            if (marbleSelection == MarbleSelection.Mouse)
            {
                ray = Utils.MousePickRay(mouseX, mouseY, clientRectangle, ref projection, ref view);
            }
            else
            {
                ray = camera.Forward;
            }
            bool pickHad = false;

            //Vector3 ray = Vector3.Transform(CameraForward(), Matrix4.CreateRotationZ(HorizontalFieldOfView(VerticalFieldOfView) / 2f));
            //Vector3 ray = Vector3.Transform(CameraForward(), Matrix4.CreateRotationZ(MousePositionInNDC().X * -(float)Math.Tan(HorizontalFieldOfView(VerticalFieldOfView) / VerticalFieldOfView / MathHelper.PiOver2)));

            List <int> emptySlots = new List <int>();

            for (int i = 0; i < STARTING_COUNT; i++)
            {
                emptySlots.Add(i);
            }

            Vector3 raySource = marbleSelection == MarbleSelection.Mouse ? camera.Position : camera.FocusPoint;

            foreach (Marble m in marbles)
            {
                if (!m.Alive)
                {
                    continue;
                }
                emptySlots.Remove(m.PositionSlot);
                Vector3 marblePos = m.Position();
                if (MouseIsOver(marblePos, 1f, raySource, ray, ref distance, closestMarbleDistance))
                {
                    pickHad               = true;
                    highlightedMarble     = m;
                    HighlightedSlot       = m.PositionSlot;
                    closestMarbleDistance = distance;
                }
            }
            if (Selected != null)
            {
                emptySlots.RemoveAll(i => !SlotIsValid(i, marbles));
                foreach (int i in emptySlots)
                {
                    if (MouseIsOver(Position(i), 0.375f, raySource, ray, ref distance, closestMarbleDistance))
                    {
                        pickHad               = true;
                        highlightedMarble     = null;
                        HighlightedSlot       = i;
                        closestMarbleDistance = distance;
                    }
                }
                if (!pickHad)
                {
                    foreach (int i in emptySlots)
                    {
                        if (MouseIsOver(Position(i), 1f, raySource, ray, ref distance, closestMarbleDistance))
                        {
                            //pickHad = true;
                            HighlightedSlot       = i;
                            closestMarbleDistance = distance;
                        }
                    }
                }
            }

            bool moveMade = false;

            if (newMouseState.LeftButton == Inp.ButtonState.Pressed && oldMouseState.LeftButton == Inp.ButtonState.Released)
            {
                if (HighlightedSlot != null)
                {
                    bool shift = newKeyboardState.IsKeyDown(Inp.Key.ShiftLeft) || newKeyboardState.IsKeyDown(Inp.Key.ShiftRight);
                    //marbles.Remove(GetMarbleInSlot(HighlightedSlot.Value, marbles));
                    Marble marbleToBeRemoved;
                    if (!shift && marbles.Count(m => m.Alive) == STARTING_COUNT)
                    {
                        if (animateMoves)
                        {
                            highlightedMarble.AnimateFromSlot           = highlightedMarble.PositionSlot;
                            highlightedMarble.AnimationTick             = MAX_ANIMATION_TICKS;
                            highlightedMarble.AnimatingAsInitialRemoval = true;
                        }
                        highlightedMarble.Alive = false;
                        if (undoLevel > 0)
                        {
                            moves.RemoveRange(moves.Count - undoLevel, undoLevel);
                            undoLevel = 0;
                        }
                        moves.Add(new MarbleMove(highlightedMarble.PositionSlot, -1, -1, highlightedMarble.Type));
                    }
                    else if (SlotIsValid(HighlightedSlot.Value, marbles, out marbleToBeRemoved))
                    { // Remove a marble
                        if (undoLevel > 0)
                        {
                            moves.RemoveRange(moves.Count - undoLevel, undoLevel);
                            undoLevel = 0;
                        }
                        moves.Add(new MarbleMove(Selected.PositionSlot, marbleToBeRemoved.PositionSlot, HighlightedSlot.Value, marbleToBeRemoved.Type));

                        if (animateMoves)
                        {
                            Selected.AnimateFromSlot          = Selected.PositionSlot;
                            Selected.AnimationTick            = 0;
                            marbleToBeRemoved.AnimateFromSlot = marbleToBeRemoved.PositionSlot;
                            marbleToBeRemoved.AnimationTick   = 0;
                        }
                        Selected.PositionSlot   = HighlightedSlot.Value;
                        marbleToBeRemoved.Alive = false;

                        moveMade = true;
                        //if (!Selected.CanMove(marbles))
                        Selected = null;

                        if (marbles.Count(m => m.Alive) == 1)
                        {
                            lastMarbleRemovedForWin = marbleToBeRemoved;
                        }
                    }
                    else if (shift)
                    {
                        camera.FocusPoint = highlightedMarble.Position();
                    }
                    else if (highlightedMarble == Selected)
                    {
                        Selected = null;
                    }
                    else
                    {
                        Selected = highlightedMarble;
                    }
                }
                else
                {
                    Selected = null;
                }
            }
            foreach (Marble m in marbles)
            {
                m.Update(shaderID, spinningMarbles);
            }

            if (Selected != oldSelected)
            {
                SelectionAnimationTick = 0;
            }
            return(moveMade);
        }