コード例 #1
0
        public void RemoveModel(Model model)
        {
            models.Remove(model);
            Armature armature = model.Armature;
            int      i        = 0;

            while (i < activeBones.Count)
            {
                Armature.Bone bone = activeBones[i];
                if (bone.armature == armature)
                {
                    activeBones.RemoveAt(i);
                    if (model.IsVisible)
                    {
                        int j = visibleBones.IndexOf(bone);
                        visibleBones.RemoveAt(j);
                        visibleBonesProjections.RemoveAt(j);
                    }
                }
                else
                {
                    i++;
                }
            }
            armature.ArmatureEvent -= HandleArmatureEvent;
            selectedBoneIndex       = -1;
        }
コード例 #2
0
        private void RecalculateBonePositions()
        {
            Viewport viewport         = graphicsDevice.Viewport;
            Matrix   projectionMatrix = camera.ProjectionMatrix;
            Matrix   viewMatrix       = camera.ViewMatrix;
            float    cameraNear       = camera.NearPlane;

            renderedBonesCount = 0;
            for (int i = 0; i < visibleBones.Count; i++)
            {
                Armature.Bone bone        = visibleBones[i];
                Matrix        worldMatrix = bone.armature.WorldMatrix;
                Vector3       absPos      = bone.absTransform.Translation;
                Vector3       projected   = viewport.Project(absPos, projectionMatrix, viewMatrix, worldMatrix);
                projected.Y = viewport.Height - 1 - projected.Y;
                if (projected.Z > 0 && projected.Z < 1)
                {
                    projected.Z = 0;
                    renderedBonesCount++;
                }
                else
                {
                    projected.Z = -1;
                }
                visibleBonesProjections[i] = projected;
            }
        }
コード例 #3
0
ファイル: PoseImportExport.cs プロジェクト: xphillyx/XNALara
        private void LoadPoseNew(List <string> lines)
        {
            Armature armature = selectedItem.Model.Armature;
            Dictionary <string, BoneTransform> boneTransforms = new Dictionary <string, BoneTransform>();

            foreach (string line in lines)
            {
                string[] tokens1 = line.Split(':');
                if (tokens1.Length == 2)
                {
                    string        boneName = tokens1[0].Trim();
                    Armature.Bone bone     = armature.GetBone(boneName);
                    if (bone != null)
                    {
                        string[] tokens2 = tokens1[1].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        if (tokens2.Length == 3 || tokens2.Length == 6)
                        {
                            BoneTransform boneTransform = new BoneTransform();
                            boneTransform.rotX = float.Parse(tokens2[0]);
                            boneTransform.rotY = float.Parse(tokens2[1]);
                            boneTransform.rotZ = float.Parse(tokens2[2]);
                            if (tokens2.Length == 6)
                            {
                                boneTransform.moveX = float.Parse(tokens2[3]);
                                boneTransform.moveY = float.Parse(tokens2[4]);
                                boneTransform.moveZ = float.Parse(tokens2[5]);
                            }
                            else
                            {
                                boneTransform.moveX = 0;
                                boneTransform.moveY = 0;
                                boneTransform.moveZ = 0;
                            }
                            boneTransforms[boneName] = boneTransform;
                        }
                    }
                }
            }

            ICollection <string> boneNames = boneTransforms.Keys;
            PoseFilterDialog     dialog    = new PoseFilterDialog(game, "Load pose", "Select bones to load:", boneNames, true);

            if (dialog.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }
            DataSet dataSet = dataSetDict[selectedItem];

            foreach (string boneName in boneNames)
            {
                if (dialog.IsBoneSelected(boneName))
                {
                    Armature.Bone bone          = armature.GetBone(boneName);
                    BoneTransform boneTransform = boneTransforms[boneName];
                    dataSet.boneTransforms[bone.id] = boneTransform;
                    ApplyTransformToBone(bone, boneTransform);
                }
            }
        }
