diff options
Diffstat (limited to 'src/cavegen.h')
-rw-r--r-- | src/cavegen.h | 187 |
1 files changed, 118 insertions, 69 deletions
diff --git a/src/cavegen.h b/src/cavegen.h index a1124711b..2bf503d47 100644 --- a/src/cavegen.h +++ b/src/cavegen.h @@ -21,69 +21,79 @@ with this program; if not, write to the Free Software Foundation, Inc., #define CAVEGEN_HEADER #define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1 -#define MGV5_LAVA_DEPTH -256 -#define MGV7_LAVA_DEPTH -256 +#define DEFAULT_LAVA_DEPTH (-256) -class MapgenV5; -class MapgenV6; -class MapgenV7; +class GenerateNotifier; -class CaveV5 { -public: - Mapgen *mg; - MMVManip *vm; - INodeDefManager *ndef; +/* + CavesNoiseIntersection is a cave digging algorithm that carves smooth, + web-like, continuous tunnels at points where the density of the intersection + between two separate 3d noises is above a certain value. This value, + cave_width, can be modified to set the effective width of these tunnels. - NoiseParams *np_caveliquids; + This algorithm is relatively heavyweight, taking ~80ms to generate an + 80x80x80 chunk of map on a modern processor. Use sparingly! - s16 min_tunnel_diameter; - s16 max_tunnel_diameter; - u16 tunnel_routepoints; - int dswitchint; - int part_max_length_rs; - - bool large_cave_is_flat; - bool flooded; + TODO(hmmmm): Remove dependency on biomes + TODO(hmmmm): Find alternative to overgeneration as solution for sunlight issue +*/ +class CavesNoiseIntersection { +public: + CavesNoiseIntersection(INodeDefManager *nodedef, BiomeManager *biomemgr, + v3s16 chunksize, NoiseParams *np_cave1, NoiseParams *np_cave2, + s32 seed, float cave_width); + ~CavesNoiseIntersection(); - s16 max_stone_y; - v3s16 node_min; - v3s16 node_max; + void generateCaves(MMVManip *vm, v3s16 nmin, v3s16 nmax, u8 *biomemap); - v3f orp; // starting point, relative to caved space - v3s16 of; // absolute coordinates of caved space - v3s16 ar; // allowed route area - s16 rs; // tunnel radius size - v3f main_direction; +private: + INodeDefManager *m_ndef; + BiomeManager *m_bmgr; - s16 route_y_min; - s16 route_y_max; + // configurable parameters + v3s16 m_csize; + float m_cave_width; - PseudoRandom *ps; + // intermediate state variables + u16 m_ystride; + u16 m_zstride_1d; - content_t c_water_source; - content_t c_lava_source; - content_t c_ice; + Noise *noise_cave1; + Noise *noise_cave2; +}; - int water_level; - int ystride; +/* + CavesRandomWalk is an implementation of a cave-digging algorithm that + operates on the principle of a "random walk" to approximate the stochiastic + activity of cavern development. - CaveV5() {} - CaveV5(Mapgen *mg, PseudoRandom *ps); - void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height); - void makeTunnel(bool dirswitch); - void carveRoute(v3f vec, float f, bool randomize_xz); -}; + In summary, this algorithm works by carving a randomly sized tunnel in a + random direction a random amount of times, randomly varying in width. + All randomness here is uniformly distributed; alternative distributions have + not yet been implemented. -class CaveV6 { + This algorithm is very fast, executing in less than 1ms on average for an + 80x80x80 chunk of map on a modern processor. +*/ +class CavesRandomWalk { public: - MapgenV6 *mg; MMVManip *vm; INodeDefManager *ndef; + GenerateNotifier *gennotify; + s16 *heightmap; + + // configurable parameters + s32 seed; + int water_level; + int lava_depth; + NoiseParams *np_caveliquids; + + // intermediate state variables + u16 ystride; s16 min_tunnel_diameter; s16 max_tunnel_diameter; u16 tunnel_routepoints; - int dswitchint; int part_max_length_rs; bool large_cave; @@ -104,38 +114,70 @@ public: s16 route_y_max; PseudoRandom *ps; - PseudoRandom *ps2; content_t c_water_source; content_t c_lava_source; - int water_level; - - CaveV6() {} - CaveV6(MapgenV6 *mg, PseudoRandom *ps, PseudoRandom *ps2, bool large_cave); - void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height); + // ndef is a mandatory parameter. + // If gennotify is NULL, generation events are not logged. + CavesRandomWalk(INodeDefManager *ndef, + GenerateNotifier *gennotify = NULL, + s32 seed = 0, + int water_level = 1, + content_t water_source = CONTENT_IGNORE, + content_t lava_source = CONTENT_IGNORE); + + // vm and ps are mandatory parameters. + // If heightmap is NULL, the surface level at all points is assumed to + // be water_level. + void makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, PseudoRandom *ps, + bool is_large_cave, int max_stone_height, s16 *heightmap); + +private: void makeTunnel(bool dirswitch); - void carveRoute(v3f vec, float f, bool randomize_xz, bool tunnel_above_ground); + void carveRoute(v3f vec, float f, bool randomize_xz); + + inline bool isPosAboveSurface(v3s16 p); }; -class CaveV7 { +/* + CavesV6 is the original version of caves used with Mapgen V6. + + Though it uses the same fundamental algorithm as CavesRandomWalk, it is made + separate to preserve the exact sequence of PseudoRandom calls - any change + to this ordering results in the output being radically different. + Because caves in Mapgen V6 are responsible for a large portion of the basic + terrain shape, modifying this will break our contract of reverse + compatibility for a 'stable' mapgen such as V6. + + tl;dr, + *** DO NOT TOUCH THIS CLASS UNLESS YOU KNOW WHAT YOU ARE DOING *** +*/ +class CavesV6 { public: - MapgenV7 *mg; MMVManip *vm; INodeDefManager *ndef; + GenerateNotifier *gennotify; + PseudoRandom *ps; + PseudoRandom *ps2; - NoiseParams *np_caveliquids; + // configurable parameters + s16 *heightmap; + content_t c_water_source; + content_t c_lava_source; + int water_level; + + // intermediate state variables + u16 ystride; s16 min_tunnel_diameter; s16 max_tunnel_diameter; u16 tunnel_routepoints; - int dswitchint; int part_max_length_rs; + bool large_cave; bool large_cave_is_flat; - bool flooded; - s16 max_stone_y; v3s16 node_min; v3s16 node_max; @@ -148,19 +190,26 @@ public: s16 route_y_min; s16 route_y_max; - PseudoRandom *ps; - - content_t c_water_source; - content_t c_lava_source; - content_t c_ice; - - int water_level; - - CaveV7() {} - CaveV7(MapgenV7 *mg, PseudoRandom *ps); - void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height); + // ndef is a mandatory parameter. + // If gennotify is NULL, generation events are not logged. + CavesV6(INodeDefManager *ndef, + GenerateNotifier *gennotify = NULL, + int water_level = 1, + content_t water_source = CONTENT_IGNORE, + content_t lava_source = CONTENT_IGNORE); + + // vm, ps, and ps2 are mandatory parameters. + // If heightmap is NULL, the surface level at all points is assumed to + // be water_level. + void makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, + PseudoRandom *ps, PseudoRandom *ps2, + bool is_large_cave, int max_stone_height, s16 *heightmap = NULL); + +private: void makeTunnel(bool dirswitch); - void carveRoute(v3f vec, float f, bool randomize_xz); + void carveRoute(v3f vec, float f, bool randomize_xz, bool tunnel_above_ground); + + inline s16 getSurfaceFromHeightmap(v3s16 p); }; #endif |