#ifndef RENDER_SHAPES_INTERNAL_H #define RENDER_SHAPES_INTERNAL_H /* * Inside the shapes (shapes.c, shapes_props.c): cell sizes, the painted * palette and the building blocks both share. Not for use outside. */ #include "render/shapes.h" #include /* * Every surface is subdivided into cells of at most CELL_SIZE so the * vertex shader can bend straight edges into hand-drawn lines. */ #define CELL_SIZE 0.75f /* Boxes use a finer cell that divides the 0.5 m building grid, so walls that touch share their vertices exactly (no cracks along the seams). */ #define BOX_CELL 0.5f /* ---------- Palettes (painted, slightly desaturated tones) ---------- */ enum { FACE_BACK, FACE_FRONT, FACE_LEFT, FACE_RIGHT, FACE_BOTTOM, FACE_TOP, FACE_COUNT }; #define CREAM { 0.93f, 0.88f, 0.76f } #define EARTH { 0.52f, 0.36f, 0.22f } #define TERRACOTTA { 0.88f, 0.52f, 0.30f } /* Single color for round shapes: the palette's first face. */ typedef struct { Vec3 p; /* on the middle line */ Vec3 side; /* across, to the left; longer at corners so the edges stay parallel */ float along; /* meters from the start */ } RoadRow; extern const Vec3 COLOR_BARK; extern const Vec3 COLOR_LEAVES; extern const Vec3 COLOR_STEEL; void shapes_addBox(MeshBuilder *b, Vec3 center, Vec3 size, const Vec3 colors[FACE_COUNT]); /* A lumpy rock round center (half its size each way), its colour shaded a little. */ void shapes_addRock(MeshBuilder *b, Vec3 center, Vec3 half, unsigned *seed, Vec3 color); void shapes_addTube(MeshBuilder *b, float base_y, float r_bottom, float r_top, float height, int segments, Vec3 color, bool caps); /* Box in one color. */ static inline void addBlock(MeshBuilder *b, Vec3 center, Vec3 size, Vec3 color) { Vec3 colors[FACE_COUNT]; for (int f = 0; f < FACE_COUNT; f++) colors[f] = color; shapes_addBox(b, center, size, colors); } /* The foot of a trunk of radius r standing on the ground at ground_y: flaring out towards it (up to top) and roots running into it. A tree and the stump left of it get the same foot from the same seed. */ void shapes_addTrunkFoot(MeshBuilder *b, float r, float ground_y, float top, unsigned seed, int segments); /* The sawn face at the foot of a felled trunk (y = 0). */ void shapes_addCutEnd(MeshBuilder *b, float r); /* Small deterministic random numbers for scattering shards. */ static inline float scatter(unsigned *seed) { *seed = *seed * 1664525u + 1013904223u; return (float)(*seed >> 8) / 16777216.0f; } /* Height of the ground at a point of the mesh, relative to its origin. */ static inline float groundAt(ShapeGround g, float x, float z) { return g.height(g.ctx, g.origin.x + x, g.origin.z + z) - g.origin.y; } /* Moves the vertices added since first by m (points and normals). */ static inline void transformSince(MeshBuilder *b, size_t first, Mat4 m) { for (size_t v = first; v < b->vertex_count; v++) { b->vertices[v].position = mat4_mul_point(m, b->vertices[v].position); b->vertices[v].normal = vec3_normalize(mat4_mul_dir(m, b->vertices[v].normal)); } } #endif /* RENDER_SHAPES_INTERNAL_H */