コード例 #1
0
        private static bool TryExtract(ITopoArray <Tile> sample, int nx, int ny, int nz, int x, int y, int z, out PatternArray pattern)
        {
            var width  = sample.Topology.Width;
            var height = sample.Topology.Height;
            var depth  = sample.Topology.Depth;
            var values = new Tile[nx, ny, nz];

            for (int tx = 0; tx < nx; tx++)
            {
                var sx = (x + tx) % width;
                for (int ty = 0; ty < ny; ty++)
                {
                    var sy = (y + ty) % height;
                    for (int tz = 0; tz < nz; tz++)
                    {
                        var sz    = (z + tz) % depth;
                        var index = sample.Topology.GetIndex(sx, sy, sz);
                        if (!sample.Topology.ContainsIndex(index))
                        {
                            pattern = default(PatternArray);
                            return(false);
                        }
                        values[tx, ty, tz] = sample.Get(sx, sy, sz);
                    }
                }
            }
            pattern = new PatternArray {
                Values = values
            };
            return(true);
        }
コード例 #2
0
        /// <summary>
        /// Calls <c>func</c> on each element of the array, returning a new <see cref="ITopoArray{T}"/>
        /// </summary>
        public static ITopoArray <U> Map <T, U>(this ITopoArray <T> topoArray, Func <T, U> func)
        {
            /*
             * var width = topoArray.Topology.Width;
             * var height = topoArray.Topology.Height;
             * var depth = topoArray.Topology.Depth;
             * var r = new U[width, height, depth];
             *
             * for (var z = 0; z < depth; z++)
             * {
             *  for (var y = 0; y < height; y++)
             *  {
             *      for (var x = 0; x < width; x++)
             *      {
             *          r[x, y, z] = func(topoArray.Get(x, y, z));
             *      }
             *  }
             * }
             *
             * return new TopoArray3D<U>(r, topoArray.Topology);
             */
            var r = new U[topoArray.Topology.IndexCount];

            foreach (var i in topoArray.Topology.GetIndices())
            {
                r[i] = func(topoArray.Get(i));
            }
            return(new TopoArray1D <U>(r, topoArray.Topology));
        }
コード例 #3
0
        public static ITopoArray <T> Scale <T>(ITopoArray <T> topoArray, int scale)
        {
            var topology = topoArray.Topology.AsGridTopology();

            if (topology.Mask != null)
            {
                throw new NotSupportedException();
            }
            var result = new T[topology.Width * scale, topology.Height *scale, topology.Depth *scale];

            for (var z = 0; z < topology.Depth; z++)
            {
                for (var y = 0; y < topology.Height; y++)
                {
                    for (var x = 0; x < topology.Width; x++)
                    {
                        var value = topoArray.Get(x, y, z);
                        for (var dz = 0; dz < scale; dz++)
                        {
                            for (var dy = 0; dy < scale; dy++)
                            {
                                for (var dx = 0; dx < scale; dx++)
                                {
                                    result[x * scale + dx, y *scale + dy, z *scale + dz] = value;
                                }
                            }
                        }
                    }
                }
            }
            var resultTopology = topology.WithSize(topology.Width * scale, topology.Height * scale, topology.Depth * scale);

            return(TopoArray.Create(result, resultTopology));
        }
コード例 #4
0
        private Vector3Int?GetContradictionLocation(ITopoArray <ModelTile?> result)
        {
            var topology = result.Topology;
            var mask     = topology.Mask;

            var empty = mask.ToArray();

            for (var x = 0; x < topology.Width; x++)
            {
                for (var y = 0; y < topology.Height; y++)
                {
                    for (var z = 0; z < topology.Depth; z++)
                    {
                        var p = new Vector3Int(x, y, z);
                        // Skip if already filled
                        if (!empty[GetMaskIndex(p)])
                        {
                            continue;
                        }
                        var modelTile = result.Get(x, y, z);
                        if (modelTile == null)
                        {
                            continue;
                        }
                        var tile = modelTile.Value.Tile;
                        if (tile == null)
                        {
                            return(new Vector3Int(x, y, z));
                        }
                    }
                }
            }

            return(null);
        }
