From 6463ac3dd75483df2c6c51e898488bbead3518bc Mon Sep 17 00:00:00 2001 From: veclavtalica Date: Mon, 6 Jan 2025 15:34:12 +0300 Subject: [PATCH] /apps/demos/scenery: separate height_at(), position grass right --- apps/demos/scenery/scenes/ingame.c | 58 +++++++++++++++++------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/apps/demos/scenery/scenes/ingame.c b/apps/demos/scenery/scenes/ingame.c index 308f439..6d71083 100644 --- a/apps/demos/scenery/scenes/ingame.c +++ b/apps/demos/scenery/scenes/ingame.c @@ -48,6 +48,35 @@ static void process_fly_mode(State *state) { } +static float height_at(SceneIngame *scn, Vec2 position) { + float height0, height1, height2, weight0, weight1, weight2; + + int const x = (int)(HALF_TERRAIN_DISTANCE + (position.x - scn->pos.x)); + int const y = (int)(HALF_TERRAIN_DISTANCE + (position.y - scn->pos.z)); + + height0 = heightmap[x][y]; + height1 = heightmap[x + 1][y + 1]; + + Vec2 incell = { position.x - floorf(position.x), position.y - floorf(position.y) }; + + /* who needs barycentric coordinates, am i right? */ + weight0 = 1 / sqrtf(powf(incell.x, 2) + powf(incell.y, 2)); + weight1 = 1 / sqrtf(powf(1 - incell.x, 2) + powf(1 - incell.y, 2)); + + /* find which triangle we're directly under */ + /* for this manhattan distance is sufficient */ + if (incell.x + (1 - incell.y) < (1 - incell.x) + incell.y) { + height2 = heightmap[x][y + 1]; + weight2 = 1 / sqrtf(powf(incell.x, 2) + powf(1 - incell.y, 2)); + } else { + height2 = heightmap[x + 1][y]; + weight2 = 1 / sqrtf(powf(1 - incell.x, 2) + powf(incell.y, 2)); + } + + return (height0 * weight0 + height1 * weight1 + height2 * weight2) / (weight0 + weight1 + weight2); +} + + static void process_ground_mode(State *state) { SceneIngame *scn = (SceneIngame *)state->scene; @@ -61,35 +90,13 @@ static void process_ground_mode(State *state) { /* gravity */ { - float height0, height1, height2, weight0, weight1, weight2; - - height0 = heightmap[(int)HALF_TERRAIN_DISTANCE][(int)HALF_TERRAIN_DISTANCE]; - height1 = heightmap[(int)HALF_TERRAIN_DISTANCE + 1][(int)HALF_TERRAIN_DISTANCE + 1]; - - Vec2 incell = { scn->pos.x - floorf(scn->pos.x), scn->pos.z - floorf(scn->pos.z) }; - - /* who needs barycentric coordinates, am i right? */ - weight0 = 1 / sqrtf(powf(incell.x, 2) + powf(incell.y, 2)); - weight1 = 1 / sqrtf(powf(1 - incell.x, 2) + powf(1 - incell.y, 2)); - - /* find which triangle we're directly under */ - /* for this manhattan distance is sufficient */ - if (incell.x + (1 - incell.y) < (1 - incell.x) + incell.y) { - height2 = heightmap[(int)HALF_TERRAIN_DISTANCE][(int)HALF_TERRAIN_DISTANCE + 1]; - weight2 = 1 / sqrtf(powf(incell.x, 2) + powf(1 - incell.y, 2)); - } else { - height2 = heightmap[(int)HALF_TERRAIN_DISTANCE + 1][(int)HALF_TERRAIN_DISTANCE]; - weight2 = 1 / sqrtf(powf(1 - incell.x, 2) + powf(incell.y, 2)); - } - - float height = (height0 * weight0 + height1 * weight1 + height2 * weight2) / (weight0 + weight1 + weight2); + float const height = height_at(scn, (Vec2){scn->pos.x, scn->pos.z}); if (target.y > height + PLAYER_HEIGHT) target.y = target.y - 0.4f; if (target.y < height + PLAYER_HEIGHT) target.y = height + PLAYER_HEIGHT; - } /* movement */ @@ -159,7 +166,10 @@ static void draw_terrain(SceneIngame *scn) { (Vec2){ 0, 0 }, (Vec2){ 0, 128 }); - draw_billboard("/assets/grasses/10.png", (Vec3){ (float)x, d1 + 0.1f, (float)y }, (Vec2){0.3f, 0.3f}, (Color){255, 255, 255, 255}, true); + draw_billboard("/assets/grasses/10.png", + (Vec3){ (float)x, d0 + 0.15f, (float)y }, + (Vec2){0.3f, 0.3f}, + (Color){255, 255, 255, 255}, true); } } }