Skip to content

Commit 465bb6f

Browse files
committedApr 8, 2016
Mapgen: Optimise cave noises and tunnel excavation
Instead of doing nothing at node_max.Y + 1 use 1-down overgeneration for tunnel generation and noisemaps Move some old unused code in mgv7 to end of file
1 parent c3993f6 commit 465bb6f

8 files changed

+162
-148
lines changed
 

‎src/mapgen_flat.cpp

+14-12
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge
5858
//// amount of elements to skip for the next index
5959
//// for noise/height/biome maps (not vmanip)
6060
this->ystride = csize.X;
61-
this->zstride = csize.X * (csize.Y + 2);
61+
// 1-down overgeneration
62+
this->zstride_1d = csize.X * (csize.Y + 1);
6263

6364
this->biomemap = new u8[csize.X * csize.Z];
6465
this->heightmap = new s16[csize.X * csize.Z];
@@ -80,8 +81,9 @@ MapgenFlat::MapgenFlat(int mapgenid, MapgenParams *params, EmergeManager *emerge
8081
noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z);
8182

8283
//// 3D noise
83-
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
84-
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
84+
// 1-down overgeneraion
85+
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
86+
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
8587

8688
//// Biome noise
8789
noise_heat = new Noise(&params->np_biome_heat, seed, csize.X, csize.Z);
@@ -566,19 +568,19 @@ void MapgenFlat::generateCaves(s16 max_stone_y)
566568
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
567569
bool column_is_open = false; // Is column open to overground
568570
bool is_tunnel = false; // Is tunnel or tunnel floor
569-
u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
570-
u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
571+
u32 vi = vm->m_area.index(x, node_max.Y, z);
572+
u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
571573
(x - node_min.X);
572574
// Biome of column
573575
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
574576

