public override void Generate(Chunk chunk, Biome biome = null)
        {
            SpatialHash spatialHash = chunk.defaultSpatialHash;

            if (!enabled)
            {
                output.SetObject(chunk, spatialHash); return;
            }
            if (chunk.stop)
            {
                return;
            }

            // Note - it's important that we *don't* change the seed based on the chunk coordinates, or else
            // we risk generating two different points.
            InstanceRandom rnd       = new InstanceRandom(MapMagic.instance.seed + seed /* + chunk.coord.x*1000 + chunk.coord.z */);
            Vector2        candidate = new Vector2(xMin + rnd.Random() * (xMax - xMin), zMin + rnd.Random() * (zMax - zMin));

            // MM works with coordinates specified in "terrain space". If the user specifies coordinates in
            // absolute world position, need to scale these based on resolution and size of terrain before
            // adding to the spatialhash
            if (coordinateSpace == CoordinateSpace.World)
            {
                float scaleFactor = (float)MapMagic.instance.resolution / (float)MapMagic.instance.terrainSize;
                candidate *= scaleFactor;
            }

            // If the spatial hash for this chunk does not contain the candidate point, simply return the default
            // spatial hash
            if (
                spatialHash.offset.x + spatialHash.size <= candidate.x || /* candidate point lies too far to the right */
                spatialHash.offset.x > candidate.x || /* candidate point lies too far to the left */
                spatialHash.offset.y + spatialHash.size <= candidate.y || /* candidate point lies too far forward */
                spatialHash.offset.y > candidate.y    /* candidate point lies too far backward */
                )
            {
                output.SetObject(chunk, spatialHash);
                return;
            }
            // If the candidate lies within this chunk's bounds, add it to the hash
            else
            {
                spatialHash.Add(candidate, 0, 0, 1);
            }

            if (chunk.stop)
            {
                return;
            }
            output.SetObject(chunk, spatialHash);
        }
Exemple #2
0
        public override void Generate(Chunk chunk, Biome biome = null)
        {
            //return on stop/disable
            if (chunk.stop || !enabled)
            {
                return;
            }

            InstanceRandom rnd = new InstanceRandom(MapMagic.instance.seed + seed /* + chunk.coord.x*1000 + chunk.coord.z*/);

            // Calculate the total weight of all layers
            float sumOfWeights = 0f;

            for (int i = 0; i < layers.Length; i++)
            {
                sumOfWeights += layers[i].weight;
            }

            // Pick a random value less than the total weight
            float rouletteSelection = rnd.Random(0, sumOfWeights);

            // Loop through the layers, keeping a running sum of weights
            // The layer that contains the chosen rouletteWeight gets sent the input
            // All other layers get sent the default matrix
            float prevRunningWeight = 0f;
            float nextRunningWeight = 0f;

            for (int i = 0; i < layers.Length; i++)
            {
                nextRunningWeight = prevRunningWeight + layers[i].weight;
                if (prevRunningWeight < rouletteSelection && nextRunningWeight > rouletteSelection)
                {
                    layers[i].output.SetObject(chunk, (Matrix)input.GetObject(chunk));
                }
                else
                {
                    layers[i].output.SetObject(chunk, chunk.defaultMatrix);
                }
                prevRunningWeight = nextRunningWeight;
            }
        }
