Mgv5/v7/flat/fractal: Move tunnel noise calculation into generateCaves

Tunnel 3D noises are only calculated when solid terrain is present
in mapchunk, avoiding large amounts of unnecessary calculations
Change 'int' to 's16' in calculateNoise
Change 'i' to 'vi' for voxelmanip indexes for consistency
Keep 'u32 index3d' local to a smaller part of tunnel code
Mgv7: Don't call CaveV7 if no solid terrain in mapchunk
Give 'open' bool a more descriptive name
This commit is contained in:
paramat 2016-01-31 04:23:46 +00:00
parent 80c7612e76
commit 0a8af88147
4 changed files with 165 additions and 159 deletions

@ -323,20 +323,16 @@ void MapgenFlat::makeChunk(BlockMakeData *data)
void MapgenFlat::calculateNoise() void MapgenFlat::calculateNoise()
{ {
//TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO);
int x = node_min.X; s16 x = node_min.X;
int y = node_min.Y - 1; s16 z = node_min.Z;
int z = node_min.Z;
if ((spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS)) if ((spflags & MGFLAT_LAKES) || (spflags & MGFLAT_HILLS))
noise_terrain->perlinMap2D(x, z); noise_terrain->perlinMap2D(x, z);
// Cave noises are calculated in generateCaves()
// only if solid terrain is present in mapchunk
noise_filler_depth->perlinMap2D(x, z); noise_filler_depth->perlinMap2D(x, z);
if (flags & MG_CAVES) {
noise_cave1->perlinMap3D(x, y, z);
noise_cave2->perlinMap3D(x, y, z);
}
noise_heat->perlinMap2D(x, z); noise_heat->perlinMap2D(x, z);
noise_humidity->perlinMap2D(x, z); noise_humidity->perlinMap2D(x, z);
noise_heat_blend->perlinMap2D(x, z); noise_heat_blend->perlinMap2D(x, z);
@ -550,41 +546,45 @@ void MapgenFlat::dustTopNodes()
void MapgenFlat::generateCaves(s16 max_stone_y) void MapgenFlat::generateCaves(s16 max_stone_y)
{ {
if (max_stone_y >= node_min.Y) { if (max_stone_y < node_min.Y)
v3s16 em = vm->m_area.getExtent(); return;
u32 index2d = 0;
u32 index3d;
for (s16 z = node_min.Z; z <= node_max.Z; z++) noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
bool open = false; // Is column open to overground
u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
(x - node_min.X);
// Biome of column
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; v3s16 em = vm->m_area.getExtent();
y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { u32 index2d = 0;
content_t c = vm->m_data[vi].getContent();
if (c == CONTENT_AIR || c == biome->c_water_top || for (s16 z = node_min.Z; z <= node_max.Z; z++)
c == biome->c_water) { for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
open = true; bool column_is_open = false; // Is column open to overground
continue; u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
} u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
// Ground (x - node_min.X);
float d1 = contour(noise_cave1->result[index3d]); // Biome of column
float d2 = contour(noise_cave2->result[index3d]); Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
// In tunnel and ground content, excavate for (s16 y = node_max.Y + 1; y >= node_min.Y - 1;
vm->m_data[vi] = MapNode(CONTENT_AIR); y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) {
} else if (open && (c == biome->c_filler || c == biome->c_stone)) { content_t c = vm->m_data[vi].getContent();
// Tunnel entrance floor if (c == CONTENT_AIR || c == biome->c_water_top ||
vm->m_data[vi] = MapNode(biome->c_top); c == biome->c_water) {
open = false; column_is_open = true;
} else { continue;
open = false; }
} // Ground
float d1 = contour(noise_cave1->result[index3d]);
float d2 = contour(noise_cave2->result[index3d]);
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
// In tunnel and ground content, excavate
vm->m_data[vi] = MapNode(CONTENT_AIR);
} else if (column_is_open &&
(c == biome->c_filler || c == biome->c_stone)) {
// Tunnel entrance floor
vm->m_data[vi] = MapNode(biome->c_top);
column_is_open = false;
} else {
column_is_open = false;
} }
} }
} }