575-
for (s16 y = node_max.Y + 1; y >= node_min.Y - 1;
576-
y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) {
577-
// Don't excavate the overgenerated stone at node_max.Y + 1,
578-
// this creates a 'roof' over the tunnel, preventing light in
579-
// tunnels at mapchunk borders when generating mapchunks upwards.
580-
if (y > node_max.Y)
581-
continue;
577+
// Don't excavate the overgenerated stone at node_max.Y + 1,
578+
// this creates a 'roof' over the tunnel, preventing light in
579+
// tunnels at mapchunk borders when generating mapchunks upwards.
580+
// This 'roof' is removed when the mapchunk above is generated.
581+
for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
582+
index3d -= ystride,
583+
vm->m_area.add_y(em, vi, -1)) {
582584

583585
content_t c = vm->m_data[vi].getContent();
584586
if (c == CONTENT_AIR || c == biome->c_water_top ||

‎src/mapgen_flat.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class MapgenFlat : public Mapgen {
6060
BiomeManager *bmgr;
6161

6262
int ystride;
63-
int zstride;
63+
int zstride_1d;
6464
u32 spflags;
6565

6666
v3s16 node_min;

‎src/mapgen_fractal.cpp

+14-12
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *
5656
//// amount of elements to skip for the next index
5757
//// for noise/height/biome maps (not vmanip)
5858
this->ystride = csize.X;
59-
this->zstride = csize.X * (csize.Y + 2);
59+
// 1-down overgeneration
60+
this->zstride_1d = csize.X * (csize.Y + 1);
6061

6162
this->biomemap = new u8[csize.X * csize.Z];
6263
this->heightmap = new s16[csize.X * csize.Z];
@@ -85,8 +86,9 @@ MapgenFractal::MapgenFractal(int mapgenid, MapgenParams *params, EmergeManager *
8586
noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z);
8687

8788
//// 3D terrain noise
88-
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
89-
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
89+
// 1-down overgeneraion
90+
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
91+
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
9092

9193
//// Biome noise
9294
noise_heat = new Noise(&params->np_biome_heat, seed, csize.X, csize.Z);
@@ -694,19 +696,19 @@ void MapgenFractal::generateCaves(s16 max_stone_y)
694696
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
695697
bool column_is_open = false; // Is column open to overground
696698
bool is_tunnel = false; // Is tunnel or tunnel floor
697-
u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
698-
u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
699+
u32 vi = vm->m_area.index(x, node_max.Y, z);
700+
u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
699701
(x - node_min.X);
700702
// Biome of column
701703
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
702704

703-
for (s16 y = node_max.Y + 1; y >= node_min.Y - 1;
704-
y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) {
705-
// Don't excavate the overgenerated stone at node_max.Y + 1,
706-
// this creates a 'roof' over the tunnel, preventing light in
707-
// tunnels at mapchunk borders when generating mapchunks upwards.
708-
if (y > node_max.Y)
709-
continue;
705+
// Don't excavate the overgenerated stone at node_max.Y + 1,
706+
// this creates a 'roof' over the tunnel, preventing light in
707+
// tunnels at mapchunk borders when generating mapchunks upwards.
708+
// This 'roof' is removed when the mapchunk above is generated.
709+
for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
710+
index3d -= ystride,
711+
vm->m_area.add_y(em, vi, -1)) {
710712

711713
content_t c = vm->m_data[vi].getContent();
712714
if (c == CONTENT_AIR || c == biome->c_water_top ||

‎src/mapgen_fractal.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class MapgenFractal : public Mapgen {
6565
BiomeManager *bmgr;
6666

6767
int ystride;
68-
int zstride;
68+
int zstride_1d;
6969
u16 formula;
7070
bool julia;
7171

‎src/mapgen_v7.cpp

+113-106
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
5959
//// amount of elements to skip for the next index
6060
//// for noise/height/biome maps (not vmanip)
6161
this->ystride = csize.X;
62-
this->zstride = csize.X * (csize.Y + 2);
62+
// 1-down overgeneration
63+
this->zstride_1d = csize.X * (csize.Y + 1);
6364

6465
this->biomemap = new u8[csize.X * csize.Z];
6566
this->heightmap = new s16[csize.X * csize.Z];
@@ -80,10 +81,12 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
8081
noise_ridge_uwater = new Noise(&sp->np_ridge_uwater, seed, csize.X, csize.Z);
8182

8283
//// 3d terrain noise
84+
// 1-up 1-down overgeneration
8385
noise_mountain = new Noise(&sp->np_mountain, seed, csize.X, csize.Y + 2, csize.Z);
8486
noise_ridge = new Noise(&sp->np_ridge, seed, csize.X, csize.Y + 2, csize.Z);
85-
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
86-
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
87+
// 1-down overgeneraion
88+
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
89+
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
8790

8891
//// Biome noise
8992
noise_heat = new Noise(&params->np_biome_heat, seed, csize.X, csize.Z);
@@ -199,7 +202,7 @@ void MapgenV7Params::writeParams(Settings *settings) const
199202
}
200203

201204

202-
///////////////////////////////////////
205+
///////////////////////////////////////////////////////////////////////////////
203206

204207

205208
int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
@@ -451,41 +454,6 @@ bool MapgenV7::getMountainTerrainFromMap(int idx_xyz, int idx_xz, s16 y)
451454
}
452455

453456

454-
#if 0
455-
void MapgenV7::carveRivers() {
456-
MapNode n_air(CONTENT_AIR), n_water_source(c_water_source);
457-
MapNode n_stone(c_stone);
458-
u32 index = 0;
459-
460-
int river_depth = 4;
461-
462-
for (s16 z = node_min.Z; z <= node_max.Z; z++)
463-
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
464-
float terrain_mod = noise_terrain_mod->result[index];
465-
NoiseParams *np = noise_terrain_river->np;
466-
np.persist = noise_terrain_persist->result[index];
467-
float terrain_river = NoisePerlin2DNoTxfm(np, x, z, seed);
468-
float height = terrain_river * (1 - abs(terrain_mod)) *
469-
noise_terrain_river->np.scale;
470-
height = log(height * height); //log(h^3) is pretty interesting for terrain
471-
472-
s16 y = heightmap[index];
473-
if (height < 1.0 && y > river_depth &&
474-
y - river_depth >= node_min.Y && y <= node_max.Y) {
475-
476-
for (s16 ry = y; ry != y - river_depth; ry--) {
477-
u32 vi = vm->m_area.index(x, ry, z);
478-
vm->m_data[vi] = n_air;
479-
}
480-
481-
u32 vi = vm->m_area.index(x, y - river_depth, z);
482-
vm->m_data[vi] = n_water_source;
483-
}
484-
}
485-
}
486-
#endif
487-
488-
489457
int MapgenV7::generateTerrain()
490458
{
491459
s16 stone_surface_min_y;
@@ -765,6 +733,112 @@ void MapgenV7::dustTopNodes()
765733
}
766734

767735

736+
void MapgenV7::generateCaves(s16 max_stone_y)
737+
{
738+
if (max_stone_y < node_min.Y)
739+
return;
740+
741+
noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
742+
noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
743+
744+
v3s16 em = vm->m_area.getExtent();
745+
u32 index2d = 0;
746+
747+
for (s16 z = node_min.Z; z <= node_max.Z; z++)
748+
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
749+
bool column_is_open = false; // Is column open to overground
750+
bool is_tunnel = false; // Is tunnel or tunnel floor
751+
// Indexes at column top (node_max.Y)
752+
u32 vi = vm->m_area.index(x, node_max.Y, z);
753+
u32 index3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride +
754+
(x - node_min.X);
755+
// Biome of column
756+
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
757+
758+
// Don't excavate the overgenerated stone at node_max.Y + 1,
759+
// this creates a 'roof' over the tunnel, preventing light in
760+
// tunnels at mapchunk borders when generating mapchunks upwards.
761+
// This 'roof' is removed when the mapchunk above is generated.
762+
for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
763+
index3d -= ystride,
764+
vm->m_area.add_y(em, vi, -1)) {
765+
766+
content_t c = vm->m_data[vi].getContent();
767+
if (c == CONTENT_AIR || c == biome->c_water_top ||
768+
c == biome->c_water) {
769+
column_is_open = true;
770+
continue;
771+
}
772+
// Ground
773+
float d1 = contour(noise_cave1->result[index3d]);
774+
float d2 = contour(noise_cave2->result[index3d]);
775+
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
776+
// In tunnel and ground content, excavate
777+
vm->m_data[vi] = MapNode(CONTENT_AIR);
778+
is_tunnel = true;
779+
} else if (is_tunnel && column_is_open &&
780+
(c == biome->c_filler || c == biome->c_stone)) {
781+
// Tunnel entrance floor
782+
vm->m_data[vi] = MapNode(biome->c_top);
783+
column_is_open = false;
784+
is_tunnel = false;
785+
} else {
786+
column_is_open = false;
787+
is_tunnel = false;
788+
}
789+
}
790+
}
791+
792+
if (node_min.Y >= water_level)
793+
return;
794+
795+
PseudoRandom ps(blockseed + 21343);
796+
u32 bruises_count = ps.range(0, 2);
797+
for (u32 i = 0; i < bruises_count; i++) {
798+
CaveV7 cave(this, &ps);
799+
cave.makeCave(node_min, node_max, max_stone_y);
800+
}
801+
}
802+
803+
804+
///////////////////////////////////////////////////////////////
805+
806+
807+
#if 0
808+
void MapgenV7::carveRivers() {
809+
MapNode n_air(CONTENT_AIR), n_water_source(c_water_source);
810+
MapNode n_stone(c_stone);
811+
u32 index = 0;
812+
813+
int river_depth = 4;
814+
815+
for (s16 z = node_min.Z; z <= node_max.Z; z++)
816+
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
817+
float terrain_mod = noise_terrain_mod->result[index];
818+
NoiseParams *np = noise_terrain_river->np;
819+
np.persist = noise_terrain_persist->result[index];
820+
float terrain_river = NoisePerlin2DNoTxfm(np, x, z, seed);
821+
float height = terrain_river * (1 - abs(terrain_mod)) *
822+
noise_terrain_river->np.scale;
823+
height = log(height * height); //log(h^3) is pretty interesting for terrain
824+
825+
s16 y = heightmap[index];
826+
if (height < 1.0 && y > river_depth &&
827+
y - river_depth >= node_min.Y && y <= node_max.Y) {
828+
829+
for (s16 ry = y; ry != y - river_depth; ry--) {
830+
u32 vi = vm->m_area.index(x, ry, z);
831+
vm->m_data[vi] = n_air;
832+
}
833+
834+
u32 vi = vm->m_area.index(x, y - river_depth, z);
835+
vm->m_data[vi] = n_water_source;
836+
}
837+
}
838+
}
839+
#endif
840+
841+
768842
#if 0
769843
void MapgenV7::addTopNodes()
770844
{
@@ -859,70 +933,3 @@ void MapgenV7::addTopNodes()
859933
}
860934
}
861935
#endif
862-
863-
864-
void MapgenV7::generateCaves(s16 max_stone_y)
865-
{
866-
if (max_stone_y < node_min.Y)
867-
return;
868-
869-
noise_cave1->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
870-
noise_cave2->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
871-
872-
v3s16 em = vm->m_area.getExtent();
873-
u32 index2d = 0;
874-
875-
for (s16 z = node_min.Z; z <= node_max.Z; z++)
876-
for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) {
877-
bool column_is_open = false; // Is column open to overground
878-
bool is_tunnel = false; // Is tunnel or tunnel floor
879-
u32 vi = vm->m_area.index(x, node_max.Y + 1, z);
880-
u32 index3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride +
881-
(x - node_min.X);
882-
// Biome of column
883-
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
884-
885-
for (s16 y = node_max.Y + 1; y >= node_min.Y - 1;
886-
y--, index3d -= ystride, vm->m_area.add_y(em, vi, -1)) {
887-
// Don't excavate the overgenerated stone at node_max.Y + 1,
888-
// this creates a 'roof' over the tunnel, preventing light in
889-
// tunnels at mapchunk borders when generating mapchunks upwards.
890-
if (y > node_max.Y)
891-
continue;
892-
893-
content_t c = vm->m_data[vi].getContent();
894-
if (c == CONTENT_AIR || c == biome->c_water_top ||
895-
c == biome->c_water) {
896-
column_is_open = true;
897-
continue;
898-
}
899-
// Ground
900-
float d1 = contour(noise_cave1->result[index3d]);
901-
float d2 = contour(noise_cave2->result[index3d]);
902-
if (d1 * d2 > 0.3f && ndef->get(c).is_ground_content) {
903-
// In tunnel and ground content, excavate
904-
vm->m_data[vi] = MapNode(CONTENT_AIR);
905-
is_tunnel = true;
906-
} else if (is_tunnel && column_is_open &&
907-
(c == biome->c_filler || c == biome->c_stone)) {
908-
// Tunnel entrance floor
909-
vm->m_data[vi] = MapNode(biome->c_top);
910-
column_is_open = false;
911-
is_tunnel = false;
912-
} else {
913-
column_is_open = false;
914-
is_tunnel = false;
915-
}
916-
}
917-
}
918-
919-
if (node_min.Y >= water_level)
920-
return;
921-
922-
PseudoRandom ps(blockseed + 21343);
923-
u32 bruises_count = ps.range(0, 2);
924-
for (u32 i = 0; i < bruises_count; i++) {
925-
CaveV7 cave(this, &ps);
926-
cave.makeCave(node_min, node_max, max_stone_y);
927-
}
928-
}

