traza/types.h

295 lines
5.8 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 <stdio.h>
#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 */