regionCenter GeneratePoint(int x, int y, Vector2 center, float islandRadius) { regionCenter ret = new regionCenter(); Vector2 offset = Random.insideUnitCircle * .5f; ret.point = new Vector2(offset.x + x, offset.y + y); float distance = Vector2.Distance( ret.point, center); distance /= islandRadius; float altitude = 1f - distance; //Debug.Log("P:" + new Vector2(col,row) + "D:" + distance + " A: " + altitude); altitude *= Random.Range(1f - altitudeRandomness, 1f + altitudeRandomness); altitude -= seaLevel; altitude /= (1f - seaLevel); ret.elavation = altitude; if (altitude > 0f) { ret.color = landGradient.Evaluate(altitude); } else { ret.color = seaGradient.Evaluate(-1f * altitude / seaLevel); } ret.color.r *= Random.Range(1f - colorRandomness, 1f + colorRandomness); ret.color.g *= Random.Range(1f - colorRandomness, 1f + colorRandomness); ret.color.b *= Random.Range(1f - colorRandomness, 1f + colorRandomness); return(ret); }
// TODO Highly unoptimized, we can do a lot better than this because we have a general idea of the point layout in a grid. regionCenter GetClosestRegion(Vector2 worldPoint) { regionCenter ret = new regionCenter(); float bestDistance = float.PositiveInfinity; ret.point = new Vector2(float.NegativeInfinity, float.NegativeInfinity); regionCenter[] ballpark = GetNeighborPoints(worldPoint, 2); foreach (regionCenter current in ballpark) { float newDistance = Vector2.Distance(worldPoint, current.point); if (bestDistance > newDistance) { ret = current; bestDistance = newDistance; } } return(ret); }
//public int pointsSavedFromDictionaryOptimization = 0; public float GetAltitude(Vector2 position) { if (visitedPoints.ContainsKey(position)) { //pointsSavedFromDictionaryOptimization++; return visitedPoints[position]; } regionCenter[] regions = GetNeighborPoints(position, 2); regionCenter one = new regionCenter(); float distOne = float.PositiveInfinity; regionCenter two = new regionCenter(); float distTwo = float.PositiveInfinity; regionCenter three = new regionCenter(); float distThree = float.PositiveInfinity; foreach (regionCenter r in regions) { float newDist = Vector2.Distance(position, r.point); if (newDist < distOne) { three = two; distThree = distTwo; two = one; distTwo = distOne; one = r; distOne = newDist; } else if (newDist < distTwo) { three = two; distThree = distTwo; two = r; distTwo = newDist; } else if (newDist < distThree) { three = r; distThree = newDist; } } float ret = 0f; // Interpolate geometrically by calculating triangle areas. float oneTwo = Vector2.Distance(one.point,two.point); float twoThree = Vector2.Distance(two.point,three.point); float oneThree = Vector2.Distance(one.point,three.point); float areaOne = Herons(twoThree,distTwo,distThree); float areaTwo = Herons(oneThree,distOne,distThree); float areaThree = Herons(oneTwo,distOne,distTwo); float totalArea = areaOne+areaTwo+areaThree; ret += areaOne/totalArea * one.elavation; ret += areaTwo/totalArea * two.elavation; ret += areaThree/totalArea * three.elavation; /* float average = one.elavation + two.elavation + three.elavation; ret = Mathf.Lerp(one.elavation,average,distOne/(distOne+distTwo+distThree)+ slopeSmoothing* Mathf.Cos(Vector2.Angle(two.point-position,three.point-position))* Mathf.Cos(Vector2.Angle(one.point-position,three.point-position))); */ // Deterministic noise function. ret += (1f+ret)/2f*slopeSmoothing*distOne/(distOne+distTwo+distThree)* Mathf.Cos(Vector2.Angle(two.point-position,three.point-position)) *Mathf.Cos(Vector2.Angle(one.point-position,three.point-position)) *Mathf.Cos(Vector2.Angle(one.point-position,two.point-position)); visitedPoints.Add(position,ret); return ret; }
// TODO Highly unoptimized, we can do a lot better than this because we have a general idea of the point layout in a grid. regionCenter GetClosestRegion(Vector2 worldPoint) { regionCenter ret = new regionCenter(); float bestDistance = float.PositiveInfinity; ret.point = new Vector2(float.NegativeInfinity, float.NegativeInfinity); regionCenter[] ballpark = GetNeighborPoints(worldPoint, 2); foreach (regionCenter current in ballpark) { float newDistance = Vector2.Distance(worldPoint,current.point); if (bestDistance > newDistance) { ret = current; bestDistance = newDistance; } } return ret; }
regionCenter GeneratePoint(int x, int y, Vector2 center, float islandRadius) { regionCenter ret = new regionCenter(); Vector2 offset = Random.insideUnitCircle * .5f; ret.point = new Vector2(offset.x + x, offset.y + y); float distance = Vector2.Distance ( ret.point, center); distance /= islandRadius; float altitude = 1f - distance; //Debug.Log("P:" + new Vector2(col,row) + "D:" + distance + " A: " + altitude); altitude *= Random.Range(1f-altitudeRandomness, 1f+altitudeRandomness); altitude -= seaLevel; altitude /= (1f-seaLevel); ret.elavation = altitude; if (altitude > 0f) { ret.color = landGradient.Evaluate(altitude); } else { ret.color = seaGradient.Evaluate(-1f*altitude/seaLevel); } ret.color.r *= Random.Range(1f-colorRandomness,1f+colorRandomness); ret.color.g *= Random.Range(1f-colorRandomness,1f+colorRandomness); ret.color.b *= Random.Range(1f-colorRandomness,1f+colorRandomness); return ret; }
//public int pointsSavedFromDictionaryOptimization = 0; public float GetAltitude(Vector2 position) { if (visitedPoints.ContainsKey(position)) { //pointsSavedFromDictionaryOptimization++; return(visitedPoints[position]); } regionCenter[] regions = GetNeighborPoints(position, 2); regionCenter one = new regionCenter(); float distOne = float.PositiveInfinity; regionCenter two = new regionCenter(); float distTwo = float.PositiveInfinity; regionCenter three = new regionCenter(); float distThree = float.PositiveInfinity; foreach (regionCenter r in regions) { float newDist = Vector2.Distance(position, r.point); if (newDist < distOne) { three = two; distThree = distTwo; two = one; distTwo = distOne; one = r; distOne = newDist; } else if (newDist < distTwo) { three = two; distThree = distTwo; two = r; distTwo = newDist; } else if (newDist < distThree) { three = r; distThree = newDist; } } float ret = 0f; // Interpolate geometrically by calculating triangle areas. float oneTwo = Vector2.Distance(one.point, two.point); float twoThree = Vector2.Distance(two.point, three.point); float oneThree = Vector2.Distance(one.point, three.point); float areaOne = Herons(twoThree, distTwo, distThree); float areaTwo = Herons(oneThree, distOne, distThree); float areaThree = Herons(oneTwo, distOne, distTwo); float totalArea = areaOne + areaTwo + areaThree; ret += areaOne / totalArea * one.elavation; ret += areaTwo / totalArea * two.elavation; ret += areaThree / totalArea * three.elavation; /* * float average = one.elavation + two.elavation + three.elavation; * ret = Mathf.Lerp(one.elavation,average,distOne/(distOne+distTwo+distThree)+ * slopeSmoothing* * Mathf.Cos(Vector2.Angle(two.point-position,three.point-position))* * Mathf.Cos(Vector2.Angle(one.point-position,three.point-position))); */ // Deterministic noise function. ret += (1f + ret) / 2f * slopeSmoothing * distOne / (distOne + distTwo + distThree) * Mathf.Cos(Vector2.Angle(two.point - position, three.point - position)) * Mathf.Cos(Vector2.Angle(one.point - position, three.point - position)) * Mathf.Cos(Vector2.Angle(one.point - position, two.point - position)); visitedPoints.Add(position, ret); return(ret); }
IEnumerator DoRaster() { float scale = rasterSize; scale /= (float)gridSize + 1; scale = 1f / scale; float left = -1f; // Space on left edge float bottom = left; int coro = 0; output = new Texture2D(rasterSize, rasterSize); Debug.Log("Rasterizing image."); // Draw voronoi regions. for (int row = 0; row < rasterSize; row++) { for (int col = 0; col < rasterSize; col++) { Vector2 worldPoint = new Vector2( col * scale + left, row * scale + bottom ); float t = GetAltitude(worldPoint); Color pointColor = Color.magenta; if (t >= 0f) { pointColor = landGradient.Evaluate(t); } else { pointColor = seaGradient.Evaluate(t * -1f); } output.SetPixel(col, row, pointColor); if (overlayRegions) { regionCenter r = GetClosestRegion(worldPoint); output.SetPixel(col, row, Color.Lerp(r.color, pointColor, .5f)); } coro++; if (coro % rasterSize == 0) { output.Apply(); yield return(0); } } } // Draw black dots for each of the points. if (drawCenters) { float colorMod = .75f; foreach (regionCenter r in regionPoints) { Vector2 v = r.point; Vector2 rasterPoint = new Vector2( (v.x - left) / scale, (v.y - bottom) / scale ); output.SetPixel( (int)rasterPoint.x, (int)rasterPoint.y, new Color( r.color.r * colorMod, r.color.g * colorMod, r.color.b * colorMod ) ); } } output.Apply(); DumpMapToFile(output); return(true); }