public Texture2D SetupTextureAtlas(GraphicsDevice graphicsDevice)
        {
            var triangles = Models.SelectMany(m => m.ModelTriangles).ToList();
            var dict      = new Dictionary <KeyValuePair <string, Rectangle>, TrianglesWithCroppedTexture>();

            foreach (var triangle in triangles)
            {
                if (!dict.ContainsKey(triangle.TextureKey))
                {
                    if (!TextureHandler.HasCroppedTexture(triangle.TextureKey))
                    {
                        TextureHandler.AddCroppedTexture(triangle.TextureKey, TextureHandler.CropTexture(triangle.OriginalTexture, triangle.OriginalTextureRectangle));
                    }

                    dict.Add(triangle.TextureKey, new TrianglesWithCroppedTexture()
                    {
                        CroppedTexture       = TextureHandler.GetCroppedTexture(triangle.TextureKey).Key,
                        HasTransparentPixels = TextureHandler.GetCroppedTexture(triangle.TextureKey).Value
                    });
                }

                dict[triangle.TextureKey].ModelTriangles.Add(triangle);
            }

            var packer = new RectanglePacker(4096, 4096);

            foreach (var pair in dict)
            {
                var rect = pair.Value.CroppedTexture.Bounds;
                if (!packer.Pack(rect.Width, rect.Height, out rect.X, out rect.Y))
                {
                    throw new Exception("Uh oh, we couldn't pack the rectangles");
                }
                pair.Value.AtlasRectangle = rect;
            }

            foreach (var pair in dict)
            {
                foreach (var triangle in pair.Value.ModelTriangles)
                {
                    triangle.AtlasTextureRectangle = pair.Value.AtlasRectangle;
                    triangle.HasTransparentPixels  = pair.Value.HasTransparentPixels;
                }
            }

            var atlas = new Texture2D(graphicsDevice, 4096, 4096);

            foreach (var pair in dict)
            {
                var data = new Color[pair.Value.CroppedTexture.Width * pair.Value.CroppedTexture.Height];
                pair.Value.CroppedTexture.GetData(0, pair.Value.CroppedTexture.Bounds, data, 0, data.Length);
                atlas.SetData(0, pair.Value.AtlasRectangle, data, 0, data.Length);
                pair.Value.CroppedTexture = null;
            }

            return(atlas);
        }