diff options
| author | KonAki <konaki@anokonaki.org> | 2026-10-11 00:14:24 +0800 |
|---|---|---|
| committer | KonAki <konaki@anokonaki.org> | 2026-10-11 00:14:24 +0800 |
| commit | a0775c7a437516b52c7978194583d7fee99fb5e9 (patch) | |
| tree | 44addcb2da14b6e4bed50aafb3c91fae6fa54ee3 /kon/kon3d.h | |
| parent | 6768cb73611bfb2e780bb1da95d32e079a241a7e (diff) | |
3d: editable height terrain, chunk culling, walking on slopes
Diffstat (limited to 'kon/kon3d.h')
| -rw-r--r-- | kon/kon3d.h | 53 |
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); |
