terrain

Real-time terrain generation using marching cubes
git clone git://git.christianermann.dev/terrain
Log | Files | Refs | README | LICENSE

commit 0bd78557e526be25ade169f09af521a9da1bf9fc
parent 278db91aa4fe744eed70175ac422994071fcb517
Author: Christian Ermann <christianermann@gmail.com>
Date:   Wed, 14 Jul 2021 21:55:46 -0700

Chunk origin at corner instead of center

Diffstat:
Minclude/chunk.h | 7++++---
Minclude/chunk_manager.h | 2+-
Msrc/chunk.c | 80+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/chunk_manager.c | 59+++++++++++++++++++++++++++++++++--------------------------
4 files changed, 80 insertions(+), 68 deletions(-)

diff --git a/include/chunk.h b/include/chunk.h @@ -1,13 +1,14 @@ #ifndef CHUNK_H #define CHUNK_H -extern const int CHUNK_RADIUS; +extern const int CHUNK_WIDTH; typedef struct { - float center[3]; + int id[3]; + float origin[3]; } Chunk; -Chunk Chunk_create(float x, float y, float z); +Chunk Chunk_create(int x, int y, int z); void Chunk_outline(const Chunk* chunk, float corners[24], unsigned int offset, unsigned int indices[24]); diff --git a/include/chunk_manager.h b/include/chunk_manager.h @@ -6,7 +6,7 @@ typedef struct { int radius; int chunk_count; - int center[3]; + int origin[3]; int* offsets; Chunk* chunks; } ChunkManager; diff --git a/src/chunk.c b/src/chunk.c @@ -1,51 +1,55 @@ #include "chunk.h" -const int CHUNK_RADIUS = 8; +const int CHUNK_WIDTH = 16; -Chunk Chunk_create(float x, float y, float z) +Chunk Chunk_create(int x, int y, int z) { Chunk chunk; - chunk.center[0] = x; - chunk.center[1] = y; - chunk.center[2] = z; + chunk.id[0] = x; + chunk.id[1] = y; + chunk.id[2] = z; + + chunk.origin[0] = x * CHUNK_WIDTH; + chunk.origin[1] = y * CHUNK_WIDTH; + chunk.origin[2] = z * CHUNK_WIDTH; return chunk; } -void Cube_corners(const float center[3], float radius, float corners[24]) +void Cube_corners(const float origin[3], float width, float corners[24]) { - corners[0] = center[0] - radius; - corners[1] = center[1] - radius; - corners[2] = center[2] - radius; - - corners[3] = center[0] + radius; - corners[4] = center[1] - radius; - corners[5] = center[2] - radius; - - corners[6] = center[0] + radius; - corners[7] = center[1] - radius; - corners[8] = center[2] + radius; - - corners[9] = center[0] - radius; - corners[10] = center[1] - radius; - corners[11] = center[2] + radius; - - corners[12] = center[0] - radius; - corners[13] = center[1] + radius; - corners[14] = center[2] - radius; - - corners[15] = center[0] + radius; - corners[16] = center[1] + radius; - corners[17] = center[2] - radius; - - corners[18] = center[0] + radius; - corners[19] = center[1] + radius; - corners[20] = center[2] + radius; - - corners[21] = center[0] - radius; - corners[22] = center[1] + radius; - corners[23] = center[2] + radius; + corners[0] = origin[0]; + corners[1] = origin[1]; + corners[2] = origin[2]; + + corners[3] = origin[0] + width; + corners[4] = origin[1]; + corners[5] = origin[2]; + + corners[6] = origin[0] + width; + corners[7] = origin[1]; + corners[8] = origin[2] + width; + + corners[9] = origin[0]; + corners[10] = origin[1]; + corners[11] = origin[2] + width; + + corners[12] = origin[0]; + corners[13] = origin[1] + width; + corners[14] = origin[2]; + + corners[15] = origin[0] + width; + corners[16] = origin[1] + width; + corners[17] = origin[2]; + + corners[18] = origin[0] + width; + corners[19] = origin[1] + width; + corners[20] = origin[2] + width; + + corners[21] = origin[0]; + corners[22] = origin[1] + width; + corners[23] = origin[2] + width; } void Cube_outlineIndices(unsigned int offset, unsigned int indices[24]) @@ -84,6 +88,6 @@ void Cube_outlineIndices(unsigned int offset, unsigned int indices[24]) void Chunk_outline(const Chunk* chunk, float corners[24], unsigned int offset, unsigned int indices[24]) { - Cube_corners(chunk->center, CHUNK_RADIUS, corners); + Cube_corners(chunk->origin, CHUNK_WIDTH, corners); Cube_outlineIndices(offset, indices); } diff --git a/src/chunk_manager.c b/src/chunk_manager.c @@ -17,9 +17,9 @@ int ChunkManager_offsets(int radius, int* offsets) { if (offsets != NULL) { - offsets[count] = x * 2 * CHUNK_RADIUS; - offsets[count + 1] = y * 2 * CHUNK_RADIUS; - offsets[count + 2] = z * 2 * CHUNK_RADIUS; + offsets[count] = x; + offsets[count + 1] = y; + offsets[count + 2] = z; } count += 3; } @@ -29,6 +29,28 @@ int ChunkManager_offsets(int radius, int* offsets) return count; } +void ChunkManager_worldToChunk(const float src[3], int dst[3]) +{ + dst[0] = (int)floor(src[0] / CHUNK_WIDTH); + dst[1] = (int)floor(src[1] / CHUNK_WIDTH); + dst[2] = (int)floor(src[2] / CHUNK_WIDTH); +} + +void ChunkManager_recenter(ChunkManager* chunk_manager, const int origin[3]) +{ + chunk_manager->origin[0] = origin[0]; + chunk_manager->origin[1] = origin[1]; + chunk_manager->origin[2] = origin[2]; + for (int i = 0; i < chunk_manager->chunk_count; i++) + { + chunk_manager->chunks[i] = Chunk_create( + origin[0] + chunk_manager->offsets[i * 3], + origin[1] + chunk_manager->offsets[i * 3 + 1], + origin[2] + chunk_manager->offsets[i * 3 + 2] + ); + } +} + ChunkManager ChunkManager_create(int radius, float player[3]) { ChunkManager chunk_manager; @@ -43,35 +65,20 @@ ChunkManager ChunkManager_create(int radius, float player[3]) chunk_manager.chunks = (Chunk*)malloc(chunk_manager.chunk_count * sizeof(Chunk)); - chunk_manager.center[0] = 0; - chunk_manager.center[1] = 0; - chunk_manager.center[2] = 0; - ChunkManager_update(&chunk_manager, player); + ChunkManager_worldToChunk(player, chunk_manager.origin); + ChunkManager_recenter(&chunk_manager, chunk_manager.origin); return chunk_manager; } void ChunkManager_update(ChunkManager* chunk_manager, float player[3]) { - int chunk_x = (int)floor(player[0] / (2 * CHUNK_RADIUS)); - int chunk_y = (int)floor(player[1] / (2 * CHUNK_RADIUS)); - int chunk_z = (int)floor(player[2] / (2 * CHUNK_RADIUS)); - chunk_x = chunk_x * 2 * CHUNK_RADIUS + CHUNK_RADIUS; - chunk_y = chunk_y * 2 * CHUNK_RADIUS + CHUNK_RADIUS; - chunk_z = chunk_z * 2 * CHUNK_RADIUS + CHUNK_RADIUS; - if (chunk_x != chunk_manager->center[0] || chunk_y - != chunk_manager->center[1] || chunk_z != chunk_manager->center[2]) + int new_origin[3]; + ChunkManager_worldToChunk(player, new_origin); + if (new_origin[0] != chunk_manager->origin[0] + || new_origin[1] != chunk_manager->origin[1] + || new_origin[2] != chunk_manager->origin[2]) { - chunk_manager->center[0] = chunk_x; - chunk_manager->center[1] = chunk_y; - chunk_manager->center[2] = chunk_z; - for (int i = 0; i < chunk_manager->chunk_count; i++) - { - chunk_manager->chunks[i] = Chunk_create( - chunk_x + chunk_manager->offsets[i * 3], - chunk_y + chunk_manager->offsets[i * 3 + 1], - chunk_z + chunk_manager->offsets[i * 3 + 2] - ); - } + ChunkManager_recenter(chunk_manager, new_origin); } }