コード例 #4
0
        private Armature LoadArmature(BinaryReader file, Model model)
        {
            int boneCount = file.ReadInt32();

            if (boneCount == 0)
            {
                return(null);
            }
            Armature armature = new Armature(model);

            Armature.Bone[] bones     = new Armature.Bone[boneCount];
            int[]           parentIDs = new int[boneCount];
            for (int boneID = 0; boneID < boneCount; boneID++)
            {
                Armature.Bone bone = new Armature.Bone();
                bone.armature     = armature;
                bone.id           = boneID;
                bone.name         = file.ReadString();
                parentIDs[boneID] = file.ReadInt16();
                float absPosX = file.ReadSingle();
                float absPosY = file.ReadSingle();
                float absPosZ = file.ReadSingle();
                bone.absPosition = new Vector3(absPosX, absPosY, absPosZ);
                bones[boneID]    = bone;
            }
            for (int boneID = 0; boneID < boneCount; boneID++)
            {
                Armature.Bone bone     = bones[boneID];
                int           parentID = parentIDs[boneID];
                if (parentID >= 0)
                {
                    Armature.Bone parent = bones[parentID];
                    bone.parent = parent;
                    parent.children.Add(bone);
                }
            }
            armature.Bones = bones;
            return(armature);
        }
コード例 #5
0
ファイル: Utils.cs プロジェクト: xphillyx/XNALara
        public static Vector3 GetTransformedBone(Armature.Bone bone, Matrix worldMatrix)
        {
            Matrix m = bone.absTransform * worldMatrix;

            return(Vector3.Transform(Vector3.Zero, m));
        }
コード例 #6
0
        private void MirrorPose()
        {
            if (selectedItem == null)
            {
                return;
            }

            Armature armature = selectedItem.Model.Armature;

            List <string> labels = new List <string>();

            foreach (Armature.Bone bone in armature.Bones)
            {
                int    origSide;
                string mirroredName = GetMirroredBoneName(bone.name, out origSide);
                if (mirroredName != null && origSide < 0 && armature.GetBone(mirroredName) != null)
                {
                    labels.Add("L: " + bone.name);
                }
            }
            foreach (Armature.Bone bone in armature.Bones)
            {
                int    origSide;
                string mirroredName = GetMirroredBoneName(bone.name, out origSide);
                if (mirroredName != null && origSide > 0 && armature.GetBone(mirroredName) != null)
                {
                    labels.Add("R: " + bone.name);
                }
            }

            PoseFilterDialog dialog = new PoseFilterDialog(game, "Mirror (copy) pose left/right", "Select bones to mirror pose from:", labels, false);

            if (dialog.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }

            DataSet dataSet = dataSetDict[selectedItem];

            foreach (string label in labels)
            {
                if (!dialog.IsBoneSelected(label))
                {
                    continue;
                }

                string        boneNameFrom      = label.Substring(3);
                Armature.Bone boneFrom          = armature.GetBone(boneNameFrom);
                BoneTransform boneTransformFrom = dataSet.boneTransforms[boneFrom.id];

                string        boneNameTo      = GetMirroredBoneName(boneNameFrom);
                Armature.Bone boneTo          = armature.GetBone(boneNameTo);
                BoneTransform boneTransformTo = dataSet.boneTransforms[boneTo.id];

                boneTransformTo.moveX = -boneTransformFrom.moveX;
                boneTransformTo.moveY = +boneTransformFrom.moveY;
                boneTransformTo.moveZ = +boneTransformFrom.moveZ;

                boneTransformTo.rotX = +boneTransformFrom.rotX;
                boneTransformTo.rotY = -boneTransformFrom.rotY;
                boneTransformTo.rotZ = -boneTransformFrom.rotZ;

                ApplyTransformToBone(boneTo, boneTransformTo);
            }
        }
