X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fcavegen.h;h=db3e091f6f3fd6a8fb404ae5548d9d1d2c432c2e;hb=1d8d01074fdb52946f81110bebf1d001185b394b;hp=0b57bf4dc20898150d4d4aee473600de1164dddb;hpb=38e62805527b774e478617d9781bde72ce2bdcb9;p=dragonfireclient.git diff --git a/src/cavegen.h b/src/cavegen.h index 0b57bf4dc..db3e091f6 100644 --- a/src/cavegen.h +++ b/src/cavegen.h @@ -22,65 +22,111 @@ with this program; if not, write to the Free Software Foundation, Inc., #define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1 -class MapgenV5; -class MapgenV6; -class MapgenV7; +class GenerateNotifier; -class CaveV5 { +/* + 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. + + This algorithm is relatively heavyweight, taking ~80ms to generate an + 80x80x80 chunk of map on a modern processor. Use sparingly! + + TODO(hmmmm): Remove dependency on biomes + TODO(hmmmm): Find alternative to overgeneration as solution for sunlight issue +*/ +class CavesNoiseIntersection +{ public: - MapgenV5 *mg; - MMVManip *vm; - INodeDefManager *ndef; + CavesNoiseIntersection(INodeDefManager *nodedef, BiomeManager *biomemgr, + v3s16 chunksize, NoiseParams *np_cave1, NoiseParams *np_cave2, + s32 seed, float cave_width); + ~CavesNoiseIntersection(); - NoiseParams *np_caveliquids; + void generateCaves(MMVManip *vm, v3s16 nmin, v3s16 nmax, u8 *biomemap); - s16 min_tunnel_diameter; - s16 max_tunnel_diameter; - u16 tunnel_routepoints; - int dswitchint; - int part_max_length_rs; +private: + INodeDefManager *m_ndef; + BiomeManager *m_bmgr; - bool large_cave_is_flat; - bool flooded; + // configurable parameters + v3s16 m_csize; + float m_cave_width; - s16 max_stone_y; - v3s16 node_min; - v3s16 node_max; + // intermediate state variables + u16 m_ystride; + u16 m_zstride_1d; - 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; + Noise *noise_cave1; + Noise *noise_cave2; +}; - s16 route_y_min; - s16 route_y_max; +/* + CavernsNoise is a cave digging algorithm +*/ +class CavernsNoise +{ +public: + CavernsNoise(INodeDefManager *nodedef, v3s16 chunksize, NoiseParams *np_cavern, + s32 seed, float cavern_limit, float cavern_taper, + float cavern_threshold); + ~CavernsNoise(); - PseudoRandom *ps; + bool generateCaverns(MMVManip *vm, v3s16 nmin, v3s16 nmax); + +private: + INodeDefManager *m_ndef; + + // configurable parameters + v3s16 m_csize; + float m_cavern_limit; + float m_cavern_taper; + float m_cavern_threshold; + + // intermediate state variables + u16 m_ystride; + u16 m_zstride_1d; + + Noise *noise_cavern; content_t c_water_source; content_t c_lava_source; - content_t c_ice; +}; - int water_level; +/* + 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(MapgenV5 *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, bool is_ravine); -}; + 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; @@ -101,39 +147,69 @@ class CaveV6 { s16 route_y_max; PseudoRandom *ps; - PseudoRandom *ps2; content_t c_water_source; content_t c_lava_source; - int water_level; + // 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, int lava_depth = -256); + + // 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); - CaveV6() {} - CaveV6(MapgenV6 *mg, PseudoRandom *ps, PseudoRandom *ps2, bool large_cave); - void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height); +private: void makeTunnel(bool dirswitch); 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; @@ -146,19 +222,24 @@ class CaveV7 { s16 route_y_min; s16 route_y_max; - PseudoRandom *ps; - - content_t c_water_source; - content_t c_lava_source; - content_t c_ice; + // 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); - int water_level; + // 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); - CaveV7() {} - CaveV7(MapgenV7 *mg, PseudoRandom *ps, bool large_cave); - void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height); +private: void makeTunnel(bool dirswitch); - void carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine); + void carveRoute(v3f vec, float f, bool randomize_xz, bool tunnel_above_ground); + + inline s16 getSurfaceFromHeightmap(v3s16 p); }; #endif