コード例 #5
0
ファイル: VoxUtils.cs プロジェクト: tkwebster/DeBroglie
        private static void Save(Size size, Xyzi xyzi, ITopoArray <byte> topArray)
        {
            // TODO
            size.SizeX  = topArray.Topology.Width;
            size.SizeY  = topArray.Topology.Height;
            size.SizeZ  = topArray.Topology.Depth;
            xyzi.Voxels = new List <Voxel>();

            for (var z = 0; z < size.SizeZ; z++)
            {
                for (var y = 0; y < size.SizeY; y++)
                {
                    for (var x = 0; x < size.SizeX; x++)
                    {
                        var colorIndex = topArray.Get(x, y, z);
                        if (colorIndex != 0)
                        {
                            xyzi.Voxels.Add(new Voxel
                            {
                                X          = (byte)x,
                                Y          = (byte)y,
                                Z          = (byte)z,
                                ColorIndex = colorIndex,
                            });
                        }
                    }
                }
            }
        }
コード例 #6
0
        private static FrequencySet[] GetFrequencySets(ITopoArray <IDictionary <Tile, PriorityAndWeight> > weights, TileModelMapping tileModelMapping)
        {
            var frequencies = new FrequencySet[tileModelMapping.PatternTopology.IndexCount];

            foreach (var patternIndex in tileModelMapping.PatternTopology.GetIndices())
            {
                // TODO
                if (tileModelMapping.PatternCoordToTileCoordIndexAndOffset != null)
                {
                    throw new NotImplementedException();
                }

                // TODO: Detect duplicate dictionaries by reference and share the frequency sets?

                var tileIndex     = patternIndex;
                var offset        = 0;
                var weightDict    = weights.Get(tileIndex);
                var newWeights    = new double[tileModelMapping.PatternModel.PatternCount];
                var newPriorities = new int[tileModelMapping.PatternModel.PatternCount];
                foreach (var kv in weightDict)
                {
                    var pattern = tileModelMapping.TilesToPatternsByOffset[offset][kv.Key].Single();
                    newWeights[pattern]    = kv.Value.Weight;
                    newPriorities[pattern] = kv.Value.Priority;
                }
                frequencies[patternIndex] = new FrequencySet(newWeights, newPriorities);
            }
            return(frequencies);
        }
コード例 #7
0
        public void DoBan(int index, int pattern)
        {
            var clean = cleanPatterns.Get(index);

            if (clean == pattern)
            {
                dirtyIndices.Add(index);
            }
        }
コード例 #8
0
ファイル: AdjacentModel.cs プロジェクト: studentutu/DeBroglie
        public void AddSample(ITopoArray <Tile> sample)
        {
            var topology = sample.Topology.AsGridTopology();

            SetDirections(topology.Directions);

            var width          = topology.Width;
            var height         = topology.Height;
            var depth          = topology.Depth;
            var directionCount = topology.Directions.Count;

            for (var z = 0; z < depth; z++)
            {
                for (var y = 0; y < height; y++)
                {
                    for (var x = 0; x < width; x++)
                    {
                        var index = topology.GetIndex(x, y, z);
                        if (!topology.ContainsIndex(index))
                        {
                            continue;
                        }

                        // Find the pattern and update the frequency
                        var pattern = GetPattern(sample.Get(x, y, z));

                        frequencies[pattern] += 1;

                        // Update propagator
                        for (var d = 0; d < directionCount; d++)
                        {
                            int x2, y2, z2;
                            if (topology.TryMove(x, y, z, (Direction)d, out x2, out y2, out z2))
                            {
                                var pattern2 = GetPattern(sample.Get(x2, y2, z2));
                                propagator[pattern][d].Add(pattern2);
                            }
                        }
                    }
                }
            }
        }