@ -339,18 +339,15 @@ void MapgenFractal::makeChunk(BlockMakeData *data)
void MapgenFractal::calculateNoise() void MapgenFractal::calculateNoise()
{ {
//TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO);
int x = node_min.X; s16 x = node_min.X;
int y = node_min.Y - 1; s16 z = node_min.Z;
int z = node_min.Z;
noise_seabed->perlinMap2D(x, z); noise_seabed->perlinMap2D(x, z);
// Cave noises are calculated in generateCaves()
// only if solid terrain is present in mapchunk
noise_filler_depth->perlinMap2D(x, z); noise_filler_depth->perlinMap2D(x, z);
if (flags & MG_CAVES) {
noise_cave1->perlinMap3D(x, y, z);
noise_cave2->perlinMap3D(x, y, z);
}
noise_heat->perlinMap2D(x, z); noise_heat->perlinMap2D(x, z);
noise_humidity->perlinMap2D(x, z); noise_humidity->perlinMap2D(x, z);
noise_heat_blend->perlinMap2D(x, z); noise_heat_blend->perlinMap2D(x, z);
@ -673,41 +670,45 @@ void MapgenFractal::dustTopNodes()
void MapgenFractal::generateCaves(s16 max_stone_y) void MapgenFractal::generateCaves(s16 max_stone_y)
{ {
if (max_stone_y >= node_min.Y) { if (max_stone_y < node_min.Y)
v3s16 em = vm->m_area.getExtent(); return;
u32 index2d = 0;
u32 index3d;
for (s16 z = node_min.Z; z <= node_max.Z; z++) noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
bool open = false; // Is column open to overground
u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
(x - node_min.X);
// Biome of column
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; v3s16 em = vm->m_area.getExtent();
y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { u32 index2d = 0;
content_t c = vm->m_data[vi].getContent();
if (c == CONTENT_AIR || c == biome->c_water_top || for (s16 z = node_min.Z; z <= node_max.Z; z++)
c == biome->c_water) { for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
open = true; bool column_is_open = false; // Is column open to overground
continue; u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
} u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
// Ground (x - node_min.X);
float d1 = contour(noise_cave1->result[index3d]); // Biome of column
float d2 = contour(noise_cave2->result[index3d]); Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
// In tunnel and ground content, excavate for (s16 y = node_max.Y + 1; y >= node_min.Y - 1;
vm->m_data[vi] = MapNode(CONTENT_AIR); y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) {
} else if (open && (c == biome->c_filler || c == biome->c_stone)) { content_t c = vm->m_data[vi].getContent();
// Tunnel entrance floor if (c == CONTENT_AIR || c == biome->c_water_top ||
vm->m_data[vi] = MapNode(biome->c_top); c == biome->c_water) {
open = false; column_is_open = true;
} else { continue;
open = false; }
} // Ground
float d1 = contour(noise_cave1->result[index3d]);
float d2 = contour(noise_cave2->result[index3d]);
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
// In tunnel and ground content, excavate
vm->m_data[vi] = MapNode(CONTENT_AIR);
} else if (column_is_open &&
(c == biome->c_filler || c == biome->c_stone)) {
// Tunnel entrance floor
vm->m_data[vi] = MapNode(biome->c_top);
column_is_open = false;
} else {
column_is_open = false;
} }
} }
} }

