1
- use std:: sync:: { Arc , Mutex } ;
1
+ use glam:: Vec3 ;
2
+ use std:: ffi:: c_void;
3
+ use std:: sync:: { Arc , Mutex , Weak } ;
2
4
3
5
use wgpu:: util:: DeviceExt ;
4
6
7
+ use crate :: world:: World ;
5
8
use crate :: {
6
9
blocks:: {
7
10
block:: { Block , BlockFace , BlockVertexData , FaceDirections } ,
@@ -10,40 +13,49 @@ use crate::{
10
13
world:: { NoiseData , CHUNK_HEIGHT , CHUNK_SIZE , NOISE_CHUNK_PER_ROW , NOISE_SIZE } ,
11
14
} ;
12
15
13
- pub type BlockVec = Vec < Vec < Arc < Mutex < Block > > > > ;
16
+ pub type BlockVec = Vec < Vec < Option < Arc < Mutex < Block > > > > > ;
17
+
14
18
pub struct Chunk {
15
19
// probably there needs to be a cube type with more info ( regarding type, etc. )
16
20
pub x : i32 ,
17
21
pub y : i32 ,
18
22
pub blocks : BlockVec ,
19
23
pub indices : u32 ,
24
+ pub device : Arc < wgpu:: Device > ,
25
+ pub queue : Arc < wgpu:: Queue > ,
26
+ pub noise_data : Arc < NoiseData > ,
20
27
pub chunk_bind_group : wgpu:: BindGroup ,
21
28
pub chunk_position_buffer : wgpu:: Buffer ,
22
- // pub chunk_vertex_buffer: wgpu::Buffer,
23
- pub chunk_index_buffer : wgpu:: Buffer ,
24
- pub chunk_vertex_buffer : wgpu:: Buffer ,
29
+ pub chunk_index_buffer : Option < wgpu:: Buffer > ,
30
+ pub chunk_vertex_buffer : Option < wgpu:: Buffer > ,
25
31
}
26
32
27
33
impl Chunk {
34
+ pub fn remove_block ( & mut self , block_r_position : & Vec3 ) {
35
+ let y_blocks = self
36
+ . blocks
37
+ . get_mut ( ( ( block_r_position. x * CHUNK_SIZE as f32 ) + block_r_position. z ) as usize )
38
+ . expect ( "Cannot delete oob block" ) ;
39
+ y_blocks[ block_r_position. y as usize ] = None ;
40
+ }
28
41
pub fn exists_block_at ( blocks : & BlockVec , position : & glam:: Vec3 ) -> bool {
29
42
if let Some ( y_blocks) =
30
43
blocks. get ( ( ( position. x as u32 * CHUNK_SIZE ) + position. z as u32 ) as usize )
31
44
{
32
- if let Some ( _ ) = y_blocks. get ( position. y as usize ) {
33
- return true ;
34
- } else {
35
- return false ;
45
+ if let Some ( block_opt ) = y_blocks. get ( position. y as usize ) {
46
+ if let Some ( _ ) = block_opt {
47
+ return true ;
48
+ }
36
49
}
37
- } else {
38
- return false ;
39
- } ;
50
+ }
51
+ return false ;
40
52
}
41
53
pub fn get_block_at_relative ( & self , position : & glam:: Vec3 ) -> Option < Arc < Mutex < Block > > > {
42
54
if let Some ( y_blocks) = self
43
55
. blocks
44
56
. get ( ( ( position. x * CHUNK_SIZE as f32 ) + position. z ) as usize )
45
57
{
46
- if let Some ( block) = y_blocks. get ( position. y as usize ) {
58
+ if let Some ( block) = y_blocks. get ( position. y as usize ) ? {
47
59
return Some ( Arc :: clone ( block) ) ;
48
60
}
49
61
}
@@ -67,87 +79,103 @@ impl Chunk {
67
79
false
68
80
}
69
81
}
70
- // Returns the number of indices added to the chunk - it would've been better to be a mutable method but i can't do it because of borrow checker
71
- pub fn build_mesh (
72
- chunk_x : i32 ,
73
- chunk_y : i32 ,
74
- blocks : & BlockVec ,
75
- noise_data : Arc < NoiseData > ,
76
- device : Arc < wgpu:: Device > ,
77
- ) -> ( u32 , wgpu:: Buffer , wgpu:: Buffer ) {
82
+ pub fn build_mesh ( & mut self , other_chunks : Vec < Arc < Mutex < Chunk > > > ) {
78
83
let mut vertex: Vec < BlockVertexData > = vec ! [ ] ;
79
84
let mut indices: Vec < u32 > = vec ! [ ] ;
80
85
for x in 0 ..CHUNK_SIZE {
81
86
for z in 0 ..CHUNK_SIZE {
82
- let region = & blocks[ ( x * CHUNK_SIZE + z) as usize ] ;
87
+ let region = & self . blocks [ ( x * CHUNK_SIZE + z) as usize ] ;
83
88
for y in 0 ..region. len ( ) {
84
89
let block = & region[ y] ;
85
- let block = block. lock ( ) . unwrap ( ) ;
86
- let position = block. position ;
87
- let faces = block. faces . as_ref ( ) . unwrap ( ) ;
90
+ if let Some ( block) = block {
91
+ let block = block. lock ( ) . unwrap ( ) ;
92
+ let position = block. position ;
93
+ let faces = block. faces . as_ref ( ) . unwrap ( ) ;
88
94
89
- for face in faces. iter ( ) {
90
- let mut is_visible = true ;
91
- let face_position = face. get_normal_vector ( ) + position;
95
+ for face in faces. iter ( ) {
96
+ let mut is_visible = true ;
97
+ let face_position = face. get_normal_vector ( ) + position;
92
98
93
- if Chunk :: is_outside_bounds ( & face_position) {
94
- is_visible = false ;
95
- } else if Chunk :: is_outside_chunk ( & face_position) {
96
- let target_chunk_x =
97
- chunk_x + ( f32:: floor ( face_position. x / CHUNK_SIZE as f32 ) as i32 ) ;
98
- let target_chunk_y =
99
- chunk_y + ( f32:: floor ( face_position. z / CHUNK_SIZE as f32 ) as i32 ) ;
99
+ if Chunk :: is_outside_bounds ( & face_position) {
100
+ is_visible = false ;
101
+ } else if Chunk :: is_outside_chunk ( & face_position) {
102
+ let target_chunk_x = self . x
103
+ + ( f32:: floor ( face_position. x / CHUNK_SIZE as f32 ) as i32 ) ;
104
+ let target_chunk_y = self . y
105
+ + ( f32:: floor ( face_position. z / CHUNK_SIZE as f32 ) as i32 ) ;
100
106
101
- let target_block = glam:: vec3 (
102
- ( face_position. x + CHUNK_SIZE as f32 ) % CHUNK_SIZE as f32 ,
103
- face_position. y ,
104
- ( face_position. z + CHUNK_SIZE as f32 ) % CHUNK_SIZE as f32 ,
105
- ) ;
107
+ let target_block = glam:: vec3 (
108
+ ( face_position. x + CHUNK_SIZE as f32 ) % CHUNK_SIZE as f32 ,
109
+ face_position. y ,
110
+ ( face_position. z + CHUNK_SIZE as f32 ) % CHUNK_SIZE as f32 ,
111
+ ) ;
106
112
107
- // This probably needs to be looked at again when the blocks can be placed/destroyed
108
- if face_position. y as u32
109
- <= Chunk :: get_height_value (
110
- target_chunk_x,
111
- target_chunk_y,
112
- target_block. x as u32 ,
113
- target_block. z as u32 ,
114
- noise_data. clone ( ) ,
115
- )
116
- {
117
- is_visible = false
118
- } ;
119
- } else if Chunk :: exists_block_at ( & blocks, & face_position) {
120
- is_visible = false ;
121
- }
113
+ let target_chunk = other_chunks. iter ( ) . find ( |c| {
114
+ let c = c. lock ( ) . unwrap ( ) ;
115
+ c. x == target_chunk_x && c. y == target_chunk_y
116
+ } ) ;
117
+ match target_chunk {
118
+ Some ( chunk) => {
119
+ println ! ( "TARGET CHUNK FOUND" ) ;
120
+ let chunk = chunk. lock ( ) . unwrap ( ) ;
121
+ if Chunk :: exists_block_at ( & chunk. blocks , & target_block) {
122
+ println ! (
123
+ "TARGET BLOCK TRUE {:?} {} {}" ,
124
+ target_block, target_chunk_x, target_chunk_y
125
+ ) ;
126
+ is_visible = false ;
127
+ }
128
+ }
129
+ None => {
130
+ if face_position. y as u32
131
+ <= Chunk :: get_height_value (
132
+ target_chunk_x,
133
+ target_chunk_y,
134
+ target_block. x as u32 ,
135
+ target_block. z as u32 ,
136
+ self . noise_data . clone ( ) ,
137
+ )
138
+ {
139
+ is_visible = false
140
+ } ;
141
+ }
142
+ }
143
+ } else if Chunk :: exists_block_at ( & self . blocks , & face_position) {
144
+ is_visible = false ;
145
+ }
122
146
123
- if is_visible {
124
- let ( mut vertex_data, index_data) = face. create_face_data ( & block) ;
125
- vertex. append ( & mut vertex_data) ;
126
- let indices_offset = vertex. len ( ) as u32 - 4 ;
127
- indices. append (
128
- & mut index_data. iter ( ) . map ( |i| i + indices_offset) . collect ( ) ,
129
- )
147
+ if is_visible {
148
+ let ( mut vertex_data, index_data) = face. create_face_data ( & block) ;
149
+ vertex. append ( & mut vertex_data) ;
150
+ let indices_offset = vertex. len ( ) as u32 - 4 ;
151
+ indices. append (
152
+ & mut index_data. iter ( ) . map ( |i| i + indices_offset) . collect ( ) ,
153
+ )
154
+ }
130
155
}
131
156
}
132
157
}
133
158
}
134
159
}
135
160
136
- let chunk_vertex_buffer = device. create_buffer_init ( & wgpu:: util:: BufferInitDescriptor {
137
- contents : bytemuck:: cast_slice ( & vertex) ,
138
- label : Some ( & format ! ( "chunk-vertex-{chunk_x}-{chunk_y}" ) ) ,
139
- usage : wgpu:: BufferUsages :: VERTEX | wgpu:: BufferUsages :: COPY_DST ,
140
- } ) ;
141
- let chunk_index_buffer = device. create_buffer_init ( & wgpu:: util:: BufferInitDescriptor {
142
- contents : bytemuck:: cast_slice ( & indices) ,
143
- label : Some ( & format ! ( "chunk-index-{chunk_x}-{chunk_y}" ) ) ,
144
- usage : wgpu:: BufferUsages :: INDEX | wgpu:: BufferUsages :: COPY_DST ,
145
- } ) ;
146
- return (
147
- indices. len ( ) as u32 ,
148
- chunk_vertex_buffer,
149
- chunk_index_buffer,
150
- ) ;
161
+ let chunk_vertex_buffer =
162
+ self . device
163
+ . create_buffer_init ( & wgpu:: util:: BufferInitDescriptor {
164
+ contents : bytemuck:: cast_slice ( & vertex) ,
165
+ label : Some ( & format ! ( "chunk-vertex-{}-{}" , self . x, self . y) ) ,
166
+ usage : wgpu:: BufferUsages :: VERTEX | wgpu:: BufferUsages :: COPY_DST ,
167
+ } ) ;
168
+ let chunk_index_buffer =
169
+ self . device
170
+ . create_buffer_init ( & wgpu:: util:: BufferInitDescriptor {
171
+ contents : bytemuck:: cast_slice ( & indices) ,
172
+ label : Some ( & format ! ( "chunk-vertex-{}-{}" , self . x, self . y) ) ,
173
+ usage : wgpu:: BufferUsages :: INDEX | wgpu:: BufferUsages :: COPY_DST ,
174
+ } ) ;
175
+
176
+ self . indices = indices. len ( ) as u32 ;
177
+ self . chunk_vertex_buffer = Some ( chunk_vertex_buffer) ;
178
+ self . chunk_index_buffer = Some ( chunk_index_buffer) ;
151
179
}
152
180
pub fn get_bind_group_layout ( ) -> wgpu:: BindGroupLayoutDescriptor < ' static > {
153
181
wgpu:: BindGroupLayoutDescriptor {
@@ -164,6 +192,7 @@ impl Chunk {
164
192
} ] ,
165
193
}
166
194
}
195
+
167
196
pub fn get_height_value (
168
197
chunk_x : i32 ,
169
198
chunk_y : i32 ,
@@ -218,7 +247,7 @@ impl Chunk {
218
247
219
248
block. lock ( ) . unwrap ( ) . faces = Some ( face_directions) ;
220
249
let curr = & mut blocks[ ( ( x * CHUNK_SIZE ) + z) as usize ] ;
221
- curr. push ( block. clone ( ) ) ;
250
+ curr. push ( Some ( block. clone ( ) ) ) ;
222
251
}
223
252
}
224
253
}
@@ -233,10 +262,9 @@ impl Chunk {
233
262
device : Arc < wgpu:: Device > ,
234
263
queue : Arc < wgpu:: Queue > ,
235
264
chunk_data_layout : Arc < wgpu:: BindGroupLayout > ,
265
+ other_chunks : Vec < Arc < Mutex < Chunk > > > ,
236
266
) -> Self {
237
267
let blocks = Self :: create_blocks_data ( x, y, noise_data. clone ( ) ) ;
238
- let ( indices, chunk_vertex_buffer, chunk_index_buffer) =
239
- Self :: build_mesh ( x, y, & blocks, noise_data. clone ( ) , device. clone ( ) ) ;
240
268
241
269
let chunk_position_buffer = device. create_buffer_init ( & wgpu:: util:: BufferInitDescriptor {
242
270
contents : bytemuck:: cast_slice ( & [ x, y] ) ,
@@ -253,15 +281,21 @@ impl Chunk {
253
281
} ] ,
254
282
} ) ;
255
283
256
- return Chunk {
284
+ let mut chunk = Chunk {
285
+ blocks,
257
286
x,
258
287
y,
259
- blocks,
288
+ device,
289
+ queue,
290
+ noise_data,
291
+ chunk_vertex_buffer : None ,
292
+ chunk_index_buffer : None ,
260
293
chunk_bind_group,
261
- chunk_index_buffer,
262
294
chunk_position_buffer,
263
- chunk_vertex_buffer,
264
- indices,
295
+ indices : 0 ,
265
296
} ;
297
+ chunk. build_mesh ( other_chunks) ;
298
+
299
+ return chunk;
266
300
}
267
301
}
0 commit comments