Beispiel #1
0
        /// <summary>
        /// Creates a MapData instance
        /// </summary>
        /// <param name="index">The index value of the converted ValueMap</param>
        /// <param name="threshold">Minimum threshold to convert from</param>
        public static MapData CreateInstance(ValueMap map, int index, float threshold)
        {
            MapData output = CreateInstance <MapData>();

            output.Initialize(map, index, threshold);
            return(output);
        }
Beispiel #2
0
        public override object GetValue(NodePort port)
        {
            var graph = (Terra2DGraph)this.graph;

            if (graph.isComputing)
            {
                try
                {
                    currentState = GetCurrentState();
                    if (currentState != previousState)
                    {
                        noise = NoiseGenerator.FractalNoise(graph.seed.GetHashCode(), graph.size, offset, noiseType, fractalType, depth, frequency);
                        if (normalize)
                        {
                            noise = noise.MapToRange(0, 1);
                        }

                        previousState = currentState;
                    }
                    return(noise);
                }
                catch (System.Exception e)
                {
                    graph.isComputing = false;
                    throw e;
                }
            }
            return(null);
        }
Beispiel #3
0
        public override object GetValue(NodePort port)
        {
            var graph = (Terra2DGraph)this.graph;

            if (graph.isComputing)
            {
                try
                {
                    mask = GetInputValue <ValueMap>("mask", null);

                    Vector2Int coord = new Vector2Int();
                    coord.x = (int)(graph.size.x * start.x);
                    coord.y = (int)(graph.size.y * start.y);

                    output = new SpaceColonizer(graph.seed, graph.size, stepSize, maxDistance, minDistance, leafCount, maxSteps, mask != null ? mask : null)
                             .Generate(coord);
                }
                catch (System.Exception e)
                {
                    graph.isComputing = false;
                    throw e;
                }
            }

            return(output);
        }
Beispiel #4
0
        /// <summary>
        /// Maps all values to a range
        /// </summary>
        public ValueMap MapToRange(float min, float max)
        {
            float cmin = float.MaxValue;
            float cmax = float.MinValue;

            ValueMap output = CreateInstance <ValueMap>();

            output.Initialize(Width, Height);

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    if (values[x, y] < cmin)
                    {
                        cmin = values[x, y];
                    }
                    else if (values[x, y] > cmax)
                    {
                        cmax = values[x, y];
                    }
                }
            }

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    output[x, y] = Mathf.Lerp(min, max, Mathf.InverseLerp(cmin, cmax, values[x, y]));
                }
            }

            return(output);
        }
Beispiel #5
0
        public override object GetValue(NodePort port)
        {
            var graph = (Terra2DGraph)this.graph;

            if (graph.isComputing)
            {
                try
                {
                    var input = GetInputValue("input", this.input);

                    if (input == null)
                    {
                        input = CreateInstance <ValueMap>();
                        input.Initialize(graph.size);
                    }

                    output = new CaveGenerator(input, threshold, iterations, searchRadius, birthRule, deathRule).Generate();
                    return(output);
                }
                catch (System.Exception e)
                {
                    graph.isComputing = false;
                    throw e;
                }
            }
            return(null);
        }
Beispiel #6
0
        /// <summary>
        /// Selects certain values from a map, and sets them to 1, and the rest to zero. Usefull for conversions
        /// </summary>
        public ValueMap Select(SelectOperation operation, float value)
        {
            ValueMap output = CreateInstance <ValueMap>();

            output.Initialize(Width, Height);

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    switch (operation)
                    {
                    case SelectOperation.EqualTo:
                        output[x, y] = values[x, y] == value ? 1 : 0;
                        break;

                    case SelectOperation.GreaterThan:
                        output[x, y] = values[x, y] > value ? 1 : 0;
                        break;

                    case SelectOperation.LessThan:
                        output[x, y] = values[x, y] < value ? 1 : 0;
                        break;
                    }
                }
            }

            return(output);
        }
Beispiel #7
0
        public ValueMap Generate()
        {
            map = input.Clone();

            for (int i = 0; i < iterations; i++)
            {
                buffer.Initialize(size);

                for (int x = 0; x < size.x; x++)
                {
                    for (int y = 0; y < size.y; y++)
                    {
                        // Count alive neighbours
                        int neighbours = map.GetNeighbours(new Vector2Int(x, y), searchRadius, true).FindAll(n => map[n] > threshold).Count;

                        // cell is alive
                        if (neighbours > birthRule)
                        {
                            buffer[x, y] = 1;
                        }
                        // cell is dead
                        else if (neighbours < deathRule)
                        {
                            buffer[x, y] = 0;
                        }
                    }
                }

                map = buffer.Clone();
            }

            return(map);
        }
