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);
        }
Beispiel #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;
            }
        }
        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);
        }