88#include "worker.h"
99#include "world.h"
1010
11- static bool Contains (World * world , int x , int z )
11+ static bool Contains (const World * world , int x , int z )
1212{
1313 return x >= 0 && z >= 0 && x < WORLD_WIDTH && z < WORLD_WIDTH ;
1414}
@@ -142,6 +142,7 @@ static void CreateIndexBuffer(World* world, Uint32 size)
142142
143143void UpdateWorld (World * world , const Camera * camera , Save * save , Noise * noise )
144144{
145+ // TODO: generating everything before meshing can cause artifacts to appear until generation finishes
145146 Move (world , camera );
146147 WorkerJob jobs [WORLD_WORKERS ] = {0 };
147148 int numJobs = 0 ;
@@ -240,7 +241,7 @@ void RenderWorld(World* world, const Camera* camera, SDL_GPUCommandBuffer* comma
240241 }
241242}
242243
243- Chunk * GetWorldChunk (World * world , int x , int y , int z )
244+ Chunk * GetWorldChunk (const World * world , int x , int y , int z )
244245{
245246 if (Contains (world , x , z ))
246247 {
@@ -251,3 +252,120 @@ Chunk* GetWorldChunk(World* world, int x, int y, int z)
251252 return NULL ;
252253 }
253254}
255+
256+ static int FloorChunkIndex (float index )
257+ {
258+ return SDL_floorf (index / CHUNK_WIDTH );
259+ }
260+
261+ Block GetWorldBlock (const World * world , int x , int y , int z )
262+ {
263+ int chunkX = FloorChunkIndex (x - world -> X * CHUNK_WIDTH );
264+ int chunkY = FloorChunkIndex (y - world -> Y * CHUNK_HEIGHT );
265+ int chunkZ = FloorChunkIndex (z - world -> Z * CHUNK_WIDTH );
266+ Chunk * chunk = GetWorldChunk (world , chunkX , chunkY , chunkZ );
267+ if (chunk )
268+ {
269+ return GetChunkBlock (chunk , x , y , z );
270+ }
271+ else
272+ {
273+ return BlockEmpty ;
274+ }
275+ }
276+
277+ void SetWorldBlock (World * world , int x , int y , int z , Block block )
278+ {
279+ int chunkX = FloorChunkIndex (x - world -> X * CHUNK_WIDTH );
280+ int chunkY = FloorChunkIndex (y - world -> Y * CHUNK_HEIGHT );
281+ int chunkZ = FloorChunkIndex (z - world -> Z * CHUNK_WIDTH );
282+ Chunk * chunk = GetWorldChunk (world , chunkX , chunkY , chunkZ );
283+ if (chunk )
284+ {
285+ SetChunkBlock (chunk , x , y , z , block );
286+ }
287+ else
288+ {
289+ SDL_Log ("Bad block position: %d, %d, %d" , x , y , z );
290+ }
291+ }
292+
293+ WorldQuery RaycastWorld (const World * world , float x , float y , float z , float dx , float dy , float dz , float length )
294+ {
295+ WorldQuery query = {0 };
296+ query .Position [0 ] = SDL_floorf (x );
297+ query .Position [1 ] = SDL_floorf (y );
298+ query .Position [2 ] = SDL_floorf (z );
299+ float position [3 ] = {x , y , z };
300+ float direction [3 ] = {dx , dy , dz };
301+ float distances [3 ] = {0 };
302+ int steps [3 ] = {0 };
303+ float delta [3 ] = {0 };
304+ for (int i = 0 ; i < 3 ; i ++ )
305+ {
306+ query .PreviousPosition [i ] = query .Position [i ];
307+ if (SDL_fabsf (direction [i ]) > SDL_FLT_EPSILON )
308+ {
309+ delta [i ] = SDL_fabsf (1.0f / direction [i ]);
310+ }
311+ else
312+ {
313+ delta [i ] = 1e6 ;
314+ }
315+ if (direction [i ] < 0.0f )
316+ {
317+ steps [i ] = -1 ;
318+ distances [i ] = (position [i ] - query .Position [i ]) * delta [i ];
319+ }
320+ else
321+ {
322+ steps [i ] = 1 ;
323+ distances [i ] = (query .Position [i ] + 1.0f - position [i ]) * delta [i ];
324+ }
325+ }
326+ float traveled = 0.0f ;
327+ while (traveled <= length )
328+ {
329+ query .HitBlock = GetWorldBlock (world , query .Position [0 ], query .Position [1 ], query .Position [2 ]);
330+ if (query .HitBlock != BlockEmpty )
331+ {
332+ return query ;
333+ }
334+ for (int i = 0 ; i < 3 ; i ++ )
335+ {
336+ query .PreviousPosition [i ] = query .Position [i ];
337+ }
338+ if (distances [0 ] < distances [1 ])
339+ {
340+ if (distances [0 ] < distances [2 ])
341+ {
342+ traveled = distances [0 ];
343+ distances [0 ] += delta [0 ];
344+ query .Position [0 ] += steps [0 ];
345+ }
346+ else
347+ {
348+ traveled = distances [2 ];
349+ distances [2 ] += delta [2 ];
350+ query .Position [2 ] += steps [2 ];
351+ }
352+ }
353+ else
354+ {
355+ if (distances [1 ] < distances [2 ])
356+ {
357+ traveled = distances [1 ];
358+ distances [1 ] += delta [1 ];
359+ query .Position [1 ] += steps [1 ];
360+ }
361+ else
362+ {
363+ traveled = distances [2 ];
364+ distances [2 ] += delta [2 ];
365+ query .Position [2 ] += steps [2 ];
366+ }
367+ }
368+ }
369+ query .HitBlock = BlockEmpty ;
370+ return query ;
371+ }
0 commit comments