#ifndef TYPEDEFS #define TYPEDEFS typedef double scalar; typedef unsigned char byte; typedef scalar grid3x3[3][3]; typedef scalar grid4x4[4][4]; #endif /* TYPEDEFS */ #ifdef SUB_INCLUDE_TYPES #undef SUB_INCLUDE_TYPES STRUCT(rgb) FIELD(r, byte) FIELD(g, byte) FIELD(b, byte) FIELD(a, byte) END_STRUCT STRUCT(vec2) FIELD(x, scalar) FIELD(y, scalar) END_STRUCT STRUCT(vec3) FIELD(x, scalar) FIELD(y, scalar) FIELD(z, scalar) END_STRUCT STRUCT(vec4) FIELD(x, scalar) FIELD(y, scalar) FIELD(z, scalar) FIELD(w, scalar) END_STRUCT STRUCT(mat3x3) FIELD(nums, grid3x3) END_STRUCT STRUCT(mat4x4) FIELD(nums, grid4x4) END_STRUCT STRUCT(camera) FIELD(znear, scalar) FIELD(pos, vec3) FIELD(front, vec3) FIELD(up, vec3) FIELD(right, vec3) FIELD(yaw, scalar) FIELD(pitch, scalar) END_STRUCT STRUCT(triangle2) FIELD(a, vec2) FIELD(b, vec2) FIELD(c, vec2) END_STRUCT STRUCT(triangle3) FIELD(a, vec3) FIELD(b, vec3) FIELD(c, vec3) END_STRUCT #else #include #define STRUCT(N) typedef struct N N; struct N { #define END_STRUCT }; #define FIELD(N, T) T N; #define SUB_INCLUDE_TYPES #include __FILE__ /* undefs to get rid of redef warnings */ #undef STRUCT #undef FIELD #undef END_STRUCT #ifdef TYPES_IMPL void print_grid(size_t y_sz, size_t x_sz, scalar grid[y_sz][x_sz]) { printf("\n"); for (size_t y = 0; y < y_sz; y++) { for (size_t x = 0; x < x_sz; x++) { printf(" %f ", grid[y][x]); } printf("\n"); } } void print_scalar(scalar d) { printf(" %f ", d); } void print_byte(byte b) { printf(" %d ", b); } void print_grid3x3(grid3x3 grid) { print_grid(3, 3, grid); } void print_grid4x4(grid4x4 grid) { print_grid(4, 4, grid); } #define STRUCT(N) \ void print_##N (N s) { \ printf("(" #N ") {"); #define FIELD(N, T) \ print_##T(s . N); #define END_STRUCT \ printf("}\n"); \ } #define SUB_INCLUDE_TYPES #include __FILE__ // undefs to get rid of redef warnings #undef STRUCT #undef FIELD #undef END_STRUCT const vec3 UP = {0, 1, 0}; vec3 vec3_add(vec3 u, vec3 v) { return (vec3) { .x = u.x + v.x, .y = u.y + v.y, .z = u.z + v.z, }; } vec3 vec3_sub(vec3 u, vec3 v) { return (vec3) { .x = u.x - v.x, .y = u.y - v.y, .z = u.z - v.z, }; } vec3 vec3_scalar_mul(vec3 v, scalar s) { return (vec3) { .x = v.x * s, .y = v.y * s, .z = v.z * s, }; } vec3 vec3_cross(vec3 u, vec3 v) { return (vec3) { .x = u.y * v.z - u.z * v.y, .y = u.z * v.x - u.x * v.z, .z = u.x * v.y - u.y * v.x, }; } scalar vec3_dot(vec3 u, vec3 v) { return u.x * v.x + u.y * v.y + u.z * v.z; } vec3 vec3_normalize(vec3 u) { scalar len = sqrt(u.x*u.x + u.y*u.y + u.z*u.z); return (vec3) { .x = u.x / len, .y = u.y / len, .z = u.z / len, }; } vec4 vec3_to_vec4(vec3 v) { return (vec4){v.x, v.y, v.z, 1.0}; } vec4 vec4_add(vec4 u, vec4 v) { return (vec4) { .x = u.x + v.x, .y = u.y + v.y, .z = u.z + v.z, .w = u.w + v.w, }; } vec4 vec4_sub(vec4 u, vec4 v) { return (vec4) { .x = u.x - v.x, .y = u.y - v.y, .z = u.z - v.z, .w = u.w - v.w, }; } void mat_mul(size_t dim, scalar m1[dim][dim], scalar m2[dim][dim], scalar out[dim][dim]) { for (size_t i = 0; i < dim; i++) { for (size_t j = 0; j < dim; j++) { for (size_t k = 0; k < dim; k++) { out[i][j] += m1[i][k] * m2[k][j]; } } } } mat3x3 mat3x3_mul(mat3x3 r, mat3x3 s) { mat3x3 ret = { .nums = {{0}} }; mat_mul(3, r.nums, s.nums, ret.nums); return ret; } mat4x4 mat4x4_mul(mat4x4 r, mat4x4 s) { mat4x4 ret = { .nums = {{0}} }; mat_mul(4, r.nums, s.nums, ret.nums); return ret; } vec3 vec3_mat3x3_mul(vec3 v, mat3x3 r) { return (vec3) { .x = (v.x * r.nums[0][0]) + (v.y * r.nums[0][1]) + (v.z * r.nums[0][2]), .y = (v.x * r.nums[1][0]) + (v.y * r.nums[1][1]) + (v.z * r.nums[1][2]), .z = (v.x * r.nums[2][0]) + (v.y * r.nums[2][1]) + (v.z * r.nums[2][2]) }; } vec4 vec4_mat4x4_mul(vec4 v, mat4x4 r) { return (vec4) { .x = (v.x * r.nums[0][0]) + (v.y * r.nums[0][1]) + (v.z * r.nums[0][2]) + (v.w * r.nums[0][3]), .y = (v.x * r.nums[1][0]) + (v.y * r.nums[1][1]) + (v.z * r.nums[1][2]) + (v.w * r.nums[1][3]), .z = (v.x * r.nums[2][0]) + (v.y * r.nums[2][1]) + (v.z * r.nums[2][2]) + (v.w * r.nums[2][3]), .w = (v.x * r.nums[3][0]) + (v.y * r.nums[3][1]) + (v.z * r.nums[3][2]) + (v.w * r.nums[3][3]) }; } mat4x4 lookat(camera cam) { /* vec3 dir = vec3_add(cam.pos, cam.front); */ return mat4x4_mul( (mat4x4) { .nums = {{cam.right.x, cam.right.y, cam.right.z, 0}, {cam.up.x, cam.up.y, cam.up.z, 0}, {cam.front.x, cam.front.y, cam.front.z, 0}, {0, 0, 0, 1}} }, (mat4x4) { .nums = {{1, 0, 0, -cam.pos.x}, {0, 1, 0, -cam.pos.y}, {0, 0, 1, -cam.pos.z}, {0, 0, 0, 1}} } ); } void update_camera(camera *cam) { scalar α = cos(cam->pitch); scalar β = sin(cam->pitch); scalar x = cos(cam->yaw); scalar y = sin(cam->yaw); vec3 front = { .x = α * y, .y = β, .z = -α * x, }; cam->front = vec3_normalize(front); cam->right = vec3_normalize(vec3_cross(cam->front, UP)); cam->up = vec3_normalize(vec3_cross(cam->right, cam->front)); } #endif #endif /* SUB_INCLUDE_TYPES */