// This avoids duplicating the code in terrainLevelFromNoise, adding // only the final step of terrain generation without a noise map. float MapgenValleys::adjustedTerrainLevelFromNoise(TerrainNoise *tn) { float mount = terrainLevelFromNoise(tn); s16 y_start = myround(mount); for (s16 y = y_start; y <= y_start + 1000; y++) { float fill = NoisePerlin3D(&noise_inter_valley_fill->np, tn->x, y, tn->z, seed); if (fill * *tn->slope <= y - mount) { mount = MYMAX(y - 1, mount); break; } } return mount; }
// This avoids duplicating the code in terrainLevelFromNoise, adding // only the final step of terrain generation without a noise map. float MapgenValleys::adjustedTerrainLevelFromNoise(TerrainNoise *tn) { float mount = terrainLevelFromNoise(tn); if (!fast_terrain) { for (s16 y = round(mount); y <= round(mount) + 1000; y++) { float fill = NoisePerlin3D(&noise_inter_valley_fill->np, tn->x, y, tn->z, seed); if (fill * *tn->slope <= y - mount) { mount = fmax(y - 1, mount); break; } } } return mount; }
// Populate the noise tables and do most of the // calculation necessary to determine terrain height. void MapgenValleys::calculateNoise() { //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); int x = node_min.X; int y = node_min.Y - 1; int z = node_min.Z; //TimeTaker tcn("actualNoise"); noise_filler_depth->perlinMap2D(x, z); noise_heat_blend->perlinMap2D(x, z); noise_heat->perlinMap2D(x, z); noise_humidity_blend->perlinMap2D(x, z); noise_humidity->perlinMap2D(x, z); noise_inter_valley_slope->perlinMap2D(x, z); noise_rivers->perlinMap2D(x, z); noise_terrain_height->perlinMap2D(x, z); noise_valley_depth->perlinMap2D(x, z); noise_valley_profile->perlinMap2D(x, z); noise_inter_valley_fill->perlinMap3D(x, y, z); //mapgen_profiler->avg("noisemaps", tcn.stop() / 1000.f); for (s32 index = 0; index < csize.X * csize.Z; index++) { noise_heat->result[index] += noise_heat_blend->result[index]; noise_humidity->result[index] += noise_humidity_blend->result[index]; } TerrainNoise tn; u32 index = 0; for (tn.z = node_min.Z; tn.z <= node_max.Z; tn.z++) for (tn.x = node_min.X; tn.x <= node_max.X; tn.x++, index++) { // The parameters that we actually need to generate terrain // are passed by address (and the return value). tn.terrain_height = noise_terrain_height->result[index]; // River noise is replaced with base terrain, which // is basically the height of the water table. tn.rivers = &noise_rivers->result[index]; // Valley depth noise is replaced with the valley // number that represents the height of terrain // over rivers and is used to determine about // how close a river is for humidity calculation. tn.valley = &noise_valley_depth->result[index]; tn.valley_profile = noise_valley_profile->result[index]; // Slope noise is replaced by the calculated slope // which is used to get terrain height in the slow // method, to create sharper mountains. tn.slope = &noise_inter_valley_slope->result[index]; tn.inter_valley_fill = noise_inter_valley_fill->result[index]; // This is the actual terrain height. float mount = terrainLevelFromNoise(&tn); noise_terrain_height->result[index] = mount; } heatmap = noise_heat->result; humidmap = noise_humidity->result; }
// Populate the noise tables and do most of the // calculation necessary to determine terrain height. void MapgenValleys::calculateNoise() { //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); int x = node_min.X; int y = node_min.Y - 1; int z = node_min.Z; //TimeTaker tcn("actualNoise"); noise_filler_depth->perlinMap2D(x, z); noise_heat_blend->perlinMap2D(x, z); noise_heat->perlinMap2D(x, z); noise_humidity_blend->perlinMap2D(x, z); noise_humidity->perlinMap2D(x, z); noise_inter_valley_slope->perlinMap2D(x, z); noise_rivers->perlinMap2D(x, z); noise_terrain_height->perlinMap2D(x, z); noise_valley_depth->perlinMap2D(x, z); noise_valley_profile->perlinMap2D(x, z); if (fast_terrain) { // Make this 2D for speed, if requested. noise_inter_valley_fill->perlinMap2D(x, z); if (cliff_terrain) noise_cliffs->perlinMap2D(x, z); if (rugged_terrain) noise_corr->perlinMap2D(x, z); } else { noise_inter_valley_fill->perlinMap3D(x, y, z); } if (flags & MG_CAVES) { noise_simple_caves_1->perlinMap3D(x, y, z); noise_simple_caves_2->perlinMap3D(x, y, z); } //mapgen_profiler->avg("noisemaps", tcn.stop() / 1000.f); for (s32 index = 0; index < csize.X * csize.Z; index++) { noise_heat->result[index] += noise_heat_blend->result[index]; noise_heat->result[index] += temperature_adjust; noise_humidity->result[index] += noise_humidity_blend->result[index]; } TerrainNoise tn; u32 index = 0; for (tn.z = node_min.Z; tn.z <= node_max.Z; tn.z++) for (tn.x = node_min.X; tn.x <= node_max.X; tn.x++, index++) { // The parameters that we actually need to generate terrain // are passed by address (and the return value). tn.terrain_height = noise_terrain_height->result[index]; // River noise is replaced with base terrain, which // is basically the height of the water table. tn.rivers = &noise_rivers->result[index]; // Valley depth noise is replaced with the valley // number that represents the height of terrain // over rivers and is used to determine about // how close a river is for humidity calculation. tn.valley = &noise_valley_depth->result[index]; tn.valley_profile = noise_valley_profile->result[index]; // Slope noise is replaced by the calculated slope // which is used to get terrain height in the slow // method, to create sharper mountains. tn.slope = &noise_inter_valley_slope->result[index]; tn.inter_valley_fill = noise_inter_valley_fill->result[index]; tn.cliffs = noise_cliffs->result[index]; tn.corr = noise_corr->result[index]; // This is the actual terrain height. float mount = terrainLevelFromNoise(&tn); noise_terrain_height->result[index] = mount; if (fast_terrain) { // Assign humidity adjusted by water proximity. // I can't think of a reason why a mod would expect base humidity // from noise or at any altitude other than ground level. noise_humidity->result[index] = humidityByTerrain( noise_humidity->result[index], mount, noise_rivers->result[index], noise_valley_depth->result[index]); // Assign heat adjusted by altitude. See humidity, above. if (use_altitude_chill && mount > 0.f) noise_heat->result[index] *= pow(0.5f, (mount - altitude_chill / 3.f) / altitude_chill); } } heatmap = noise_heat->result; humidmap = noise_humidity->result; }