camera
This commit is contained in:
parent
a539bf2b8f
commit
f937f1cdbd
68
cube.obj
68
cube.obj
|
@ -1,46 +1,44 @@
|
|||
# Blender v2.93.5 OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib cube.mtl
|
||||
o Cube_Cube.002
|
||||
v -50.000000 -50.000000 50.000000
|
||||
v -50.000000 50.000000 50.000000
|
||||
v -50.000000 -50.000000 -50.000000
|
||||
v -50.000000 50.000000 -50.000000
|
||||
v 50.000000 -50.000000 50.000000
|
||||
v 50.000000 50.000000 50.000000
|
||||
v 50.000000 -50.000000 -50.000000
|
||||
v 50.000000 50.000000 -50.000000
|
||||
o Cube
|
||||
v 1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 1.000000
|
||||
vt 0.875000 0.500000
|
||||
vt 0.625000 0.750000
|
||||
vt 0.625000 0.500000
|
||||
vt 0.375000 1.000000
|
||||
vt 0.375000 0.750000
|
||||
vt 0.625000 0.000000
|
||||
vt 0.375000 0.250000
|
||||
vt 0.375000 0.000000
|
||||
vt 0.625000 0.250000
|
||||
vt 0.375000 0.500000
|
||||
vt 0.625000 0.500000
|
||||
vt 0.375000 0.750000
|
||||
vt 0.625000 0.750000
|
||||
vt 0.375000 1.000000
|
||||
vt 0.125000 0.750000
|
||||
vt 0.125000 0.500000
|
||||
vt 0.875000 0.500000
|
||||
vt 0.625000 1.000000
|
||||
vt 0.625000 0.250000
|
||||
vt 0.875000 0.750000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vt 0.625000 1.000000
|
||||
vn 0.0000 1.0000 0.0000
|
||||
usemtl None
|
||||
vn 0.0000 0.0000 1.0000
|
||||
vn -1.0000 0.0000 0.0000
|
||||
vn 0.0000 -1.0000 0.0000
|
||||
vn 1.0000 0.0000 0.0000
|
||||
vn 0.0000 0.0000 -1.0000
|
||||
s off
|
||||
f 2/1/1 3/2/1 1/3/1
|
||||
f 4/4/2 7/5/2 3/2/2
|
||||
f 8/6/3 5/7/3 7/5/3
|
||||
f 6/8/4 1/9/4 5/7/4
|
||||
f 7/5/5 1/10/5 3/11/5
|
||||
f 4/12/6 6/8/6 8/6/6
|
||||
f 2/1/1 4/4/1 3/2/1
|
||||
f 4/4/2 8/6/2 7/5/2
|
||||
f 8/6/3 6/8/3 5/7/3
|
||||
f 6/8/4 2/13/4 1/9/4
|
||||
f 7/5/5 5/7/5 1/10/5
|
||||
f 4/12/6 2/14/6 6/8/6
|
||||
f 5/1/1 3/2/1 1/3/1
|
||||
f 3/2/2 8/4/2 4/5/2
|
||||
f 7/6/3 6/7/3 8/8/3
|
||||
f 2/9/4 8/10/4 6/11/4
|
||||
f 1/3/5 4/5/5 2/9/5
|
||||
f 5/12/6 2/9/6 6/7/6
|
||||
f 5/1/1 7/13/1 3/2/1
|
||||
f 3/2/2 7/14/2 8/4/2
|
||||
f 7/6/3 5/12/3 6/7/3
|
||||
f 2/9/4 4/5/4 8/10/4
|
||||
f 1/3/5 3/2/5 4/5/5
|
||||
f 5/12/6 1/3/6 2/9/6
|
||||
|
|
86
iso.obj
86
iso.obj
|
@ -1,49 +1,48 @@
|
|||
# Blender v2.93.5 OBJ File: ''
|
||||
# www.blender.org
|
||||
mtllib iso.mtl
|
||||
o Icosphere_Icosphere.001
|
||||
v 0.000000 -100.000000 0.000000
|
||||
v 72.360733 -44.721951 52.572529
|
||||
v -27.638802 -44.721985 85.064926
|
||||
v -89.442619 -44.721561 0.000000
|
||||
v -27.638802 -44.721985 -85.064926
|
||||
v 72.360733 -44.721951 -52.572529
|
||||
v 27.638802 44.721985 85.064926
|
||||
v -72.360733 44.721951 52.572529
|
||||
v -72.360733 44.721951 -52.572529
|
||||
v 27.638802 44.721985 -85.064926
|
||||
v 89.442619 44.721561 0.000000
|
||||
v 0.000000 100.000000 0.000000
|
||||
v -16.245556 -85.065445 49.999527
|
||||
v 42.532269 -85.065422 30.901140
|
||||
v 26.286882 -52.573765 80.901161
|
||||
v 85.064789 -52.573593 0.000000
|
||||
v 42.532269 -85.065422 -30.901140
|
||||
v -52.572979 -85.065170 0.000000
|
||||
v -68.818939 -52.573620 49.999695
|
||||
v -16.245556 -85.065445 -49.999527
|
||||
v -68.818939 -52.573620 -49.999695
|
||||
v 26.286882 -52.573765 -80.901161
|
||||
v 95.105782 0.000000 30.901262
|
||||
v 95.105782 0.000000 -30.901262
|
||||
v 0.000000 0.000000 99.999992
|
||||
v 58.778561 0.000000 80.901672
|
||||
v -95.105782 0.000000 30.901262
|
||||
v -58.778561 0.000000 80.901672
|
||||
v -58.778561 0.000000 -80.901672
|
||||
v -95.105782 0.000000 -30.901262
|
||||
v 58.778561 0.000000 -80.901672
|
||||
v 0.000000 0.000000 -99.999992
|
||||
v 68.818939 52.573620 49.999695
|
||||
v -26.286882 52.573765 80.901161
|
||||
v -85.064789 52.573593 0.000000
|
||||
v -26.286882 52.573765 -80.901161
|
||||
v 68.818939 52.573620 -49.999695
|
||||
v 16.245556 85.065437 49.999527
|
||||
v 52.572979 85.065170 0.000000
|
||||
v -42.532269 85.065422 30.901140
|
||||
v -42.532269 85.065422 -30.901140
|
||||
v 16.245556 85.065437 -49.999527
|
||||
v 0.000000 -1.000000 0.000000
|
||||
v 0.723607 -0.447220 0.525725
|
||||
v -0.276388 -0.447220 0.850649
|
||||
v -0.894426 -0.447216 0.000000
|
||||
v -0.276388 -0.447220 -0.850649
|
||||
v 0.723607 -0.447220 -0.525725
|
||||
v 0.276388 0.447220 0.850649
|
||||
v -0.723607 0.447220 0.525725
|
||||
v -0.723607 0.447220 -0.525725
|
||||
v 0.276388 0.447220 -0.850649
|
||||
v 0.894426 0.447216 0.000000
|
||||
v 0.000000 1.000000 0.000000
|
||||
v -0.162456 -0.850654 0.499995
|
||||
v 0.425323 -0.850654 0.309011
|
||||
v 0.262869 -0.525738 0.809012
|
||||
v 0.850648 -0.525736 0.000000
|
||||
v 0.425323 -0.850654 -0.309011
|
||||
v -0.525730 -0.850652 0.000000
|
||||
v -0.688189 -0.525736 0.499997
|
||||
v -0.162456 -0.850654 -0.499995
|
||||
v -0.688189 -0.525736 -0.499997
|
||||
v 0.262869 -0.525738 -0.809012
|
||||
v 0.951058 0.000000 0.309013
|
||||
v 0.951058 0.000000 -0.309013
|
||||
v 0.000000 0.000000 1.000000
|
||||
v 0.587786 0.000000 0.809017
|
||||
v -0.951058 0.000000 0.309013
|
||||
v -0.587786 0.000000 0.809017
|
||||
v -0.587786 0.000000 -0.809017
|
||||
v -0.951058 0.000000 -0.309013
|
||||
v 0.587786 0.000000 -0.809017
|
||||
v 0.000000 0.000000 -1.000000
|
||||
v 0.688189 0.525736 0.499997
|
||||
v -0.262869 0.525738 0.809012
|
||||
v -0.850648 0.525736 0.000000
|
||||
v -0.262869 0.525738 -0.809012
|
||||
v 0.688189 0.525736 -0.499997
|
||||
v 0.162456 0.850654 0.499995
|
||||
v 0.525730 0.850652 0.000000
|
||||
v -0.425323 0.850654 0.309011
|
||||
v -0.425323 0.850654 -0.309011
|
||||
v 0.162456 0.850654 -0.499995
|
||||
vt 0.181819 0.000000
|
||||
vt 0.227273 0.078731
|
||||
vt 0.136365 0.078731
|
||||
|
@ -187,7 +186,6 @@ vn 0.3313 -0.9435 0.0000
|
|||
vn -0.0385 -0.6617 0.7488
|
||||
vn 0.1876 -0.7947 0.5773
|
||||
vn 0.4713 -0.6617 0.5831
|
||||
usemtl None
|
||||
s off
|
||||
f 1/1/1 14/2/1 13/3/1
|
||||
f 2/4/2 14/5/2 16/6/2
|
||||
|
|
262
main.c
262
main.c
|
@ -57,42 +57,30 @@ typedef struct {
|
|||
uint32_t *indices;
|
||||
} mesh;
|
||||
|
||||
vec3
|
||||
vec3_matrix3x3_multiply(vec3 v, matrix3x3 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])
|
||||
};
|
||||
}
|
||||
|
||||
camera
|
||||
new_camera(double znear, vec3 pos, vec3 target, vec3 up)
|
||||
new_camera(double znear, vec3 pos, vec3 up, double yaw, double pitch)
|
||||
{
|
||||
if (pos.x == target.x &&
|
||||
pos.y == target.y &&
|
||||
pos.z == target.z)
|
||||
die("cannot create camera with same target and position");
|
||||
|
||||
camera ret = {
|
||||
.znear = znear,
|
||||
.pos = pos,
|
||||
.target = target,
|
||||
.up = up,
|
||||
.yaw = yaw,
|
||||
.pitch = pitch
|
||||
};
|
||||
ret.dir = vec3_normalize(vec3_sub(pos, target));
|
||||
ret.right = vec3_normalize(vec3_cross(up, ret.dir));
|
||||
|
||||
update_camera(&ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
mesh
|
||||
new_mesh(uint32_t vertex_num,
|
||||
uint32_t tri_num,
|
||||
uint32_t index_num,
|
||||
vec3 vertices[],
|
||||
uint32_t indices[])
|
||||
new_mesh(
|
||||
uint32_t vertex_num,
|
||||
uint32_t tri_num,
|
||||
uint32_t index_num,
|
||||
vec3 vertices[],
|
||||
uint32_t indices[]
|
||||
)
|
||||
{
|
||||
mesh ret;
|
||||
|
||||
|
@ -147,11 +135,13 @@ load_mesh(char *path)
|
|||
mesh
|
||||
copy_mesh(mesh orig)
|
||||
{
|
||||
return new_mesh(orig.vertex_num,
|
||||
orig.tri_num,
|
||||
orig.index_num,
|
||||
orig.vertices,
|
||||
orig.indices);
|
||||
return new_mesh(
|
||||
orig.vertex_num,
|
||||
orig.tri_num,
|
||||
orig.index_num,
|
||||
orig.vertices,
|
||||
orig.indices
|
||||
);
|
||||
}
|
||||
|
||||
void free_mesh(mesh mesh) { free(mesh.vertices); free(mesh.indices); }
|
||||
|
@ -188,15 +178,17 @@ init_sdl(void)
|
|||
|
||||
sdl_state ret;
|
||||
|
||||
ret.window = SDL_CreateWindow("Game",
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
W,
|
||||
H,
|
||||
// TODO: when we have a proper event loop, we can
|
||||
// add resizing windows.
|
||||
/* SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN); */
|
||||
SDL_WINDOW_MOUSE_CAPTURE | SDL_WINDOW_SHOWN);
|
||||
ret.window = SDL_CreateWindow(
|
||||
"Game",
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
W,
|
||||
H,
|
||||
// TODO: when we have a proper event loop, we can
|
||||
// add resizing windows.
|
||||
/* SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN); */
|
||||
SDL_WINDOW_MOUSE_CAPTURE | SDL_WINDOW_SHOWN
|
||||
);
|
||||
ret.renderer = SDL_CreateRenderer(ret.window, -1, SDL_RENDERER_SOFTWARE);
|
||||
SDL_SetRenderDrawColor(ret.renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(ret.renderer);
|
||||
|
@ -502,13 +494,20 @@ midpoint(vec2 a, vec2 b)
|
|||
};
|
||||
}
|
||||
|
||||
vec2
|
||||
project(camera c, vec3 v)
|
||||
vec3
|
||||
view_matricize(camera c, vec3 v)
|
||||
{
|
||||
vec3 u = vec3_sub(v, c.pos);
|
||||
// TODO rotation
|
||||
double r = c.znear / u.z;
|
||||
return (vec2){W / 2 + r * u.x, H / 2 + r * u.y};
|
||||
mat4x4 view = lookat(c);
|
||||
vec4 tmp = vec4_mat4x4_mul(vec3_to_vec4(v), view);
|
||||
return (vec3) {.x = tmp.x, .y = tmp.y, .z = tmp.z};
|
||||
}
|
||||
|
||||
vec2
|
||||
project(camera c, vec3 u)
|
||||
{
|
||||
double r = c.znear / (u.z);
|
||||
|
||||
return (vec2){(W / 2) * (u.x * r + 1), (H / 2) * (r * (-u.y) + 1) * (800.0 / 600.0)};
|
||||
}
|
||||
|
||||
triangle2
|
||||
|
@ -548,76 +547,66 @@ draw_mesh(rgb canvas[], rgb col, camera c, mesh mesh)
|
|||
v1 = mesh.vertices[mesh.indices[3*i+1]],
|
||||
v2 = mesh.vertices[mesh.indices[3*i+2]];
|
||||
|
||||
if (v0.z > c.znear && v1.z > c.znear && v2.z > c.znear) continue;
|
||||
|
||||
vec3 norm = vec3_normalize(vec3_cross(vec3_sub(v1, v0), vec3_sub(v2, v0)));
|
||||
vec3 norm = vec3_normalize(
|
||||
vec3_cross(vec3_sub(v1, v0), vec3_sub(v2, v0))
|
||||
);
|
||||
double x = vec3_dot(vec3_sub(v0, c.pos), norm);
|
||||
|
||||
if (wireframe) {
|
||||
if (x < 0)
|
||||
draw_triangle(canvas, col, project_triangle(c, (triangle3) {
|
||||
v0, v1, v2
|
||||
}));
|
||||
/* else */
|
||||
/* draw_triangle(canvas, */
|
||||
/* (rgb) { */
|
||||
/* .r = col.r * 0.2, */
|
||||
/* .g = col.g * 0.2, */
|
||||
/* .b = col.b * 0.2, */
|
||||
/* .a = col.a */
|
||||
/* }, */
|
||||
/* project_triangle(c, (triangle3) { */
|
||||
/* v0, v1, v2 */
|
||||
/* })); */
|
||||
vec3 us[3] = {view_matricize(c, v0), view_matricize(c, v1), view_matricize(c, v2)};
|
||||
int skip_triangle = 0;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (us[i].z > 0.0)
|
||||
skip_triangle = 1;
|
||||
}
|
||||
else {
|
||||
if (x < 0) {
|
||||
double col_mod = clamp(vec3_dot(norm, vec3_normalize(c.pos)), 0.0, 1.0);
|
||||
fill_triangle(canvas,
|
||||
(rgb) {
|
||||
.r = col.r * col_mod,
|
||||
.g = col.g * col_mod,
|
||||
.b = col.b * col_mod
|
||||
},
|
||||
project_triangle(c, (triangle3) {
|
||||
v0, v1, v2
|
||||
}));
|
||||
|
||||
if (!skip_triangle) {
|
||||
if (wireframe) {
|
||||
if (x < 0)
|
||||
draw_triangle(canvas, col, project_triangle(c, (triangle3) {
|
||||
us[0], us[1], us[2]
|
||||
}));
|
||||
/* else */
|
||||
/* draw_triangle(canvas, */
|
||||
/* (rgb) { */
|
||||
/* .r = col.r * 0.2, */
|
||||
/* .g = col.g * 0.2, */
|
||||
/* .b = col.b * 0.2, */
|
||||
/* .a = col.a */
|
||||
/* }, */
|
||||
/* project_triangle(c, (triangle3) { */
|
||||
/* v0, v1, v2 */
|
||||
/* })); */
|
||||
}
|
||||
else {
|
||||
if (x < 0) {
|
||||
double col_mod = clamp(
|
||||
vec3_dot(norm, vec3_normalize((vec3){2,2,2})),
|
||||
0.0, 1.0);
|
||||
fill_triangle(canvas,
|
||||
(rgb) {
|
||||
.r = col.r * col_mod,
|
||||
.g = col.g * col_mod,
|
||||
.b = col.b * col_mod
|
||||
},
|
||||
project_triangle(c, (triangle3) {
|
||||
us[0], us[1], us[2]
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
matrix3x3
|
||||
matrix3x3_multiply(matrix3x3 r, matrix3x3 s)
|
||||
{
|
||||
#define a r.nums
|
||||
#define b s.nums
|
||||
return (matrix3x3) {
|
||||
.nums =
|
||||
{{a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0],
|
||||
a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1],
|
||||
a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2]},
|
||||
{a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0],
|
||||
a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1],
|
||||
a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[1][2] * b[2][2]},
|
||||
{a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0],
|
||||
a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1],
|
||||
a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[2][2] * b[2][2]}}
|
||||
};
|
||||
#undef a
|
||||
#undef b
|
||||
}
|
||||
|
||||
double
|
||||
to_deg(double deg)
|
||||
{
|
||||
return deg * 2 * PI / 360.0;
|
||||
}
|
||||
|
||||
matrix3x3
|
||||
mat3x3
|
||||
x_rotation(double deg)
|
||||
{
|
||||
return (matrix3x3) {
|
||||
return (mat3x3) {
|
||||
.nums =
|
||||
{{1, 0, 0},
|
||||
{0, cos(to_deg(deg)), -sin(to_deg(deg))},
|
||||
|
@ -625,10 +614,10 @@ x_rotation(double deg)
|
|||
};
|
||||
}
|
||||
|
||||
matrix3x3
|
||||
mat3x3
|
||||
y_rotation(double deg)
|
||||
{
|
||||
return (matrix3x3) {
|
||||
return (mat3x3) {
|
||||
.nums =
|
||||
{{ cos(to_deg(deg)), 0, sin(to_deg(deg))},
|
||||
{ 0, 1, 0},
|
||||
|
@ -636,10 +625,10 @@ y_rotation(double deg)
|
|||
};
|
||||
}
|
||||
|
||||
matrix3x3
|
||||
mat3x3
|
||||
z_rotation(double deg)
|
||||
{
|
||||
return (matrix3x3) {
|
||||
return (mat3x3) {
|
||||
.nums =
|
||||
{{cos(to_deg(deg)), -sin(to_deg(deg)), 0},
|
||||
{sin(to_deg(deg)), cos(to_deg(deg)), 0},
|
||||
|
@ -653,14 +642,15 @@ int
|
|||
main(void)
|
||||
{
|
||||
sdl_state state = init_sdl();
|
||||
camera cam = new_camera(180, (vec3){0, 0, 200}, (vec3){0, 0, 0}, UP);
|
||||
|
||||
/* print_camera(cam); */
|
||||
camera cam = new_camera(-1.0, (vec3){0, 1, 30}, UP, PI/2, 0.0);
|
||||
print_camera(cam);
|
||||
|
||||
SDL_Event event;
|
||||
|
||||
const mesh obj = load_mesh("iso.mod");
|
||||
mesh obj_copy = copy_mesh(obj);
|
||||
const mesh iso = load_mesh("iso.mod");
|
||||
mesh iso_copy = copy_mesh(iso);
|
||||
const mesh plane = load_mesh("plane.mod");
|
||||
mesh plane_copy = copy_mesh(plane);
|
||||
|
||||
uint64_t t = 0;
|
||||
|
||||
|
@ -668,41 +658,65 @@ main(void)
|
|||
for (;;) {
|
||||
double elapsed, start = SDL_GetPerformanceCounter();
|
||||
|
||||
matrix3x3 rotation = matrix3x3_multiply(
|
||||
matrix3x3_multiply(
|
||||
z_rotation(1.2 * t * rot_speed),
|
||||
y_rotation(1.1 * t * rot_speed)),
|
||||
x_rotation(1.0 * t * rot_speed));
|
||||
mat3x3 rotation = mat3x3_mul(
|
||||
mat3x3_mul(
|
||||
z_rotation(1.0 * t * rot_speed),
|
||||
y_rotation(1.2 * t * rot_speed)),
|
||||
x_rotation(1.3 * t * rot_speed));
|
||||
|
||||
int x, y;
|
||||
uint32_t buttons = SDL_GetMouseState(&x, &y);
|
||||
|
||||
clear_canvas(state.canvas, (rgb){7, 7, 7, 255});
|
||||
|
||||
for (size_t i = 0; i < obj.vertex_num; i++) {
|
||||
obj_copy.vertices[i] = vec3_matrix3x3_multiply(obj.vertices[i], rotation);
|
||||
for (size_t i = 0; i < iso.vertex_num; i++) {
|
||||
iso_copy.vertices[i] = vec3_mat3x3_mul(iso.vertices[i], rotation);
|
||||
}
|
||||
|
||||
draw_mesh(state.canvas, WHITE, cam, obj_copy);
|
||||
draw_mesh(state.canvas, WHITE, cam, plane_copy);
|
||||
draw_mesh(state.canvas, WHITE, cam, iso_copy);
|
||||
|
||||
|
||||
render(state);
|
||||
|
||||
/* continuous keyboard events */
|
||||
const uint8_t *keyboard = SDL_GetKeyboardState(NULL);
|
||||
double velocity = 0.1;
|
||||
if (keyboard[SDL_SCANCODE_W]) {
|
||||
cam.pos = vec3_sub(cam.pos, vec3_scalar_mul(cam.front, velocity));
|
||||
}
|
||||
if (keyboard[SDL_SCANCODE_S]) {
|
||||
cam.pos = vec3_add(cam.pos, vec3_scalar_mul(cam.front, velocity));
|
||||
}
|
||||
if (keyboard[SDL_SCANCODE_E]) {
|
||||
cam.pos = vec3_add(cam.pos, vec3_scalar_mul(cam.right, velocity));
|
||||
}
|
||||
if (keyboard[SDL_SCANCODE_Q]) {
|
||||
cam.pos = vec3_sub(cam.pos, vec3_scalar_mul(cam.right, velocity));
|
||||
}
|
||||
if (keyboard[SDL_SCANCODE_D]) {
|
||||
cam.yaw -= 0.05;
|
||||
}
|
||||
if (keyboard[SDL_SCANCODE_A]) {
|
||||
cam.yaw += 0.05;
|
||||
}
|
||||
update_camera(&cam);
|
||||
|
||||
/* other events */
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_KEYDOWN: {
|
||||
case SDL_KEYDOWN:
|
||||
switch (event.key.keysym.scancode) {
|
||||
case SDL_SCANCODE_F3: {
|
||||
case SDL_SCANCODE_F3:
|
||||
if (!event.key.repeat) wireframe = !wireframe;
|
||||
break;
|
||||
}
|
||||
case SDL_SCANCODE_F6: {
|
||||
case SDL_SCANCODE_F6:
|
||||
if (!event.key.repeat) screenshot(state.canvas);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_QUIT:
|
||||
goto quit;
|
||||
}
|
||||
|
@ -715,7 +729,9 @@ main(void)
|
|||
}
|
||||
|
||||
quit:
|
||||
free_mesh(obj);
|
||||
free_mesh(obj_copy);
|
||||
free_mesh(iso);
|
||||
free_mesh(iso_copy);
|
||||
free_mesh(plane);
|
||||
free_mesh(plane_copy);
|
||||
free_sdl(state);
|
||||
}
|
||||
|
|
108
types.h
108
types.h
|
@ -35,21 +35,22 @@ STRUCT(vec4)
|
|||
FIELD(w, double)
|
||||
END_STRUCT
|
||||
|
||||
STRUCT(matrix3x3)
|
||||
STRUCT(mat3x3)
|
||||
FIELD(nums, grid3x3)
|
||||
END_STRUCT
|
||||
|
||||
STRUCT(matrix4x4)
|
||||
STRUCT(mat4x4)
|
||||
FIELD(nums, grid4x4)
|
||||
END_STRUCT
|
||||
|
||||
STRUCT(camera)
|
||||
FIELD(znear, double)
|
||||
FIELD(pos, vec3)
|
||||
FIELD(target, vec3)
|
||||
FIELD(front, vec3)
|
||||
FIELD(up, vec3)
|
||||
FIELD(dir, vec3)
|
||||
FIELD(right, vec3)
|
||||
FIELD(yaw, double)
|
||||
FIELD(pitch, double)
|
||||
END_STRUCT
|
||||
|
||||
#else
|
||||
|
@ -120,6 +121,16 @@ vec3_sub(vec3 u, vec3 v)
|
|||
};
|
||||
}
|
||||
|
||||
vec3
|
||||
vec3_scalar_mul(vec3 v, double s)
|
||||
{
|
||||
return (vec3) {
|
||||
.x = v.x * s,
|
||||
.y = v.y * s,
|
||||
.z = v.z * s,
|
||||
};
|
||||
}
|
||||
|
||||
vec3
|
||||
vec3_cross(vec3 u, vec3 v)
|
||||
{
|
||||
|
@ -147,6 +158,12 @@ vec3_normalize(vec3 u)
|
|||
};
|
||||
}
|
||||
|
||||
vec4
|
||||
vec3_to_vec4(vec3 v)
|
||||
{
|
||||
return (vec4){v.x, v.y, v.z, 1.0};
|
||||
}
|
||||
|
||||
vec4
|
||||
vec4_add(vec4 u, vec4 v)
|
||||
{
|
||||
|
@ -169,6 +186,89 @@ vec4_sub(vec4 u, vec4 v)
|
|||
};
|
||||
}
|
||||
|
||||
void
|
||||
mat_mul(size_t dim, double m1[dim][dim], double m2[dim][dim], double 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)
|
||||
{
|
||||
vec3 front = {
|
||||
.x = cos(cam->yaw) * cos(cam->pitch),
|
||||
.y = sin(cam->pitch),
|
||||
.z = sin(cam->yaw) * cos(cam->pitch)
|
||||
};
|
||||
cam->front = vec3_normalize(front);
|
||||
cam->right = vec3_normalize(vec3_cross(cam->front, cam->up));
|
||||
/* cam->up = vec3_normalize(vec3_cross(cam->right, cam->front)); */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SUB_INCLUDE_TYPES */
|
||||
|
|
Loading…
Reference in New Issue