tinyrenderer/src/vec.h

164 lines
6.4 KiB
C

#ifndef VEC_H
#define VEC_H
#include "aliases.h"
#include "typed_list.h"
#include <math.h>
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