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/src/render/shapes.h raw
#ifndef RENDER_SHAPES_H
#define RENDER_SHAPES_H
/*
* Procedural meshes. All meshes are centered on X/Z.
* Buildings and trees are described by size structs so the game code can
* build matching colliders from the same numbers.
*/
#include <stdbool.h>
#include "math/linalg.h"
#include "render/mesh.h"
typedef enum {
PALETTE_STANDARD, /* white */
PALETTE_GROUND, /* brown sides, grass top */
PALETTE_MODERN, /* one bright color per face */
PALETTE_WARM, /* orange */
} Palette;
/* Box centered on the origin. */
Mesh Shapes_box(Vec3 size, Palette palette);
/* A white unit block (tinted when drawn): wood chips, sawdust. */
Mesh Shapes_chip(void);
/* A ball of smoke (1 across, white: tinted), drawn soft and see-through (Renderer_drawPuff). */
Mesh Shapes_puff(void);
/* Upright cylinder centered on the origin (single palette color). */
Mesh Shapes_cylinder(float diameter, float height, int segments, Palette palette);
typedef struct {
float trunk_height;
float trunk_radius;
int leaf_layers; /* stacked cones, 0.6 apart, each 0.8 high */
float leaf_radius; /* radius of the lowest cone (fruit trees: the widest) */
bool fruit; /* a round crown with apples instead of a pine */
bool cut; /* felled: no foot, the cut face at its end (else the foot flares into roots) */
bool old; /* old and half dead: gaps in the crown, brown dead layers, the top snapped off (a bare snag) */
unsigned seed; /* the foot's roots (Shapes_stump makes the same ones from the same seed) */
} TreeSize;
#define TREE_FRUIT_LAYERS 8 /* layers of a whole fruit tree crown */
/* Total height of a tree (trunk plus cones). */
float Shapes_treeHeight(TreeSize size);
/* Trunk with stacked cone layers; base at y = 0. Seed for a spot: Shapes_treeSeed. */
unsigned Shapes_treeSeed(float x, float z);
Mesh Shapes_tree(TreeSize size);
/* Brick walls and a slate roof, or a farm hall: light walls, gray, red or solar roof. */
typedef enum {
BUILDING_BRICK,
BUILDING_PLASTER, /* light walls, light grey roof */
BUILDING_PLASTER_DARK, /* light walls, dark roof */
BUILDING_HALL, BUILDING_HALL_RED, BUILDING_HALL_SOLAR
} BuildingLook;
typedef struct {
float length; /* along X, the roof ridge direction */
float width; /* along Z */
float wall_height;
float roof_height; /* ridge height above the walls */
BuildingLook look;
bool door_set; /* the front door at door_x (along X) instead of near the -X end */
float door_x;
} BuildingSize;
typedef enum { BOTTLE_BEER, BOTTLE_SPIRITS, BOTTLE_WATER, BOTTLE_COLA, BOTTLE_ORANGE, BOTTLE_MATE } BottleStyle;
/* Bottle centered on the origin: glass, label, neck and cap.
Brown beer bottle, clear with a red cap for spirits, light blue for water. */
Mesh Shapes_bottle(float diameter, float height, BottleStyle style);
/* Food, centered on the origin. */
Mesh Shapes_apple(float diameter);
/* Alice's toys: variant 0 a ball (size.x across), 1 a rope with knots (size.x long, size.y thick). */
Mesh Shapes_toy(int variant, Vec3 size);
Mesh Shapes_bread(Vec3 size);
/* Supplies, centered on the origin: a crate heaped with apples, a water barrel,
a cool box (sausages), a carton with a roll of garbage bags. */
Mesh Shapes_appleCrate(Vec3 size);
Mesh Shapes_barrel(float diameter, float height);
Mesh Shapes_coolBox(Vec3 size);
Mesh Shapes_bagCarton(Vec3 size);
/* A sausage along Y, centered; brown and striped once grilled. */
Mesh Shapes_sausage(float length, bool grilled);
/* Fireplace: a ring of stones round a bed of ashes, base at y = 0, and the
wooden tripod over it (the grill hangs from it). */
Mesh Shapes_fireplace(float diameter);
/* Where the tripod's pole k (0..2) stands, from the fireplace's middle. */
Vec3 Shapes_tripodFoot(float diameter, int k);
#define TRIPOD_OUT 1.3f /* its poles stand this far outside the stones (they don't catch fire) ... */
#define TRIPOD_PAST 0.6f /* ... and reach this far past the top */
/* Flames over the middle, base at y = 0. Their colors glow in the dark. */
Mesh Shapes_flames(void);
/* Litter, centered on the origin; kind as in OBJ_TRASH (a palette). */
Mesh Shapes_trash(Palette kind, unsigned seed);
/* A cigarette butt: the filter and a burnt end. */
Mesh Shapes_butt(void);
/* Size of a piece of litter. */
Vec3 Shapes_trashSize(Palette kind);
/* A black garbage bag, centered; fullness 0 (empty) .. 1 (full). */
Mesh Shapes_bag(float fullness);
Vec3 Shapes_bagSize(float fullness);
/* A glowing dashed frame lying at y = 0 (length along X, depth along Z): "here". */
Mesh Shapes_marker(float length, float depth);
/* The grill: chain and grate hanging below the top of the tripod (origin). */
Mesh Shapes_grill(void);
#define GRILL_TOP 3.9f /* the tripod's rods meet this high over the fire */
#define GRILL_DROP 3.3f /* the grate hangs this far below */
typedef enum {
FURN_WORKBENCH, FURN_TOOLWALL, FURN_SHELF, FURN_STOVE, FURN_COUNTER, FURN_TABLE,
FURN_CHAIR, FURN_BENCH, FURN_CAR, FURN_TIRES, FURN_TOILET, FURN_TAP, FURN_ASHTRAY, FURN_GATE, FURN_SMOKES, FURN_BAR, FURN_COUNT
} FurnitureKind;
#define SEAT_HEIGHT 0.45f /* chairs and log benches */
/* Furniture standing on y = 0, size = its box (length along X, height, depth along Z).
Fronts face +Z. */
Mesh Shapes_furniture(FurnitureKind kind, Vec3 size);
/* The ashtray with this many butts in it (a few show, a heap when full). */
Mesh Shapes_ashtray(Vec3 size, int butts);
/* Ivy up a wall (at z = 0, facing +Z), this wide and high. */
Mesh Shapes_ivy(float width, float height, unsigned seed);
/* Your estate car standing on y = 0, nose to +Z (CAR_WIDTH x about 1.45 m x CAR_LENGTH); the boot open:
the hatch up. */
#define CAR_WIDTH 1.78f
#define CAR_LENGTH 4.6f
#define CAR_COLOR ((Vec3){ 0.50f, 0.55f, 0.46f }) /* (an old faded green) */
Mesh Shapes_car(Vec3 color, bool boot_open);
/* ... seen from the driver's seat: the bonnet, the dashboard, the wheel, the pillars, the roof. */
Mesh Shapes_carInside(Vec3 color);
/* Rain: a thin light streak at each drop (world space), len long. */
Mesh Shapes_rain(const Vec3 *drops, int n, float len, Vec3 lean);
/* A crate of bottles (centred): variant 0 beer, 1 water, 2 soda (cola and orange), 3 mate; this many bottles in it. */
#define CRATE_SIZE_X 0.40f
#define CRATE_SIZE_Y 0.30f
#define CRATE_SIZE_Z 0.30f
/* What's in each slot of a crate: 0 nothing, else a bottle - its kind
(CRATE_KIND) and how many sips are left in it (CRATE_SIPS, 0: an empty). */
#define CRATE_SLOTS 20
enum { BOTTLE_KIND_NONE, BOTTLE_KIND_BEER, BOTTLE_KIND_WATER, BOTTLE_KIND_COLA, BOTTLE_KIND_ORANGE, BOTTLE_KIND_MATE };
#define CRATE_SLOT(kind, sips) ((unsigned char)(((kind) & 7) | ((sips) << 3)))
#define CRATE_KIND(code) ((code) & 7)
#define CRATE_SIPS(code) ((code) >> 3)
Mesh Shapes_crate(int variant, const unsigned char *slots, int n);
/* An umbrella along Y, centred, length long: folded (a crook at the bottom), or
open (the canopy over the top end, radius across). */
/* shape: UMBRELLA_FOLDED, UMBRELLA_OPEN, UMBRELLA_INSIDE_OUT (blown: the canopy up like a cup, ribs bent) */
enum { UMBRELLA_FOLDED, UMBRELLA_OPEN, UMBRELLA_INSIDE_OUT };
Mesh Shapes_umbrella(float length, float radius, int shape, Vec3 color);
/* A floor's stage as far as it's built: stage (0 marked out .. 5 done) and how far into
it (0..1); width along X, depth along Z (the front at +Z), its colour for the paint and
the banners. The platform is STAGE_DECK high once the floor is in. */
#define STAGE_DECK 0.5f
Mesh Shapes_stage(int stage, float part, float width, float depth, Vec3 accent);
/* A hat lying about (HAT_CAP, HAT_BEANIE), its crown up, the cap's brim along +Z. */
Mesh Shapes_hat(int kind, Vec3 color);
/* Camping things (centred, lying along X): kind 0 a sleeping bag in its sack, 1 a foam mat rolled up,
2 a small tent in its bag, 3 a big one. */
Mesh Shapes_gear(int kind, Vec3 color);
/* The scythe (centred, its snath along Y, the blade at the bottom); a vineyard snail (on y = 0);
a log carved into a figure (on y = 0): kind 0 an owl, 1 a bear, 2 a mushroom man. */
Mesh Shapes_scythe(float length);
Mesh Shapes_snail(void);
/* The ambulance (the estate's shape: white, a red band, blue lights). */
Mesh Shapes_ambulance(void);
/* The big tree's rope from a to c (local), sagging; coil: the rest lying in loops at c. The throw line's bag. */
Mesh Shapes_rope(Vec3 a, Vec3 c, float sag, bool coil);
Mesh Shapes_throwBag(void);
/* A wooden phone pole this high (mast: the tall one), and the wires along n cross arms' middles (local);
down: torn, hanging to the ground (ground_y under each point, local; may be NULL). */
Mesh Shapes_phonePole(float height, bool mast);
Mesh Shapes_wires(const Vec3 *points, int n, bool down, const float *ground_y);
Mesh Shapes_sculpture(int kind, float diameter, float height);
/* The marker over who or what to go to next: a diamond, centred, this tall. */
Mesh Shapes_questMarker(float height, Vec3 color);
/* A party pavilion on y = 0 (centred): side x side, the eaves and the roof's peak this high, its canvas colour. */
Mesh Shapes_pavilion(float side, float eaves, float peak, Vec3 canvas);
/* Building material (centred, size = its box): kind 0 a strapped bundle of 8 boards (long along X),
1 a box of nails, 2 a box of screws, 3 a bucket of paint (size.x across). */
Mesh Shapes_material(int kind, Vec3 size);
/* A dome tent standing on y = 0, the door to +Z: big 0 small (two people
squeezed), 1 the big one. How far it's up: stage 0 laid out flat, 1 the
poles going in and up (progress 0..1), 2 the cover going over it (from the
back), 3 being pegged (pegs in), 4 standing. */
#define TENT_STAGES 5
#define TENT_W(big) ((big) ? 2.2f : 1.4f)
#define TENT_L(big) ((big) ? 2.4f : 2.1f)
#define TENT_H(big) ((big) ? 1.3f : 1.0f)
#define TENT_PEGS(big) ((big) ? 10 : 6)
Mesh Shapes_tent(int big, int stage, float progress, int pegs, Vec3 inner, Vec3 fly);
/* Where peg k goes (local, the tent's middle at 0, 0). */
void Shapes_tentPeg(int big, int k, float *x, float *z);
/* A pullover put down (see clothes.h), its colour: lay 0 spread out flat on the ground (y = 0 under it,
the neck to +Z, sleeves out), 1 hung over an edge along X (y = 0 its top; gap: how thick that edge is),
2 folded up (y = 0 under it). */
Mesh Shapes_pullover(int lay, Vec3 color, float gap);
/* A dachshund, its nose towards -Z, standing on y = 0: a plain body for picking it
out (she's drawn as a painted figure, see people/dog.c); her proportions. */
Mesh Shapes_dogBody(void);
#define DOG_HIP_Y 0.13f
#define DOG_HIP_X 0.055f
#define DOG_HIP_Z 0.20f
#define DOG_TAIL_Y 0.24f
#define DOG_TAIL_Z 0.27f
/* Garden hose: its nozzle (centered), and one piece of hose 1 m long along +Y from the origin. */
Mesh Shapes_hoseNozzle(void);
Mesh Shapes_hosePiece(void);
/* Duct tape round a piece of hose (like Shapes_hosePiece, a bit thicker, grey). */
Mesh Shapes_hoseTape(void);
/* A roll of duct tape, centered, lying flat. */
Mesh Shapes_tapeRoll(void);
/* A watering can, centered, spout towards +Z. */
Mesh Shapes_wateringCan(void);
#define TAP_HEIGHT 0.8f /* where the hose comes out of the tap */
#define SMOKES_PACKS 20 /* a pack from the cigarette machine (FURN_SMOKES: on a wall, back at z = -hz) */
/* A telescopic ladder: rungs on tubes that slide into each other. Local +Y up
along it from the feet (y = 0), rungs along X. extend 0 = slid together .. 1 = out. */
#define LADDER_RUNGS 20
#define LADDER_WIDTH 0.48f
float Shapes_ladderLength(float extend);
/* Height of rung k (0 = the lowest) along the ladder. */
float Shapes_ladderRung(float extend, int k);
Mesh Shapes_ladder(float extend);
/* The folding ladder (two hinged sections): unfold 0 = folded .. 1 = straight. */
#define FOLD_RUNGS 9 /* per section */
float Shapes_foldLadderLength(float unfold);
float Shapes_foldLadderRung(int k);
Mesh Shapes_foldLadder(float unfold);
/* The step ladder: a front leg with flat treads (+Y up it, +Z its front) and a
back leg hinged at the top. open 0 = folded flat .. 1 = standing (legs spread). */
#define STEP_TREADS 5 /* the top platform comes on top of these */
#define STEP_HINGE_Z -0.06f /* the back leg's hinge, behind the front leg */
float Shapes_stepLadderLength(void);
/* Tread k along the front leg; k = STEP_TREADS: the top platform. */
float Shapes_stepLadderRung(int k);
/* Angle between the legs (rad). */
float Shapes_stepLadderSpread(float open);
Mesh Shapes_stepLadder(float open);
/* A round bush, base at y = 0. */
Mesh Shapes_bush(float diameter, float height, unsigned seed);
/* A big waste container, centered on the origin. */
Mesh Shapes_bin(Vec3 size);
/* Ground under a decal: surface height at world (x, z), and where the mesh origin is. */
typedef struct {
float (*height)(const void *ctx, float x, float z);
const void *ctx;
Vec3 origin;
} ShapeGround;
/* A tree stump (centered), and the roots left when it's chopped out (lying on the ground). */
Mesh Shapes_stump(float diameter, float height, unsigned seed);
Mesh Shapes_roots(float diameter, unsigned seed, ShapeGround ground);
/* Log (a tree trunk without branches) centered on the origin, along Y. */
Mesh Shapes_log(float diameter, float length);
/* Cut-off branch along Y with a few twigs and leaves. */
Mesh Shapes_branch(float length);
/* Two sleepers on the ground for a woodpile (length along X, depth along Z). */
Mesh Shapes_woodpile(float length, float depth);
/* A half (parts 2) or quarter (parts 4) of a log along Y, centered on its
bounding box; the bark side faces +Z. */
Mesh Shapes_firewood(float diameter, float length, int parts);
/* Pruning shears along Y, blades up. */
Mesh Shapes_shears(float length);
/* Chainsaw: motor at the back, bar along -Z (forward). About 0.18 x 0.25 x 0.75 m. */
Mesh Shapes_chainsaw(void);
/* Axe centered on the origin: handle along Y, blade at the top towards +Z. */
Mesh Shapes_axe(float length);
/* Sick on the ground (following its bumps), and stink lines rising from the ground. */
Mesh Shapes_vomit(float radius, unsigned seed, ShapeGround ground);
Mesh Shapes_stink(float radius, unsigned seed, ShapeGround ground);
/* A painted line on a road: across offset from the middle, width, and
dash / gap lengths (gap 0: a solid line). */
typedef struct {
float offset, width, dash, gap;
} RoadLine;
/* Painted lines along a road (world x/z, y ignored), lying on the ground
(the road itself is part of the ground: see Site_surface). */
Mesh Shapes_roadLines(const Vec3 *points, int count, const RoadLine *lines, int line_count, ShapeGround ground);
/* Loose stones lying on a gravel road (or a gravelled patch) along points:
fewer in the ruts and the grassy middle of a road, bigger ones at the
edges (density: stones per square meter). */
Mesh Shapes_gravelStones(const Vec3 *points, int count, float width, float density, bool road, ShapeGround ground);
/* A loose stone, lumpy and flattened, centered (size = bounding box). */
Mesh Shapes_stone(Vec3 size, unsigned seed);
/* A flat square of water (centered, side length), its surface at y = 0. */
Mesh Shapes_water(float side);
/* A broken bottle: glass pieces in a beer puddle, lying at y = 0. */
Mesh Shapes_shards(float diameter, unsigned seed);
/* Walls with a gable roof; base at y = 0. Details adds windows and doors. */
Mesh Shapes_building(BuildingSize size, bool with_details);
/* A building made of parts (see world/manor.c): boxes, windows and doors on
the walls, gable roofs. */
typedef struct { Vec3 min, max; Vec3 color; bool brick; } ShapeSlab; /* brick: mortar courses on its sides */
typedef enum { OPENING_WINDOW, OPENING_PANE, OPENING_DOOR, OPENING_FRAME } OpeningKind;
typedef struct {
OpeningKind kind;
Vec3 at; /* on the wall face: a window's middle, a door's foot */
float yaw; /* turns its front (+Z) to yaw_front(yaw) (see linalg.h) */
float w, h;
Vec3 frame;
} ShapeOpening;
typedef struct {
Vec3 center; /* x, z of the middle */
float length, width, wall_top, roof_height; /* length along the ridge: X, or Z if across */
BuildingLook look;
bool across;
float valley; /* > 0: the ridge runs on this far past its +X end into a roof across it (valleys, no eaves) */
} ShapeRoof;
Mesh Shapes_structure(const ShapeSlab *slabs, int n_slabs, const ShapeOpening *openings, int n_openings,
const ShapeRoof *roofs, int n_roofs);
Vec3 Shapes_roofColor(BuildingLook look);
#endif /* RENDER_SHAPES_H */