コード例 #9
0
        public FrequencySet Get(int index)
        {
            var id = weightSetByIndex.Get(index);

            if (frequencySets.TryGetValue(id, out var fs))
            {
                return(fs);
            }

            return(frequencySets[id] = GetFrequencySet(weightSets[id], tileModelMapping));
        }
コード例 #10
0
        private static ITopoArray <T> RotateInner <T>(ITopoArray <T> original, Func <int, int, ValueTuple <int, int> > mapCoord, TileRotate <T> tileRotate = null)
        {
            var originalTopology = original.Topology.AsGridTopology();

            // Find new bounds
            var(x1, y1) = mapCoord(0, 0);
            var(x2, y2) = mapCoord(originalTopology.Width - 1, 0);
            var(x3, y3) = mapCoord(originalTopology.Width - 1, originalTopology.Height - 1);
            var(x4, y4) = mapCoord(0, originalTopology.Height - 1);

            var minx = Math.Min(Math.Min(x1, x2), Math.Min(x3, x4));
            var maxx = Math.Max(Math.Max(x1, x2), Math.Max(x3, x4));
            var miny = Math.Min(Math.Min(y1, y2), Math.Min(y3, y4));
            var maxy = Math.Max(Math.Max(y1, y2), Math.Max(y3, y4));

            // Arrange so that co-ordinate transfer is into the rect bounced by width, height
            var offsetx = -minx;
            var offsety = -miny;
            var width   = maxx - minx + 1;
            var height  = maxy - miny + 1;
            var depth   = originalTopology.Depth;

            var mask     = new bool[width * height * depth];
            var topology = new GridTopology(originalTopology.Directions, width, height, originalTopology.Depth, false, false, false, mask);
            var values   = new T[width, height, depth];

            // Copy from original to values based on the rotation, setting up the mask as we go.
            for (var z = 0; z < originalTopology.Depth; z++)
            {
                for (var y = 0; y < originalTopology.Height; y++)
                {
                    for (var x = 0; x < originalTopology.Width; x++)
                    {
                        var(newX, newY) = mapCoord(x, y);
                        newX           += offsetx;
                        newY           += offsety;
                        int  newIndex    = topology.GetIndex(newX, newY, z);
                        var  newValue    = original.Get(x, y, z);
                        bool hasNewValue = true;
                        if (tileRotate != null)
                        {
                            hasNewValue = tileRotate(newValue, out newValue);
                        }
                        values[newX, newY, z] = newValue;
                        mask[newIndex]        = hasNewValue && originalTopology.ContainsIndex(originalTopology.GetIndex(x, y, z));
                    }
                }
            }

            return(new TopoArray3D <T>(values, topology));
        }
コード例 #11
0
        /// <summary>
        /// Converts from DeBroglie's array format back to Tessera's.
        /// </summary>
        internal IEnumerable <TesseraTileInstance> GetTesseraTileInstances(ITopoArray <ModelTile?> result)
        {
            var topology = result.Topology;
            var mask     = topology.Mask;

            var empty = mask.ToArray();

            for (var x = 0; x < topology.Width; x++)
            {
                for (var y = 0; y < topology.Height; y++)
                {
                    for (var z = 0; z < topology.Depth; z++)
                    {
                        var p = new Vector3Int(x, y, z);
                        // Skip if already filled
                        if (!empty[GetMaskIndex(p)])
                        {
                            continue;
                        }
                        var modelTile = result.Get(x, y, z);
                        if (modelTile == null)
                        {
                            continue;
                        }
                        var rot  = modelTile.Value.Rotation;
                        var tile = modelTile.Value.Tile;
                        if (tile == null)
                        {
                            continue;
                        }

                        var ti = GetTesseraTileInstance(x, y, z, modelTile.Value);

                        // Fill locations
                        foreach (var p2 in ti.Cells)
                        {
                            if (InBounds(p2))
                            {
                                empty[GetMaskIndex(p2)] = false;
                            }
                        }

                        if (ti != null)
                        {
                            yield return(ti);
                        }
                    }
                }
            }
        }
