static FloorTextureComposer() { var patternsForLayers = FloorSpritePatterns.CreatePatternsForPrimaryLayers(); var allCombinations = GenerateNeighborsCombinations(); // All possible combinations are known now. // Let's check all known combinations against all known patterns and setup atlas chunks. var wallChunkTypes = GenerateAtlas( allCombinations, patternsForLayers, PrimaryAtlasColumnsCount, out var atlasSize); AtlasSize = atlasSize; FloorChunkPresets = wallChunkTypes; }
private static Dictionary <NeighborsPattern, FloorChunkPreset> GenerateAtlas( List <NeighborsPattern> allCombinations, List <FloorPatternLayer> patternsForLayers, byte columnsCount, out TextureAtlasSize atlasSize) { var selectedChunks = new List <FloorChunkPreset>(); var atlasPosition = 0; var layers = new List <FloorPatternLayer>(8); foreach (var variant in allCombinations) { foreach (var patternLayer in patternsForLayers) { if (patternLayer.IsPass(variant)) { layers.Add(patternLayer); } } if (layers.Count == 0) { continue; } var newChunkLayers = layers.SelectMany(l => l.SourceChunks).ToArray(); var newChunkLayersHashCode = CalculateLayersHashCode(newChunkLayers); FloorChunkPreset wallChunkPreset = null; foreach (var chunk in selectedChunks) { if (chunk.Layers != null && chunk.LayersHashCode == newChunkLayersHashCode && chunk.Layers.SequenceEqual(newChunkLayers)) { // the same layers are used - reuse its target address wallChunkPreset = new FloorChunkPreset( variant, chunk.TargetColumn, chunk.TargetRow, null, newChunkLayersHashCode, linkedLayersFromOtherChunk: chunk.Layers); break; } } if (wallChunkPreset == null) { // new chunk preset wallChunkPreset = new FloorChunkPreset( variant, (byte)(atlasPosition % columnsCount), (byte)(atlasPosition / columnsCount), newChunkLayers, newChunkLayersHashCode, linkedLayersFromOtherChunk: null); atlasPosition++; } selectedChunks.Add(wallChunkPreset); layers.Clear(); } var wallChunkTypes = selectedChunks.ToDictionary(p => p.Pattern); // Atlas chunks are ready - calculate atlas size. var rowsCount = (byte)(1 + atlasPosition / columnsCount); atlasSize = new TextureAtlasSize(columnsCount, rowsCount); foreach (var selectedChunk in selectedChunks) { if (selectedChunk.TargetRow >= rowsCount) { Api.Logger.Error($"Target row position exceeded: {selectedChunk.TargetRow}>={rowsCount}"); } if (selectedChunk.TargetColumn >= columnsCount) { Api.Logger.Error($"Target column position exceeded: {selectedChunk.TargetColumn}>={columnsCount}"); } } Api.Logger.Important( string.Format( "Floor combinations calculated, total: {0} all combinations, {1} selected combinations, with unique atlas chunks {2} combinations.", allCombinations.Count, selectedChunks.Count, selectedChunks.Count(c => c.Layers != null))); return(wallChunkTypes); }