public void Tick()
        {
            float deltaTime = 0.016f;
            float moveSpeed = ModifierKeys == Keys.Shift ? 40 : 10;

            if (rMouse)
            {
                camera.rotation.Z -= (Cursor.Position.X - lastMouseX) * camera.speed * 0.016f;
                camera.rotation.X -= (Cursor.Position.Y - lastMouseY) * camera.speed * 0.016f;
                camera.rotation.X  = MathHelper.Clamp(camera.rotation.X, MathHelper.DegreesToRadians(-89.9f), MathHelper.DegreesToRadians(89.9f));
                InvalidateView();
            }

            Vector3 moveDir = GetInputAxes();

            if (moveDir.Length > 0)
            {
                moveDir *= moveSpeed * deltaTime;
                InvalidateView();
            }
            camera.Translate(Vector3.Transform(moveDir, camera.GetRotationMatrix()));

            view = camera.GetViewMatrix();

            Vector3 mouseRay = MouseToWorldRay(projection, view, new Size(Width, Height), new Vector2(Cursor.Position.X, Cursor.Position.Y));

            if (xLock || yLock || zLock)
            {
                Vector3 direction = Vector3.Zero;
                if (xLock)
                {
                    direction = Vector3.UnitX;
                }
                else if (yLock)
                {
                    direction = Vector3.UnitY;
                }
                else if (zLock)
                {
                    direction = Vector3.UnitZ;
                }
                float   magnitudeMultiplier = 20;
                Vector3 magnitude           = (mouseRay - prevMouseRay) * magnitudeMultiplier;


                switch (currentTool)
                {
                case TranslationTool t:
                    selectedObject.Translate(direction * magnitude);
                    break;

                case RotationTool t:
                    selectedObject.Rotate(direction * magnitude);
                    break;

                case ScalingTool t:
                    selectedObject.Scale(direction * magnitude + Vector3.One);
                    break;

                case VertexTranslationTool t:
                    if (selectedObject is Spline spline)
                    {
                        /*spline.TranslateVertex(currentSplineVertex, direction * magnitude);
                         * //write at 0x346BA1180 + 0xC0 + spline.offset + currentSplineVertex * 0x10;
                         * // List of splines 0x300A51BE0
                         *
                         * byte[] ptrBuff = new byte[0x04];
                         * int bytesRead = 0;
                         * ReadProcessMemory(processHandle, 0x300A51BE0 + level.splines.IndexOf(spline) * 0x04, ptrBuff, ptrBuff.Length, ref bytesRead);
                         * long splinePtr = ReadUint(ptrBuff, 0) + 0x300000010;
                         *
                         * byte[] buff = new byte[0x0C];
                         * Vector3 vec = spline.GetVertex(currentSplineVertex);
                         * WriteFloat(buff, 0x00, vec.X);
                         * WriteFloat(buff, 0x04, vec.Y);
                         * WriteFloat(buff, 0x08, vec.Z);
                         *
                         * WriteProcessMemory(processHandle, splinePtr + currentSplineVertex * 0x10, buff, buff.Length, ref bytesRead);*/
                    }
                    break;
                }

                InvalidateView();
            }

            prevMouseRay = mouseRay;
            lastMouseX   = Cursor.Position.X;
            lastMouseY   = Cursor.Position.Y;

            if (invalidate)
            {
                Invalidate();
                //invalidate = false;
            }
        }