コード例 #12
0
        private static List <T> SliceZ <T>(ITopoArray <T> topoArray, int z)
        {
            var l        = new List <T>();
            var topology = topoArray.Topology;

            for (var y = 0; y < topology.Height; y++)
            {
                for (var x = 0; x < topology.Width; x++)
                {
                    var i = topology.GetIndex(x, y, z);
                    l.Add(topology.ContainsIndex(i) ? topoArray.Get(i) : default(T));
                }
            }
            return(l);
        }
コード例 #13
0
        private static List <T> SliceY <T>(ITopoArray <T> topoArray, int y)
        {
            var l        = new List <T>();
            var topology = topoArray.Topology;

            for (var z = 0; z < topology.Depth; z++)
            {
                for (var x = 0; x < topology.Width; x++)
                {
                    var i = topology.GetIndex(x, y, z);
                    l.Add(topology.ContainsIndex(i) ? topoArray.Get(i) : default(T));
                }
            }
            return(l);
        }
コード例 #14
0
        /// <summary>
        /// Copies a <see cref="ITopoArray{T}"/> into a 2d array.
        /// </summary>
        public static T[,] ToArray2d <T>(this ITopoArray <T> topoArray)
        {
            var width   = topoArray.Topology.Width;
            var height  = topoArray.Topology.Height;
            var results = new T[width, height];

            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    results[x, y] = topoArray.Get(x, y);
                }
            }
            return(results);
        }
コード例 #15
0
        /// <summary>
        /// Copies a <see cref="ITopoArray{T}"/> into a 3d array.
        /// </summary>
        public static T[,,] ToArray3d <T>(this ITopoArray <T> topoArray)
        {
            var width   = topoArray.Topology.Width;
            var height  = topoArray.Topology.Height;
            var depth   = topoArray.Topology.Depth;
            var results = new T[width, height, depth];

            for (var x = 0; x < width; x++)
            {
                for (var y = 0; y < height; y++)
                {
                    for (var z = 0; z < depth; z++)
                    {
                        results[x, y, z] = topoArray.Get(x, y, z);
                    }
                }
            }
            return(results);
        }
コード例 #16
0
        /// <summary>
        /// Calls <c>func</c> on each element of the array, returning a new <see cref="ITopoArray{T}"/>
        /// </summary>
        public static ITopoArray <U> Map <T, U>(this ITopoArray <T> topoArray, Func <T, U> func)
        {
            var width  = topoArray.Topology.Width;
            var height = topoArray.Topology.Height;
            var depth  = topoArray.Topology.Depth;
            var r      = new U[width, height, depth];

            for (var z = 0; z < depth; z++)
            {
                for (var y = 0; y < height; y++)
                {
                    for (var x = 0; x < width; x++)
                    {
                        r[x, y, z] = func(topoArray.Get(x, y, z));
                    }
                }
            }

            return(new TopoArray3D <U>(r, topoArray.Topology));
        }
コード例 #17
0
        /// <summary>
        /// Returns a <see cref="GridTopology"/> with the same parameters, but with the specified mask
        /// </summary>
        public GridTopology WithMask(ITopoArray <bool> mask)
        {
            if (!IsSameSize(mask.Topology.AsGridTopology()))
            {
                throw new System.Exception("Mask size doesn't fit the topology");
            }
            var boolMask = new bool[Width * Height * Depth];

            for (var z = 0; z < Depth; z++)
            {
                for (var y = 0; y < Height; y++)
                {
                    for (var x = 0; x < Width; x++)
                    {
                        boolMask[x + y * Width + z * Width * Height] = mask.Get(x, y, z);
                    }
                }
            }
            return(WithMask(boolMask));
        }
