Bilinear interpolation for movement.

This commit is contained in:
2025-06-04 17:41:39 +02:00
parent 3140b5d9ab
commit 04bbee09dd
5 changed files with 57 additions and 14 deletions
+45 -7
View File
@@ -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
+7 -1
View File
@@ -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;
}
+4 -1
View File
@@ -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)
+1 -1
View File
@@ -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);
}
}
-4
View File
@@ -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)