private ModelBone ProcessBone(PooledTexture2D texture, EntityModel source, EntityModelBone bone, List <VertexPositionColorTexture> vertices, Vector2 uvScale, Vector2 textureSize, Dictionary <string, ModelBone> modelBones)
        {
            ModelBone modelBone;

            List <short> indices = new List <short>();

            bone.Pivot *= new Vector3(-1f, 1f, 1f);

            if (bone.Cubes != null)
            {
                foreach (var cube in bone.Cubes)
                {
                    if (cube == null)
                    {
                        Log.Warn("Cube was null!");
                        continue;
                    }

                    Cube built = new Cube(cube.InflatedSize, textureSize, cube.Uv, uvScale, bone.Mirror);

                    vertices = ModifyCubeIndexes(vertices, cube, ref built.Front, bone.Mirror);
                    vertices = ModifyCubeIndexes(vertices, cube, ref built.Back, bone.Mirror);
                    vertices = ModifyCubeIndexes(vertices, cube, ref built.Top, bone.Mirror);
                    vertices = ModifyCubeIndexes(vertices, cube, ref built.Bottom, bone.Mirror);
                    vertices = ModifyCubeIndexes(vertices, cube, ref built.Left, bone.Mirror);
                    vertices = ModifyCubeIndexes(vertices, cube, ref built.Right, bone.Mirror);

                    indices.AddRange(built.Front.indexes.Concat(built.Back.indexes).Concat(built.Top.indexes)
                                     .Concat(built.Bottom.indexes).Concat(built.Left.indexes).Concat(built.Right.indexes)
                                     .ToArray());
                }
            }

            var bindPoseMatrix = Matrix.CreateTranslation(-bone.Pivot)
                                 * Matrix.CreateRotationY(MathUtils.ToRadians(bone.BindPoseRotation.Y))
                                 * Matrix.CreateRotationX(MathUtils.ToRadians(-bone.BindPoseRotation.X))
                                 * Matrix.CreateRotationZ(MathUtils.ToRadians(bone.BindPoseRotation.Z))
                                 * Matrix.CreateTranslation(bone.Pivot);

            /*var boneMatrix = Matrix.Identity * Matrix.CreateTranslation(-bone.Pivot)
             * Matrix.CreateFromAxisAngle(
             *                                       Vector3.Right, MathUtils.ToRadians(bone.Rotation.X))
             * Matrix.CreateFromAxisAngle(
             *                                       Vector3.Backward, MathUtils.ToRadians(bone.Rotation.Z))
             * Matrix.CreateFromAxisAngle(
             *                                       Vector3.Up, MathUtils.ToRadians(bone.Rotation.Y))
             * Matrix.CreateTranslation(bone.Pivot);*/
            var boneMatrix =
                Matrix.CreateTranslation(-bone.Pivot)
                * Matrix.CreateRotationY(MathUtils.ToRadians(bone.Rotation.Y))
                * Matrix.CreateRotationX(MathUtils.ToRadians(-bone.Rotation.X))
                * Matrix.CreateRotationZ(MathUtils.ToRadians(bone.Rotation.Z))
                * Matrix.CreateTranslation(bone.Pivot);

            modelBone = new ModelBone(texture, indices.ToArray(), bone, bindPoseMatrix * boneMatrix);
            modelBone.Setup(Alex.Instance.GraphicsDevice);

            foreach (var childBone in source.Bones.Where(
                         x => string.Equals(x.Parent, bone.Name, StringComparison.InvariantCultureIgnoreCase)))
            {
                var child = ProcessBone(texture, source, childBone, vertices, uvScale, textureSize, modelBones);
                child.Parent = modelBone;

                modelBone.AddChild(child);

                if (!modelBones.TryAdd(childBone.Name, child))
                {
                    Log.Warn($"Failed to add bone! {childBone.Name}");
                }
            }

            return(modelBone);
        }
        private ModelBone ProcessBone(PooledTexture2D texture,
                                      EntityModel source,
                                      EntityModelBone bone,
                                      List <VertexPositionColorTexture> vertices,
                                      Vector2 textureSize,
                                      Dictionary <string, ModelBone> modelBones)
        {
            ModelBone modelBone;

            List <short> indices = new List <short>();

            //bone.Pivot *= new Vector3(-1f, 1f, 1f);

            if (bone.Cubes != null)
            {
                foreach (var cube in bone.Cubes)
                {
                    if (cube == null)
                    {
                        Log.Warn("Cube was null!");

                        continue;
                    }

                    //if (cube.Uv.IsOutOfBound(textureSize))
                    {
                        //	continue;
                    }

                    var  inflation = (float)(cube.Inflate ?? bone.Inflate);
                    var  mirror    = cube.Mirror ?? bone.Mirror;
                    Cube built     = new Cube(source, cube, textureSize, mirror, inflation);

                    vertices = ModifyCubeIndexes(vertices, cube, ref built.Front, bone, inflation);
                    vertices = ModifyCubeIndexes(vertices, cube, ref built.Back, bone, inflation);
                    vertices = ModifyCubeIndexes(vertices, cube, ref built.Top, bone, inflation);
                    vertices = ModifyCubeIndexes(vertices, cube, ref built.Bottom, bone, inflation);
                    vertices = ModifyCubeIndexes(vertices, cube, ref built.Left, bone, inflation);
                    vertices = ModifyCubeIndexes(vertices, cube, ref built.Right, bone, inflation);

                    indices.AddRange(
                        built.Front.indexes.Concat(built.Back.indexes).Concat(built.Top.indexes)
                        .Concat(built.Bottom.indexes).Concat(built.Left.indexes).Concat(built.Right.indexes)
                        .ToArray());
                }
            }

            var pivot      = bone.Pivot ?? Vector3.Zero;
            var boneMatrix = Matrix.Identity;

            if (bone.BindPoseRotation.HasValue)
            {
                var rotation = bone.BindPoseRotation.Value;

                boneMatrix = Matrix.CreateTranslation(-pivot)
                             * Matrix.CreateRotationX(MathUtils.ToRadians(-rotation.X))
                             * Matrix.CreateRotationY(MathUtils.ToRadians(rotation.Y))
                             * Matrix.CreateRotationZ(MathUtils.ToRadians(rotation.Z))
                             * Matrix.CreateTranslation(pivot);
            }

            modelBone = new ModelBone(texture, indices.ToArray(), bone, boneMatrix);

            if (bone.Rotation.HasValue)
            {
                var r = bone.Rotation.Value;
                modelBone.Rotation = new Vector3(r.X, r.Y, r.Z);
            }

            modelBone.Setup(Alex.Instance.GraphicsDevice);

            foreach (var childBone in source.Bones.Where(
                         x => x.Parent != null && string.Equals(x.Parent, bone.Name, StringComparison.OrdinalIgnoreCase)))
            {
                if (childBone.Parent != null && childBone.Parent.Equals(childBone.Name))
                {
                    continue;
                }

                if (string.IsNullOrWhiteSpace(childBone.Name))
                {
                    childBone.Name = Guid.NewGuid().ToString();
                }

                var child = ProcessBone(texture, source, childBone, vertices, textureSize, modelBones);
                child.Parent = modelBone;

                modelBone.AddChild(child);

                if (!modelBones.TryAdd(childBone.Name, child))
                {
                    Log.Warn($"Failed to add bone! {childBone.Name}");
                    break;
                }
            }

            return(modelBone);
        }