#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 { f32 x; f32 y; f32 z; }; 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 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 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_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); #endif // VEC_H