Exemplo n.º 1
0
        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;
        }
Exemplo n.º 2
0
        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);
        }