aboutsummaryrefslogtreecommitdiffstats
path: root/src/world.c
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 /src/world.c
parent1abde5cdf85269597b180d5e88e9d62798fc893c (diff)
downloadFindThings-811d5bf064ce992bc742f55c112a777801126861.tar.gz
FindThings-811d5bf064ce992bc742f55c112a777801126861.tar.bz2
FindThings-811d5bf064ce992bc742f55c112a777801126861.zip
Finally smooth walking
Diffstat (limited to 'src/world.c')
-rw-r--r--src/world.c75
1 files changed, 56 insertions, 19 deletions
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.