コード例 #7
0
ファイル: PoseFlip.cs プロジェクト: xphillyx/XNALara
        private void FlipPose()
        {
            if (selectedItem == null)
            {
                return;
            }

            Armature armature = selectedItem.Model.Armature;

            List <string> labels = new List <string>();
            Dictionary <string, string> labelsToBoneNames = new Dictionary <string, string>();

            foreach (Armature.Bone bone in armature.Bones)
            {
                int    origSide;
                string flippedName = GetFlippedBoneName(bone.name, out origSide);
                if (flippedName != null && origSide < 0 && armature.GetBone(flippedName) != null)
                {
                    string combinedName = GetCombinedBoneName(bone.name);
                    labels.Add(combinedName);
                    labelsToBoneNames[combinedName] = bone.name;
                }
            }

            PoseFilterDialog dialog = new PoseFilterDialog(game, "Flip (swap) pose left/right", "Select bone pairs whose pose to flip:", labels, false);

            if (dialog.ShowDialog(this) != DialogResult.OK)
            {
                return;
            }

            DataSet dataSet = dataSetDict[selectedItem];

            foreach (string label in labels)
            {
                if (!dialog.IsBoneSelected(label))
                {
                    continue;
                }

                string        boneName1      = labelsToBoneNames[label];
                Armature.Bone bone1          = armature.GetBone(boneName1);
                BoneTransform boneTransform1 = dataSet.boneTransforms[bone1.id];

                string        boneName2      = GetFlippedBoneName(boneName1);
                Armature.Bone bone2          = armature.GetBone(boneName2);
                BoneTransform boneTransform2 = dataSet.boneTransforms[bone2.id];

                float moveX1 = boneTransform1.moveX;
                float moveY1 = boneTransform1.moveY;
                float moveZ1 = boneTransform1.moveZ;

                float rotX1 = boneTransform1.rotX;
                float rotY1 = boneTransform1.rotY;
                float rotZ1 = boneTransform1.rotZ;

                float moveX2 = boneTransform2.moveX;
                float moveY2 = boneTransform2.moveY;
                float moveZ2 = boneTransform2.moveZ;

                float rotX2 = boneTransform2.rotX;
                float rotY2 = boneTransform2.rotY;
                float rotZ2 = boneTransform2.rotZ;

                boneTransform2.moveX = -moveX1;
                boneTransform2.moveY = +moveY1;
                boneTransform2.moveZ = +moveZ1;

                boneTransform2.rotX = +rotX1;
                boneTransform2.rotY = -rotY1;
                boneTransform2.rotZ = -rotZ1;

                boneTransform1.moveX = -moveX2;
                boneTransform1.moveY = +moveY2;
                boneTransform1.moveZ = +moveZ2;

                boneTransform1.rotX = +rotX2;
                boneTransform1.rotY = -rotY2;
                boneTransform1.rotZ = -rotZ2;

                ApplyTransformToBone(bone1, boneTransform1);
                ApplyTransformToBone(bone2, boneTransform2);
            }
        }
