void DiamondSquare::diamondSquare() { _terrain[IDX(0, 0, _resolution)] = 1 - edges(randomEngine); _terrain[IDX(_resolution, _resolution, _resolution)] = edges(randomEngine); _terrain[IDX(_resolution, 0, _resolution)] = 1 - edges(randomEngine); _terrain[IDX(0, _resolution, _resolution)] = edges(randomEngine); int halfRes = _resolution / 2; int iteration = 0; for (int s = halfRes; s >= 1; s /= 2) { iteration++; //increase // Diamondstep for (int y = s; y < _resolution; y += +(s + s)) { for (int x = s; x < _resolution; x += (s + s)) { diamondStep(x, y, s, iteration); } } // Squarestep for (int y = s; y < _resolution; y += +(s + s)) { for (int x = s; x < _resolution; x += (s + s)) { squareStep(x, y, s, iteration); } } } //Cutoff float min = 0; float max = 1; for (int i = 0; i < _resolution; i++) { for (int j = 0; j < _resolution; j++) { float current = _terrain[IDX(i, j, _resolution)]; if (current < min) min = current; if (current > max) max = current; } } min *= -1; float range = max + min; for (int i = 0; i < _resolution; i++) { for (int j = 0; j < _resolution; j++) { _terrain[IDX(i, j, _resolution)] = (_terrain[IDX(i, j, _resolution)] + min) / range; } } }
std::vector<float> DiamondSquare::doDiamondSquare() { std::cout << "[DiamondSquare] Creating Heightmap..." << std::endl; // start-values field[IDX(0, 0, calcResolution)] = getRandom(0, 1); field[IDX(calcResolution - 1, 0, calcResolution)] = getRandom(0, 1); field[IDX(0, calcResolution - 1, calcResolution)] = getRandom(0, 1); field[IDX(calcResolution - 1, calcResolution - 1, calcResolution)] = getRandom(0, 1); int res = this->calcResolution-1; for (int step = res; step >= 2; step /= 2) { int halfstep = step / 2; for (int y = halfstep; y < res; y += step) { for (int x = halfstep; x < res; x += step) { diamondStep(x, y, halfstep, roughnessIteration); } } for (int y = 0; y <= res; y += step) { for (int x = halfstep; x < res; x += step) { squareStep(x, y, halfstep, roughnessIteration); } } for (int y = halfstep; y < res; y += step) { for (int x = 0; x <= res; x += step) { squareStep(x, y, halfstep, roughnessIteration); } } roughnessIteration *= roughness; } normalizeHeightField(); if (this->inputResolution != this->calcResolution) { std::vector<float> cuttedField(inputResolution * inputResolution); for (int y = 0; y < this->inputResolution; y++) { for (int x = 0; x < this->inputResolution; x++) { cuttedField[IDX(x, y, this->inputResolution)] = field[IDX(x, y, this->calcResolution)]; } } field = cuttedField; } std::cout << "[DiamondSquare] Smoothing Heightmap..." << std::endl; for (int i = 0; i < smoothCount; i++) { smoothHeightField(); } return field; }