1
1
use glam:: Vec3 ;
2
+ use std:: borrow:: Borrow ;
3
+ use std:: collections:: HashMap ;
2
4
use std:: fs:: File ;
3
5
use std:: ops:: { Deref , DerefMut } ;
4
6
use std:: sync:: { Mutex , RwLock } ;
@@ -22,7 +24,7 @@ pub const FREQUENCY: f32 = 1. / 128.;
22
24
pub const NOISE_CHUNK_PER_ROW : u32 = NOISE_SIZE / CHUNK_SIZE ;
23
25
pub const MAX_TREES_PER_CHUNK : u32 = 3 ;
24
26
25
- pub const CHUNKS_PER_ROW : u32 = 9 ;
27
+ pub const CHUNKS_PER_ROW : u32 = 25 ;
26
28
pub const CHUNKS_REGION : u32 = CHUNKS_PER_ROW * CHUNKS_PER_ROW ;
27
29
pub const WATER_HEIGHT_LEVEL : u8 = 5 ;
28
30
@@ -40,7 +42,7 @@ pub type NoiseData = Vec<f32>;
40
42
41
43
pub type WorldChunk = Arc < RwLock < Chunk > > ;
42
44
pub struct World {
43
- pub chunks : Vec < WorldChunk > ,
45
+ pub chunks : HashMap < ( i32 , i32 ) , WorldChunk > ,
44
46
pub thread_pool : Option < ThreadPool > ,
45
47
pub seed : u32 ,
46
48
pub noise_data : Arc < NoiseData > ,
@@ -50,24 +52,9 @@ pub struct World {
50
52
}
51
53
52
54
impl World {
53
- // gets all the chunks except the one passed in the index
54
- pub fn get_other_chunks_by_index ( & self , chunk_index : usize ) -> Vec < WorldChunk > {
55
- self . chunks
56
- . iter ( )
57
- . enumerate ( )
58
- . filter_map ( |( i, c) | {
59
- return if i != chunk_index {
60
- Some ( c. clone ( ) )
61
- } else {
62
- None
63
- } ;
64
- } )
65
- . collect ( )
66
- }
67
- // gets all the chunks except the one passed
68
55
pub fn get_other_chunks ( & self , chunk_ptr : WorldChunk ) -> Vec < WorldChunk > {
69
56
self . chunks
70
- . iter ( )
57
+ . values ( )
71
58
. filter_map ( |c| {
72
59
return if !Arc :: ptr_eq ( & chunk_ptr, c) {
73
60
Some ( c. clone ( ) )
@@ -78,89 +65,55 @@ impl World {
78
65
. collect ( )
79
66
}
80
67
pub fn place_block ( & mut self , block : Arc < RwLock < Block > > ) {
81
- let mut chunks_to_rerender = vec ! [ ] ;
82
-
83
68
let block_borrow = block. read ( ) . unwrap ( ) ;
84
- let chunk_coords = block_borrow. get_chunk_coords ( ) ;
69
+ let mut chunks_to_rerender = vec ! [ block_borrow. get_chunk_coords( ) ] ;
85
70
let chunk = self
86
71
. chunks
87
- . iter ( )
88
- . find ( |c| {
89
- let c = c. read ( ) . unwrap ( ) ;
90
- c. x == chunk_coords. 0 && c. y == chunk_coords. 1
91
- } )
72
+ . get ( & chunks_to_rerender[ 0 ] )
92
73
. expect ( "Cannot delete a block from unloaded chunk" ) ;
93
74
94
- chunks_to_rerender. push ( chunk. clone ( ) ) ;
95
75
let mut chunk_lock = chunk. write ( ) . unwrap ( ) ;
96
76
chunk_lock. add_block ( block. clone ( ) , true ) ;
97
77
98
78
let block_borrow = block. read ( ) . unwrap ( ) ;
99
- let block_neighbour_chunks = block_borrow. get_neighbour_chunks_coords ( ) ;
79
+ chunks_to_rerender . append ( & mut block_borrow. get_neighbour_chunks_coords ( ) ) ;
100
80
std:: mem:: drop ( chunk_lock) ;
101
81
102
- if block_neighbour_chunks. len ( ) > 0 {
103
- for neighbour_chunk in block_neighbour_chunks {
104
- let neighbour_chunk = self
105
- . chunks
106
- . iter ( )
107
- . find ( |o| {
108
- let c = o. read ( ) . unwrap ( ) ;
109
- return c. x == neighbour_chunk. 0 && c. y == neighbour_chunk. 1 ;
110
- } )
111
- . expect ( "Cannot destroy a block without neighbour being loaded" ) ;
112
-
113
- chunks_to_rerender. push ( neighbour_chunk. clone ( ) ) ;
114
- }
115
- }
82
+ // if block_neighbour_chunks.len() > 0 {
83
+ // for neighbour_chunk in block_neighbour_chunks {
84
+ // let neighbour_chunk = self
85
+ // .chunks
86
+ // .get(&neighbour_chunk)
87
+ // .expect("Cannot destroy a block without neighbour being loaded");
88
+
89
+ // chunks_to_rerender.push(neighbour_chunk.clone());
90
+ // }
91
+ // }
116
92
117
- self . render_chunks ( & chunks_to_rerender) ;
93
+ self . render_chunks ( chunks_to_rerender)
94
+ // self.render_chunks(block_neighbour_chunks.append(&mut vec![chunk_coords]));
118
95
}
119
96
pub fn remove_block ( & mut self , block : Arc < RwLock < Block > > ) {
120
- let mut chunks_to_rerender = vec ! [ ] ;
121
-
122
97
let block_borrow = block. read ( ) . unwrap ( ) ;
123
- let chunk_coords = block_borrow. get_chunk_coords ( ) ;
98
+ let mut chunks_to_rerender = vec ! [ block_borrow. get_chunk_coords( ) ] ;
124
99
let chunk = self
125
100
. chunks
126
- . iter ( )
127
- . find ( |c| {
128
- let c = c. read ( ) . unwrap ( ) ;
129
- c. x == chunk_coords. 0 && c. y == chunk_coords. 1
130
- } )
101
+ . get ( & chunks_to_rerender[ 0 ] )
131
102
. expect ( "Cannot delete a block from unloaded chunk" ) ;
132
103
133
104
let mut chunk_lock = chunk. write ( ) . unwrap ( ) ;
134
105
chunk_lock. remove_block ( & ( block_borrow. position ) ) ;
135
- chunks_to_rerender. push ( chunk. clone ( ) ) ;
136
106
// chunk_lock.build_mesh(self.get_other_chunks(chunk.clone()));
137
- let block_neighbour_chunks = block_borrow. get_neighbour_chunks_coords ( ) ;
107
+ chunks_to_rerender . append ( & mut block_borrow. get_neighbour_chunks_coords ( ) ) ;
138
108
// I hate this so much
139
109
std:: mem:: drop ( chunk_lock) ;
140
110
141
- if block_neighbour_chunks. len ( ) > 0 {
142
- for neighbour_chunk in block_neighbour_chunks {
143
- let neighbour_chunk = self
144
- . chunks
145
- . iter ( )
146
- . find ( |o| {
147
- let c = o. read ( ) . unwrap ( ) ;
148
- c. x == neighbour_chunk. 0 && c. y == neighbour_chunk. 1
149
- } )
150
- . expect ( "Cannot destroy a block without neighbour being loaded" ) ;
151
-
152
- chunks_to_rerender. push ( neighbour_chunk. clone ( ) ) ;
153
- }
154
- }
155
- self . render_chunks ( & chunks_to_rerender) ;
111
+ self . render_chunks ( chunks_to_rerender) ;
156
112
}
157
113
pub fn get_blocks_absolute ( & self , position : & Vec3 ) -> Option < Arc < RwLock < Block > > > {
158
114
let ( chunk_x, chunk_y) = position. get_chunk_from_position_absolute ( ) ;
159
115
160
- let chunk = self . chunks . iter ( ) . find ( |c| {
161
- let c = c. read ( ) . unwrap ( ) ;
162
- c. x == chunk_x && c. y == chunk_y
163
- } ) ?;
116
+ let chunk = self . chunks . get ( & ( chunk_x, chunk_y) ) ?;
164
117
let chunk = chunk. read ( ) . unwrap ( ) ;
165
118
166
119
let relative_position = position. relative_from_absolute ( ) ;
@@ -252,20 +205,20 @@ impl World {
252
205
} )
253
206
. collect ( ) ;
254
207
255
- let mut indices_to_remove : Vec < usize > = vec ! [ ] ;
256
- for ( i , chunk ) in self . chunks . iter ( ) . enumerate ( ) {
257
- let chunk = chunk. read ( ) . unwrap ( ) ;
258
- if ( delta. 1 != 0 && chunk . y == chunk_y_remove)
259
- || ( delta. 0 != 0 && chunk . x == chunk_x_remove)
208
+ let mut keys_to_remove = vec ! [ ] ;
209
+ for key in self . chunks . keys ( ) {
210
+ // let chunk = chunk.read().unwrap();
211
+ if ( delta. 1 != 0 && key . 1 == chunk_y_remove)
212
+ || ( delta. 0 != 0 && key . 0 == chunk_x_remove)
260
213
{
261
- indices_to_remove . push ( i ) ;
214
+ keys_to_remove . push ( key . clone ( ) ) ;
262
215
}
263
216
}
264
217
265
218
// Save the unloaded chunks
266
219
let ( sender, receiver) = mpsc:: channel ( ) ;
267
- for ( o , index ) in indices_to_remove . iter ( ) . enumerate ( ) {
268
- let chunk = self . chunks . remove ( index - o ) ;
220
+ for key in keys_to_remove . iter ( ) {
221
+ let chunk = self . chunks . remove ( key ) . expect ( "Something went wrong" ) ;
269
222
let sender = sender. clone ( ) ;
270
223
self . thread_pool . as_ref ( ) . unwrap ( ) . execute ( move || {
271
224
let chunk = chunk. write ( ) . unwrap ( ) ;
@@ -276,7 +229,7 @@ impl World {
276
229
} )
277
230
}
278
231
279
- for _ in indices_to_remove . iter ( ) {
232
+ for _ in keys_to_remove . iter ( ) {
280
233
receiver. recv ( ) . unwrap ( ) ;
281
234
}
282
235
@@ -306,19 +259,20 @@ impl World {
306
259
307
260
for _ in 0 ..chunks_added {
308
261
let chunk = receiver. recv ( ) . unwrap ( ) ;
309
- self . chunks . push ( Arc :: new ( RwLock :: new ( chunk) ) ) ;
262
+ self . chunks
263
+ . insert ( ( chunk. x , chunk. y ) , Arc :: new ( RwLock :: new ( chunk) ) ) ;
310
264
}
311
265
self . handle_outside_blocks ( ) ;
312
- self . render_chunks ( & self . chunks [ self . chunks . len ( ) - chunks_added..] ) ;
313
266
// Re-render only the last inserted chunks
267
+ self . render_chunks ( new_chunks_positions) ;
314
268
}
315
269
316
270
player_write. current_chunk = current_chunk;
317
271
std:: mem:: drop ( player_write) ;
318
272
// Update visible chunks based on player position and direction
319
273
{
320
274
let ( sender, receiver) = mpsc:: channel ( ) ;
321
- for chunk in self . chunks . iter ( ) {
275
+ for chunk in self . chunks . values ( ) {
322
276
let chunk = Arc :: clone ( & chunk) ;
323
277
let sender = sender. clone ( ) ;
324
278
let player = Arc :: clone ( & player) ;
@@ -338,7 +292,7 @@ impl World {
338
292
}
339
293
340
294
pub fn save_state ( & self ) {
341
- for chunk in self . chunks . iter ( ) {
295
+ for chunk in self . chunks . values ( ) {
342
296
let chunkbrw = chunk. read ( ) . unwrap ( ) ;
343
297
if chunkbrw. modified {
344
298
chunkbrw. save ( ) . expect ( "failed to save" ) ;
@@ -349,7 +303,6 @@ impl World {
349
303
let ( sender, receiver) = mpsc:: channel ( ) ;
350
304
let player = player. read ( ) . unwrap ( ) ;
351
305
352
- let mut chunks = vec ! [ ] ;
353
306
for chunk_x in LB + player. current_chunk . 0 ..=UB + player. current_chunk . 0 {
354
307
for chunk_y in LB + player. current_chunk . 1 ..=UB + player. current_chunk . 1 {
355
308
let sender = sender. clone ( ) ;
@@ -373,30 +326,36 @@ impl World {
373
326
374
327
for _ in 0 ..CHUNKS_PER_ROW * CHUNKS_PER_ROW {
375
328
let chunk = receiver. recv ( ) . expect ( "Some chunks are missing" ) ;
376
- chunks. push ( Arc :: new ( RwLock :: new ( chunk) ) ) ;
329
+ self . chunks
330
+ . insert ( ( chunk. x , chunk. y ) , Arc :: new ( RwLock :: new ( chunk) ) ) ;
377
331
}
378
- self . chunks . append ( & mut chunks) ; // Add chunks to self
379
332
380
333
self . handle_outside_blocks ( ) ;
381
- self . render_chunks ( & self . chunks ) ;
334
+ // this is kinda slow
335
+ self . render_chunks ( self . chunks . keys ( ) . collect :: < Vec < _ > > ( ) ) ;
382
336
}
383
337
// chunks: slice containing the chunk to re-render
384
- fn render_chunks ( & self , chunks : & [ WorldChunk ] ) {
338
+ fn render_chunks < I > ( & self , chunk_keys : Vec < I > )
339
+ where
340
+ I : Borrow < ( i32 , i32 ) > ,
341
+ {
385
342
let ( sender, receiver) = mpsc:: channel ( ) ;
386
343
387
- for chunk in chunks. iter ( ) {
388
- let sender = sender. clone ( ) ;
389
- let other = self . get_other_chunks ( chunk. clone ( ) ) ;
390
- let chunk = chunk. clone ( ) ;
391
-
392
- self . thread_pool . as_ref ( ) . unwrap ( ) . execute ( move || {
393
- let chunk_ptr = chunk. clone ( ) ;
394
- let chunk = chunk. read ( ) . unwrap ( ) ;
395
- let res = chunk. build_mesh ( other) ;
396
- sender. send ( ( res, chunk_ptr) ) . unwrap ( ) ;
397
- } ) ;
344
+ for key in chunk_keys. iter ( ) {
345
+ if let Some ( chunk) = self . chunks . get ( key. borrow ( ) ) {
346
+ let sender = sender. clone ( ) ;
347
+ let other = self . get_other_chunks ( chunk. clone ( ) ) ;
348
+ let chunk = chunk. clone ( ) ;
349
+
350
+ self . thread_pool . as_ref ( ) . unwrap ( ) . execute ( move || {
351
+ let chunk_ptr = chunk. clone ( ) ;
352
+ let chunk = chunk. read ( ) . unwrap ( ) ;
353
+ let res = chunk. build_mesh ( other) ;
354
+ sender. send ( ( res, chunk_ptr) ) . unwrap ( ) ;
355
+ } ) ;
356
+ }
398
357
}
399
- for _ in chunks . iter ( ) {
358
+ for _ in chunk_keys . iter ( ) {
400
359
let (
401
360
(
402
361
indices,
@@ -419,7 +378,7 @@ impl World {
419
378
}
420
379
fn handle_outside_blocks ( & mut self ) {
421
380
let mut blocks_to_add = vec ! [ ] ;
422
- for chunk in self . chunks . iter ( ) {
381
+ for chunk in self . chunks . values ( ) {
423
382
let mut chunkbrw = chunk. write ( ) . unwrap ( ) ;
424
383
blocks_to_add. append ( & mut chunkbrw. outside_blocks ) ;
425
384
}
@@ -428,10 +387,7 @@ impl World {
428
387
429
388
for block in blocks_to_add. iter ( ) {
430
389
let chunk_coords = block. read ( ) . unwrap ( ) . get_chunk_coords ( ) ;
431
- if let Some ( chunkptr) = self . chunks . iter ( ) . find ( |c| {
432
- let c = c. read ( ) . unwrap ( ) ;
433
- c. x == chunk_coords. 0 && c. y == chunk_coords. 1
434
- } ) {
390
+ if let Some ( chunkptr) = self . chunks . get ( & chunk_coords) {
435
391
let mut chunkbrw = chunkptr. write ( ) . unwrap ( ) ;
436
392
chunkbrw. add_block ( block. clone ( ) , false ) ;
437
393
if let None = chunks_to_rerender. iter ( ) . find ( |c| Arc :: ptr_eq ( c, chunkptr) ) {
@@ -453,7 +409,7 @@ impl World {
453
409
454
410
World {
455
411
chunk_data_layout,
456
- chunks : vec ! [ ] ,
412
+ chunks : HashMap :: new ( ) ,
457
413
noise_data,
458
414
device,
459
415
queue,
0 commit comments