private void GenerateAtlas(GraphicsDevice device, IDictionary <ResourceLocation, ImageEntry> blockTextures, IProgressReceiver progressReceiver) { Stopwatch sw = Stopwatch.StartNew(); Log.Info($"Generating texture atlas out of {(blockTextures.Count)} bitmaps..."); long totalSize = 0; Image <Rgba32> no; using (MemoryStream ms = new MemoryStream(ResourceManager.ReadResource("Alex.Resources.no.png"))) { no = Image.Load <Rgba32>(ms); } Dictionary <ResourceLocation, TextureInfo> stillFrameInfo = new Dictionary <ResourceLocation, TextureInfo>(); GenerateAtlasInternal( new[] { new KeyValuePair <ResourceLocation, Image <Rgba32> >("no_texture", no), }.Concat( blockTextures .Where(x => x.Value.Image.Height == TextureHeight && x.Value.Image.Width == TextureWidth).Select( x => new KeyValuePair <ResourceLocation, Image <Rgba32> >(x.Key, x.Value.Image))).ToArray(), progressReceiver, stillFrameInfo, false, out var stillAtlas); AtlasSize = new Vector2(stillAtlas.Width, stillAtlas.Height); // totalSize += size; _atlasLocations = stillFrameInfo; var stillFrame = GetMipMappedTexture2D(device, stillAtlas); totalSize += stillFrame.MemoryUsage; _stillFrame = stillFrame; _frames = ProcessFrames(device, progressReceiver, blockTextures); totalSize += _frames.Sum(x => x.MemoryUsage); sw.Stop(); Log.Info( $"TextureAtlas's generated in {sw.ElapsedMilliseconds}ms! ({PlayingState.GetBytesReadable(totalSize, 2)})"); }
public ModelDebugState() { _debugInfo = new GuiDebugInfo(); Background = Color.DeepSkyBlue; BlockModelExplorer = new BlockModelExplorer(Alex.Instance, null); EntityModelExplorer = new EntityModelExplorer(Alex.Instance, null); ModelExplorer = BlockModelExplorer; //AddChild(_wrap = new GuiStackContainer() //{ // Orientation = Orientation.Horizontal, // Anchor = Alignment.Fill, // ChildAnchor = Alignment.FillY //}); AddChild(_modelExplorerView = new GuiModelExplorerView(ModelExplorer, new Vector3(0f, 1.85f, 6f), new Vector3(0.5f, 0.5f, 0.5f)) { Anchor = Alignment.Fill, Background = Color.TransparentBlack, BackgroundOverlay = new Color(Color.Black, 0.15f), Margin = new Thickness(0), Width = 92, Height = 128, AutoSizeMode = AutoSizeMode.None, //Anchor = Alignment.BottomRight, // Width = 100, // Height = 100 }); AddChild(_mainMenu = new GuiStackMenu() { Margin = new Thickness(0, 0, 15, 0), Padding = new Thickness(0, 50, 0, 0), Width = 125, Anchor = Alignment.FillY | Alignment.MinX, ChildAnchor = Alignment.CenterY | Alignment.FillX, BackgroundOverlay = new Color(Color.Black, 0.35f) }); //_wrap.AddChild(_modelRenderer = new DebugModelRenderer(Alex) //{ // Anchor = Alignment.Fill, // // Width = 100, // // Height = 100 //}); _mainMenu.AddMenuItem("Skip", () => { Task.Run(() => { ModelExplorer.Skip(); }); }); _mainMenu.AddMenuItem("Next", NextModel); _mainMenu.AddMenuItem("Previous", PrevModel); _mainMenu.AddMenuItem("Switch Models", () => { SwitchModelExplorers(); _modelExplorerView.ModelExplorer = ModelExplorer; }); //AddChild(_mainMenu); _debugInfo.AddDebugRight(() => Alex.DotnetRuntime); //_debugInfo.AddDebugRight(() => MemoryUsageDisplay); _debugInfo.AddDebugRight(() => $"RAM: {PlayingState.GetBytesReadable(_ramUsage, 2)}"); _debugInfo.AddDebugRight(() => $"GPU: {PlayingState.GetBytesReadable(GpuResourceManager.GetMemoryUsage, 2)}"); _debugInfo.AddDebugRight(() => { return ($"Threads: {(_threadsUsed):00}/{_maxThreads}\nCompl.ports: {_complPortUsed:00}/{_maxComplPorts}"); }); _debugInfo.AddDebugRight(() => { if (ModelExplorer == null) { return(string.Empty); } return(ModelExplorer.GetDebugInfo()); }); _keyState = Keyboard.GetState(); }
public bool CheckUpdate(IProgressReceiver progressReceiver, out string path) { path = String.Empty; progressReceiver?.UpdateProgress(0, "Checking for resource updates..."); using var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = true, }); try { // string assetsZipSavePath = String.Empty; string currentVersion; if (TryGetStoredAssetVersion(out currentVersion)) { path = Path.Combine("assets", $"bedrock-{currentVersion}.zip"); if (!Storage.Exists(path)) { currentVersion = null; } } try { var zipDownloadHeaders = httpClient.Send( new HttpRequestMessage(HttpMethod.Get, DownloadURL), HttpCompletionOption.ResponseHeadersRead); var fileName = zipDownloadHeaders.Content?.Headers?.ContentDisposition?.FileName ?? zipDownloadHeaders.RequestMessage?.RequestUri?.LocalPath; var versionMatch = ExtractVersionFromFilename.Match(fileName); if (versionMatch.Success) { var latestVersion = versionMatch.Groups["version"].Value; if (latestVersion != currentVersion || (!string.IsNullOrWhiteSpace(path) && !Storage.Exists(path))) { if (Storage.Exists(path)) { Storage.Delete(path); } progressReceiver?.UpdateProgress( 0, "Downloading latest bedrock assets...", "This could take a while..."); /* zipDownloadHeaders = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, * zipDownloadHeaders.Headers.Location), HttpCompletionOption.ResponseContentRead); * var content = await zipDownloadHeaders.Content.ReadAsByteArrayAsync();*/ Stopwatch sw = new Stopwatch(); WebClient wc = new WebClient(); wc.DownloadProgressChanged += (sender, args) => { var downloadSpeed = $"Download speed: {PlayingState.GetBytesReadable((long) (Convert.ToDouble(args.BytesReceived) / sw.Elapsed.TotalSeconds), 2)}/s"; progressReceiver?.UpdateProgress( args.ProgressPercentage, $"Downloading latest bedrock assets...", downloadSpeed); }; bool complete = false; string archivePath = string.Empty; wc.DownloadDataCompleted += (sender, args) => { var content = args.Result; archivePath = Path.Combine("assets", $"bedrock-{latestVersion}.zip"); // save locally Storage.TryWriteString(CurrentBedrockVersionStorageKey, latestVersion); Storage.TryWriteBytes(archivePath, content); complete = true; }; wc.DownloadDataAsync(zipDownloadHeaders.RequestMessage.RequestUri); sw.Restart(); SpinWait.SpinUntil(() => complete); path = archivePath; return(true); } } return(false); } catch (Exception ex) { Log.Error(ex, "Failed to download bedrock assets..."); return(false); } } catch (Exception ex) { Log.Error(ex, "Failed to fetch latest bedrock assets pack."); throw; } }
public void GenerateAtlas(GraphicsDevice device, KeyValuePair <string, Image <Rgba32> >[] bitmaps, IReadOnlyDictionary <string, TextureMeta> meta, IProgressReceiver progressReceiver) { Stopwatch sw = Stopwatch.StartNew(); Log.Info($"Generating texture atlas out of {bitmaps.Length} bitmaps..."); long totalSize = 0; Image <Rgba32> no; using (MemoryStream ms = new MemoryStream(ResourceManager.ReadResource("Alex.Resources.no.png"))) { no = Image.Load <Rgba32>(ms); } // Dictionary<string, Bitmap[]> animatedFrames = new Dictionary<string, Bitmap[]>(); foreach (var bmp in bitmaps) { if (meta.TryGetValue(bmp.Key, out var textureMeta)) { if (textureMeta.Animation == null || textureMeta.Animation == default) { continue; } // Bitmap[] bmpFrames = GetFrames(bmp.Value); // animatedFrames.Add(bmp.Key, bmpFrames); } } var regular = new[] { new KeyValuePair <string, Image <Rgba32> >("no_texture", no), }.Concat(bitmaps.Where(x => x.Value.Height == TextureHeight && x.Value.Width == TextureWidth)).ToArray(); var others = bitmaps.Where(x => x.Value.Height != TextureHeight || x.Value.Width != TextureWidth).ToList(); Image <Rgba32>[] waterFrames = new Image <Rgba32> [0]; Image <Rgba32>[] lavaFrames = new Image <Rgba32> [0]; Image <Rgba32>[] waterFlowFrames = new Image <Rgba32> [0]; Image <Rgba32>[] lavaFlowFrames = new Image <Rgba32> [0]; Image <Rgba32>[] fireFrames = new Image <Rgba32> [0]; Image <Rgba32>[] fireFrames2 = new Image <Rgba32> [0]; Image <Rgba32>[] portalFrames = new Image <Rgba32> [0]; Image <Rgba32>[] seagrassFrames = new Image <Rgba32> [0]; foreach (var other in others.ToArray()) { if (other.Key.Contains("water") && other.Key.Contains("still")) { waterFrames = GetFrames(other.Value); others.Remove(other); } else if (other.Key.Contains("water") && other.Key.Contains("flow")) { waterFlowFrames = GetFrames(other.Value); others.Remove(other); } else if (other.Key.Contains("lava") && other.Key.Contains("still")) { lavaFrames = GetFrames(other.Value); others.Remove(other); } else if (other.Key.Contains("lava") && other.Key.Contains("flow")) { lavaFlowFrames = GetFrames(other.Value); others.Remove(other); } else if (other.Key.Contains("fire_0")) { fireFrames = GetFrames(other.Value); others.Remove(other); } else if (other.Key.Contains("fire_1")) { fireFrames2 = GetFrames(other.Value); others.Remove(other); } else if (other.Key.Contains("nether_portal")) { portalFrames = GetFrames(other.Value); others.Remove(other); } else if (other.Key.Contains("seagrass")) { seagrassFrames = GetFrames(other.Value); others.Remove(other); } //seagrass } Dictionary <string, TextureInfo> stillFrameInfo = new Dictionary <string, TextureInfo>(); GenerateAtlasInternal(regular, others.ToArray(), progressReceiver, stillFrameInfo, out var stillAtlas); _stillFrame = TextureUtils.BitmapToTexture2D(device, stillAtlas, out var size); //stillAtlas.Save(Path.Combine(DebugPath, "atlas.png")); totalSize += size; _atlasLocations = stillFrameInfo; Dictionary <string, Image <Rgba32> > animated = new Dictionary <string, Image <Rgba32> >(); if (waterFrames.Length > 0) { animated.Add("block/water_still", waterFrames[0]); } if (waterFlowFrames.Length > 0) { animated.Add("block/water_flow", waterFlowFrames[0]); } if (lavaFrames.Length > 0) { animated.Add("block/lava_still", lavaFrames[0]); } if (lavaFlowFrames.Length > 0) { animated.Add("block/lava_flow", lavaFlowFrames[0]); } if (fireFrames.Length > 0) { animated.Add("block/fire_0", fireFrames[0]); } if (fireFrames2.Length > 0) { animated.Add("block/fire_1", fireFrames2[0]); } if (portalFrames.Length > 0) { animated.Add("block/nether_portal", portalFrames[0]); } if (seagrassFrames.Length > 0) { animated.Add("block/seagrass", seagrassFrames[0]); } var animatedFrameInfo = new Dictionary <string, TextureInfo>(); GenerateAtlasInternal(animated.ToArray(), new KeyValuePair <string, Image <Rgba32> > [0], progressReceiver, animatedFrameInfo, out Image <Rgba32> animatedFrame); AnimatedAtlasSize = new Vector2(animatedFrame.Width, animatedFrame.Height); TextureInfo waterLocation, waterFlowLocation, lavaLocation, lavaFlowLocation, fireLocation, fireLocation2, portalLocation, seagrassLocation; animatedFrameInfo.TryGetValue("block/water_still", out waterLocation); animatedFrameInfo.TryGetValue("block/water_flow", out waterFlowLocation); animatedFrameInfo.TryGetValue("block/lava_still", out lavaLocation); animatedFrameInfo.TryGetValue("block/lava_flow", out lavaFlowLocation); animatedFrameInfo.TryGetValue("block/fire_0", out fireLocation); animatedFrameInfo.TryGetValue("block/fire_1", out fireLocation2); animatedFrameInfo.TryGetValue("block/nether_portal", out portalLocation); animatedFrameInfo.TryGetValue("block/seagrass", out seagrassLocation); //var waterLocation = new Vector3(); // var baseBitmap = new Bitmap(stillAtlas.Width, stillAtlas.Height); var frameCount = Math.Max(Math.Max(Math.Max(waterFrames.Length, Math.Max(waterFlowFrames.Length, Math.Max(lavaFrames.Length, Math.Max(lavaFlowFrames.Length, fireFrames.Length)))), portalFrames.Length), seagrassFrames.Length); while (frameCount % 2 != 0) { frameCount++; } var frames = new Texture2D[frameCount]; for (int i = 0; i < frames.Length; i++) { var target = animatedFrame.CloneAs <Rgba32>(); //new Bitmap(animatedFrame); var r = new System.Drawing.Rectangle(0, 0, TextureWidth, TextureHeight); var destination = new System.Drawing.Rectangle((int)waterLocation.Position.X, (int)waterLocation.Position.Y, TextureWidth, TextureHeight); if (waterFrames.Length > 0) { TextureUtils.CopyRegionIntoImage(waterFrames[((i % 3 == 0 ? i - 1 : i) / 6) % waterFrames.Length], r, ref target, destination); } destination = new System.Drawing.Rectangle((int)waterFlowLocation.Position.X, (int)waterFlowLocation.Position.Y, TextureWidth, TextureHeight); if (waterFlowFrames.Length > 0) { TextureUtils.CopyRegionIntoImage(waterFlowFrames[i % waterFlowFrames.Length], r, ref target, destination); } destination = new System.Drawing.Rectangle((int)lavaLocation.Position.X, (int)lavaLocation.Position.Y, TextureWidth, TextureHeight); if (lavaFrames.Length > 0) { TextureUtils.CopyRegionIntoImage(lavaFrames[i % lavaFrames.Length], r, ref target, destination); } destination = new System.Drawing.Rectangle((int)lavaFlowLocation.Position.X, (int)lavaFlowLocation.Position.Y, TextureWidth, TextureHeight); if (lavaFlowFrames.Length > 0) { TextureUtils.CopyRegionIntoImage(lavaFlowFrames[i % lavaFlowFrames.Length], r, ref target, destination); } destination = new System.Drawing.Rectangle((int)fireLocation.Position.X, (int)fireLocation.Position.Y, TextureWidth, TextureHeight); if (fireFrames.Length > 0) { TextureUtils.CopyRegionIntoImage(fireFrames[i % fireFrames.Length], r, ref target, destination); } destination = new System.Drawing.Rectangle((int)fireLocation2.Position.X, (int)fireLocation2.Position.Y, TextureWidth, TextureHeight); if (fireFrames2.Length > 0) { TextureUtils.CopyRegionIntoImage(fireFrames2[i % fireFrames2.Length], r, ref target, destination); } destination = new System.Drawing.Rectangle((int)portalLocation.Position.X, (int)portalLocation.Position.Y, TextureWidth, TextureHeight); if (portalFrames.Length > 0) { TextureUtils.CopyRegionIntoImage(portalFrames[i % portalFrames.Length], r, ref target, destination); } destination = new System.Drawing.Rectangle((int)seagrassLocation.Position.X, (int)seagrassLocation.Position.Y, TextureWidth, TextureHeight); if (seagrassFrames.Length > 0) { TextureUtils.CopyRegionIntoImage(seagrassFrames[i % seagrassFrames.Length], r, ref target, destination); } frames[i] = TextureUtils.BitmapToTexture2D(device, target, out var s); totalSize += s; // target.Save(Path.Combine(DebugFramePath, $"frame{i}.png")); } _animatedAtlasLocations = animatedFrameInfo; AtlasSize = new Vector2(stillAtlas.Width, stillAtlas.Height); _frames = frames; sw.Stop(); Log.Info($"TextureAtlas generated in {sw.ElapsedMilliseconds}ms! ({PlayingState.GetBytesReadable(totalSize, 2)})"); }
private void GenerateAtlas(GraphicsDevice device, IDictionary <ResourceLocation, ImageEntry> blockTextures, IProgressReceiver progressReceiver) { Stopwatch sw = Stopwatch.StartNew(); Log.Info($"Generating texture atlas out of {(blockTextures.Count)} bitmaps..."); long totalSize = 0; Image <Rgba32> no = new Image <Rgba32>(TextureWidth, TextureHeight); for (int x = 0; x < no.Width; x++) { var xCheck = x < no.Width / 2; for (int y = 0; y < no.Height; y++) { var yCheck = y < no.Height / 2; if ((xCheck && yCheck) || (!xCheck && !yCheck)) { no[x, y] = Color.Purple; } else { no[x, y] = Color.Black; } } } /* * using (MemoryStream ms = new MemoryStream(ResourceManager.ReadResource("Alex.Resources.no.png"))) * { * no = Image.Load<Rgba32>(ms); * }*/ var normal = blockTextures.Where(x => x.Value.Height == TextureHeight && x.Value.Width == TextureWidth) .Select(x => new KeyValuePair <ResourceLocation, Image <Rgba32> >(x.Key, x.Value.Image)).ToArray(); var nonNormal = blockTextures.Where(x => x.Value.Height != x.Value.Width) .ToDictionary(x => x.Key, x => x.Value); // .Select(x => new KeyValuePair<ResourceLocation, Image<Rgba32>>(x.Key, x.Value.Image.Value)).ToArray(); Dictionary <ResourceLocation, TextureInfo> stillFrameInfo = new Dictionary <ResourceLocation, TextureInfo>(); GenerateAtlasInternal( new[] { new KeyValuePair <ResourceLocation, Image <Rgba32> >("no_texture", no), }.Concat( normal ).ToArray(), progressReceiver, stillFrameInfo, false, out var stillAtlas); foreach (var nor in normal) { nor.Value.Dispose(); } AtlasSize = new Vector2(stillAtlas.Width, stillAtlas.Height); // totalSize += size; _atlasLocations = stillFrameInfo; var stillFrame = GetMipMappedTexture2D(device, stillAtlas); totalSize += stillFrame.MemoryUsage; _stillFrame = stillFrame; _frames = ProcessFrames(device, progressReceiver, nonNormal); totalSize += _frames.Sum(x => x.MemoryUsage); sw.Stop(); Log.Info( $"TextureAtlas's generated in {sw.ElapsedMilliseconds}ms! ({PlayingState.GetBytesReadable(totalSize, 2)})"); }
private void GenerateAtlas(GraphicsDevice device, IDictionary <ResourceLocation, ImageEntry> blockTextures, IProgressReceiver progressReceiver) { Stopwatch sw = Stopwatch.StartNew(); Log.Info($"Generating texture atlas out of {(blockTextures.Count)} bitmaps..."); long totalSize = 0; Image <Rgba32> no; using (MemoryStream ms = new MemoryStream(ResourceManager.ReadResource("Alex.Resources.no.png"))) { no = Image.Load <Rgba32>(ms); } Dictionary <ResourceLocation, TextureInfo> stillFrameInfo = new Dictionary <ResourceLocation, TextureInfo>(); GenerateAtlasInternal( new[] { new KeyValuePair <ResourceLocation, Image <Rgba32> >("no_texture", no), }.Concat( blockTextures .Where(x => x.Value.Image.Height == TextureHeight && x.Value.Image.Width == TextureWidth).Select( x => new KeyValuePair <ResourceLocation, Image <Rgba32> >(x.Key, x.Value.Image))).ToArray(), progressReceiver, stillFrameInfo, false, out var stillAtlas); AtlasSize = new Vector2(stillAtlas.Width, stillAtlas.Height); // totalSize += size; _atlasLocations = stillFrameInfo; Dictionary <ResourceLocation, Image <Rgba32>[]> blockFrames = new Dictionary <ResourceLocation, Image <Rgba32>[]>(); foreach (var other in blockTextures.Where( x => x.Value.Image.Height != x.Value.Image.Width)) { if (!blockFrames.TryGetValue(other.Key, out _)) { blockFrames.Add(other.Key, GetFrames(other.Value.Image, TextureWidth, TextureHeight)); } } var animatedFrameInfo = new Dictionary <ResourceLocation, TextureInfo>(); GenerateAtlasInternal( blockFrames.Select(x => new KeyValuePair <ResourceLocation, Image <Rgba32> >(x.Key, x.Value[0])).ToArray(), progressReceiver, animatedFrameInfo, true, out Image <Rgba32> animatedFrame); AnimatedAtlasSize = new Vector2(animatedFrame.Width, animatedFrame.Height); _animatedAtlasLocations = animatedFrameInfo; var frameCount = blockFrames.Max(x => x.Value.Length); while (frameCount % 2 != 0) { frameCount++; } var frames = new Image <Rgba32> [frameCount]; frames[0] = animatedFrame; for (int i = 1; i < frames.Length; i++) { double percentage = 100D * ((double)i / (double)frames.Length); progressReceiver.UpdateProgress((int)percentage, $"Animating frame {i + 1} / {frames.Length}..."); var target = (i > 0 ? frames[i - 1] : animatedFrame).CloneAs <Rgba32>(); //new Bitmap(animatedFrame); // System.Drawing.Rectangle destination; foreach (var animated in blockFrames) { progressReceiver.UpdateProgress((int)percentage, null, animated.Key.ToString()); if (animatedFrameInfo.TryGetValue(animated.Key, out var textureInfo)) { //((i % 3 == 0 ? i - 1 : i) / 6) var destination = new System.Drawing.Rectangle( (int)textureInfo.Position.X, (int)textureInfo.Position.Y, textureInfo.Width, textureInfo.Height); var sourceRegion = new System.Drawing.Rectangle(0, 0, textureInfo.Width, textureInfo.Height); var index = i % animated.Value.Length; var indexOffset = 0; bool shouldInterpolate = false; float interpolationValue = 0.5f; if (blockTextures.TryGetValue(animated.Key, out var imageEntry) && imageEntry.Meta != null) { var meta = imageEntry.Meta; if (meta.Animation != null) { if (meta.Animation.Interpolate) { int extraFrames = (frames.Length - animated.Value.Length); var interpolationFrames = (int)Math.Floor(((double)extraFrames / (double)animated.Value.Length)); var remainder = i % interpolationFrames; if (remainder != 0) { shouldInterpolate = true; interpolationValue = (1f / interpolationFrames) * remainder; indexOffset = -remainder; // index -= remainder; } } if (meta.Animation.Frames != null) { var entry = meta.Animation.Frames[(i + indexOffset) % meta.Animation.Frames.Length]; if (entry.Integer.HasValue) { index = (int)entry.Integer.Value; } else if (entry.FrameClass != null) { index = (int)entry.FrameClass.Index; } } else { index = (i + indexOffset) % animated.Value.Length; } } } //TextureUtils.ClearRegion(ref target, destination); if (shouldInterpolate) { TextureUtils.CopyRegionIntoImage( ((i + indexOffset >= 0) ? frames[(i + indexOffset) % frames.Length] : animatedFrame), destination, ref target, destination, clear: true); } var texture = animated.Value[index]; TextureUtils.CopyRegionIntoImage(texture, sourceRegion, ref target, destination, shouldInterpolate, interpolationValue, clear: !shouldInterpolate); } } frames[i] = target; } _frames = frames.Select( x => { var a = TextureUtils.BitmapToTexture2D(device, x, out var s); totalSize += s; return(a); }).ToArray(); _stillFrame = TextureUtils.BitmapToTexture2D(device, stillAtlas, out var size); totalSize += size; sw.Stop(); Log.Info( $"TextureAtlas's generated in {sw.ElapsedMilliseconds}ms! ({PlayingState.GetBytesReadable(totalSize, 2)})"); /* * PngEncoder encoder = new PngEncoder(); * * stillAtlas.Save("atlas.png", encoder); * * if (!Directory.Exists("frames")) * Directory.CreateDirectory("frames"); * * for (var index = 0; index < frames.Length; index++) * { * var frame = frames[index]; * * frame.Save(Path.Combine("frames", $"frame-{index}.png"), encoder); * }*/ }
public async Task <string> CheckAndDownloadResources(IProgressReceiver progressReceiver) { progressReceiver?.UpdateProgress(0, "Checking for resource updates..."); using var httpClient = new HttpClient(new HttpClientHandler { AllowAutoRedirect = true, }); try { string assetsZipSavePath = String.Empty; if (Storage.TryReadString(CurrentBedrockVersionStorageKey, out var currentVersion)) { assetsZipSavePath = Path.Combine("assets", $"bedrock-{currentVersion}.zip"); if (!Storage.Exists(assetsZipSavePath)) { currentVersion = null; } } try { // var preRedirectHeaders = await httpClient.SendAsync( // new HttpRequestMessage(HttpMethod.Get, DownloadURL), HttpCompletionOption.ResponseHeadersRead); // if (preRedirectHeaders.StatusCode == HttpStatusCode.MovedPermanently) // { var zipDownloadHeaders = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, DownloadURL), HttpCompletionOption.ResponseHeadersRead); var fileName = zipDownloadHeaders.Content?.Headers?.ContentDisposition?.FileName ?? zipDownloadHeaders.RequestMessage?.RequestUri?.LocalPath; var versionMatch = ExtractVersionFromFilename.Match(fileName); if (versionMatch.Success) { var latestVersion = versionMatch.Groups["version"].Value; if (latestVersion != currentVersion || (!string.IsNullOrWhiteSpace(assetsZipSavePath) && !Storage.Exists(assetsZipSavePath))) { progressReceiver?.UpdateProgress( 0, "Downloading latest bedrock assets...", "This could take a while..."); /* zipDownloadHeaders = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, * zipDownloadHeaders.Headers.Location), HttpCompletionOption.ResponseContentRead); * var content = await zipDownloadHeaders.Content.ReadAsByteArrayAsync();*/ Stopwatch sw = Stopwatch.StartNew(); WebClient wc = new WebClient(); wc.DownloadProgressChanged += (sender, args) => { var downloadSpeed = $"Download speed: {PlayingState.GetBytesReadable((long) (Convert.ToDouble(args.BytesReceived) / sw.Elapsed.TotalSeconds), 2)}/s"; progressReceiver?.UpdateProgress( args.ProgressPercentage, $"Downloading latest bedrock assets...", downloadSpeed); }; var content = await wc.DownloadDataTaskAsync(zipDownloadHeaders.RequestMessage.RequestUri); assetsZipSavePath = Path.Combine("assets", $"bedrock-{latestVersion}.zip"); // save locally Storage.TryWriteString(CurrentBedrockVersionStorageKey, latestVersion); Storage.TryWriteBytes(assetsZipSavePath, content); var existingPath = Path.Combine("assets", "bedrock"); Storage.TryDeleteDirectory(existingPath); } } // } return(assetsZipSavePath); } catch (Exception ex) { Log.Error(ex, "Failed to download bedrock assets..."); return(assetsZipSavePath); } } catch (Exception ex) { Log.Error(ex, "Failed to fetch latest bedrock assets pack."); throw; } }
private void GenerateAtlas(GraphicsDevice device, IDictionary <ResourceLocation, Image <Rgba32>[]> blockFrames, IDictionary <ResourceLocation, Image <Rgba32> > blockTextures, IProgressReceiver progressReceiver) { Stopwatch sw = Stopwatch.StartNew(); Log.Info($"Generating texture atlas out of {(blockFrames.Count + blockTextures.Count)} bitmaps..."); long totalSize = 0; Image <Rgba32> no; using (MemoryStream ms = new MemoryStream(ResourceManager.ReadResource("Alex.Resources.no.png"))) { no = Image.Load <Rgba32>(ms); } var regularTextures = new[] { new KeyValuePair <ResourceLocation, Image <Rgba32> >("no_texture", no), }.Concat(blockTextures.Where(x => x.Value.Height == TextureHeight && x.Value.Width == TextureWidth)).ToArray(); var oddSizedTextures = blockTextures.Where(x => x.Value.Height != TextureHeight || x.Value.Width != TextureWidth).ToArray(); for (var index = 0; index < oddSizedTextures.Length; index++) { var other = oddSizedTextures[index]; if (blockFrames.TryGetValue(other.Key, out var values)) { oddSizedTextures[index] = new KeyValuePair <ResourceLocation, Image <Rgba32> >(other.Key, values[0]); } } Dictionary <ResourceLocation, TextureInfo> stillFrameInfo = new Dictionary <ResourceLocation, TextureInfo>(); GenerateAtlasInternal(regularTextures, oddSizedTextures, progressReceiver, stillFrameInfo, false, out var stillAtlas); _stillFrame = TextureUtils.BitmapToTexture2D(device, stillAtlas, out var size); AtlasSize = new Vector2(stillAtlas.Width, stillAtlas.Height); totalSize += size; _atlasLocations = stillFrameInfo; var animatedFrameInfo = new Dictionary <ResourceLocation, TextureInfo>(); GenerateAtlasInternal(blockFrames.Select(x => new KeyValuePair <ResourceLocation, Image <Rgba32> >(x.Key, x.Value[0])).ToArray(), new KeyValuePair <ResourceLocation, Image <Rgba32> > [0], progressReceiver, animatedFrameInfo, true, out Image <Rgba32> animatedFrame); AnimatedAtlasSize = new Vector2(animatedFrame.Width, animatedFrame.Height); _animatedAtlasLocations = animatedFrameInfo; var frameCount = blockFrames.Max(x => x.Value.Length); while (frameCount % 2 != 0) { frameCount++; } var frames = new Texture2D[frameCount]; for (int i = 0; i < frames.Length; i++) { double percentage = 100D * ((double)i / (double)frames.Length); progressReceiver.UpdateProgress((int)percentage, $"Animating frame {i}..."); var target = animatedFrame.CloneAs <Rgba32>(); //new Bitmap(animatedFrame); // System.Drawing.Rectangle destination; foreach (var animated in blockFrames) { progressReceiver.UpdateProgress((int)percentage, null, animated.Key.ToString()); if (animatedFrameInfo.TryGetValue(animated.Key, out var textureInfo)) { //((i % 3 == 0 ? i - 1 : i) / 6) var destination = new System.Drawing.Rectangle( (int)textureInfo.Position.X, (int)textureInfo.Position.Y, textureInfo.Width, textureInfo.Height); TextureUtils.CopyRegionIntoImage( animated.Value[i % animated.Value.Length], new System.Drawing.Rectangle(0, 0, textureInfo.Width, textureInfo.Height), ref target, destination); } } frames[i] = TextureUtils.BitmapToTexture2D(device, target, out var s); totalSize += s; } _frames = frames; sw.Stop(); Log.Info($"TextureAtlas generated in {sw.ElapsedMilliseconds}ms! ({PlayingState.GetBytesReadable(totalSize, 2)})"); }
public void GenerateAtlas(KeyValuePair <string, Bitmap>[] bitmaps, IProgressReceiver progressReceiver) { Log.Info($"Generating texture atlas out of {bitmaps.Length} bitmaps..."); long totalSize = 0; Bitmap no; using (MemoryStream ms = new MemoryStream(ResourceManager.ReadResource("Alex.Resources.no.png"))) { no = new Bitmap(ms); } var regular = new[] { new KeyValuePair <string, Bitmap>("no_texture", no), }.Concat(bitmaps.Where(x => x.Value.Height == TextureHeight && x.Value.Width == TextureWidth)).ToArray(); var others = bitmaps.Where(x => x.Value.Height != TextureHeight || x.Value.Width != TextureWidth).ToList(); Bitmap[] waterFrames = new Bitmap[0]; Bitmap[] lavaFrames = new Bitmap[0]; Bitmap[] waterFlowFrames = new Bitmap[0]; Bitmap[] lavaFlowFrames = new Bitmap[0]; foreach (var other in others.ToArray()) { if (other.Key.Contains("water") && other.Key.Contains("still")) { waterFrames = GetFrames(other.Value); others.Remove(other); } else if (other.Key.Contains("water") && other.Key.Contains("flow")) { waterFlowFrames = GetFrames(other.Value); others.Remove(other); } else if (other.Key.Contains("lava") && other.Key.Contains("still")) { lavaFrames = GetFrames(other.Value); others.Remove(other); } else if (other.Key.Contains("lava") && other.Key.Contains("flow")) { lavaFlowFrames = GetFrames(other.Value); others.Remove(other); } } Dictionary <string, TextureInfo> stillFrameInfo = new Dictionary <string, TextureInfo>(); GenerateAtlasInternal(regular, others.ToArray(), progressReceiver, stillFrameInfo, out Bitmap stillAtlas); _stillFrame = TextureUtils.BitmapToTexture2D(Graphics, stillAtlas, out var size); totalSize += size; _atlasLocations = stillFrameInfo; Dictionary <string, Bitmap> animated = new Dictionary <string, Bitmap>(); if (waterFrames.Length > 0) { // total++; animated.Add("block/water_still", waterFrames[0]); // regular = regular.Append(new KeyValuePair<string, Bitmap>("block/water_still", waterFrames[0])).ToArray(); } if (waterFlowFrames.Length > 0) { // total++; animated.Add("block/water_flow", waterFlowFrames[0]); // regular = regular.Append(new KeyValuePair<string, Bitmap>("block/water_flow", waterFlowFrames[0])).ToArray(); } if (lavaFrames.Length > 0) { animated.Add("block/lava_still", lavaFrames[0]); // total++; // regular = regular.Append(new KeyValuePair<string, Bitmap>("block/lava_still", lavaFrames[0])).ToArray(); } if (lavaFlowFrames.Length > 0) { animated.Add("block/lava_flow", lavaFlowFrames[0]); // total++; // regular = regular.Append(new KeyValuePair<string, Bitmap>("block/lava_flow", lavaFlowFrames[0])).ToArray(); } var animatedFrameInfo = new Dictionary <string, TextureInfo>(); GenerateAtlasInternal(animated.ToArray(), new KeyValuePair <string, Bitmap> [0], progressReceiver, animatedFrameInfo, out Bitmap animatedFrame); TextureInfo waterLocation, waterFlowLocation, lavaLocation, lavaFlowLocation; animatedFrameInfo.TryGetValue("block/water_still", out waterLocation); animatedFrameInfo.TryGetValue("block/water_flow", out waterFlowLocation); animatedFrameInfo.TryGetValue("block/lava_still", out lavaLocation); animatedFrameInfo.TryGetValue("block/lava_flow", out lavaFlowLocation); //var waterLocation = new Vector3(); // var baseBitmap = new Bitmap(stillAtlas.Width, stillAtlas.Height); var frames = new Texture2D[Math.Max(waterFrames.Length, waterFlowFrames.Length)]; for (int i = 0; i < frames.Length; i++) { var target = new Bitmap(animatedFrame); var r = new System.Drawing.Rectangle(0, 0, TextureWidth, TextureHeight); var destination = new System.Drawing.Rectangle((int)waterLocation.Position.X, (int)waterLocation.Position.Y, TextureWidth, TextureHeight); if (waterFrames.Length > 0) { TextureUtils.CopyRegionIntoImage(waterFrames[((i % 3 == 0 ? i - 1 : i) / 6) % waterFrames.Length], r, ref target, destination); } destination = new System.Drawing.Rectangle((int)waterFlowLocation.Position.X, (int)waterFlowLocation.Position.Y, TextureWidth, TextureHeight); if (waterFlowFrames.Length > 0) { TextureUtils.CopyRegionIntoImage(waterFlowFrames[i % waterFlowFrames.Length], r, ref target, destination); } destination = new System.Drawing.Rectangle((int)lavaLocation.Position.X, (int)lavaLocation.Position.Y, TextureWidth, TextureHeight); if (lavaFrames.Length > 0) { TextureUtils.CopyRegionIntoImage(lavaFrames[i % lavaFrames.Length], r, ref target, destination); } destination = new System.Drawing.Rectangle((int)lavaFlowLocation.Position.X, (int)lavaFlowLocation.Position.Y, TextureWidth, TextureHeight); if (lavaFlowFrames.Length > 0) { TextureUtils.CopyRegionIntoImage(lavaFlowFrames[i % lavaFlowFrames.Length], r, ref target, destination); } frames[i] = TextureUtils.BitmapToTexture2D(Graphics, target, out var s); totalSize += s; } _animatedAtlasLocations = animatedFrameInfo; AtlasSize = new Vector2(stillAtlas.Width, stillAtlas.Height); _frames = frames; Log.Info($"TextureAtlas generated! ({PlayingState.GetBytesReadable(totalSize, 2)})"); }