#ifndef VEC_H #define VEC_H #include "aliases.h" #include "typed_list.h" #include typedef struct i64x2 V2i; struct i64x2 { i64 x; i64 y; }; typedef struct u64x2 V2u; struct u64x2 { u64 x; u64 y; }; typedef struct f32x2 V2f; struct f32x2 { union { f32 x; f32 u; }; union { f32 y; f32 v; }; }; typedef struct f32x3 V3f; struct f32x3 { union { f32 elements[3]; struct { union { f32 x; f32 r; }; union { f32 y; f32 g; }; union { f32 z; f32 b; }; }; }; }; typedef struct f32x4 V4f; struct f32x4 { f32 x; f32 y; f32 z; f32 w; }; typedef struct u64x3 V3u; struct u64x3 { u64 x; u64 y; u64 z; }; typedef struct f32_3x3 M3x3f; struct f32_3x3 { V3f row0; V3f row1; V3f row2; }; typedef struct f32_4x4 M4x4f; struct f32_4x4 { V4f row0; V4f row1; V4f row2; V4f row3; }; MAKE_LIST_TYPE(V3f); MAKE_LIST_TYPE(V2f); #define V2(T, ELEM_T, X0, Y0, X1, Y1) \ ((T){(ELEM_T)X1 - (ELEM_T)X0, (ELEM_T)Y1 - (ELEM_T)Y0}) #define V3(T, ELEM_T, X0, Y0, Z0, X1, Y1, Z1) \ ((T){(ELEM_T)X1 - (ELEM_T)X0, (ELEM_T)Y1 - (ELEM_T)Y0, \ (ELEM_T)Z1 - (ELEM_T)Z0}) #define V3_to_V4(V3) ((V4f){.x = V3.x, .y = V3.y, .z = V3.z, .w = 1.0f}) #define dot_v2(V1, V2) ((f32)V1.x * (f32)V2.x + (f32)V1.y * (f32)V2.y) #define dot_v3(V1, V2) \ ((f32)V1.x * (f32)V2.x + (f32)V1.y * (f32)V2.y + (f32)V1.z * (f32)V2.z) #define add_v3(V1, V2) \ ((V3f){ \ .x = V1.x + V2.x, \ .y = V1.y + V2.y, \ .z = V1.z + V2.z, \ }) #define sub_v3(V1, V2) \ ((V3f){ \ .x = V1.x - V2.x, \ .y = V1.y - V2.y, \ .z = V1.z - V2.z, \ }) #define mul_v3(V1, V2) \ ((V3f){ \ .x = V1.x * V2.x, \ .y = V1.y * V2.y, \ .z = V1.z * V2.z, \ }) #define num_mul_v3(V, N) ((V3f){.x = (N) * V.x, .y = (N) * V.y, .z = (N) * V.z}) #define num_div_v3(V, N) ((V3f){.x = V.x / (N), .y = V.y / (N), .z = V.z / (N)}) #define magnitude_v3(V) (sqrtf(dot_v3(V, V))) #define normalise_v3(V) \ do { \ f32 magnitude = magnitude_v3(V); \ V.x /= magnitude; \ V.y /= magnitude; \ V.z /= magnitude; \ } while (0) #define cross_product(V1, V2) \ ((V3f){ \ .x = V1.y * V2.z - V1.z * V2.y, \ .y = V1.z * V2.x - V1.x * V2.z, \ .z = V1.x * V2.y - V1.y * V2.x, \ }) #define mat4x4_identity \ ((M4x4f){ \ .row0 = {1.0f, 0.0f, 0.0f, 0.0f}, \ .row1 = {0.0f, 1.0f, 0.0f, 0.0f}, \ .row2 = {0.0f, 0.0f, 1.0f, 0.0f}, \ .row3 = {0.0f, 0.0f, 0.0f, 1.0f}, \ }) #define mat4x4_to_array(MAT) \ ((f32[4][4]){ \ {MAT.row0.x, MAT.row0.y, MAT.row0.z, MAT.row0.w}, \ {MAT.row1.x, MAT.row1.y, MAT.row1.z, MAT.row1.w}, \ {MAT.row2.x, MAT.row2.y, MAT.row2.z, MAT.row2.w}, \ {MAT.row3.x, MAT.row3.y, MAT.row3.z, MAT.row3.w}, \ }) #define array_to_mat4x4(arr) \ ((M4x4f){ \ .row0 = {arr[0][0], arr[0][1], arr[0][2], arr[0][3]}, \ .row1 = {arr[1][0], arr[1][1], arr[1][2], arr[1][3]}, \ .row2 = {arr[2][0], arr[2][1], arr[2][2], arr[2][3]}, \ .row3 = {arr[3][0], arr[3][1], arr[3][2], arr[3][3]}, \ }) #define mat4x4_transpose(MAT) \ ((M4x4f){ \ .row0 = {.x = MAT.row0.x, \ .y = MAT.row1.x, \ .z = MAT.row2.x, \ .w = MAT.row3.x}, \ .row1 = {.x = MAT.row0.y, \ .y = MAT.row1.y, \ .z = MAT.row2.y, \ .w = MAT.row3.y}, \ .row2 = {.x = MAT.row0.z, \ .y = MAT.row1.z, \ .z = MAT.row2.z, \ .w = MAT.row3.z}, \ .row3 = {.x = MAT.row0.w, \ .y = MAT.row1.w, \ .z = MAT.row2.w, \ .w = MAT.row3.w}, \ }) #define mat4x4_mul(MAT1, MAT2) \ ((M4x4f){ \ .row0.x = MAT1.row0.x * MAT2.row0.x + MAT1.row0.y * MAT2.row1.x + \ MAT1.row0.z * MAT2.row2.x + MAT1.row0.w * MAT2.row3.x, \ .row0.y = MAT1.row0.x * MAT2.row0.y + MAT1.row0.y * MAT2.row1.y + \ MAT1.row0.z * MAT2.row2.y + MAT1.row0.w * MAT2.row3.y, \ .row0.z = MAT1.row0.x * MAT2.row0.z + MAT1.row0.y * MAT2.row1.z + \ MAT1.row0.z * MAT2.row2.z + MAT1.row0.w * MAT2.row3.z, \ .row0.w = MAT1.row0.x * MAT2.row0.w + MAT1.row0.y * MAT2.row1.w + \ MAT1.row0.z * MAT2.row2.w + MAT1.row0.w * MAT2.row3.w, \ .row1.x = MAT1.row1.x * MAT2.row0.x + MAT1.row1.y * MAT2.row1.x + \ MAT1.row1.z * MAT2.row2.x + MAT1.row1.w * MAT2.row3.x, \ .row1.y = MAT1.row1.x * MAT2.row0.y + MAT1.row1.y * MAT2.row1.y + \ MAT1.row1.z * MAT2.row2.y + MAT1.row1.w * MAT2.row3.y, \ .row1.z = MAT1.row1.x * MAT2.row0.z + MAT1.row1.y * MAT2.row1.z + \ MAT1.row1.z * MAT2.row2.z + MAT1.row1.w * MAT2.row3.z, \ .row1.w = MAT1.row1.x * MAT2.row0.w + MAT1.row1.y * MAT2.row1.w + \ MAT1.row1.z * MAT2.row2.w + MAT1.row1.w * MAT2.row3.w, \ .row2.x = MAT1.row2.x * MAT2.row0.x + MAT1.row2.y * MAT2.row1.x + \ MAT1.row2.z * MAT2.row2.x + MAT1.row2.w * MAT2.row3.x, \ .row2.y = MAT1.row2.x * MAT2.row0.y + MAT1.row2.y * MAT2.row1.y + \ MAT1.row2.z * MAT2.row2.y + MAT1.row2.w * MAT2.row3.y, \ .row2.z = MAT1.row2.x * MAT2.row0.z + MAT1.row2.y * MAT2.row1.z + \ MAT1.row2.z * MAT2.row2.z + MAT1.row2.w * MAT2.row3.z, \ .row2.w = MAT1.row2.x * MAT2.row0.w + MAT1.row2.y * MAT2.row1.w + \ MAT1.row2.z * MAT2.row2.w + MAT1.row2.w * MAT2.row3.w, \ .row3.x = MAT1.row3.x * MAT2.row0.x + MAT1.row3.y * MAT2.row1.x + \ MAT1.row3.z * MAT2.row2.x + MAT1.row3.w * MAT2.row3.x, \ .row3.y = MAT1.row3.x * MAT2.row0.y + MAT1.row3.y * MAT2.row1.y + \ MAT1.row3.z * MAT2.row2.y + MAT1.row3.w * MAT2.row3.y, \ .row3.z = MAT1.row3.x * MAT2.row0.z + MAT1.row3.y * MAT2.row1.z + \ MAT1.row3.z * MAT2.row2.z + MAT1.row3.w * MAT2.row3.z, \ .row3.w = MAT1.row3.x * MAT2.row0.w + MAT1.row3.y * MAT2.row1.w + \ MAT1.row3.z * MAT2.row2.w + MAT1.row3.w * MAT2.row3.w, \ }) #define mat4x4_mul_vec4(MAT, V) \ ((V4f){ \ .x = MAT.row0.x * V.x + MAT.row0.y * V.y + MAT.row0.z * V.z + \ MAT.row0.w * V.w, \ .y = MAT.row1.x * V.x + MAT.row1.y * V.y + MAT.row1.z * V.z + \ MAT.row1.w * V.w, \ .z = MAT.row2.x * V.x + MAT.row2.y * V.y + MAT.row2.z * V.z + \ MAT.row2.w * V.w, \ .w = MAT.row3.x * V.x + MAT.row3.y * V.y + MAT.row3.z * V.z + \ MAT.row3.w * V.w, \ }) #define project_vec4(V) ((V3f){.x = V.x / V.w, .y = V.y / V.w, .z = V.z / V.w}) M4x4f lookat(V3f eye, V3f target, V3f up); M4x4f projection(f32 coeff); M4x4f viewport(f32 x, f32 y, u64 w, u64 h); M4x4f mat4x4_inv(M4x4f matrix); #endif // VEC_H