コード例 #18
0
        public static ITopoArray <V> Explode <U, V>(ITopoArray <U> topoArray, Func <U, ITopoArray <V> > getSubTile, int tileWidth, int tileHeight, int tileDepth)
        {
            var inTopology = topoArray.Topology.AsGridTopology();

            if (inTopology.Directions.Type != DirectionSetType.Cartesian2d && inTopology.Directions.Type != DirectionSetType.Cartesian3d)
            {
                throw new NotImplementedException();
            }

            var inWidth  = inTopology.Width;
            var inHeight = inTopology.Height;
            var inDepth  = inTopology.Depth;

            var resultTopology = inTopology.WithSize(
                inWidth * tileWidth,
                inHeight * tileHeight,
                inDepth * tileDepth
                );
            var result = new V[resultTopology.Width, resultTopology.Height, resultTopology.Depth];
            var mask   = new bool[resultTopology.Width * resultTopology.Height * resultTopology.Depth];

            for (var z = 0; z < inDepth; z++)
            {
                for (var y = 0; y < inHeight; y++)
                {
                    for (var x = 0; x < inWidth; x++)
                    {
                        if (inTopology.Mask != null)
                        {
                            var index = inTopology.GetIndex(x, y, z);
                            if (!inTopology.Mask[index])
                            {
                                continue;
                            }
                        }
                        var inTile  = topoArray.Get(x, y, z);
                        var subTile = getSubTile(inTile);
                        if (subTile == null)
                        {
                            continue;
                        }
                        for (var tz = 0; tz < tileDepth; tz++)
                        {
                            for (var ty = 0; ty < tileHeight; ty++)
                            {
                                for (var tx = 0; tx < tileWidth; tx++)
                                {
                                    if (subTile.Topology.Mask != null)
                                    {
                                        var index = subTile.Topology.GetIndex(tx, ty, tz);
                                        if (!subTile.Topology.Mask[index])
                                        {
                                            continue;
                                        }
                                    }
                                    result[x * tileWidth + tx, y *tileHeight + ty, z *tileDepth + tz]
                                        = subTile.Get(tx, ty, tz);
                                    mask[resultTopology.GetIndex(x * tileWidth + tx, y * tileHeight + ty, z * tileDepth + tz)] = true;
                                }
                            }
                        }
                    }
                }
            }

            return(TopoArray.Create(result, resultTopology));
        }
コード例 #19
0
ファイル: TiledUtil.cs プロジェクト: tkwebster/DeBroglie
        /// <summary>
        /// Convers a <see cref="ITopoArray{T}"/> to a layer of a Map
        /// If the array is 3d, this reads a place with a given z co-ordinate.
        /// </summary>
        public static TileLayer MakeTileLayer(Map map, ITopoArray <Tile> array, int z = 0)
        {
            if (map.Orientation == Orientation.orthogonal || map.Orientation == Orientation.isometric && map.StaggerAxis == StaggerAxis.None)
            {
                var width  = array.Topology.Width;
                var height = array.Topology.Height;
                var data   = new int[width * height];
                var i      = 0;
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        data[i++] = TileToGid(array.Get(x, y, z), Orientation.orthogonal);
                    }
                }
                var layer = new TileLayer();
                layer.Encoding  = "base64";
                layer.Data      = data;
                layer.Width     = width;
                layer.Height    = height;
                layer.Visible   = true;
                layer.Opacity   = 1.0;
                layer.LayerType = LayerType.tilelayer;
                return(layer);
            }
            else if (map.Orientation == Orientation.hexagonal)
            {
                // Tiled uses a staggered hex layout, while we use an axial one
                // Convert between them, masking out the dead space
                // For now, only support one mode of staggering
                if (map.StaggerAxis != StaggerAxis.y)
                {
                    throw new NotImplementedException($"Maps staggered on x axis not supported");
                }

                var width     = array.Topology.Width;
                var height    = array.Topology.Height;
                var newWidth  = width + (height + 1) / 2;
                var newHeight = height;
                var data      = new int[newWidth * newHeight];

                var isStaggered = map.StaggerIndex == StaggerIndex.even;
                var xoffset     = (isStaggered ? 1 : 0) + (height + 1) / 2;
                for (int y = 0; y < height; y++)
                {
                    if (isStaggered)
                    {
                        xoffset -= 1;
                    }
                    for (int x = 0; x < width; x++)
                    {
                        var newY = y;
                        var newX = x + xoffset;
                        data[newX + newY * newWidth] = TileToGid(array.Get(x, y, 0), Orientation.hexagonal);
                    }
                    isStaggered = !isStaggered;
                }
                var layer = new TileLayer();
                layer.Encoding = "base64";
                layer.Data     = data;
                layer.Width    = newWidth;
                layer.Height   = newHeight;
                layer.Visible  = true;
                layer.Opacity  = 1.0;
                return(layer);
            }
            else
            {
                throw new NotImplementedException($"{map.Orientation} not supported");
            }
        }
