]> git.lizzy.rs Git - minetest.git/blob - src/cavegen.h
Cavegen/Mgv5/Mgv7: Add optional giant caverns
[minetest.git] / src / cavegen.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef CAVEGEN_HEADER
21 #define CAVEGEN_HEADER
22
23 #define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1
24 #define DEFAULT_LAVA_DEPTH (-256)
25
26 class GenerateNotifier;
27
28 /*
29         CavesNoiseIntersection is a cave digging algorithm that carves smooth,
30         web-like, continuous tunnels at points where the density of the intersection
31         between two separate 3d noises is above a certain value.  This value,
32         cave_width, can be modified to set the effective width of these tunnels.
33
34         This algorithm is relatively heavyweight, taking ~80ms to generate an
35         80x80x80 chunk of map on a modern processor.  Use sparingly!
36
37         TODO(hmmmm): Remove dependency on biomes
38         TODO(hmmmm): Find alternative to overgeneration as solution for sunlight issue
39 */
40 class CavesNoiseIntersection {
41 public:
42         CavesNoiseIntersection(INodeDefManager *nodedef, BiomeManager *biomemgr,
43                 v3s16 chunksize, NoiseParams *np_cave1, NoiseParams *np_cave2,
44                 s32 seed, float cave_width);
45         ~CavesNoiseIntersection();
46
47         void generateCaves(MMVManip *vm, v3s16 nmin, v3s16 nmax, u8 *biomemap);
48
49 private:
50         INodeDefManager *m_ndef;
51         BiomeManager *m_bmgr;
52
53         // configurable parameters
54         v3s16 m_csize;
55         float m_cave_width;
56
57         // intermediate state variables
58         u16 m_ystride;
59         u16 m_zstride_1d;
60
61         Noise *noise_cave1;
62         Noise *noise_cave2;
63 };
64
65 /*
66         CavernsNoise is a cave digging algorithm
67 */
68 class CavernsNoise {
69 public:
70         CavernsNoise(INodeDefManager *nodedef, v3s16 chunksize, NoiseParams *np_cavern,
71         s32 seed, float cavern_limit, float cavern_taper, float cavern_threshold);
72         ~CavernsNoise();
73
74         bool generateCaverns(MMVManip *vm, v3s16 nmin, v3s16 nmax);
75
76 private:
77         INodeDefManager *m_ndef;
78
79         // configurable parameters
80         v3s16 m_csize;
81         float m_cavern_limit;
82         float m_cavern_taper;
83         float m_cavern_threshold;
84
85         // intermediate state variables
86         u16 m_ystride;
87         u16 m_zstride_1d;
88
89         Noise *noise_cavern;
90
91         content_t c_water_source;
92         content_t c_lava_source;
93 };
94
95 /*
96         CavesRandomWalk is an implementation of a cave-digging algorithm that
97         operates on the principle of a "random walk" to approximate the stochiastic
98         activity of cavern development.
99
100         In summary, this algorithm works by carving a randomly sized tunnel in a
101         random direction a random amount of times, randomly varying in width.
102         All randomness here is uniformly distributed; alternative distributions have
103         not yet been implemented.
104
105         This algorithm is very fast, executing in less than 1ms on average for an
106         80x80x80 chunk of map on a modern processor.
107 */
108 class CavesRandomWalk {
109 public:
110         MMVManip *vm;
111         INodeDefManager *ndef;
112         GenerateNotifier *gennotify;
113         s16 *heightmap;
114
115         // configurable parameters
116         s32 seed;
117         int water_level;
118         int lava_depth;
119         NoiseParams *np_caveliquids;
120
121         // intermediate state variables
122         u16 ystride;
123
124         s16 min_tunnel_diameter;
125         s16 max_tunnel_diameter;
126         u16 tunnel_routepoints;
127         int part_max_length_rs;
128
129         bool large_cave;
130         bool large_cave_is_flat;
131         bool flooded;
132
133         s16 max_stone_y;
134         v3s16 node_min;
135         v3s16 node_max;
136
137         v3f orp;  // starting point, relative to caved space
138         v3s16 of; // absolute coordinates of caved space
139         v3s16 ar; // allowed route area
140         s16 rs;   // tunnel radius size
141         v3f main_direction;
142
143         s16 route_y_min;
144         s16 route_y_max;
145
146         PseudoRandom *ps;
147
148         content_t c_water_source;
149         content_t c_lava_source;
150
151         // ndef is a mandatory parameter.
152         // If gennotify is NULL, generation events are not logged.
153         CavesRandomWalk(INodeDefManager *ndef,
154                 GenerateNotifier *gennotify = NULL,
155                 s32 seed = 0,
156                 int water_level = 1,
157                 content_t water_source = CONTENT_IGNORE,
158                 content_t lava_source = CONTENT_IGNORE);
159
160         // vm and ps are mandatory parameters.
161         // If heightmap is NULL, the surface level at all points is assumed to
162         // be water_level.
163         void makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax, PseudoRandom *ps,
164                 bool is_large_cave, int max_stone_height, s16 *heightmap);
165
166 private:
167         void makeTunnel(bool dirswitch);
168         void carveRoute(v3f vec, float f, bool randomize_xz);
169
170         inline bool isPosAboveSurface(v3s16 p);
171 };
172
173 /*
174         CavesV6 is the original version of caves used with Mapgen V6.
175
176         Though it uses the same fundamental algorithm as CavesRandomWalk, it is made
177         separate to preserve the exact sequence of PseudoRandom calls - any change
178         to this ordering results in the output being radically different.
179         Because caves in Mapgen V6 are responsible for a large portion of the basic
180         terrain shape, modifying this will break our contract of reverse
181         compatibility for a 'stable' mapgen such as V6.
182
183         tl;dr,
184         *** DO NOT TOUCH THIS CLASS UNLESS YOU KNOW WHAT YOU ARE DOING ***
185 */
186 class CavesV6 {
187 public:
188         MMVManip *vm;
189         INodeDefManager *ndef;
190         GenerateNotifier *gennotify;
191         PseudoRandom *ps;
192         PseudoRandom *ps2;
193
194         // configurable parameters
195         s16 *heightmap;
196         content_t c_water_source;
197         content_t c_lava_source;
198         int water_level;
199
200         // intermediate state variables
201         u16 ystride;
202
203         s16 min_tunnel_diameter;
204         s16 max_tunnel_diameter;
205         u16 tunnel_routepoints;
206         int part_max_length_rs;
207
208         bool large_cave;
209         bool large_cave_is_flat;
210
211         v3s16 node_min;
212         v3s16 node_max;
213
214         v3f orp;  // starting point, relative to caved space
215         v3s16 of; // absolute coordinates of caved space
216         v3s16 ar; // allowed route area
217         s16 rs;   // tunnel radius size
218         v3f main_direction;
219
220         s16 route_y_min;
221         s16 route_y_max;
222
223         // ndef is a mandatory parameter.
224         // If gennotify is NULL, generation events are not logged.
225         CavesV6(INodeDefManager *ndef,
226                 GenerateNotifier *gennotify = NULL,
227                 int water_level = 1,
228                 content_t water_source = CONTENT_IGNORE,
229                 content_t lava_source = CONTENT_IGNORE);
230
231         // vm, ps, and ps2 are mandatory parameters.
232         // If heightmap is NULL, the surface level at all points is assumed to
233         // be water_level.
234         void makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax,
235                 PseudoRandom *ps, PseudoRandom *ps2,
236                 bool is_large_cave, int max_stone_height, s16 *heightmap = NULL);
237
238 private:
239         void makeTunnel(bool dirswitch);
240         void carveRoute(v3f vec, float f, bool randomize_xz, bool tunnel_above_ground);
241
242         inline s16 getSurfaceFromHeightmap(v3s16 p);
243 };
244
245 #endif