aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornathan <nathansmith@disroot.org>2025-07-06 21:38:08 +0000
committernathan <nathansmith@disroot.org>2025-07-06 21:38:08 +0000
commit811d5bf064ce992bc742f55c112a777801126861 (patch)
tree5842fa0f76b2b0dbd4a04ac7a237b4d5753fdd1d
parent1abde5cdf85269597b180d5e88e9d62798fc893c (diff)
downloadFindThings-811d5bf064ce992bc742f55c112a777801126861.tar.gz
FindThings-811d5bf064ce992bc742f55c112a777801126861.tar.bz2
FindThings-811d5bf064ce992bc742f55c112a777801126861.zip
Finally smooth walking
-rw-r--r--src/player.c15
-rw-r--r--src/utils.h1
-rw-r--r--src/world.c75
-rw-r--r--src/world.h1
4 files changed, 68 insertions, 24 deletions
diff --git a/src/player.c b/src/player.c
index 0342040..9c66627 100644
--- a/src/player.c
+++ b/src/player.c
@@ -18,6 +18,14 @@ Player createPlayer()
};
}
+// Fake physics, distance from ground.
+void updatePlayerHeight(Player* player, Game* game)
+{
+ float height = getWorldHeightAtLocation(
+ game->world, player->position.x, player->position.z) + PLAYER_HEIGHT;
+ player->position.y = height;
+}
+
// TODO: move magic numbers to settings
void updatePlayer(Player* player, Game* game)
{
@@ -65,14 +73,13 @@ void updatePlayer(Player* player, Game* game)
player->velocity = Vector3Scale(player->velocity, 10.0);
- // Apply velocity
+ // Apply velocity.
player->position = Vector3Add(
player->position, Vector3Scale(player->velocity, GetFrameTime()));
+
+ updatePlayerHeight(player, game);
// Apply camera.
camera->position = player->position;
camera->target = Vector3Add(player->position, player->direction);
-
- player->position.y = getWorldHeightAtLocation(
- game->world, player->position.x, player->position.z) + PLAYER_HEIGHT;
}
diff --git a/src/utils.h b/src/utils.h
index c165e2c..e4cefee 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
+#include <float.h>
#include <raylib.h>
#include <raymath.h>
diff --git a/src/world.c b/src/world.c
index 1fdb1ce..b444ff1 100644
--- a/src/world.c
+++ b/src/world.c
@@ -7,7 +7,7 @@ World createWorld(const Assets* assets)
world.size = (Vector3){1000.0, 100.0, 1000.0};
// Heightmap image.
- Image image = GenImagePerlinNoise(1024, 1024, 0, 0, 2.0);
+ Image image = GenImagePerlinNoise(100, 100, 0, 0, 5.0);
// Heightmap.
Mesh mesh = GenMeshHeightmap(image, world.size);
@@ -27,7 +27,6 @@ World createWorld(const Assets* assets)
Entity entity = createEntity(seed % ENTITY_COUNT, Vector3Zero());
FT_RANDOM16(seed);
- // It be funky and give negative numbers.
entity.position.x = seed % (int)world.size.x;
FT_RANDOM16(seed);
entity.position.z = seed % (int)world.size.z;
@@ -55,29 +54,67 @@ void freeWorld(World world)
UnloadModel(world.heightmap);
}
-float getWorldPixelHeight(World world, int x, int y)
+float getWorldHeightAtLocation(World world, float x, float y)
{
- int verticeStart = (y * (world.texture.width - 1) + x) * 18;
- float height = 0.0;
- int count = 0;
+ float toMapX = (float)world.texture.width / world.size.x;
+ float toMapY = (float)world.texture.height / world.size.z;
+ int pixelX = x * toMapX;
+ int pixelY = y * toMapY;
+
+ int verticeStart = (pixelY * (world.texture.width - 1) + pixelX) * 18;
+ float* vertices = &world.heightmap.meshes[0].vertices[verticeStart];
+
+ // Clamp x and y to prevent ray being out of bounds.
+ Vector2 min = (Vector2){vertices[0], vertices[2]};
+ Vector2 max = (Vector2){vertices[0], vertices[2]};
- for (int index = 1; index < 18; index += 3)
+ for (int index = 0; index < 18; index += 3)
{
- height += world.heightmap.meshes[0].vertices[verticeStart + index];
- ++count;
+ Vector2 vertex = (Vector2){vertices[index], vertices[index + 2]};
+ min = Vector2Min(min, vertex);
+ max = Vector2Max(max, vertex);
}
- return (float)height / count;
-}
-
-float getWorldHeightAtLocation(World world, float x, float y)
-{
- float toMapX = (float)world.texture.width / world.size.x;
- float toMapY = (float)world.texture.height / world.size.z;
- int pixelX = roundf((float)x * toMapX);
- int pixelY = roundf((float)y * toMapY);
+ // Cast to triangles at pixel. Really hacky indeed.
+ Ray ray = (Ray){
+ .position = (Vector3){
+ Clamp(x, min.x, max.x),
+ FLT_MAX_EXP,
+ Clamp(y, min.y, max.y)},
+ .direction = (Vector3){0.0, -1.0, 0.0}
+ };
+
+ RayCollision result = GetRayCollisionTriangle(
+ ray,
+ (Vector3){vertices[0], vertices[1], vertices[2]},
+ (Vector3){vertices[3], vertices[4], vertices[5]},
+ (Vector3){vertices[6], vertices[7], vertices[8]});
+
+ // Test other triangle.
+ if (!result.hit)
+ {
+ result = GetRayCollisionTriangle(
+ ray,
+ (Vector3){vertices[9], vertices[10], vertices[11]},
+ (Vector3){vertices[12], vertices[13], vertices[14]},
+ (Vector3){vertices[15], vertices[16], vertices[17]});
+ }
- return getWorldPixelHeight(world, pixelX, pixelY);
+ if (result.hit)
+ {
+ return result.point.y;
+ }
+ else // Fall back.
+ {
+ float height = 0.0;
+
+ for (int index = 1; index < 18; index += 3)
+ {
+ height += vertices[index];
+ }
+
+ return height / 6.0;
+ }
}
// Abortions are good. Get more abortions.
diff --git a/src/world.h b/src/world.h
index 980f315..e06d628 100644
--- a/src/world.h
+++ b/src/world.h
@@ -35,7 +35,6 @@ void updateWorld(World* world, Game* game);
void freeWorld(World world);
// Dam, I wanta live in a free world ):
-float getWorldPixelHeight(World world, int x, int y);
float getWorldHeightAtLocation(World world, float x, float y);
#endif