#ifndef RENDER_FIGURE_H #define RENDER_FIGURE_H /* * 2D painted people (see assets/shaders/figure.frag). * * The game poses a skeleton (people/body_pose.c); the renderer draws a smooth body * around it on a card facing the viewer. */ #include #include "math/linalg.h" typedef enum { HAIR_SHORT, HAIR_LONG, } HairStyle; typedef struct { Vec3 skin; Vec3 hair; Vec3 shirt; Vec3 pants; Vec3 shoes; float height; /* meters */ HairStyle hair_style; bool long_sleeves; int garment; /* GARMENT_*: what's on the legs */ int top; /* TOP_*: the shirt on, or off (working in the sun), or a jacket over it (cold nights) */ Vec3 jacket; /* the jacket's colour */ bool jacket_tied; /* the jacket off and along with them: tied round the waist by its sleeves */ float belly; /* 0 .. 1: a belly (Kurti's) */ bool keeps_shirt; /* never takes the shirt off, sun or no sun */ float wet; /* 0 .. 1: clothes and hair wet from the rain (darker) */ bool hoodie; /* the jacket has a hood ... */ bool hood_up; /* ... pulled up over the head (rain) */ int hat; /* HAT_*: on the head (off under a hood) ... */ Vec3 hat_color; /* ... its colour */ int cast; /* a plaster cast: 0 none, 1 left forearm, 2 right forearm, 3 left shin, 4 right shin */ } FigureLook; enum { TOP_SHIRT, TOP_BARE, TOP_CROP, TOP_JACKET }; /* A cap (a brim in front: the wind takes it easily) or a knitted beanie (stays on). */ enum { HAT_NONE, HAT_CAP, HAT_BEANIE }; /* Trousers (pants colour), shorts (knee-length), a skirt (pants colour) or a dress (shirt colour). */ enum { GARMENT_TROUSERS, GARMENT_SHORTS, GARMENT_SKIRT, GARMENT_DRESS }; /* * Joints in figure space: meters, origin between the feet on the ground, * x = figure's right, y = up, z = figure's forward. * Keep in sync with the J_* constants in figure.frag. */ typedef enum { JOINT_PELVIS, JOINT_CHEST, JOINT_NECK, JOINT_HEAD, JOINT_HIP_L, JOINT_KNEE_L, JOINT_ANKLE_L, JOINT_TOE_L, JOINT_HIP_R, JOINT_KNEE_R, JOINT_ANKLE_R, JOINT_TOE_R, JOINT_SHOULDER_L, JOINT_ELBOW_L, JOINT_WRIST_L, JOINT_HAND_L, JOINT_SHOULDER_R, JOINT_ELBOW_R, JOINT_WRIST_R, JOINT_HAND_R, JOINT_COUNT } Joint; /* Face paint, all 0..1 except brow and smile (-1..1). */ typedef struct { float mouth; /* open */ float eyelids; /* closed */ float brow; /* -1 = inner ends up (shy, sad) .. 1 = raised */ float smile; /* -1 = frown .. 1 = smile */ float gaze; /* -1 = eyes down .. 1 = up */ } Face; typedef struct { Vec3 joints[JOINT_COUNT]; Vec3 head_forward; /* where the face points (unit, figure space) */ Vec3 head_up; /* top of the head (unit) */ Vec3 chest_forward; /* front of the torso (unit) */ Vec3 waist_bend; /* the waist off the straight line from pelvis to chest: the back curves */ Face face; /* A stream from the body to the ground: pee or sick (4 points of an arc) */ Vec3 stream[4]; int stream_kind; /* STREAM_NONE / STREAM_PEE / STREAM_VOMIT */ float stream_width; /* meters */ Vec3 uri_a, uri_b; /* a Urinella held to the body (figure space): the wide end, the spout ... */ bool uri; /* ... shown */ Vec3 cig_a, cig_tip; /* a cigarette (figure space): the end at the hand / lips, the burning end ... */ float cig_glow; /* ... how it glows (-1: no cigarette, 0: not lit .. 1: a drag) */ float undress; /* to pee: squatting trousers down / skirt up (0..1); standing fly open / skirt lifted in front (-1..0) */ int species; /* FIGURE_PERSON, or FIGURE_DOG: the joints are her body (see people/dog.c) */ Vec3 tail_a, tail_b; /* the dog's tail */ } Skeleton; enum { FIGURE_PERSON, FIGURE_DOG }; enum { STREAM_NONE, STREAM_PEE, STREAM_VOMIT, STREAM_WATER }; typedef struct { Vec3 position; /* feet, world space */ Vec3 facing; /* horizontal unit vector (figure's forward) */ FigureLook look; Skeleton skeleton; } FigurePose; /* A few painted outfits; any index works (wraps around). */ FigureLook Figure_wardrobe(int index); /* Figure space <-> world space */ Vec3 Figure_toWorld(Vec3 position, Vec3 facing, Vec3 local); Vec3 Figure_toLocal(Vec3 position, Vec3 facing, Vec3 world); #endif /* RENDER_FIGURE_H */