Exemple #3
0
        public override void Generate(MapMagic.Chunk chunk)
        {
            Matrix matrix = (Matrix)input.GetObject(chunk); if (matrix != null)

            {
                matrix = matrix.Copy(null);
            }

            if (matrix == null)
            {
                matrix = chunk.defaultMatrix;
            }
            Matrix mask = (Matrix)maskIn.GetObject(chunk);

            if (chunk.stop)
            {
                return;
            }
            if (!enabled || intensity == 0 || cellCount == 0)
            {
                output.SetObject(chunk, matrix); return;
            }

            //NoiseGenerator.Noise(matrix,200,0.5f,Vector2.zero);
            //matrix.Multiply(amount);

            InstanceRandom random = new InstanceRandom(MapMagic.instance.seed + seed);

            //creating point matrix
            float             cellSize = 1f * matrix.rect.size.x / cellCount;
            Matrix2 <Vector3> points   = new Matrix2 <Vector3>(new CoordRect(0, 0, cellCount + 2, cellCount + 2));

            points.rect.offset = new Coord(-1, -1);

            Coord matrixSpaceOffset = new Coord((int)(matrix.rect.offset.x / cellSize), (int)(matrix.rect.offset.z / cellSize));

            //scattering points
            for (int x = -1; x < points.rect.size.x - 1; x++)
            {
                for (int z = -1; z < points.rect.size.z - 1; z++)
                {
                    Vector3 randomPoint = new Vector3(x + random.CoordinateRandom(x + matrixSpaceOffset.x, z + matrixSpaceOffset.z), 0, z + random.NextCoordinateRandom());
                    Vector3 centerPoint = new Vector3(x + 0.5f, 0, z + 0.5f);
                    Vector3 point       = randomPoint * (1 - uniformity) + centerPoint * uniformity;
                    point        = point * cellSize + new Vector3(matrix.rect.offset.x, 0, matrix.rect.offset.z);
                    point.y      = random.NextCoordinateRandom();
                    points[x, z] = point;
                }
            }

            Coord min = matrix.rect.Min; Coord max = matrix.rect.Max;

            for (int x = min.x; x < max.x; x++)
            {
                for (int z = min.z; z < max.z; z++)
                {
                    //finding current cell
                    Coord cell = new Coord((int)((x - matrix.rect.offset.x) / cellSize), (int)((z - matrix.rect.offset.z) / cellSize));

                    //finding min dist
                    float minDist = 200000000; float secondMinDist = 200000000;
                    float minHeight = 0;             //float secondMinHeight = 0;
                    for (int ix = -1; ix <= 1; ix++)
                    {
                        for (int iz = -1; iz <= 1; iz++)
                        {
                            Coord nearCell = new Coord(cell.x + ix, cell.z + iz);
                            //if (!points.rect.CheckInRange(nearCell)) continue; //no need to perform test as points have 1-cell border around matrix

                            Vector3 point = points[nearCell];
                            float   dist  = (x - point.x) * (x - point.x) + (z - point.z) * (z - point.z);
                            if (dist < minDist)
                            {
                                secondMinDist = minDist; minDist = dist;
                                minHeight     = point.y;
                            }
                            else if (dist < secondMinDist)
                            {
                                secondMinDist = dist;
                            }
                        }
                    }

                    float val = 0;
                    switch (blendType)
                    {
                    case BlendType.flat: val = minHeight; break;

                    case BlendType.closest: val = minDist / (MapMagic.instance.resolution * 16); break;

                    case BlendType.secondClosest: val = secondMinDist / (MapMagic.instance.resolution * 16); break;

                    case BlendType.cellular: val = (secondMinDist - minDist) / (MapMagic.instance.resolution * 16); break;

                    case BlendType.organic: val = (secondMinDist + minDist) / 2 / (MapMagic.instance.resolution * 16); break;
                    }
                    if (mask == null)
                    {
                        matrix[x, z] += val * intensity;
                    }
                    else
                    {
                        matrix[x, z] += val * intensity * mask[x, z];
                    }
                }
            }

            if (chunk.stop)
            {
                return;                         //do not write object is generating is stopped
            }
            output.SetObject(chunk, matrix);
        }
        public float uniformity = 0.1f;         //aka candidatesNum/100

        public override void Generate(Chunk chunk, Biome biome = null)
        {
            Matrix      probMatrix  = (Matrix)probability.GetObject(chunk);
            SpatialHash spatialHash = chunk.defaultSpatialHash;

            if (!enabled)
            {
                output.SetObject(chunk, spatialHash); return;
            }
            if (chunk.stop)
            {
                return;
            }

            InstanceRandom rnd = new InstanceRandom(MapMagic.instance.seed + seed + chunk.coord.x * 1000 + chunk.coord.z);

            //Rect terrainRect = terrain.coord.ToRect(terrain.size);
            //terrainRect.position += Vector2.one; terrainRect.size-=Vector2.one*2;

            //SpatialHash spatialHash = new SpatialHash(terrain.coord.ToVector2(terrain.size), terrain.size, 16);


            //float square = terrainRect.width * terrainRect.height;
            //float count = square*(density/1000000); //number of items per terrain

            //positioned scatter

            /*float sideCount = Mathf.Sqrt(count);
             * float step = spatialHash.size / sideCount;
             *
             * //int uniformity = 100;
             * //Random.seed = 12345;
             * for (float x=spatialHash.offset.x+step/2; x<spatialHash.offset.x+spatialHash.size-step/2; x+=step)
             *      for (float y=spatialHash.offset.y+step/2; y<spatialHash.offset.y+spatialHash.size-step/2; y+=step)
             * {
             *      Vector2 offset = new Vector2(((Random.value*2-1)*uniformity), ((Random.value*2-1)*uniformity));
             *      Vector2 point = new Vector2(x,y) + offset;
             *      if (point.x > spatialHash.size) point.x -= spatialHash.size; if (point.x < 0) point.x += spatialHash.size;
             *      if (point.y > spatialHash.size) point.y -= spatialHash.size; if (point.y < 0) point.y += spatialHash.size;
             *      spatialHash.Add(point, 0,0,0);
             * }*/

            //realRandom algorithm
            int candidatesNum = (int)(uniformity * 100);

            for (int i = 0; i < count; i++)
            {
                Vector2 bestCandidate = Vector3.zero;
                float   bestDist      = 0;

                for (int c = 0; c < candidatesNum; c++)
                {
                    Vector2 candidate = new Vector2((spatialHash.offset.x + 1) + (rnd.Random() * (spatialHash.size - 2.01f)), (spatialHash.offset.y + 1) + (rnd.Random() * (spatialHash.size - 2.01f)));

                    //checking if candidate available here according to probability map
                    if (probMatrix != null && probMatrix[candidate] < rnd.Random() + 0.0001f)
                    {
                        continue;
                    }

                    //checking if candidate is the furthest one
                    float dist = spatialHash.MinDist(candidate);
                    if (dist > bestDist)
                    {
                        bestDist = dist; bestCandidate = candidate;
                    }
                }

                if (bestDist > 0.001f)
                {
                    spatialHash.Add(bestCandidate, 0, 0, 1);                                  //adding only if some suitable candidate found
                }
            }

            if (chunk.stop)
            {
                return;
            }
            output.SetObject(chunk, spatialHash);
        }
        public float uniformity = 0.1f;         //aka candidatesNum/100

        public override void Generate(Chunk chunk, Biome biome = null)
        {
            Matrix      probMatrix  = (Matrix)probability.GetObject(chunk);
            SpatialHash spatialHash = chunk.defaultSpatialHash;

            if (!enabled)
            {
                output.SetObject(chunk, spatialHash); return;
            }
            if (chunk.stop)
            {
                return;
            }

            // If the bounds of this chunk don't contain the specified zValue then return the
            // default spatialHash
            if (spatialHash.offset.y > zValue || spatialHash.offset.y + spatialHash.size <= zValue)
            {
                output.SetObject(chunk, spatialHash);
                return;
            }

            InstanceRandom rnd = new InstanceRandom(MapMagic.instance.seed + seed + chunk.coord.x * 1000 + chunk.coord.z);

            int candidatesNum = (int)(uniformity * 100);

            for (int i = 0; i < count; i++)
            {
                Vector2 bestCandidate = Vector3.zero;
                float   bestDist      = 0;

                for (int c = 0; c < candidatesNum; c++)
                {
                    Vector2 candidate = new Vector2((spatialHash.offset.x + 1) + (rnd.Random() * (spatialHash.size - 2.01f)), zValue);

                    //checking if candidate available here according to probability map
                    if (probMatrix != null && probMatrix[candidate] < rnd.Random())
                    {
                        continue;
                    }

                    //checking if candidate is the furthest one
                    float dist = spatialHash.MinDist(candidate);
                    if (dist > bestDist)
                    {
                        bestDist = dist; bestCandidate = candidate;
                    }
                }

                if (bestDist > 0.001f)
                {
                    spatialHash.Add(bestCandidate, 0, 0, 1); //adding only if some suitable candidate found
                }
            }

            if (chunk.stop)
            {
                return;
            }
            output.SetObject(chunk, spatialHash);
        }