コード例 #20
0
        public static ITopoArray <IEnumerable <V> > ExplodeSets <U, V>(ITopoArray <ISet <U> > topoArray, Func <U, ITopoArray <V> > getSubTile, int tileWidth, int tileHeight, int tileDepth)
        {
            if (topoArray.Topology.Directions.Type != DirectionsType.Cartesian2d && topoArray.Topology.Directions.Type != DirectionsType.Cartesian3d)
            {
                throw new NotImplementedException();
            }

            var inTopology = topoArray.Topology;
            var inWidth    = inTopology.Width;
            var inHeight   = inTopology.Height;
            var inDepth    = inTopology.Depth;

            var resultTopology = inTopology.WithSize(
                inWidth * tileWidth,
                inHeight * tileHeight,
                inDepth * tileDepth
                );
            var result = new IEnumerable <V> [resultTopology.Width, resultTopology.Height, resultTopology.Depth];
            var mask   = new bool[resultTopology.Width * resultTopology.Height * resultTopology.Depth];

            for (var z = 0; z < inDepth; z++)
            {
                for (var y = 0; y < inHeight; y++)
                {
                    for (var x = 0; x < inWidth; x++)
                    {
                        if (inTopology.Mask != null)
                        {
                            var index = inTopology.GetIndex(x, y, z);
                            if (!inTopology.Mask[index])
                            {
                                continue;
                            }
                        }
                        var inTileSet = topoArray.Get(x, y, z);
                        if (inTileSet.Count == 0)
                        {
                            continue;
                        }
                        for (var tz = 0; tz < tileDepth; tz++)
                        {
                            for (var ty = 0; ty < tileHeight; ty++)
                            {
                                for (var tx = 0; tx < tileWidth; tx++)
                                {
                                    var outSet = new List <V>();
                                    foreach (var inTile in inTileSet)
                                    {
                                        var subTile = getSubTile(inTile);
                                        if (subTile == null)
                                        {
                                            continue;
                                        }

                                        if (subTile.Topology.Mask != null)
                                        {
                                            var index = subTile.Topology.GetIndex(tx, ty, tz);
                                            if (!subTile.Topology.Mask[index])
                                            {
                                                continue;
                                            }
                                        }
                                        outSet.Add(subTile.Get(tx, ty, tz));
                                        mask[resultTopology.GetIndex(x * tileWidth + tx, y * tileHeight + ty, z * tileDepth + tz)] = true;
                                    }
                                    result[x * tileWidth + tx, y *tileHeight + ty, z *tileDepth + tz] = outSet;
                                }
                            }
                        }
                    }
                }
            }

            return(TopoArray.Create(result, resultTopology));
        }