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