‎src/mapgen_v7.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class MapgenV7 : public Mapgen {
5959
BiomeManager *bmgr;
6060

6161
int ystride;
62-
int zstride;
62+
int zstride_1d;
6363
u32 spflags;
6464

6565
v3s16 node_min;

‎src/mapgen_valleys.cpp

+17-15
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *
7474
//// for noise/height/biome maps (not vmanip)
7575
this->ystride = csize.X;
7676
this->zstride = csize.X * (csize.Y + 2);
77+
// 1-down overgeneration
78+
this->zstride_1d = csize.X * (csize.Y + 1);
7779

7880
this->biomemap = new u8[csize.X * csize.Z];
7981
this->heightmap = new s16[csize.X * csize.Z];
@@ -113,10 +115,12 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *
113115
noise_valley_profile = new Noise(&sp->np_valley_profile, seed, csize.X, csize.Z);
114116

115117
//// 3D Terrain noise
116-
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
117-
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
118+
// 1-up 1-down overgeneration
118119
noise_inter_valley_fill = new Noise(&sp->np_inter_valley_fill, seed, csize.X, csize.Y + 2, csize.Z);
119-
noise_massive_caves = new Noise(&sp->np_massive_caves, seed, csize.X, csize.Y + 2, csize.Z);
120+
// 1-down overgeneraion
121+
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 1, csize.Z);
122+
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 1, csize.Z);
123+
noise_massive_caves = new Noise(&sp->np_massive_caves, seed, csize.X, csize.Y + 1, csize.Z);
120124

