summaryrefslogtreecommitdiff
path: root/kon/kon3d.h
diff options
context:
space:
mode:
authorKonAki <konaki@anokonaki.org>2026-10-11 00:14:24 +0800
committerKonAki <konaki@anokonaki.org>2026-10-11 00:14:24 +0800
commita0775c7a437516b52c7978194583d7fee99fb5e9 (patch)
tree44addcb2da14b6e4bed50aafb3c91fae6fa54ee3 /kon/kon3d.h
parent6768cb73611bfb2e780bb1da95d32e079a241a7e (diff)
3d: editable height terrain, chunk culling, walking on slopes
Diffstat (limited to 'kon/kon3d.h')
-rw-r--r--kon/kon3d.h53
1 files changed, 51 insertions, 2 deletions
diff --git a/kon/kon3d.h b/kon/kon3d.h
index e4ffc6b..510fb86 100644
--- a/kon/kon3d.h
+++ b/kon/kon3d.h
@@ -40,9 +40,25 @@ typedef struct kon_fp {
float speed; /* tiles per second, 2.5 */
float turnSpeed; /* radians per second for the arrow keys, 2 */
float fov; /* vertical, radians, 60 degrees */
+ float farZ; /* how far you see, 40 */
int forward, strafe, turn; /* -1, 0 or 1, set by kon_fpEvent */
+ float feet; /* height of the floor under you, the eyes are eyeHeight above this */
+ float fall; /* downward speed while dropping */
+ float maxSlope; /* rise over run you can walk up, 1 is 45 degrees. anything steeper is a wall */
+ float gravity; /* 20 */
} kon_fp_t;
+/* a grid of heights, one world unit per cell, x is the column and z the row like the tilemap. every cell is two triangles.
+ edit the heights any time, it is drawn in chunks that are skipped when they are off screen */
+typedef struct kon_terrain {
+ int columns, rows; /* cells, there is one more height than that each way */
+ float *heights;
+ int chunk; /* cells per chunk side, 16 */
+ int chunkColumns, chunkRows;
+ float *chunkMin, *chunkMax;
+ const kon_material_t *material; /* the texture repeats once per cell */
+} kon_terrain_t;
+
/* what to draw for a map. solid is indexed by tile id like in kon_tilemapMove, solid tiles become walls.
ceiling can be NULL, that leaves the sky colour */
typedef struct kon_level3d {
@@ -62,8 +78,12 @@ void kon_fpInit(kon_fp_t *fp, const kon_tilemap_t *map, int column, int row);
a click grabs the mouse and tab lets go */
int kon_fpEvent(kon_fp_t *fp, kon_program_t *program, const kon_event_t *event);
-/* walks and turns, slides along solid tiles. lets the mouse go while the debug console is open */
-void kon_fpUpdate(kon_fp_t *fp, kon_program_t *program, const kon_tilemap_t *map, const uint8_t *solid, int solidCount, double dt);
+/* walks and turns, slides along solid tiles. lets the mouse go while the debug console is open.
+ terrain can be NULL for flat ground, otherwise you follow it, fall off ledges and stop at slopes steeper than maxSlope */
+void kon_fpUpdate(kon_fp_t *fp, kon_program_t *program, const kon_tilemap_t *map, const uint8_t *solid, int solidCount, const kon_terrain_t *terrain, double dt);
+
+/* puts your feet on the ground right away, for after kon_fpInit or a teleport */
+void kon_fpPlace(kon_fp_t *fp, const kon_tilemap_t *map, const kon_terrain_t *terrain);
/* where the eyes are in world units */
kon_vec3_t kon_fpEye(const kon_fp_t *fp, const kon_tilemap_t *map);
@@ -78,6 +98,35 @@ void kon_fpDebug(kon_fp_t *fp, kon_debug_t *debug);
so the depth test throws out what the walls already cover */
void kon_drawLevel(kon_framebuffer_t *fb, const kon_camera_t *camera, const kon_level3d_t *level, const kon_light_t *light);
+/*** terrain ***/
+
+/* all heights start at 0. NULL if the size is bad or there is no memory */
+kon_terrain_t *kon_terrainCreate(int columns, int rows);
+void kon_terrainFree(kon_terrain_t *terrain);
+
+/* the corner at column, row, from 0 to columns and 0 to rows. both do nothing outside */
+float kon_terrainCorner(const kon_terrain_t *terrain, int column, int row);
+void kon_terrainSetCorner(kon_terrain_t *terrain, int column, int row, float height);
+
+/* the exact height of the surface at x, z, the same triangles that get drawn. clamps at the edges */
+float kon_terrainHeight(const kon_terrain_t *terrain, float x, float z);
+
+/* pushes the ground up (or down with a negative amount) around x, z. full strength in the middle, nothing at radius */
+void kon_terrainRaise(kon_terrain_t *terrain, float x, float z, float radius, float amount);
+void kon_terrainFill(kon_terrain_t *terrain, float height);
+
+/* walks along the ray in small steps. returns 1 and the point if it hits the ground inside maxDistance */
+int kon_terrainRay(const kon_terrain_t *terrain, kon_vec3_t origin, kon_vec3_t direction, float maxDistance, kon_vec3_t *hit);
+
+/* a text file, "kter columns rows" and then the heights, so it is easy to read and diff. returns 0 on success */
+int kon_terrainSave(const kon_terrain_t *terrain, const char *path);
+kon_terrain_t *kon_terrainLoad(const char *path);
+
+void kon_drawTerrain(kon_framebuffer_t *fb, const kon_camera_t *camera, const kon_terrain_t *terrain, const kon_light_t *light);
+
+/* adds the commands tsave file, tload file and tfill height. the terrain has to stay where it is, a load changes it in place */
+void kon_terrainDebug(kon_terrain_t *terrain, kon_debug_t *debug);
+
/* 1 up close and less the further away, for dimming sprites. falloff 0.18 is gentle */
float kon_distanceFade(float distance, float falloff);