Beispiel #8
0
        /// <summary>
        /// Creates a ValueMap instance from a gradient
        /// </summary>
        public static ValueMap CreateInstance(int width, int height, Gradient gradient, bool vertical = false)
        {
            ValueMap output = CreateInstance <ValueMap>();

            output.Initialize(width, height, gradient, vertical);
            return(output);
        }
Beispiel #9
0
        /// <summary>
        /// Creates a ValueMap instance from a Texture2D (converted to grayscale)
        /// </summary>
        public static ValueMap CreateInstance(Texture2D image)
        {
            ValueMap output = CreateInstance <ValueMap>();

            output.Initialize(image);
            return(output);
        }
Beispiel #10
0
        /// <summary>
        /// Creates a ValueMap instance
        /// </summary>
        public static ValueMap CreateInstance(int width, int height)
        {
            ValueMap map = CreateInstance <ValueMap>();

            map.Initialize(width, height);
            return(map);
        }
Beispiel #11
0
        /// <summary>
        /// Creates a ValueMap instance
        /// </summary>
        public static ValueMap CreateInstance(Vector2Int size)
        {
            ValueMap map = CreateInstance <ValueMap>();

            map.Initialize(size.x, size.y);
            return(map);
        }
Beispiel #12
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="seed">The seed for randomness</param>
 /// <param name="size">Width and Height of the maze</param>
 /// <param name="start">Starting point for the maze</param>
 /// <param name="wallSpacing">Spacing between passages</param>
 /// <param name="includeDiagonals">Allow diagonal passages</param>
 /// <param name="waviness">Higher values yield long passages with fewer dead ends, and vice versa</param>
 /// <param name="mask">Generate maze inside a mask, make sure the start point is inisde this mask</param>
 public MazeGenerator(string seed, Vector2Int size, Vector2Int start, int wallSpacing, bool includeDiagonals, float waviness = 0.5f, ValueMap mask = null)
 {
     this.seed             = seed;
     this.size             = size;
     this.start            = start;
     this.wallSpacing      = wallSpacing;
     this.includeDiagonals = includeDiagonals;
     this.waviness         = waviness;
     this.mask             = mask;
 }
Beispiel #13
0
        public ValueMap GetValueMap(string id)
        {
            ValueMapOutputNode node = (ValueMapOutputNode)nodes.FindAll(n => n is ValueMapOutputNode).Find(n => ((ValueMapOutputNode)n).id == id);

            isComputing = true;
            ValueMap map = node.GetInputValue("valueMap", node.valueMap);

            isComputing = false;

            return(map);
        }
Beispiel #14
0
 public SpaceColonizer(string seed, Vector2Int size, int stepSize, int maxDistance, int minDistance, int leafCount, int maxSteps, ValueMap mask = null)
 {
     this.seed        = seed.GetHashCode();
     this.size        = size;
     this.stepSize    = stepSize;
     this.maxDistance = maxDistance;
     this.minDistance = minDistance;
     this.leafCount   = leafCount;
     this.maxSteps    = maxSteps;
     this.mask        = mask;
 }