@ -322,18 +322,16 @@ void MapgenV5::makeChunk(BlockMakeData *data)
void MapgenV5::calculateNoise() void MapgenV5::calculateNoise()
{ {
//TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO);
int x = node_min.X; s16 x = node_min.X;
int y = node_min.Y - 1; s16 y = node_min.Y - 1;
int z = node_min.Z; s16 z = node_min.Z;
noise_factor->perlinMap2D(x, z); noise_factor->perlinMap2D(x, z);
noise_height->perlinMap2D(x, z); noise_height->perlinMap2D(x, z);
noise_ground->perlinMap3D(x, y, z); noise_ground->perlinMap3D(x, y, z);
if (flags & MG_CAVES) { // Cave noises are calculated in generateCaves()
noise_cave1->perlinMap3D(x, y, z); // only if solid terrain is present in mapchunk
noise_cave2->perlinMap3D(x, y, z);
}
noise_filler_depth->perlinMap2D(x, z); noise_filler_depth->perlinMap2D(x, z);
noise_heat->perlinMap2D(x, z); noise_heat->perlinMap2D(x, z);
@ -377,9 +375,9 @@ int MapgenV5::generateBaseTerrain()
for (s16 z=node_min.Z; z<=node_max.Z; z++) { for (s16 z=node_min.Z; z<=node_max.Z; z++) {
for (s16 y=node_min.Y - 1; y<=node_max.Y + 1; y++) { for (s16 y=node_min.Y - 1; y<=node_max.Y + 1; y++) {
u32 i = vm->m_area.index(node_min.X, y, z); u32 vi = vm->m_area.index(node_min.X, y, z);
for (s16 x=node_min.X; x<=node_max.X; x++, i++, index++, index2d++) { for (s16 x=node_min.X; x<=node_max.X; x++, vi++, index++, index2d++) {
if (vm->m_data[i].getContent() != CONTENT_IGNORE) if (vm->m_data[vi].getContent() != CONTENT_IGNORE)
continue; continue;
float f = 0.55 + noise_factor->result[index2d]; float f = 0.55 + noise_factor->result[index2d];
@ -391,11 +389,11 @@ int MapgenV5::generateBaseTerrain()
if (noise_ground->result[index] * f < y - h) { if (noise_ground->result[index] * f < y - h) {
if (y <= water_level) if (y <= water_level)
vm->m_data[i] = MapNode(c_water_source); vm->m_data[vi] = MapNode(c_water_source);
else else
vm->m_data[i] = MapNode(CONTENT_AIR); vm->m_data[vi] = MapNode(CONTENT_AIR);
} else { } else {
vm->m_data[i] = MapNode(c_stone); vm->m_data[vi] = MapNode(c_stone);
if (y > stone_surface_max_y) if (y > stone_surface_max_y)
stone_surface_max_y = y; stone_surface_max_y = y;
} }
@ -508,22 +506,26 @@ MgStoneType MapgenV5::generateBiomes(float *heat_map, float *humidity_map)
void MapgenV5::generateCaves(int max_stone_y) void MapgenV5::generateCaves(int max_stone_y)
{ {
if (max_stone_y >= node_min.Y) { if (max_stone_y < node_min.Y)
u32 index = 0; return;
for (s16 z = node_min.Z; z <= node_max.Z; z++) noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
u32 i = vm->m_area.index(node_min.X, y, z);
for (s16 x = node_min.X; x <= node_max.X; x++, i++, index++) {
float d1 = contour(noise_cave1->result[index]);
float d2 = contour(noise_cave2->result[index]);
if (d1 * d2 > 0.125f) {
content_t c = vm->m_data[i].getContent();
if (!ndef->get(c).is_ground_content || c == CONTENT_AIR)
continue;
vm->m_data[i] = MapNode(CONTENT_AIR); u32 index = 0;
}
for (s16 z = node_min.Z; z <= node_max.Z; z++)
for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
u32 vi = vm->m_area.index(node_min.X, y, z);
for (s16 x = node_min.X; x <= node_max.X; x++, vi++, index++) {
float d1 = contour(noise_cave1->result[index]);
float d2 = contour(noise_cave2->result[index]);
if (d1 * d2 > 0.125f) {
content_t c = vm->m_data[vi].getContent();
if (!ndef->get(c).is_ground_content || c == CONTENT_AIR)
continue;
vm->m_data[vi] = MapNode(CONTENT_AIR);
} }
} }
} }

@ -345,9 +345,9 @@ void MapgenV7::makeChunk(BlockMakeData *data)
void MapgenV7::calculateNoise() void MapgenV7::calculateNoise()
{ {
//TimeTaker t("calculateNoise", NULL, PRECISION_MICRO); //TimeTaker t("calculateNoise", NULL, PRECISION_MICRO);
int x = node_min.X; s16 x = node_min.X;
int y = node_min.Y - 1; s16 y = node_min.Y - 1;
int z = node_min.Z; s16 z = node_min.Z;
noise_terrain_persist->perlinMap2D(x, z); noise_terrain_persist->perlinMap2D(x, z);
float *persistmap = noise_terrain_persist->result; float *persistmap = noise_terrain_persist->result;
@ -356,17 +356,16 @@ void MapgenV7::calculateNoise()
noise_terrain_alt->perlinMap2D(x, z, persistmap); noise_terrain_alt->perlinMap2D(x, z, persistmap);
noise_height_select->perlinMap2D(x, z); noise_height_select->perlinMap2D(x, z);
if (flags & MG_CAVES) {
noise_cave1->perlinMap3D(x, y, z);
noise_cave2->perlinMap3D(x, y, z);
}
if ((spflags & MGV7_RIDGES) && node_max.Y >= water_level) { if ((spflags & MGV7_RIDGES) && node_max.Y >= water_level) {
noise_ridge->perlinMap3D(x, y, z); noise_ridge->perlinMap3D(x, y, z);
noise_ridge_uwater->perlinMap2D(x, z); noise_ridge_uwater->perlinMap2D(x, z);
} }
// Cave noises are calculated in generateCaves()
// only if solid terrain is present in mapchunk
// Mountain noises are calculated in generateMountainTerrain() // Mountain noises are calculated in generateMountainTerrain()
// only if solid terrain surface dips into mapchunk
noise_filler_depth->perlinMap2D(x, z); noise_filler_depth->perlinMap2D(x, z);
noise_heat->perlinMap2D(x, z); noise_heat->perlinMap2D(x, z);
@ -527,17 +526,17 @@ void MapgenV7::generateBaseTerrain(s16 *stone_surface_min_y, s16 *stone_surface_
if (surface_y > surface_max_y) if (surface_y > surface_max_y)
surface_max_y = surface_y; surface_max_y = surface_y;
u32 i = vm->m_area.index(x, node_min.Y - 1, z); u32 vi = vm->m_area.index(x, node_min.Y - 1, z);
for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
if (vm->m_data[i].getContent() == CONTENT_IGNORE) { if (vm->m_data[vi].getContent() == CONTENT_IGNORE) {
if (y <= surface_y) if (y <= surface_y)
vm->m_data[i] = n_stone; vm->m_data[vi] = n_stone;
else if (y <= water_level) else if (y <= water_level)
vm->m_data[i] = n_water; vm->m_data[vi] = n_water;
else else
vm->m_data[i] = n_air; vm->m_data[vi] = n_air;
} }
vm->m_area.add_y(em, i, 1); vm->m_area.add_y(em, vi, 1);
} }
} }
@ -585,7 +584,7 @@ void MapgenV7::generateRidgeTerrain()
MapNode n_water(c_water_source); MapNode n_water(c_water_source);
MapNode n_air(CONTENT_AIR); MapNode n_air(CONTENT_AIR);
u32 index = 0; u32 index = 0;
float width = 0.2; // TODO: figure out acceptable perlin noise values float width = 0.2;
for (s16 z = node_min.Z; z <= node_max.Z; z++) for (s16 z = node_min.Z; z <= node_max.Z; z++)
for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) { for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
@ -862,41 +861,45 @@ void MapgenV7::addTopNodes()
void MapgenV7::generateCaves(s16 max_stone_y) void MapgenV7::generateCaves(s16 max_stone_y)
{ {
if (max_stone_y >= node_min.Y) { if (max_stone_y < node_min.Y)
v3s16 em = vm->m_area.getExtent(); return;
u32 index2d = 0;
u32 index3d;
for (s16 z = node_min.Z; z <= node_max.Z; z++) noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
bool open = false; // Is column open to overground
u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
(x - node_min.X);
// Biome of column
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
for (s16 y = node_max.Y + 1; y >= node_min.Y - 1; v3s16 em = vm->m_area.getExtent();
y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) { u32 index2d = 0;
content_t c = vm->m_data[vi].getContent();
if (c == CONTENT_AIR || c == biome->c_water_top || for (s16 z = node_min.Z; z <= node_max.Z; z++)
c == biome->c_water) { for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
open = true; bool column_is_open = false; // Is column open to overground
continue; u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
} u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
// Ground (x - node_min.X);
float d1 = contour(noise_cave1->result[index3d]); // Biome of column
float d2 = contour(noise_cave2->result[index3d]); Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
// In tunnel and ground content, excavate for (s16 y = node_max.Y + 1; y >= node_min.Y - 1;
vm->m_data[vi] = MapNode(CONTENT_AIR); y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) {
} else if (open && (c == biome->c_filler || c == biome->c_stone)) { content_t c = vm->m_data[vi].getContent();
// Tunnel entrance floor if (c == CONTENT_AIR || c == biome->c_water_top ||
vm->m_data[vi] = MapNode(biome->c_top); c == biome->c_water) {
open = false; column_is_open = true;
} else { continue;
open = false; }
} // Ground
float d1 = contour(noise_cave1->result[index3d]);
float d2 = contour(noise_cave2->result[index3d]);
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
// In tunnel and ground content, excavate
vm->m_data[vi] = MapNode(CONTENT_AIR);
} else if (column_is_open &&
(c == biome->c_filler || c == biome->c_stone)) {
// Tunnel entrance floor
vm->m_data[vi] = MapNode(biome->c_top);
column_is_open = false;
} else {
column_is_open = false;
} }
} }
} }