Skip to content

Commit 55d88f4

Browse files
committed
dda first pass
1 parent c174aba commit 55d88f4

5 files changed

Lines changed: 169 additions & 10 deletions

File tree

src/camera.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ void CreateCamera(Camera* camera, CameraType type)
167167
camera->Height = 1.0f;
168168
camera->Fov = Radians(90.0f);
169169
camera->Near = 1.0f;
170-
camera->Far = 500.0f;
170+
camera->Far = 1000.0f;
171171
camera->Ortho = 100.0f;
172172
}
173173

src/chunk.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,15 @@ void SetChunkBlock(Chunk* chunk, int x, int y, int z, Block block)
5454
{
5555
chunk->Flags |= ChunkFlagMesh;
5656
Transform(chunk, &x, &y, &z);
57-
SetMapValue(&chunk->Blocks, x, y, z, block);
58-
// TODO: check if light (if so, add to lights)
57+
if (block != BlockEmpty)
58+
{
59+
SetMapValue(&chunk->Blocks, x, y, z, block);
60+
}
61+
else
62+
{
63+
RemoveMapValue(&chunk->Blocks, x, y, z);
64+
}
65+
// TODO: check if light (if so, add/remove)
5966
}
6067

6168
Block GetChunkBlock(const Chunk* chunk, int x, int y, int z)

src/main.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ static const float kAtlasWidth = 512.0f;
1212
static const int kAtlasMipLevels = 4;
1313
static const float kBlockWidth = 16.0f;
1414

15-
static const float kSpeed = 0.015f;
15+
static const float kSpeed = 0.01f;
1616
static const float kSensitivity = 0.1f;
17+
static const float kReach = 10.0f;
1718

1819
static SDL_Window* window;
1920
static SDL_GPUDevice* device;
@@ -448,7 +449,26 @@ SDL_AppResult SDLCALL SDL_AppEvent(void* appstate, SDL_Event* event)
448449
if (!SDL_GetWindowRelativeMouseMode(window))
449450
{
450451
SDL_SetWindowRelativeMouseMode(window, true);
451-
break;
452+
}
453+
else
454+
{
455+
float dx;
456+
float dy;
457+
float dz;
458+
GetCameraVector(&camera, &dx, &dy, &dz);
459+
WorldQuery query = RaycastWorld(&world, camera.X, camera.Y, camera.X, dx, dy, dz, kReach);
460+
if (query.HitBlock == BlockEmpty)
461+
{
462+
break;
463+
}
464+
if (event->button.button == SDL_BUTTON_LEFT)
465+
{
466+
SetWorldBlock(&world, query.Position[0], query.Position[1], query.Position[2], BlockEmpty);
467+
}
468+
else if (event->button.button == SDL_BUTTON_RIGHT)
469+
{
470+
SetWorldBlock(&world, query.PreviousPosition[0], query.PreviousPosition[1], query.PreviousPosition[2], BlockStone);
471+
}
452472
}
453473
break;
454474
}

src/world.c

Lines changed: 120 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
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

143143
void 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+
}

src/world.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#include "chunk.h"
88
#include "worker.h"
99

10-
#define WORLD_WIDTH 4
11-
#define WORLD_WORKERS 1
10+
#define WORLD_WIDTH 20
11+
#define WORLD_WORKERS 4
1212

1313
typedef struct Camera Camera;
1414
typedef struct Noise Noise;
@@ -28,8 +28,22 @@ typedef struct World
2828
}
2929
World;
3030

31+
typedef struct WorldQuery
32+
{
33+
Block HitBlock;
34+
int Position[3];
35+
int PreviousPosition[3];
36+
}
37+
WorldQuery;
38+
3139
void CreateWorld(World* world, SDL_GPUDevice* device);
3240
void DestroyWorld(World* world);
3341
void UpdateWorld(World* world, const Camera* camera, Save* save, Noise* noise);
3442
void RenderWorld(World* world, const Camera* camera, SDL_GPUCommandBuffer* commandBuffer, SDL_GPURenderPass* pass, ChunkMeshType type);
35-
Chunk* GetWorldChunk(World* world, int x, int y, int z);
43+
Chunk* GetWorldChunk(const World* world, int x, int y, int z);
44+
45+
// TODO: convert to take arrays for position instead
46+
Block GetWorldBlock(const World* world, int x, int y, int z);
47+
void SetWorldBlock(World* world, int x, int y, int z, Block block);
48+
49+
WorldQuery RaycastWorld(const World* world, float x, float y, float z, float dx, float dy, float dz, float length);

0 commit comments

Comments
 (0)