Beispiel #15
0
        /// <summary>
        /// Detects and returns edges in a map
        /// </summary>
        public ValueMap DetectEdges(float threshold)
        {
            ValueMap firstPass = CreateInstance <ValueMap>();

            firstPass.Initialize(Width, Height);

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    firstPass[x, y] = 0;

                    for (int i = x - 1; i <= x + 1; i++)
                    {
                        for (int j = y - 1; j <= y + 1; j++)
                        {
                            if (IsInsideBounds(i, j))
                            {
                                if (Mathf.Abs(this[x, y] - this[i, j]) > threshold)
                                {
                                    firstPass[x, y] = 1;
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            ValueMap secondPass = CreateInstance <ValueMap>();

            secondPass.Initialize(Width, Height);

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    if (firstPass.CountItemsInRegion(new Vector2Int(x - 1, y - 1), new Vector2Int(x + 1, y + 1), 1) > 8)
                    {
                        secondPass[x, y] = 0;
                    }
                    else
                    {
                        secondPass[x, y] = firstPass[x, y];
                    }
                }
            }

            return(secondPass);
        }
Beispiel #16
0
        /// <summary>
        /// Create a new Cave Generator
        /// </summary>
        /// <param name="input">The input map, usually white noise</param>
        /// <param name="threshold">Input values below this threshold will be treated as zero</param>
        /// <param name="iterations">How many times to iterate the automata, higher values give smoother caves, but are slow</param>
        /// <param name="searchRadius">Neighbour search radius</param>
        /// <param name="birthRule"></param>
        /// <param name="deathRule"></param>
        public CaveGenerator(ValueMap input, float threshold, int iterations = 3, int searchRadius = 1, int birthRule = 2, int deathRule = 3)
        {
            this.threshold    = threshold;
            this.iterations   = iterations;
            this.searchRadius = searchRadius;
            this.birthRule    = birthRule;
            this.deathRule    = deathRule;
            this.input        = input;

            size = new Vector2Int(input.Width, input.Height);

            map    = ValueMap.CreateInstance(size);
            buffer = ValueMap.CreateInstance(size);
        }
Beispiel #17
0
        /// <summary>
        /// Clamps values between a range
        /// </summary>
        public ValueMap Clamp(float min, float max)
        {
            ValueMap output = CreateInstance <ValueMap>();

            output.Initialize(Width, Height);

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    output[x, y] = (this[x, y] < min) ? min : ((this[x, y] > max) ? max : this[x, y]);
                }
            }

            return(output);
        }
Beispiel #18
0
        /// <summary>
        /// Applies am AnimationCurve on all values
        /// </summary>
        public ValueMap ApplyCurve(AnimationCurve curve)
        {
            ValueMap output = CreateInstance <ValueMap>();

            output.Initialize(Width, Height);

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    output[x, y] = curve.Evaluate(this[x, y]);
                }
            }

            return(output);
        }
Beispiel #19
0
        /// <summary>
        /// Create a clone of this map
        /// </summary>
        public ValueMap Clone()
        {
            ValueMap output = CreateInstance <ValueMap>();

            output.Initialize(Width, Height);

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    output[x, y] = values[x, y];
                }
            }

            return(output);
        }
Beispiel #20
0
        public override object GetValue(NodePort port)
        {
            var graph = (Terra2DGraph)this.graph;

            if (graph.isComputing)
            {
                try
                {
                    ValueMap a = GetInputValue("a", this.a);
                    ValueMap b = GetInputValue("b", this.b);

                    if (method == MathOperation.Add)
                    {
                        var output = a.Add(b);
                        if (normalize)
                        {
                            output = output.MapToRange(0, 1);
                        }
                        return(output);
                    }
                    else if (method == MathOperation.Multiply)
                    {
                        var output = a.Multiply(b);
                        if (normalize)
                        {
                            output = output.MapToRange(0, 1);
                        }
                        return(output);
                    }
                    else if (method == MathOperation.Subtract)
                    {
                        var output = a.Subtract(b);
                        if (normalize)
                        {
                            output = output.MapToRange(0, 1);
                        }
                        return(output);
                    }
                }
                catch (System.Exception e)
                {
                    graph.isComputing = false;
                    throw e;
                }
            }
            return(null);
        }
Beispiel #21
0
        /// <summary>
        /// Subtracts two Value Maps
        /// </summary>
        public ValueMap Subtract(ValueMap map)
        {
            var output = Clone();

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    if (map.IsInsideBounds(x, y))
                    {
                        output.values[x, y] = values[x, y] - map.values[x, y];
                    }
                }
            }

            return(output);
        }
Beispiel #22
0
        /// <summary>
        /// Multiplies two Value Maps
        /// </summary>
        public ValueMap Multiply(ValueMap map)
        {
            ValueMap output = Clone();

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    if (map.IsInsideBounds(x, y))
                    {
                        output.values[x, y] = values[x, y] * map.values[x, y];
                    }
                }
            }

            return(output);
        }
        public override object GetValue(NodePort port)
        {
            var graph = (Terra2DGraph)this.graph;

            if (graph.isComputing)
            {
                try
                {
                    noise = NoiseGenerator.WhiteNoise(graph.seed.GetHashCode(), graph.size, threshold);
                    return(noise);
                }
                catch (System.Exception e)
                {
                    graph.isComputing = false;
                    throw e;
                }
            }
            return(null);
        }
