Nimbin[12]?Games / Entropie / entropie/src/world/terrain.h

Entropie git · main

Entropie festival game; first steps

sdl c game entropie cmake · first commit 2026-10-10 · last commit 2026-11-02 (18 hours ago) · synced 10 hours ago

C 88.5% Markdown 9.1% GLSL 2.3%
git clone https://git.christianimmanuel.de/games/Entropie.gitwget https://git.christianimmanuel.de/games/Entropie/archive/Entropie.tar.gz
entropie/src/world/terrain.h 4.1 KB · 97 lines raw
#ifndef WORLD_TERRAIN_H
#define WORLD_TERRAIN_H

/*
 * Uneven meadow ground (heightfield) with a wear map.
 *
 * Walking characters trample the grass: first it bends, then it becomes a
 * bare earth path that sinks a little. Untouched grass recovers slowly
 * (TERRAIN_RECOVERY_DAYS in game time).
 *
 * The ground is flattened under and around static objects so buildings,
 * trees and walls stand level. Roads and paths are part of it (a surface
 * map, and their height in the ground), so everything stands on them alike.
 * Water on and in it: see wetness.h.
 */

#include <stdbool.h>
#include <stdio.h>

#include "core/gl.h"
#include "world/object.h"
#include "render/mesh.h"
#include "world/wetness.h"

#define TERRAIN_SIZE          340.0f  /* square edge length in meters, centered on 0 */
#define TERRAIN_GRASS_DEPTH   0.08f   /* how far fully trampled ground sinks */
#define TERRAIN_RECOVERY_DAYS 2.0f    /* game days for a bare path to grow back */
#define TERRAIN_TILES         8       /* the ground mesh is cut into TILES x TILES pieces */
#define TERRAIN_SURFACE_RES   2048    /* surface map cells per side (1/6 m) */

/* A hole in the ground (a basement under a building): no ground drawn there,
   and the ground's height in it is its floor. A rectangle turned by yaw. */
#define TERRAIN_PITS 8
typedef struct {
    float x, z, cos_yaw, sin_yaw; /* its middle; local x is (cos, sin) */
    float half_x, half_z;
    float floor;
} TerrainPit;

typedef struct Terrain {
    float         *heights;    /* (TERRAIN_GRID + 1)^2 base heights */
    float         *wear;       /* TERRAIN_WEAR_RES^2, 0 = meadow, 1 = bare path */
    unsigned char *wear_bytes; /* upload buffer for the wear texture */
    bool           wear_dirty;
    GLuint         wear_texture;
    unsigned char *hard;       /* TERRAIN_SURFACE_RES^2: how paved (0 meadow .. 255 tar or concrete) */
    GLuint         surface_texture; /* RGBA8: asphalt, concrete, gravel, bare earth (see Site_surface) */
    Mesh           tiles[TERRAIN_TILES * TERRAIN_TILES]; /* the ground, in tiles (drawn only in view) */
    Wetness        wet;
    TerrainPit     pits[TERRAIN_PITS];
    int            pit_count;
} Terrain;

/* A hole in the ground (see TerrainPit; yaw as objects turn). May be dug
   before Terrain_init (buildings come first): it keeps them. */
bool  Terrain_addPit(Terrain *t, Vec3 center, float yaw, float half_x, float half_z, float floor_y);
/* In a pit here? (its floor, if so) */
bool  Terrain_inPit(const Terrain *t, float x, float z, float *floor_y);

/* Builds the ground and flattens it around the static objects given. */
bool  Terrain_init(Terrain *t, Object *const *objects, int count);
void  Terrain_destroy(Terrain *t);

/* Ground height at a world position, including trampled paths.
   Returns a very low value outside the terrain (objects fall off). */
float Terrain_height(const Terrain *t, float x, float z);

/* The ground as if no pit were dug there (what a building stands on). */
float Terrain_naturalHeight(const Terrain *t, float x, float z);
/* Ground height without the trampled paths (as built). */
float Terrain_baseHeight(const Terrain *t, float x, float z);
/* The meadow's own color here (before trampling). */
Vec3  Terrain_grassColor(float x, float z);

/* How trampled (0 meadow .. 1 bare path). */
float Terrain_wear(const Terrain *t, float x, float z);
/* Saves: the worn paths out to / in from a file. */
bool  Terrain_writeWear(const Terrain *t, FILE *f);
bool  Terrain_readWear(Terrain *t, FILE *f);

/* How hard the surface is (0 meadow .. 1 tar or concrete; gravel in between). */
float Terrain_hardness(const Terrain *t, float x, float z);

/* Wears the grass down at a footstep (real seconds); wet soft ground wears
   faster, paved ground not at all. */
void  Terrain_trample(Terrain *t, float x, float z, float dt);

/* Something lies on the ground here: the grass under it lies flat (sick). */
void  Terrain_soak(Terrain *t, float x, float z, float radius);

/* Lets grass grow back (game seconds). */
void  Terrain_recover(Terrain *t, float game_dt);

/* Uploads the wear map and the wet ground to the GPU where they changed. */
void  Terrain_syncTexture(Terrain *t);

#endif /* WORLD_TERRAIN_H */