From 04bbee09dd28feba713022d5aa0e0b3df3bebaa5 Mon Sep 17 00:00:00 2001 From: Emil Kosz Date: Wed, 4 Jun 2025 17:41:39 +0200 Subject: [PATCH] Bilinear interpolation for movement. --- game/src/chunk/manager.c | 52 +++++++++++++++++++++++++++++++++------ game/src/entity/manager.c | 8 +++++- game/src/entity/meshes.c | 5 +++- game/src/event/handlers.c | 2 +- game/src/util.h | 4 --- 5 files changed, 57 insertions(+), 14 deletions(-) diff --git a/game/src/chunk/manager.c b/game/src/chunk/manager.c index 09c3093..2486c20 100644 --- a/game/src/chunk/manager.c +++ b/game/src/chunk/manager.c @@ -37,23 +37,61 @@ chunkman_world_to_chunk (float x, float z, int *cx, int *cz) *cz = floor (z / (float) CHUNK_DIM); } +static inline float +c_get_height (Chunk *c, int x, int z) +{ + return c ? c->heightmap[INDEX (x, z)] : 0.0; +} + float chunkman_get_height_at (float x, float z) { int cx, cz; chunkman_world_to_chunk (x, z, &cx, &cz); Chunk *chunk = chunkman_get_Chunk_at (cx, cz); - x -= cx * CHUNK_DIM; - z -= cz * CHUNK_DIM; - /* TODO: switch from this primitive system to something better. */ - - if (chunk != NULL) + if (chunk == NULL) { - return chunk->heightmap[INDEX ((int) floor (x), (int) floor (z))]; + return 0.0; } + + // Pozycja lokalna w chunku + float lx = x - cx * CHUNK_DIM; + float lz = z - cz * CHUNK_DIM; - return 0.0; + int x0 = (int) floor (lx); + int z0 = (int) floor (lz); + int x1 = x0 + 1; + int z1 = z0 + 1; + + float tx = lx - x0; + float tz = lz - z0; + + Chunk *r = NULL, *d = NULL, *c = NULL; + chunkman_get_Chunk_neighbors_at (cx, cz, &r, &d, &c); + + float h00 = c_get_height (chunk, x0, z0); + float h10 = (x1 < CHUNK_DIM) ? c_get_height (chunk, x1, z0) : + (r ? c_get_height (r, 0, z0) : h00); + float h01 = (z1 < CHUNK_DIM) ? c_get_height (chunk, x0, z1) : + (d ? c_get_height (d, x0, 0) : h00); + float h11; + + if (x1 < CHUNK_DIM && z1 < CHUNK_DIM) + h11 = c_get_height (chunk, x1, z1); + else if (x1 >= CHUNK_DIM && z1 < CHUNK_DIM) + h11 = r ? c_get_height (r, 0, z1) : h10; + else if (x1 < CHUNK_DIM && z1 >= CHUNK_DIM) + h11 = d ? c_get_height (d, x1, 0) : h01; + else + h11 = c ? c_get_height (c, 0, 0) : h00; + + // Interpolacja + float h0 = h00 * (1 - tx) + h10 * tx; + float h1 = h01 * (1 - tx) + h11 * tx; + float height = h0 * (1 - tz) + h1 * tz; + + return height; } void diff --git a/game/src/entity/manager.c b/game/src/entity/manager.c index fef847d..014a53a 100644 --- a/game/src/entity/manager.c +++ b/game/src/entity/manager.c @@ -8,6 +8,8 @@ static GSequence *entities; static EntityMesh mesh_quad2, mesh_quad_x; static unsigned int last_type = -1; +#define CULL_FRUSTUM 0 + void character_on_tick (Entity *entity) { @@ -70,6 +72,8 @@ entman_render_internal (gpointer data, gpointer userdata) /* TODO: Fix this up. It still isn't perfect, when you look up, sometimes the entities get culled. */ + + #if CULL_FRUSTUM vec4 planes[6]; mat4 proj, view_proj; @@ -91,6 +95,8 @@ entman_render_internal (gpointer data, gpointer userdata) { return; } + + #endif EntityMesh to_render; @@ -139,7 +145,7 @@ entman_render_internal (gpointer data, gpointer userdata) glm_translate (model, entity->position); break; default: - glm_rotate_at (model, entity->position, DEGTORAD (entity->rotation), (vec3) { 0.0, 1.0, 0.0 }); + glm_rotate_at (model, entity->position, glm_rad (entity->rotation), (vec3) { 0.0, 1.0, 0.0 }); glm_translate (model, entity->position); break; } diff --git a/game/src/entity/meshes.c b/game/src/entity/meshes.c index 63c6527..67a9f39 100644 --- a/game/src/entity/meshes.c +++ b/game/src/entity/meshes.c @@ -1,6 +1,9 @@ #include "meshes.h" -/* TODO: Split binding/rendering */ +/* TODO: Theoretically, we could fit all the transforms into one + vec4. The caveat? It would be for every vertex. There seems to be a + OpenGL function, glVertexAttrib, that repeats the attribute for + every subsequent vertex. */ void EntityMesh_bind (EntityMesh *mesh) diff --git a/game/src/event/handlers.c b/game/src/event/handlers.c index 6cdb664..6cd80db 100644 --- a/game/src/event/handlers.c +++ b/game/src/event/handlers.c @@ -18,7 +18,7 @@ evt_handler_lookaround (SDL_Event *event) camera_rotation[0] -= event->motion.xrel / 100.f; camera_rotation[1] -= event->motion.yrel / 100.f; camera_rotation[1] = - CLAMP (camera_rotation[1], -M_PI / 2 + 0.025, M_PI / 2 - 0.025); + glm_clamp (camera_rotation[1], -M_PI / 2 + 0.025, M_PI / 2 - 0.025); } } diff --git a/game/src/util.h b/game/src/util.h index ecc1581..333e0f6 100644 --- a/game/src/util.h +++ b/game/src/util.h @@ -15,10 +15,6 @@ #define WARN(fmt, args...) (fprintf (stderr, COLOR_YELLOW "[W] %s:%d:%s(): " COLOR_RESET fmt "\n", __FILE__, __LINE__, __func__, ##args)) #define FATAL(fmt, args...) (fprintf (stderr, COLOR_RED "[!] %s:%d:%s(): " COLOR_RESET fmt "\n", __FILE__, __LINE__, __func__, ##args), exit (-1)) -#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) - -#define DEGTORAD(deg) ((deg) * (M_PI / 180.0)) - #define UNUSED(...) (UNUSED_1 (__VA_ARGS__, 0)) #define UNUSED_1(arg, ...) (void) arg, UNUSED_2 (__VA_ARGS__, 0) #define UNUSED_2(arg, ...) (void) arg, UNUSED_3 (__VA_ARGS__, 0)