Beispiel #24
0
        /// <summary>
        /// Initialize map from a ValueMap
        /// </summary>
        /// <param name="index">The index value of the converted ValueMap</param>
        /// <param name="threshold">Minimum threshold to convert from</param>
        public void Initialize(ValueMap map, int index, float threshold)
        {
            Initialize(map.Width, map.Height);

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    if (map[x, y] > threshold)
                    {
                        this[x, y] = index;
                    }
                    else
                    {
                        this[x, y] = 0;
                    }
                }
            }
        }
        public override object GetValue(NodePort port)
        {
            var graph = (Terra2DGraph)this.graph;

            if (graph.isComputing)
            {
                try
                {
                    output = ValueMap.CreateInstance(graph.size.x, graph.size.y, gradient, vertical);
                    return(output);
                }
                catch (System.Exception e)
                {
                    graph.isComputing = false;
                    throw e;
                }
            }
            return(null);
        }
Beispiel #26
0
        public ValueMap Generate()
        {
            // initialize
            maze   = ValueMap.CreateInstance(size.x, size.y);
            random = new System.Random(seed.GetHashCode());
            List <Vector2Int> activeCells = new List <Vector2Int>();

            // add the start cell to the active list
            activeCells.Add(start);
            maze[start.x, start.y] = 1;

            // while active list is not empty
            while (activeCells.Count > 0)
            {
                // select cell from active list
                // randomly selected based on waviness
                // higher waviness produces long winding passages with fewer dead ends, and vice versa
                int cellIndex = random.NextDouble() > waviness?random.Next(activeCells.Count) : activeCells.Count - 1;

                var cell = activeCells[cellIndex];

                // get untraversed neighbours of selected cell
                var neighbours = GetNeighbours(cell.x, cell.y);

                if (neighbours.Count > 0)
                {
                    // randomly select a neighbour and connect it to the selected cell
                    var neighbour = neighbours[random.Next(neighbours.Count)];
                    maze.ConnectCells(cell, neighbour, 1);

                    // add that neighbour to the active list
                    activeCells.Add(neighbour);
                }
                else
                {
                    // if no traversable neighbours, remove cell from active list
                    activeCells.Remove(cell);
                }
            }

            return(maze);
        }
Beispiel #27
0
        public override object GetValue(NodePort port)
        {
            var graph = (Terra2DGraph)this.graph;

            if (graph.isComputing)
            {
                try
                {
                    ValueMap input = GetInputValue("input", this.input);
                    output = input.Dither(amount, threshold);
                    return(output);
                }
                catch (System.Exception e)
                {
                    graph.isComputing = false;
                    throw e;
                }
            }
            return(null);
        }
        public static ValueMap WhiteNoise(int seed, Vector2Int size, float threshold)
        {
            System.Random rand = new System.Random(seed);

            var noise = new FastNoise(seed);

            ValueMap output = ScriptableObject.CreateInstance <ValueMap>();

            output.Initialize(size.x, size.y);

            for (int x = 0; x < size.x; x++)
            {
                for (int y = 0; y < size.y; y++)
                {
                    output[x, y] = rand.NextDouble() > threshold?noise.GetWhiteNoise(x, y) : 0;
                }
            }

            return(output);
        }
Beispiel #29
0
        /// <summary>
        /// Uses another ValueMap to mask this one, values less then or equal to zero are treated as masked
        /// </summary>
        public ValueMap ApplyMask(ValueMap mask, float threshold)
        {
            ValueMap output = Clone();

            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    if (mask.IsInsideBounds(x, y))
                    {
                        if (mask[x, y] <= threshold)
                        {
                            output[x, y] = 0;
                        }
                    }
                }
            }

            return(output);
        }
Beispiel #30
0
        public static Texture2D ValueMapToTexture2D(ValueMap map)
        {
            map.MapToRange(0, 1);

            Texture2D texture = new Texture2D(map.Width, map.Height);

            Color[] colors = new Color[map.Width * map.Height];

            for (int x = 0; x < map.Width; x++)
            {
                for (int y = 0; y < map.Height; y++)
                {
                    colors[x + y * map.Width] = new Color(map[x, y], map[x, y], map[x, y]);
                }
            }

            texture.SetPixels(colors);
            texture.Apply();

            return(texture);
        }