295 lines
5.8 KiB
C
295 lines
5.8 KiB
C
#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 */
|