コード例 #8
0
ファイル: ModelLoaderObj.cs プロジェクト: xphillyx/XNALara
        private Model LoadModel(string filenameObj, Dictionary <string, Material> materials)
        {
            StreamReader file = null;

            try {
                file = new StreamReader(filenameObj);
            }
            catch (Exception) {
                MessageBox.Show("Could not open OBJ file.",
                                "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(null);
            }
            try {
                Model          model           = new Model(game);
                List <Vector3> vertexCoords    = new List <Vector3>();
                List <Vector3> vertexNormals   = new List <Vector3>();
                List <Vector2> vertexTexCoords = new List <Vector2>();
                List <Vector4> vertexColors    = new List <Vector4>();

                List <Vertex>            vertexList = new List <Vertex>();
                Dictionary <Vertex, int> vertexDict = new Dictionary <Vertex, int>();
                List <Face> faces = new List <Face>();

                int      meshID   = 0;
                Material material = null;
                lineCounter = 0;

                while (true)
                {
                    lineCounter++;
                    string line = file.ReadLine();
                    if (line != null)
                    {
                        line = line.TrimStart();
                    }

                    if (line == null || line.StartsWith("usemtl "))
                    {
                        if (faces.Count > 0)
                        {
                            if (material == null)
                            {
                                throw new Exception(string.Format("No material assigned (line {0}).", lineCounter));
                            }
                            if (material.textureDiffuse == null)
                            {
                                throw new Exception(string.Format("No diffuse texture defined for material \"{0}\".", material.name));
                            }
                            meshID++;
                            string   meshName = string.Format("Mesh{0}", meshID);
                            MeshDesc meshDesc = BuildMeshDesc(meshName, material, vertexList, faces);
                            model.AddMeshDesc(meshDesc);
                            vertexList.Clear();
                            vertexDict.Clear();
                            faces.Clear();
                        }
                        if (line == null)
                        {
                            break;
                        }
                        string materialName = line.Substring(7).Trim();
                        material = materials[materialName];
                    }

                    if (line.StartsWith("v "))
                    {
                        Vector3 coord = ParseVertexCoord(line.Substring(2));
                        vertexCoords.Add(coord);
                        continue;
                    }
                    if (line.StartsWith("vn "))
                    {
                        Vector3 normal = ParseVertexNormal(line.Substring(3));
                        normal.Normalize();
                        vertexNormals.Add(normal);
                        continue;
                    }
                    if (line.StartsWith("vt "))
                    {
                        Vector2 texCoord = ParseVertexTexCoord(line.Substring(3));
                        vertexTexCoords.Add(texCoord);
                        continue;
                    }
                    if (line.StartsWith("vc "))
                    {
                        Vector4 color = ParseVertexColor(line.Substring(3));
                        vertexColors.Add(color);
                        continue;
                    }
                    if (line.StartsWith("f "))
                    {
                        Face face = ParseFace(line.Substring(2));
                        try {
                            for (int i = 0; i < face.vertexIndices.Length; i++)
                            {
                                Vertex vertex = new Vertex();
                                int    index;
                                index           = face.coordIndices[i];
                                vertex.coord    = index > 0 ? vertexCoords[index - 1] : vertexCoords[vertexCoords.Count + index];
                                index           = face.normalIndices[i];
                                vertex.normal   = index > 0 ? vertexNormals[index - 1] : vertexNormals[vertexNormals.Count + index];
                                index           = face.texCoordIndices[i];
                                vertex.texCoord = index > 0 ? vertexTexCoords[index - 1] : vertexTexCoords[vertexTexCoords.Count + index];
                                if (face.colorIndices != null)
                                {
                                    index        = face.colorIndices[i];
                                    vertex.color = index > 0 ? vertexColors[index - 1] : vertexColors[vertexColors.Count + index];
                                }
                                else
                                {
                                    vertex.color = new Vector4(1, 1, 1, 1);
                                }
                                if (!vertexDict.TryGetValue(vertex, out index))
                                {
                                    index = vertexList.Count;
                                    vertexList.Add(vertex);
                                    vertexDict[vertex] = index;
                                }
                                face.vertexIndices[i] = index;
                            }
                        }
                        catch (Exception) {
                            throw new Exception(string.Format("Invalid face: invalid vertex index (line {0}).", lineCounter));
                        }
                        if (face.vertexIndices.Length == 3)
                        {
                            FlipTriangularFace(face);
                            faces.Add(face);
                        }
                        else
                        {
                            Face[] triFaces = Triangulate(face);
                            FlipTriangularFace(triFaces[0]);
                            FlipTriangularFace(triFaces[1]);
                            faces.Add(triFaces[0]);
                            faces.Add(triFaces[1]);
                        }
                        continue;
                    }
                }

                Armature      armature = new Armature(model);
                Armature.Bone bone     = new Armature.Bone();
                bone.armature    = armature;
                bone.id          = 0;
                bone.name        = "root";
                bone.absPosition = Vector3.Zero;
                bone.parent      = null;
                armature.Bones   = new Armature.Bone[] { bone };
                model.Armature   = armature;

                file.Close();
                return(model);
            }
            catch (Exception ex) {
                MessageBox.Show("Could not load OBJ file.\n" + ex.Message,
                                "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(null);
            }
        }
コード例 #9
0
        public void Render()
        {
            if (selectedBoneIndex < 0 || renderedBonesCount == 0)
            {
                return;
            }
            Color DefaultBoneColor = new Color(Color.White, 0.35f);

            Armature.Bone selectedBone     = null;
            Vector3       selectedBoneProj = Vector3.Zero;

            VertexPositionColor[] points = new VertexPositionColor[renderedBonesCount];
            int j = 0;

            for (int i = 0; i < visibleBones.Count; i++)
            {
                Vector3 boneProj = visibleBonesProjections[i];
                if (boneProj.Z < 0)
                {
                    continue;
                }
                Color color;
                if (i == selectedBoneIndex)
                {
                    color            = Color.Red;
                    selectedBone     = visibleBones[i];
                    selectedBoneProj = boneProj;
                }
                else
                {
                    color = DefaultBoneColor;
                }
                points[j] = new VertexPositionColor(boneProj, color);
                j++;
            }

            graphicsDevice.RenderState.PointSize = 5;
            graphicsDevice.VertexDeclaration     = vertexDeclaration;

            graphicsDevice.RenderState.AlphaBlendEnable = true;
            graphicsDevice.RenderState.SourceBlend      = Blend.SourceAlpha;
            graphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;

            basicEffect.VertexColorEnabled = true;
            basicEffect.World      = Matrix.Identity;
            basicEffect.View       = viewMatrix;
            basicEffect.Projection = projectionMatrix;

            basicEffect.Begin();
            foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
            {
                pass.Begin();
                graphicsDevice.DrawUserPrimitives <VertexPositionColor>(PrimitiveType.PointList, points, 0, points.Length);
                pass.End();
            }
            basicEffect.End();

            graphicsDevice.RenderState.AlphaBlendEnable = false;

            if (game.DisplayBoneNames && selectedBone != null)
            {
                spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.SaveState);
                int    x     = (int)Math.Round(selectedBoneProj.X);
                int    y     = (int)Math.Round(screenHeight - 1 - selectedBoneProj.Y - font.LineSpacing - 3);
                string label = selectedBone.name;
                spriteBatch.DrawString(font, label, new Vector2(x + 1, y + 1), Color.Black);
                spriteBatch.DrawString(font, label, new Vector2(x, y), Color.Yellow);
                spriteBatch.End();
            }
        }
コード例 #10
0
ファイル: Game.cs プロジェクト: xphillyx/XNALara
        private void ProcessKeyboard(float deltaMilliseconds)
        {
            KeyboardState keyboardState = Keyboard.GetState();

            KeyboardEventHandler.ProcessKeyboardState(keyboardState);

            if (KeyboardEventHandler.HasKeyBeenPressed(Keys.NumPad0))
            {
                Armature.Bone selectedBone = controlGUI.SelectedBone;
                if (selectedBone != null)
                {
                    controlGUI.HandleBoneRotationXChanged(selectedBone, 0);
                    controlGUI.HandleBoneRotationYChanged(selectedBone, 0);
                    controlGUI.HandleBoneRotationZChanged(selectedBone, 0);
                }
            }

            bool ctrlKeyPressed = keyboardState.IsKeyDown(Keys.LeftControl) ||
                                  keyboardState.IsKeyDown(Keys.RightControl);
            bool shiftKeyPressed = keyboardState.IsKeyDown(Keys.LeftShift) ||
                                   keyboardState.IsKeyDown(Keys.RightShift);
            bool altKeyPressed = keyboardState.IsKeyDown(Keys.LeftAlt) ||
                                 keyboardState.IsKeyDown(Keys.RightAlt);

            if (keyboardState.IsKeyDown(Keys.Up) ||
                keyboardState.IsKeyDown(Keys.Down) ||
                keyboardState.IsKeyDown(Keys.Left) ||
                keyboardState.IsKeyDown(Keys.Right))
            {
                Item selectedItem = controlGUI.SelectedItem;
                if (selectedItem != null)
                {
                    Armature armature = selectedItem.Model.Armature;
                    float    speed    = shiftKeyPressed ? 3e-3f : 1e-3f;
                    if (!altKeyPressed)
                    {
                        Vector3 dir = Vector3.Zero;
                        if (keyboardState.IsKeyDown(Keys.Up))
                        {
                            dir += DetermineMovementVector(Keys.Up);
                        }
                        if (keyboardState.IsKeyDown(Keys.Down))
                        {
                            dir += DetermineMovementVector(Keys.Down);
                        }
                        if (keyboardState.IsKeyDown(Keys.Left))
                        {
                            dir += DetermineMovementVector(Keys.Left);
                        }
                        if (keyboardState.IsKeyDown(Keys.Right))
                        {
                            dir += DetermineMovementVector(Keys.Right);
                        }
                        armature.WorldTranslation += dir * speed;
                        controlGUI.HandlePositionChanged(armature.WorldTranslation);
                    }
                    else
                    {
                        float dir = 0;
                        if (keyboardState.IsKeyDown(Keys.Up))
                        {
                            dir += 1;
                        }
                        if (keyboardState.IsKeyDown(Keys.Down))
                        {
                            dir -= 1;
                        }
                        float height = armature.WorldTranslation.Y;
                        height += dir * speed;
                        controlGUI.HandleHeightChanged(height);
                    }
                }
            }

            if (KeyboardEventHandler.HasKeyBeenPressed(Keys.F2))
            {
                cameraSavedState = camera.CameraState;
                hud.Message      = "camera state saved";
            }

            if (KeyboardEventHandler.HasKeyBeenPressed(Keys.F3))
            {
                if (cameraSavedState != null)
                {
                    camera.CameraState = cameraSavedState;
                    hud.Message        = "camera state loaded";
                }
            }

            if (KeyboardEventHandler.HasKeyBeenPressed(Keys.F5))
            {
                controlGUI.QuickSaveImage();
            }

            if (KeyboardEventHandler.HasKeyBeenPressed(Keys.F8))
            {
                controlGUI.ReloadTextures();
            }

            if (KeyboardEventHandler.HasKeyBeenPressed(Keys.F12))
            {
                if (controlGUI.IsDisposed)
                {
                    controlGUI = new ControlGUI(this);
                }
                controlGUI.Show();
            }

            if (!controlGUI.IsCameraLocked)
            {
                if (KeyboardEventHandler.HasKeyBeenPressed(Keys.D1))
                {
                    controlGUI.SetCameraPivot(0);
                }
                if (KeyboardEventHandler.HasKeyBeenPressed(Keys.D2))
                {
                    controlGUI.SetCameraPivot(1);
                }
                if (KeyboardEventHandler.HasKeyBeenPressed(Keys.D3))
                {
                    controlGUI.SetCameraPivot(2);
                }
                if (KeyboardEventHandler.HasKeyBeenPressed(Keys.D4))
                {
                    controlGUI.SetCameraPivot(3);
                }
                if (KeyboardEventHandler.HasKeyBeenPressed(Keys.D5))
                {
                    controlGUI.SetCameraPivot(4);
                }
                if (KeyboardEventHandler.HasKeyBeenPressed(Keys.D6))
                {
                    controlGUI.SetCameraPivot(5);
                }
                if (KeyboardEventHandler.HasKeyBeenPressed(Keys.D7))
                {
                    controlGUI.SetCameraPivot(6);
                }
                if (KeyboardEventHandler.HasKeyBeenPressed(Keys.D8))
                {
                    controlGUI.SetCameraPivot(7);
                }
                if (KeyboardEventHandler.HasKeyBeenPressed(Keys.D9))
                {
                    controlGUI.SetCameraPivot(8);
                }
                if (KeyboardEventHandler.HasKeyBeenPressed(Keys.D0))
                {
                    controlGUI.SetCameraPivot(9);
                }
            }

            if (ctrlKeyPressed && KeyboardEventHandler.HasKeyBeenPressed(Keys.Z) ||
                KeyboardEventHandler.HasKeyBeenPressed(Keys.NumPad5))
            {
                controlGUI.Undo();
            }
        }
コード例 #11
0
ファイル: Game.cs プロジェクト: xphillyx/XNALara
        private void ProcessMouse(float deltaMilliseconds)
        {
            MouseState mouseState = Mouse.GetState();

            KeyboardState keyboardState  = Keyboard.GetState();
            bool          axisKeyPressed = keyboardState.IsKeyDown(Keys.NumPad1) ||
                                           keyboardState.IsKeyDown(Keys.NumPad2) ||
                                           keyboardState.IsKeyDown(Keys.NumPad3) ||
                                           keyboardState.IsKeyDown(Keys.Q) ||
                                           keyboardState.IsKeyDown(Keys.W) ||
                                           keyboardState.IsKeyDown(Keys.E);
            bool ctrlKeyPressed = keyboardState.IsKeyDown(Keys.LeftControl) ||
                                  keyboardState.IsKeyDown(Keys.RightControl);
            bool shiftKeyPressed = keyboardState.IsKeyDown(Keys.LeftShift) ||
                                   keyboardState.IsKeyDown(Keys.RightShift);
            bool altKeyPressed = keyboardState.IsKeyDown(Keys.LeftAlt) ||
                                 keyboardState.IsKeyDown(Keys.RightAlt);

            if (axisKeyPressed ||
                ctrlKeyPressed ||
                shiftKeyPressed ||
                altKeyPressed)
            {
                disableBoneSelection = true;
            }
            else
            {
                if (!mouseLeftDragging)
                {
                    disableBoneSelection = false;
                }
            }

            if (mouseState.LeftButton == ButtonState.Pressed)
            {
                if (displayBones && !disableBoneSelection)
                {
                    Armature.Bone selectedBone = boneSelector.SelectedBone;
                    if (selectedBone != null)
                    {
                        controlGUI.HandleBoneSelectedIn3D(selectedBone);
                    }
                }
                if (!mouseLeftDragging)
                {
                    mouseLeftDragging = true;
                    mouseAnchor       = new Point(mouseState.X, mouseState.Y);
                }
            }
            else
            {
                mouseLeftDragging    = false;
                disableBoneSelection = false;

                if (boneTransformActive)
                {
                    boneTransformActive = false;
                    controlGUI.UndoSaveInterrupt();
                }
            }

            if (mouseState.RightButton == ButtonState.Pressed)
            {
                if (!mouseRightDragging)
                {
                    mouseRightDragging = true;
                    mouseAnchor        = new Point(mouseState.X, mouseState.Y);
                }
            }
            else
            {
                mouseRightDragging = false;
            }

            if (mouseLeftDragging && mouseRightDragging)
            {
                int dx = mouseState.X - mouseAnchor.X;
                int dy = mouseState.Y - mouseAnchor.Y;
                mouseAnchor = new Point(mouseState.X, mouseState.Y);

                if (!controlGUI.IsCameraLocked)
                {
                    camera.Target -= (camera.Left * dx - camera.Up * dy) * 0.005f;
                }
                return;
            }

            if (mouseLeftDragging)
            {
                int dx = mouseState.X - mouseAnchor.X;
                int dy = mouseState.Y - mouseAnchor.Y;
                mouseAnchor = new Point(mouseState.X, mouseState.Y);

                if (axisKeyPressed)
                {
                    Armature.Bone selectedBone = controlGUI.SelectedBone;
                    if (selectedBone != null)
                    {
                        boneTransformActive = true;

                        if (keyboardState.IsKeyDown(Keys.NumPad1) ||
                            keyboardState.IsKeyDown(Keys.Q))
                        {
                            float angle = controlGUI.GetBoneRotationX(selectedBone);
                            controlGUI.HandleBoneRotationXChanged(selectedBone, angle + (dx + dy) * 0.5f);
                        }
                        if (keyboardState.IsKeyDown(Keys.NumPad2) ||
                            keyboardState.IsKeyDown(Keys.W))
                        {
                            float angle = controlGUI.GetBoneRotationY(selectedBone);
                            controlGUI.HandleBoneRotationYChanged(selectedBone, angle + (dx + dy) * 0.5f);
                        }
                        if (keyboardState.IsKeyDown(Keys.NumPad3) ||
                            keyboardState.IsKeyDown(Keys.E))
                        {
                            float angle = controlGUI.GetBoneRotationZ(selectedBone);
                            controlGUI.HandleBoneRotationZChanged(selectedBone, angle + (dx + dy) * 0.5f);
                        }
                    }
                    return;
                }

                if (ctrlKeyPressed)
                {
                    Item selectedItem = controlGUI.SelectedItem;
                    if (selectedItem != null)
                    {
                        Vector3 point;
                        if (ProjectMouseToGround(mouseState.X, mouseState.Y, out point))
                        {
                            Armature armature = selectedItem.Model.Armature;
                            float    height   = armature.WorldTranslation.Y;
                            armature.WorldTranslation = new Vector3(point.X, height, point.Z);
                            controlGUI.HandlePositionChanged(armature.WorldTranslation);
                        }
                    }
                    return;
                }

                if (!controlGUI.IsCameraLocked)
                {
                    if (shiftKeyPressed)
                    {
                        camera.Target -= (camera.Left * dx - camera.Up * dy) * 0.005f;
                        return;
                    }
                    float rotationHorizontal = camera.RotationHorizontal - dx * 0.01f;
                    float rotationVertical   = camera.RotationVertical + dy * 0.01f;
                    camera.SetRotation(rotationHorizontal, rotationVertical);
                }
            }

            if (mouseRightDragging)
            {
                if (!controlGUI.IsCameraLocked)
                {
                    int dy = mouseState.Y - mouseAnchor.Y;
                    mouseAnchor = new Point(mouseState.X, mouseState.Y);
                    if (!shiftKeyPressed)
                    {
                        camera.Distance += dy * 0.01f;
                    }
                    else
                    {
                        camera.Target -= camera.Forward * dy * 0.005f;
                    }
                }
            }

            if (!mouseLeftDragging && !mouseRightDragging)
            {
                boneSelector.HandleMouseMoved(mouseState.X, mouseState.Y);
            }

            if (mouseWheel != mouseState.ScrollWheelValue)
            {
                if (!controlGUI.IsCameraLocked)
                {
                    int delta = mouseWheel - mouseState.ScrollWheelValue;
                    camera.Distance += delta * 0.002f;
                }
                mouseWheel = mouseState.ScrollWheelValue;
            }
        }