@@ -212,33 +212,6 @@ impl ChunkParams {
212
212
213
213
/// Generate voxels making up the chunk
214
214
pub fn generate_voxels ( & self ) -> VoxelData {
215
- // Determine whether this chunk might contain a boundary between solid and void
216
- let mut me_min = self . env . max_elevations [ 0 ] ;
217
- let mut me_max = self . env . max_elevations [ 0 ] ;
218
- for & me in & self . env . max_elevations [ 1 ..] {
219
- me_min = me_min. min ( me) ;
220
- me_max = me_max. max ( me) ;
221
- }
222
- // Maximum difference between elevations at the center of a chunk and any other point in the chunk
223
- // TODO: Compute what this actually is, current value is a guess! Real one must be > 0.6
224
- // empirically.
225
- const ELEVATION_MARGIN : f32 = 0.7 ;
226
- let center_elevation = self
227
- . surface
228
- . distance_to_chunk ( self . chunk , & na:: Vector3 :: repeat ( 0.5 ) ) ;
229
- if ( center_elevation - ELEVATION_MARGIN > me_max / TERRAIN_SMOOTHNESS )
230
- && !( self . is_road || self . is_road_support )
231
- {
232
- // The whole chunk is above ground and not part of the road
233
- return VoxelData :: Solid ( Material :: Void ) ;
234
- }
235
-
236
- if ( center_elevation + ELEVATION_MARGIN < me_min / TERRAIN_SMOOTHNESS ) && !self . is_road {
237
- // The whole chunk is underground
238
- // TODO: More accurate VoxelData
239
- return VoxelData :: Solid ( Material :: Dirt ) ;
240
- }
241
-
242
215
let mut voxels = VoxelData :: Solid ( Material :: Void ) ;
243
216
let mut rng = rand_pcg:: Pcg64Mcg :: seed_from_u64 ( hash ( self . node_spice , self . chunk as u64 ) ) ;
244
217
@@ -252,9 +225,7 @@ impl ChunkParams {
252
225
253
226
// TODO: Don't generate detailed data for solid chunks with no neighboring voids
254
227
255
- if self . dimension > 4 && matches ! ( voxels, VoxelData :: Dense ( _) ) {
256
- self . generate_trees ( & mut voxels, & mut rng) ;
257
- }
228
+ self . generate_trees ( & mut voxels, & mut rng) ;
258
229
259
230
margins:: initialize_margins ( self . dimension , & mut voxels) ;
260
231
voxels
@@ -263,6 +234,33 @@ impl ChunkParams {
263
234
/// Performs all terrain generation that can be done one voxel at a time and with
264
235
/// only the containing chunk's surrounding nodes' envirofactors.
265
236
fn generate_terrain ( & self , voxels : & mut VoxelData , rng : & mut Pcg64Mcg ) {
237
+ // Determine whether this chunk might contain a boundary between solid and void
238
+ let mut me_min = self . env . max_elevations [ 0 ] ;
239
+ let mut me_max = self . env . max_elevations [ 0 ] ;
240
+ for & me in & self . env . max_elevations [ 1 ..] {
241
+ me_min = me_min. min ( me) ;
242
+ me_max = me_max. max ( me) ;
243
+ }
244
+ // Maximum difference between elevations at the center of a chunk and any other point in the chunk
245
+ // TODO: Compute what this actually is, current value is a guess! Real one must be > 0.6
246
+ // empirically.
247
+ const ELEVATION_MARGIN : f32 = 0.7 ;
248
+ let center_elevation = self
249
+ . surface
250
+ . distance_to_chunk ( self . chunk , & na:: Vector3 :: repeat ( 0.5 ) ) ;
251
+ if center_elevation - ELEVATION_MARGIN > me_max / TERRAIN_SMOOTHNESS {
252
+ // The whole chunk is above ground
253
+ * voxels = VoxelData :: Solid ( Material :: Void ) ;
254
+ return ;
255
+ }
256
+ if center_elevation + ELEVATION_MARGIN < me_min / TERRAIN_SMOOTHNESS {
257
+ // The whole chunk is underground
258
+ * voxels = VoxelData :: Solid ( Material :: Dirt ) ;
259
+ return ;
260
+ }
261
+
262
+ // Otherwise, the chunk might contain a solid/void boundary, so the full terrain generation
263
+ // code should run.
266
264
let normal = Normal :: new ( 0.0 , 0.03 ) . unwrap ( ) ;
267
265
268
266
for ( x, y, z) in VoxelCoords :: new ( self . dimension ) {
@@ -346,6 +344,12 @@ impl ChunkParams {
346
344
347
345
/// Fills the half-plane below the road with wooden supports.
348
346
fn generate_road_support ( & self , voxels : & mut VoxelData ) {
347
+ if voxels. is_solid ( ) && voxels. get ( 0 ) != Material :: Void {
348
+ // There is guaranteed no void to fill with the road supports, so
349
+ // nothing to do here.
350
+ return ;
351
+ }
352
+
349
353
let plane = -Plane :: from ( Side :: B ) ;
350
354
351
355
for ( x, y, z) in VoxelCoords :: new ( self . dimension ) {
@@ -395,6 +399,16 @@ impl ChunkParams {
395
399
/// and a block of leaves. The leaf block is on the opposite face of the
396
400
/// wood block as the ground block.
397
401
fn generate_trees ( & self , voxels : & mut VoxelData , rng : & mut Pcg64Mcg ) {
402
+ if voxels. is_solid ( ) {
403
+ // No trees can be generated unless there's both land and air.
404
+ return ;
405
+ }
406
+
407
+ if self . dimension <= 4 {
408
+ // The tree generation algorithm can crash when the chunk size is too small.
409
+ return ;
410
+ }
411
+
398
412
// margins are added to keep voxels outside the chunk from being read/written
399
413
let random_position = Uniform :: new ( 1 , self . dimension - 1 ) . unwrap ( ) ;
400
414
0 commit comments