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.23.0: belly first
- Chest high ledges: the less sporty (or drunk) push up onto the belly, lie over the edge, bring a knee up and stand up
commit_message.txt | 6 +++--- entropie/Makefile | 2 +- entropie/README.md | 2 ++ entropie/STATE.md | 7 +++++-- entropie/commit_message.txt | 6 +++--- entropie/src/people/body.h | 3 ++- entropie/src/people/body_pose.c | 3 +++ entropie/src/people/climb.c | 27 +++++++++++++++++++++++++-- entropie/src/world/object.h | 2 ++ entropie/src/world/world.c | 1 + 10 files changed, 47 insertions(+), 12 deletions(-) diff --git a/commit_message.txt b/commit_message.txt index a0d247c..e0d62fe 100644 --- a/commit_message.txt +++ b/commit_message.txt @@ -1,4 +1,4 @@ -entropie 2.22.0: the leading shoulder +entropie 2.23.0: belly first -- Climbing a high ledge: the shoulder of the hand that reaches first turns - ahead, easing back as the other hand follows +- Chest high ledges: the less sporty (or drunk) push up onto the belly, lie + over the edge, bring a knee up and stand up diff --git a/entropie/Makefile b/entropie/Makefile index d5ad372..4ecbe6e 100644 --- a/entropie/Makefile +++ b/entropie/Makefile @@ -1,5 +1,5 @@ APP := entropie -VERSION := 2.22.0 +VERSION := 2.23.0 PREFIX ?= /usr BINDIR ?= $(PREFIX)/bin diff --git a/entropie/README.md b/entropie/README.md index 0246db2..382a0a9 100644 --- a/entropie/README.md +++ b/entropie/README.md @@ -340,6 +340,8 @@ and satellite pictures (about 340 x 340 m). turned ahead), the other follows - Hip high, the less sporty and the old take the careful way: back to it, a hop up to sit on the edge, legs swung up onto it, then stand up +- Chest high, the less sporty (or drunk) go belly first: push up, lie over + the edge, a knee up, then stand up - Jumps take off from one foot (rarely both at once); at a run, the rear foot pushes off and the front one lands first - Drunk, walking into a wall or a person easily ends on the ground diff --git a/entropie/STATE.md b/entropie/STATE.md index 1ff37d7..bdaedcc 100644 --- a/entropie/STATE.md +++ b/entropie/STATE.md @@ -290,6 +290,9 @@ Round 2.21: Round 2.22: - Climbing a high ledge, the shoulder of the first hand goes ahead: the shoulders turn up to REACH_TURN 0.35 rad to that side while the other hand still trails (`Hands.edge_turn`, set by `Climb_update`; `Body.reach_turn`, added to the chest turn in `body_pose.c`), easing back as the second hand arrives. +Round 2.23: +- The belly way up (`climb.c`, `ClimbMove.belly_way` / `belly`): something BELLY_LOW 1.0 .. BELLY_HIGH 1.55 m high (scaled), both hands free, standing, for the less sporty (fitness under BELLY_FIT 0.45) or drunk (over 0.4): hands on the edge, a push up till the hips are just over it (feet BELLY_DROP 0.9 below the top), the upper body lies flat over it (forearms on top; `Body.belly_over`, BELLY_PITCH 1.0 rad added to the bend in `body_pose.c`), wriggling on a little, a knee up, standing up. BELLY_TIME 2.6 s fresh. Checked on a 1.3 m wall. + 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). @@ -425,7 +428,7 @@ Most important first. **Body and moving** - Obstacle approach, still to do: thin round logs (under 0.2 m) are still stepped over; a step in between on top of something unstable (if clumsy); NPCs: pull up on their own for their own reasons (now only following a leader), jumping onto things -- Climbing rework, still to do: another way up by height, surface and person: belly first and roll (in: one hand first, the knee up, the other foot next to it; sitting on it and swinging the legs up) +- Climbing rework, still to do: another way up by height, surface and person: rolling over the edge (lying on it, rolled onto the top) (in: one hand first, the knee up, the other foot next to it; sitting on it and swinging the legs up; belly first) - Balance: hips over the feet, look for stable footing, play with balance - Personal movement styles, still to do: gesture variants; stepping over and climbing their own way; sporty ones more elegant (walking styles are in) - More gestures and feelings to pick personalities from: the lists in Body / Fidgets and Gestures can grow @@ -449,4 +452,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.22.0 (build 6c2f7b9)` +State of `entropie 2.23.0 (build 43b0331)` diff --git a/entropie/commit_message.txt b/entropie/commit_message.txt index a0d247c..e0d62fe 100644 --- a/entropie/commit_message.txt +++ b/entropie/commit_message.txt @@ -1,4 +1,4 @@ -entropie 2.22.0: the leading shoulder +entropie 2.23.0: belly first -- Climbing a high ledge: the shoulder of the hand that reaches first turns - ahead, easing back as the other hand follows +- Chest high ledges: the less sporty (or drunk) push up onto the belly, lie + over the edge, bring a knee up and stand up diff --git a/entropie/src/people/body.h b/entropie/src/people/body.h index fe7598f..fb79485 100644 --- a/entropie/src/people/body.h +++ b/entropie/src/people/body.h @@ -181,7 +181,8 @@ typedef struct { bool replant; /* plant the feet again next update */ bool pulling_up; /* climbing up over an edge (on_ladder too): the legs still keep clear of it */ float pull_knees; /* ... its knees up and out, eased (0..1) */ - float reach_bend, reach_bend_v; /* ... and the back bends over as far as it takes to keep the hands on it */ + float reach_bend, reach_bend_v; /* ... and the back bends over as far as it takes to keep the hands on it ... */ + float belly_over; /* ... or lies flat over the edge on the belly (0..1) */ float fitness; /* how sporty (0..1): runs smoother, steps over things surer */ float bob, bob_v; /* running: the body's rise and fall with each stride (sprung, -1..1) */ Vec3 shift; /* move the character here when getting up (taken by the world) */ diff --git a/entropie/src/people/body_pose.c b/entropie/src/people/body_pose.c index 1397a4b..da0d17d 100644 --- a/entropie/src/people/body_pose.c +++ b/entropie/src/people/body_pose.c @@ -113,6 +113,7 @@ static Vec3 reachPole(Vec3 shoulder, Vec3 palm, float sign) { } /* Damped spring step towards a target. */ +#define BELLY_PITCH 1.0f /* rad the body bends forward lying over an edge on the belly */ #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) { @@ -567,6 +568,8 @@ static void solveStanding(Body *b, Vec3 position, Vec3 facing, float s, float dt pitch -= SWING_ARCH * up * both; } } + /* Belly first over an edge: the upper body lies flat over it */ + pitch += BELLY_PITCH * b->belly_over; /* Pulling up onto something: the back bends over the edge as far as it takes to keep both hands on it (the shoulders come over the hands) */ { diff --git a/entropie/src/people/climb.c b/entropie/src/people/climb.c index 268d30f..c44fea6 100644 --- a/entropie/src/people/climb.c +++ b/entropie/src/people/climb.c @@ -10,6 +10,11 @@ #define SIT_HIGH 1.05f /* ... up to this */ #define SIT_FIT 0.45f /* ... for those less sporty than this (or old: slow on their feet) */ #define SIT_TIME 3.2f /* s it takes (fresh) */ +#define BELLY_LOW 1.0f /* the belly way: ledges this high (scaled) ... */ +#define BELLY_HIGH 1.55f /* ... up to this (higher: hanging on and pulling up) ... */ +#define BELLY_FIT 0.45f /* ... for those less sporty than this (or drunk) */ +#define BELLY_DROP 0.9f /* lying over it: the feet this far below the edge (scaled: the hips just over it) */ +#define BELLY_TIME 2.6f /* s it takes (fresh) */ #define REACH_TURN 0.35f /* rad the shoulders turn, the first hand's side going up ahead */ #define CLIMB_OVER 0.5f /* ... from this high over it at the body: the way there is clear */ @@ -108,6 +113,16 @@ int Climb_start(const World *world, Object *p, float top, Vec3 probe) { p->climb_move.yaw0 = p->rotation.y; p->climb_move.swing = p->main_hand == HAND_LEFT ? -1.0f : 1.0f; if (p->climb_move.sit_way) p->climb_move.time = SIT_TIME / fmaxf(vigor, 0.4f); + /* chest high and not so sporty (or drunk): pushed up onto the belly, lying over it, a knee up, stand up */ + bool hands_free = p->hands.state[HAND_LEFT] == HAND_FREE && p->hands.state[HAND_RIGHT] == HAND_FREE; + p->climb_move.belly_way = !p->climb_move.sit_way && hands_free && p->is_grounded && rise > BELLY_LOW * s && rise < BELLY_HIGH * s + && (p->fitness < BELLY_FIT || p->drunk > 0.4f); + p->climb_move.belly = 0.0f; + if (p->climb_move.belly_way) { + p->climb_move.time = BELLY_TIME / fmaxf(vigor, 0.4f); + p->climb_move.hang = p->position.y; + if (!hard) p->needs.stamina = fmaxf(0.0f, p->needs.stamina - 0.02f * rise / s); + } Climb_noteFeet(p); p->climbing = true; p->velocity = vec3_zero(); @@ -249,10 +264,17 @@ bool Climb_update(const World *world, Object *p, float dt) { float t = clampf(c->t, 0.0f, 1.0f); const Vec3 a = c->from, b = c->to; const float hang = c->hang; - bool high = hang > a.y + 0.02f || c->time > 1.2f; + bool high = hang > a.y + 0.02f || c->time > 1.2f || c->belly_way; float y, over; float knees = 0.0f; - if (high) { /* up to hang on (a little hop), hang a moment, pull up, then over the edge */ + if (c->belly_way) { /* a push up on the arms, the belly onto the edge, lying over it, a knee up onto it, standing up */ + float push = smoothstepf(0.1f, 0.34f, t), rise = smoothstepf(0.56f, 0.88f, t); + float belly_y = fminf(b.y - BELLY_DROP * s, a.y + 0.6f * s); + y = lerpf(lerpf(a.y, belly_y, push), b.y + 0.02f, rise); + over = 0.12f * smoothstepf(0.3f, 0.5f, t) + 0.88f * smoothstepf(0.62f, 1.0f, t); /* (wriggling on a little, then onto it) */ + c->belly = smoothstepf(0.22f, 0.4f, t) * (1.0f - smoothstepf(0.62f, 0.92f, t)); + knees = 0.7f * smoothstepf(0.58f, 0.78f, t); + } else if (high) { /* up to hang on (a little hop), hang a moment, pull up, then over the edge */ /* pulled up till the arms press down on it (hips near the edge), then the knee comes up and you rise onto it - the hands stay on it all along */ float grab = smoothstepf(0.0f, 0.18f, t), pull = smoothstepf(0.28f, 0.62f, t), rise = smoothstepf(0.56f, 0.88f, t); @@ -281,6 +303,7 @@ bool Climb_update(const World *world, Object *p, float dt) { Vec3 before = vec3_add(c->edge, vec3_add(vec3_scale(fwd, -0.12f * s), vec3(0.0f, 0.1f * s, 0.0f))); /* (coming over the edge the hands go on ahead onto the top: pressed flat on it, under the shoulders) */ Vec3 on = vec3_add(c->edge, vec3_scale(fwd, 0.35f * s * smoothstepf(0.55f, 0.9f, t))); + if (c->belly_way) on = vec3_add(c->edge, vec3_scale(fwd, 0.3f * s * smoothstepf(0.25f, 0.45f, t) + 0.1f * s * smoothstepf(0.6f, 0.9f, t))); /* (forearms flat on it, lying over) */ Hands_holdEdge(p, vec3_lerp(before, on, onto), vec3_scale(c->across, lerpf(1.9f, 1.0f, onto)), knees); /* (one hand reaches up first, the other after it - the sporty quicker; that shoulder goes ahead) */ p->hands.edge_lead = p->main_hand; diff --git a/entropie/src/world/object.h b/entropie/src/world/object.h index c9f4deb..37cd252 100644 --- a/entropie/src/world/object.h +++ b/entropie/src/world/object.h @@ -127,6 +127,8 @@ typedef struct { bool sit_now; /* ... sitting on it right now (the body sits: see world.c) ... */ float yaw0; /* ... facing the ledge when it started (rotation.y) */ float swing; /* ... which way round the legs come up (+1 / -1) */ + bool belly_way; /* chest high, not so sporty (or drunk): a push up onto the belly, lying over the edge, a knee up, stand up ... */ + float belly; /* ... lying over it this much right now (0..1: the body bends over, see world.c) */ } ClimbMove; typedef struct Object { diff --git a/entropie/src/world/world.c b/entropie/src/world/world.c index 22e59f9..c8635ec 100644 --- a/entropie/src/world/world.c +++ b/entropie/src/world/world.c @@ -888,6 +888,7 @@ static void animateCharacter(World *world, Object *o, float dt) { const bool sit_climb = o->climbing && o->climb_move.sit_way; /* (the careful way up: sitting on it, not pulling up) */ o->body.on_ladder = o->on_ladder != NULL || (o->climbing && !sit_climb); /* (or pulling up over a ledge) */ o->body.pulling_up = o->climbing && o->on_ladder == NULL && !sit_climb; + o->body.belly_over = o->climbing && o->climb_move.belly_way ? o->climb_move.belly : 0.0f; o->body.fitness = o->fitness; o->body.sulk = o->ai.annoyed; o->body.sit_goal = (o->sitting && !o->is_held && !settling) || (sit_climb && o->climb_move.sit_now) ? 1.0f : 0.0f; /* cross-legged, or on a seat */