public WorleySurfaceNoise GetEdgeData(float x, float y) { if (perterbAmp > 0) { SingleGradientPerturb(seed, perterbAmp, frequency, ref x, ref y); } x *= frequency; y *= frequency; int xr = FastRound(x); int yr = FastRound(y); float distance0 = 999999; float distance1 = 999999; // Store distance1 index int xc1 = 0, yc1 = 0; // Store distance0 index in case it is assigned to distance1 later int xc0 = 0, yc0 = 0; // All adjacent cell indices and distances NineInts otherX = new NineInts(); NineInts otherY = new NineInts(); NineFloats otherDist = new NineFloats(); for (int i = 0; i < 9; i++) { otherDist [i] = 999999; } int indexCount = 0; float3 currentCellPosition = float3.zero; int2 currentCellIndex = int2.zero; for (int xi = xr - 1; xi <= xr + 1; xi++) { for (int yi = yr - 1; yi <= yr + 1; yi++) { float2 vec = cell_2D [Hash2D(seed, xi, yi) & 255]; float vecX = xi - x + vec.x * cellularJitter; float vecY = yi - y + vec.y * cellularJitter; float cellX = xi + vec.x * cellularJitter; float cellY = yi + vec.y * cellularJitter; // Natural distance function //float newDistance = (math.abs(vecX) + math.abs(vecY)) + (vecX * vecX + vecY * vecY); // Euclidean distance function float newDistance = newDistance = vecX * vecX + vecY * vecY; if (newDistance <= distance1) // Math.Min(distance[i], newDistance) { if (newDistance >= distance0) // Math.Max((newDistance)), distance[i - 1]) { distance1 = newDistance; xc1 = xi; yc1 = yi; } else { distance1 = distance0; xc1 = xc0; yc1 = yc0; } } if (newDistance <= distance0) // Math.Min(distance0, newDistance) { distance0 = newDistance; xc0 = xi; yc0 = yi; currentCellPosition = new float3(cellX, 0, cellY) / frequency; currentCellIndex = new int2(xi, yi); } // Store all adjacent cells otherX [indexCount] = xi; otherY [indexCount] = yi; otherDist [indexCount] = newDistance; indexCount++; } } // Current cell float currentCellValue = To01(ValCoord2D(seed, xc0, yc0)); int currentBiome = TerrainTypeIndex(currentCellValue); // Final closest adjacent cell values float adjacentEdgeDistance = 999999; float adjacentCellValue = 0; // Iterate over all adjacent cells for (int i = 0; i < 9; i++) { // Find closest cell within smoothing radius float dist2Edge = otherDist [i] - distance0; if (dist2Edge < adjacentEdgeDistance) { float otherCellValue = To01(ValCoord2D(seed, otherX [i], otherY [i])); int otherBiome = TerrainTypeIndex(otherCellValue); /// Assign as final value if not current biome if (otherBiome != currentBiome) { adjacentEdgeDistance = dist2Edge; adjacentCellValue = otherCellValue; } } } if (adjacentEdgeDistance == 999999) { adjacentEdgeDistance = 0; } WorleySurfaceNoise cell = new WorleySurfaceNoise { currentSurfaceCellValue = currentCellValue, distance2Edge = adjacentEdgeDistance, adjacentSurfaceCellValue = adjacentCellValue, currentCellPosition = currentCellPosition, currentCellIndexInMap = currentCellIndex }; // Data for use in terrain generation return(cell); }
public PointData GetPointData(float x, float y) { if (perterbAmp > 0) { SingleGradientPerturb(seed, perterbAmp, frequency, ref x, ref y); } x *= frequency; y *= frequency; int xr = FastRound(x); int yr = FastRound(y); float distance0 = 999999; float distance1 = 999999; // Store distance1 index int xc1 = 0, yc1 = 0; // Store distance0 index in case it is assigned to distance1 later int xc0 = 0, yc0 = 0; // All adjacent cell indices and distances NineInts otherX = new NineInts(); NineInts otherY = new NineInts(); NineFloats otherCellX = new NineFloats(); NineFloats otherCellY = new NineFloats(); NineFloats otherDistance = new NineFloats(); for (int i = 0; i < 9; i++) { otherDistance[i] = 999999; } int indexCount = 0; float3 currentCellPosition = float3.zero; int2 currentCellIndex = int2.zero; float distance = 999999; for (int xi = xr - 1; xi <= xr + 1; xi++) { for (int yi = yr - 1; yi <= yr + 1; yi++) { float2 vec = cell_2D[Hash2D(seed, xi, yi) & 255]; float vecX = xi - x + vec.x * cellularJitter; float vecY = yi - y + vec.y * cellularJitter; float cellX = xi + vec.x * cellularJitter; float cellY = yi + vec.y * cellularJitter; float newDistance; switch (distanceFunction) { case DistanceFunction.Natural: newDistance = (math.abs(vecX) + math.abs(vecY)) + (vecX * vecX + vecY * vecY); break; case DistanceFunction.Manhatten: newDistance = math.abs(vecX) + math.abs(vecY); break; case DistanceFunction.Euclidean: newDistance = newDistance = vecX * vecX + vecY * vecY; break; default: newDistance = 0; throw new System.Exception("Unrecognised cellular distance function"); } if (newDistance < distance) { distance = newDistance; } if (newDistance <= distance1) { if (newDistance >= distance0) { distance1 = newDistance; xc1 = xi; yc1 = yi; } else { distance1 = distance0; xc1 = xc0; yc1 = yc0; } } if (newDistance <= distance0) { distance0 = newDistance; xc0 = xi; yc0 = yi; currentCellPosition = math.round(new float3(cellX, 0, cellY) / frequency); currentCellIndex = new int2(xi, yi); } // Store all adjacent cells otherCellX[indexCount] = cellX; otherCellY[indexCount] = cellY; otherX[indexCount] = xi; otherY[indexCount] = yi; otherDistance[indexCount] = newDistance; indexCount++; } } // Current cell float currentCellValue = To01(ValCoord2D(seed, xc0, yc0)); float currentBiome = EdgeBorder(currentCellIndex); // Final closest adjacent cell values float distance2Edge = 999999; float adjacentCellValue = 0; int2 adjacentCellIndex = int2.zero; float3 adjacentCellPosition = float3.zero; // Iterate over all adjacent cells for (int i = 0; i < 9; i++) { // Find closest cell within smoothing radius float dist2Edge = ApplyDistanceType(distance0, otherDistance[i]); if (dist2Edge < distance2Edge) { int2 otherCellIndex = new int2(otherX[i], otherY[i]); float otherBiome = EdgeBorder(otherCellIndex); /// Assign as final value if not current biome if (otherBiome != currentBiome) { distance2Edge = dist2Edge; adjacentCellValue = To01(ValCoord2D(seed, otherX[i], otherY[i])); adjacentCellIndex = otherCellIndex; adjacentCellPosition = math.round(new float3(otherCellX[i], 0, otherCellY[i]) / frequency); } } } if (distance2Edge == 999999) { distance2Edge = 0; } PointData cell = new PointData(); cell.distance2Edge = distance2Edge; cell.distance = distance; cell.currentCellValue = currentCellValue; cell.adjacentCellValue = adjacentCellValue; cell.currentCellPosition = currentCellPosition; cell.adjacentCellPosition = adjacentCellPosition; cell.currentCellIndex = currentCellIndex; cell.adjacentCellIndex = adjacentCellIndex; return(cell); }