Entropie git · main
Entropie festival game; first steps
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.gzentropie 2.16.1: car arrival crash and car fixes
- Fix the segfault when arriving by car: at slow frames the arm springs blew up (passengers vanished, then a NaN became a terrain index); springs now substep, NaN never reaches the body or the terrain lookup - Passengers no longer sit backwards in the car - Car inside: windscreen pillars lean back; no more looking through under the steering wheel or beside the dashboard - People sitting on a bench, chair, log or in the car no longer rotate their body to follow you (only the head turns)
commit_message.txt | 15 +++++++++------ entropie/Makefile | 2 +- entropie/STATE.md | 8 +++++++- entropie/src/people/ai_internal.h | 1 + entropie/src/people/body_pose.c | 11 +++++++++-- entropie/src/render/shapes_props.c | 8 +++++--- entropie/src/world/car.c | 4 ++-- entropie/src/world/terrain.c | 2 +- 8 files changed, 35 insertions(+), 16 deletions(-) diff --git a/commit_message.txt b/commit_message.txt index 05ea22b..2791f58 100644 --- a/commit_message.txt +++ b/commit_message.txt @@ -1,7 +1,10 @@ -entropie 2.16.0: felling room +entropie 2.16.1: car arrival crash and car fixes -- NPCs check where a tree will come down before felling it and pick a - clear direction (no houses, walls, cars, tents, furniture, fire); no room - anywhere: they leave that tree -- Nearly through, anyone in the way gets "Timber!" and steps aside; the - feller waits until the way is clear (also for you) +- Fix the segfault when arriving by car: at slow frames the arm springs + blew up (passengers vanished, then a NaN became a terrain index); + springs now substep, NaN never reaches the body or the terrain lookup +- Passengers no longer sit backwards in the car +- Car inside: windscreen pillars lean back; no more looking through under + the steering wheel or beside the dashboard +- People sitting on a bench, chair, log or in the car no longer rotate + their body to follow you (only the head turns) diff --git a/entropie/Makefile b/entropie/Makefile index d5edb5e..2c0266e 100644 --- a/entropie/Makefile +++ b/entropie/Makefile @@ -1,5 +1,5 @@ APP := entropie -VERSION := 2.16.0 +VERSION := 2.16.1 PREFIX ?= /usr BINDIR ?= $(PREFIX)/bin diff --git a/entropie/STATE.md b/entropie/STATE.md index 309d852..db3ab52 100644 --- a/entropie/STATE.md +++ b/entropie/STATE.md @@ -251,6 +251,12 @@ Round 2.16: - Felling room (`ai_work.c`): before an NPC fells a tree (`ai_taskFor` JOB_FELL -> `fellPlan`, once per tree: `fell_plan`, `fell_blocked`), FELL_DIRS 12 ways round it, nearest to the way they'd fell it first; `fallHits` looks down (rays from 14 m) at spots every metre from the stump to its top (`treeTall`), across the trunk near the stump and a crown wide further out: a house, barn, building, wall, car, tent, furniture, fireplace or woodpile hit counts. The first clear way (or the least bad): the feller stands on the other side (it falls away from them). No clear way at all: "No room for that one to come down - I'll leave it" (skipped). - Nearly through (`Tools_fellDone` over FELL_WARN 0.6): anybody where it'll come down (from the stump to its top + 1.5 m, a crown + 0.6 m wide) is warned ("Timber! Out of the way!", you: "...it's coming down there!"); NPCs step out sideways past the crown (`ai.dodge_to`, `dodge_t` 8 s, first thing in Ai_update); the feller waits (`ai.timber`, counts as fine waiting for the watchdog) till nobody's there. +Round 2.16.1: +- The crash arriving by car: at slow frames (10 fps, or a spike up to MAX_FRAME_DT 0.1) the arm springs (`body_pose.c` spring: ARM_STIFFNESS x4 running, explicit damping 22 x 0.1 s > 2) blew up - a passenger's hand went NaN (they vanished), then the ground lookup took an index from the NaN (`terrain.c` wearAt: SEGV). `spring` now splits a frame into steps of SPRING_STEP 0.02 s (60 fps: one, nothing changes there) and never hands a NaN on; `Terrain_naturalHeight` treats a NaN position as outside. Checked: the drive and the hello at 10, ~16 and 60 fps (jittered), and under AddressSanitizer. +- Passengers sat backwards: a person's yaw is turned round from a thing's (`Object_facing` vs `yaw_front`): `Car_place` gives them car yaw + pi. +- The car from inside (`Shapes_carInside`): the windscreen pillars lean back like the windscreen (were tipped forward); the footwell's front and the dashboard's underside close the hole under the wheel; the floor and the doors go on to the front (you saw the road beside and under the dashboard). +- Sitting people (on a bench, chair, log, in the car) no longer turn their whole body to follow you (`turnTowards` leaves them as they sat; the head still turns to look). + Unfinished building (Shell_build, at SHELL_AT in the frame's frame): brick shell 6.4 x 4.7, walls 2.9, open front (2 m) to the frame (now only the front half: pillars at z -13.8 / -9.2), window holes, bare floor, tiled roof with slabs. Barn: brick courses on BUILDING_BRICK walls (`addBrickCourses`: mortar a shade lighter, so the ink doesn't trace it), ivy (`Shapes_ivy`, OBJ_STRUCTUREs) on both long sides; the woodpile (OBJ_WOODPILE "Woodpile", WOODPILE_A/B) left of the toilet, everybody's woodpile from the start (`scene.c` Scene_finish). Fireplace tripod: wooden poles, feet TRIPOD_OUT 0.9 m outside the stones, TRIPOD_PAST 0.4 m past the top, a lashing; each pole an OBJ_WALL along it ("Tripod pole"). Gates (FURN_GATE, green boards): in your garages' doorways (GATES: hinge, end), `gate_open` / `gate_t`, `hinge`, `gate_shut` / `gate_out`; Object_swingGate (1.2 s), driven by showProps; a click within 1.2 m opens / shuts both leaves. Props that show (1.89, `world.c` showProps every frame): the tin's mesh is built again when its butts change (`Shapes_ashtray`: up to 12 show, the ash rises, a heap from 14; `shown` = what's built). @@ -407,4 +413,4 @@ Most important first. - Drawing many figures on a real graphics card: not measured (software GL: 300 people cost 3x the rest of the scene) --- -State of `entropie 2.16.0 (build ceace5d)` +State of `entropie 2.16.1 (build 4cd7c31)` diff --git a/entropie/src/people/ai_internal.h b/entropie/src/people/ai_internal.h index 6e98ce9..e10fe72 100644 --- a/entropie/src/people/ai_internal.h +++ b/entropie/src/people/ai_internal.h @@ -125,6 +125,7 @@ static inline void setFacing(Object *o, Vec3 dir) { /* Turns towards dir at a limited rate. */ static inline void turnTowards(Object *o, Vec3 dir, float dt) { + if (o->sitting && (o->seat || o->riding)) return; /* (on a bench, a chair, a log, in the car: they stay sat as they sat - the head turns, see look_dir) */ dir = flat(dir); if (vec3_length(dir) < 1e-4f) return; Vec3 f = Object_facing(o); diff --git a/entropie/src/people/body_pose.c b/entropie/src/people/body_pose.c index af3906b..3e0495f 100644 --- a/entropie/src/people/body_pose.c +++ b/entropie/src/people/body_pose.c @@ -113,9 +113,16 @@ static Vec3 reachPole(Vec3 shoulder, Vec3 palm, float sign) { } /* Damped spring step towards a target. */ +#define SPRING_STEP 0.02f /* s: a slow frame is split into steps this short (60 fps: one) (a stiff spring blew up at 10 fps: NaN arms, a crash) */ + static void spring(float *value, float *velocity, float target, float stiffness, float damping, float dt) { - *velocity += (stiffness * (target - *value) - damping * *velocity) * dt; - *value += *velocity * dt; + int n = dt > SPRING_STEP ? (int)ceilf(dt / SPRING_STEP) : 1; + float h = dt / (float)n; + for (int i = 0; i < n; i++) { + *velocity += (stiffness * (target - *value) - damping * *velocity) * h; + *value += *velocity * h; + } + if (!isfinite(*value) || !isfinite(*velocity)) { *value = target; *velocity = 0.0f; } /* (never a NaN into the body: it would vanish, then crash) */ } /* Head frame from yaw (> 0 = right), pitch (> 0 = up) and roll. */ diff --git a/entropie/src/render/shapes_props.c b/entropie/src/render/shapes_props.c index 405d145..414dafb 100644 --- a/entropie/src/render/shapes_props.c +++ b/entropie/src/render/shapes_props.c @@ -926,16 +926,18 @@ Mesh Shapes_carInside(Vec3 color) { for (int s = -1; s <= 1; s += 2) { /* the pillars beside the windscreen */ first = b.vertex_count; addBlock(&b, vec3(0.0f, 0.3f, 0.0f), vec3(0.05f, 0.62f, 0.05f), color); - transformSince(&b, first, mat4_mul(mat4_translate(vec3((float)s * w * 0.44f, 0.9f, 0.8f)), mat4_rotate_x(-0.55f))); + transformSince(&b, first, mat4_mul(mat4_translate(vec3((float)s * w * 0.44f, 0.9f, 0.8f)), mat4_rotate_x(0.55f))); /* (leaning back, like the windscreen) */ } + addBlock(&b, vec3(0.0f, 0.58f, 0.86f), vec3(w * 0.92f, 0.52f, 0.06f), dash); /* the footwell's front: under the dashboard */ + addBlock(&b, vec3(0.0f, 0.70f, 0.74f), vec3(w * 0.92f, 0.12f, 0.2f), dash); /* the dashboard's underside */ const float back = -l * 0.5f, cab0 = back + 0.12f, cab1 = 0.45f, cab = cab1 - cab0, mid = (cab0 + cab1) * 0.5f; const Vec3 door = vec3_scale(color, 0.75f), seat = { 0.24f, 0.24f, 0.27f }, floor = { 0.12f, 0.12f, 0.13f }; addBlock(&b, vec3(0.0f, 1.47f, mid), vec3(w * 0.92f, 0.04f, cab), roof); /* the roof lining */ addBlock(&b, vec3(0.0f, 1.44f, 0.2f), vec3(0.25f, 0.05f, 0.06f), dash); /* the mirror */ - addBlock(&b, vec3(0.0f, 0.33f, mid), vec3(w * 0.9f, 0.04f, cab), floor); /* the floor */ + addBlock(&b, vec3(0.0f, 0.33f, (cab0 + 0.9f) * 0.5f), vec3(w * 0.9f, 0.04f, 0.9f - cab0), floor); /* the floor, on under the dashboard */ for (int s = -1; s <= 1; s += 2) { float x = (float)s * (w * 0.5f - 0.04f); - addBlock(&b, vec3(x, 0.66f, mid), vec3(0.06f, 0.64f, cab), door); /* the doors, up to the windows */ + addBlock(&b, vec3(x, 0.66f, (cab0 + 0.9f) * 0.5f), vec3(0.06f, 0.64f, 0.9f - cab0), door); /* the doors, up to the windows (on past the dashboard) */ addBlock(&b, vec3(x, 1.2f, -0.6f), vec3(0.07f, 0.52f, 0.12f), door); /* the middle pillar ... */ addBlock(&b, vec3(x, 1.2f, cab0 + 0.12f), vec3(0.07f, 0.52f, 0.24f), door); /* ... and the back one */ addBlock(&b, vec3((float)s * 0.38f, 0.52f, -0.02f), vec3(0.5f, 0.12f, 0.5f), seat); /* the front seats */ diff --git a/entropie/src/world/car.c b/entropie/src/world/car.c index 0e5c72e..3c1373a 100644 --- a/entropie/src/world/car.c +++ b/entropie/src/world/car.c @@ -151,8 +151,8 @@ void Car_place(World *world, Object *car, Vec3 at, float yaw) { Vec3 p = local(car, vec3_add(seatAt(o->ride_seat), vec3(0.0f, 0.0f, 0.18f))); /* (the feet under the dashboard) */ o->position = vec3(p.x, at.y + CAR_FLOOR, p.z); o->sit_at = o->position; - o->sit_yaw = yaw; - o->rotation.y = yaw; + o->sit_yaw = yaw + PI_F; /* (a person's yaw faces the other way round from a thing's: see Object_facing / yaw_front) */ + o->rotation.y = yaw + PI_F; o->velocity = vec3_zero(); Object_syncColliders(o); } diff --git a/entropie/src/world/terrain.c b/entropie/src/world/terrain.c index 125f89a..b607a04 100644 --- a/entropie/src/world/terrain.c +++ b/entropie/src/world/terrain.c @@ -354,7 +354,7 @@ float Terrain_height(const Terrain *t, float x, float z) { } float Terrain_naturalHeight(const Terrain *t, float x, float z) { - if (x < -HALF || x > HALF || z < -HALF || z > HALF) return OUTSIDE_HEIGHT; + if (!(x >= -HALF && x <= HALF && z >= -HALF && z <= HALF)) return OUTSIDE_HEIGHT; /* (written so a NaN is outside too: never an index from it) */ float gx = fminf((x + HALF) / GRID_CELL, (float)TERRAIN_GRID - 0.001f); float gz = fminf((z + HALF) / GRID_CELL, (float)TERRAIN_GRID - 0.001f); int ix = (int)gx, iz = (int)gz;