121125
//// Biome noise
122126
noise_heat_blend = new Noise(&params->np_biome_heat_blend, seed, csize.X, csize.Z);
@@ -885,7 +889,7 @@ void MapgenValleys::generateCaves(s16 max_stone_y)
885889
if (node_max.Y <= massive_cave_depth) {
886890
noise_massive_caves->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z);
887891

888-
for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
892+
for (s16 y = node_min.Y - 1; y <= node_max.Y; y++) {
889893
float tcave = massive_cave_threshold;
890894

891895
if (y < yblmin) {
@@ -923,19 +927,17 @@ void MapgenValleys::generateCaves(s16 max_stone_y)
923927
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index_2d]);
924928
bool air_above = false;
925929
bool underground = false;
926-
u32 index_data = vm->m_area.index(x, node_max.Y + 1, z);
927-
928-
index_3d = (z - node_min.Z) * zstride + (csize.Y + 1) * ystride + (x - node_min.X);
930+
u32 index_data = vm->m_area.index(x, node_max.Y, z);
931+
index_3d = (z - node_min.Z) * zstride_1d + csize.Y * ystride + (x - node_min.X);
929932

930933
// Dig caves on down loop to check for air above.
931-
for (s16 y = node_max.Y + 1;
932-
y >= node_min.Y - 1;
933-
y--, index_3d -= ystride, vm->m_area.add_y(em, index_data, -1)) {
934-
// Don't excavate the overgenerated stone at node_max.Y + 1,
935-
// this creates a 'roof' over the tunnel, preventing light in
936-
// tunnels at mapchunk borders when generating mapchunks upwards.
937-
if (y > node_max.Y)
938-
continue;
934+
// Don't excavate the overgenerated stone at node_max.Y + 1,
935+
// this creates a 'roof' over the tunnel, preventing light in
936+
// tunnels at mapchunk borders when generating mapchunks upwards.
937+
// This 'roof' is removed when the mapchunk above is generated.
938+
for (s16 y = node_max.Y; y >= node_min.Y - 1; y--,
939+
index_3d -= ystride,
940+
vm->m_area.add_y(em, index_data, -1)) {
939941

940942
float terrain = noise_terrain_height->result[index_2d];
941943

‎src/mapgen_valleys.h

+1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class MapgenValleys : public Mapgen {
106106

107107
int ystride;
108108
int zstride;
109+
int zstride_1d;
109110

110111
float map_gen_limit;
111112

0 commit comments

Comments
 (0)
Please sign in to comment.