Compare commits

...

2 Commits

Author SHA1 Message Date
veclavtalica
b0549612a9 /apps/demos/scenery: lock movement direction to a plane 2025-01-06 15:38:40 +03:00
veclavtalica
6463ac3dd7 /apps/demos/scenery: separate height_at(), position grass right 2025-01-06 15:34:12 +03:00

View File

@ -48,12 +48,44 @@ 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) { static void process_ground_mode(State *state) {
SceneIngame *scn = (SceneIngame *)state->scene; SceneIngame *scn = (SceneIngame *)state->scene;
DrawCameraFromPrincipalAxesResult dir_and_up = DrawCameraFromPrincipalAxesResult dir_and_up =
draw_camera_from_principal_axes(scn->pos, (float)M_PI_2 * 0.8f, scn->roll, scn->pitch, scn->yaw); draw_camera_from_principal_axes(scn->pos, (float)M_PI_2 * 0.8f, scn->roll, scn->pitch, scn->yaw);
dir_and_up.direction.y = 0;
dir_and_up.direction = vec3_norm(dir_and_up.direction);
const Vec3 right = m_vec_norm(m_vec_cross(dir_and_up.direction, dir_and_up.up)); const Vec3 right = m_vec_norm(m_vec_cross(dir_and_up.direction, dir_and_up.up));
const float speed = 0.18f; /* TODO: put this in a better place */ const float speed = 0.18f; /* TODO: put this in a better place */
@ -61,35 +93,13 @@ static void process_ground_mode(State *state) {
/* gravity */ /* gravity */
{ {
float height0, height1, height2, weight0, weight1, weight2; float const height = height_at(scn, (Vec2){scn->pos.x, scn->pos.z});
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);
if (target.y > height + PLAYER_HEIGHT) if (target.y > height + PLAYER_HEIGHT)
target.y = target.y - 0.4f; target.y = target.y - 0.4f;
if (target.y < height + PLAYER_HEIGHT) if (target.y < height + PLAYER_HEIGHT)
target.y = height + PLAYER_HEIGHT; target.y = height + PLAYER_HEIGHT;
} }
/* movement */ /* movement */
@ -159,7 +169,10 @@ static void draw_terrain(SceneIngame *scn) {
(Vec2){ 0, 0 }, (Vec2){ 0, 0 },
(Vec2){ 0, 128 }); (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);
} }
} }
} }