From 7c73ee40304013e3a43f0aa3a41a0ed3c9e5194c Mon Sep 17 00:00:00 2001 From: LeonardoBizzoni Date: Sat, 18 Oct 2025 11:14:49 +0200 Subject: [PATCH] More linagen functions --- extra/code_generation.h | 5 +- extra/linear_algebra.h | 195 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 185 insertions(+), 15 deletions(-) diff --git a/extra/code_generation.h b/extra/code_generation.h index 916d8fc..f9202c5 100644 --- a/extra/code_generation.h +++ b/extra/code_generation.h @@ -35,10 +35,7 @@ static void cb_gen_write(CB_Generator *gen, char *filepath, bool append_mode) { free(full_string); cb_handle_close(file); cb_dyn_free(gen); - - gen->signature.has_args = 0; - gen->signature.spacing = 0; - gen->total_length = 0; + memset(gen, 0, sizeof *gen); } static void cb_gen_push(CB_Generator *gen, char *string) { diff --git a/extra/linear_algebra.h b/extra/linear_algebra.h index 098a4b2..5a91f99 100644 --- a/extra/linear_algebra.h +++ b/extra/linear_algebra.h @@ -31,6 +31,17 @@ cb_linagen_defun_vecn_hadamard_prod(CB_Generator *gen, char *type, static inline void cb_linagen_defun_vecn_hadamard_div(CB_Generator *gen, char *type, int32_t n, bool implementation); +static inline void +cb_linagen_defun_vecn_equal(CB_Generator *gen, char *type, + int32_t n, bool implementation); +static inline void +cb_linagen_defun_vecn_near(CB_Generator *gen, char *type, + int32_t n, bool implementation); +static inline void +cb_linagen_defun_vecn_lerp(CB_Generator *gen, char *type, + int32_t n, bool implementation); +static inline void +cb_linagen_defun_vec3_cross(CB_Generator *gen, char *type, bool implementation); static void cb_linagen_defun_vecn_scale(CB_Generator *gen, char *type, int32_t n, bool implementation); @@ -47,6 +58,12 @@ cb_linagen_defun_vecn_magnitude(CB_Generator *gen, char *type, static void cb_linagen_defun_vecn_magnitude64(CB_Generator *gen, char *type, int32_t n, bool implementation); +static void +cb_linagen_defun_vecn_distance(CB_Generator *gen, char *type, + int32_t n, bool implementation); +static void +cb_linagen_defun_vecn_distance2(CB_Generator *gen, char *type, + int32_t n, bool implementation); static inline void cb_linagen_defun_vecn_add_assign(CB_Generator *gen, char *type, @@ -69,6 +86,7 @@ cb_linagen_defun_vecn_normalize_assign(CB_Generator *gen, char *type, // ====================================================================== // Implementations + static void cb_linagen_typedef_vecn(CB_Generator *gen, char *type, int32_t n, ...) { va_list args = {0}; @@ -140,6 +158,88 @@ cb_linagen_defun_vecn_hadamard_div(CB_Generator *gen, char *type, "hadamard_div", '/'); } +static inline void +cb_linagen_defun_vecn_equal(CB_Generator *gen, char *type, + int32_t n, bool implementation) { + char *vec_suffix = strdup(type); + *vec_suffix = char_toupper(*type); + cb_gen_push_func_begin(gen, cb_format("linagen_fn bool vec%d%s_equal", + n, type)); + cb_gen_push_func_arg(gen, cb_format("Vec%d%s v1", n, vec_suffix)); + cb_gen_push_func_arg(gen, cb_format("Vec%d%s v2", n, vec_suffix)); + cb_gen_push_func_end(gen, implementation); + if (!implementation) { return; } + + cb_gen_push(gen, " {\n return v1.values[0] == v2.values[0]"); + for (int32_t i = 1; i < n; ++i) { + cb_gen_push(gen, cb_format(" &&\n v1.values[%d] == v2.values[%d]", + i, i)); + } + cb_gen_push(gen, ";\n}\n\n"); +} + +static inline void +cb_linagen_defun_vecn_near(CB_Generator *gen, char *type, + int32_t n, bool implementation) { + char *vec_suffix = strdup(type); + *vec_suffix = char_toupper(*type); + cb_gen_push_func_begin(gen, cb_format("linagen_fn bool vec%d%s_near", + n, type)); + cb_gen_push_func_arg(gen, cb_format("Vec%d%s v1", n, vec_suffix)); + cb_gen_push_func_arg(gen, cb_format("Vec%d%s v2", n, vec_suffix)); + cb_gen_push_func_arg(gen, "float eps"); + cb_gen_push_func_end(gen, implementation); + if (!implementation) { return; } + + cb_gen_push(gen, " {\n return ((float)v1.values[0] + eps >= v2.values[0] && (float)v1.values[0] - eps <= v2.values[0])"); + for (int32_t i = 1; i < n; ++i) { + cb_gen_push(gen, cb_format(" &&\n ((float)v1.values[%d] + eps >= v2.values[%d] && (float)v1.values[%d] - eps <= v2.values[%d])", + i, i, i, i)); + } + cb_gen_push(gen, ";\n}\n\n"); +} + +static inline void +cb_linagen_defun_vecn_lerp(CB_Generator *gen, char *type, + int32_t n, bool implementation) { + char *vec_suffix = strdup(type); + *vec_suffix = char_toupper(*type); + cb_gen_push_func_begin(gen, cb_format("linagen_fn Vec%d%s vec%d%s_lerp", + n, vec_suffix, n, type)); + cb_gen_push_func_arg(gen, cb_format("Vec%d%s start", n, vec_suffix)); + cb_gen_push_func_arg(gen, cb_format("Vec%d%s end", n, vec_suffix)); + cb_gen_push_func_arg(gen, cb_format("%s t", type)); + cb_gen_push_func_end(gen, implementation); + if (!implementation) { return; } + + cb_gen_push(gen, cb_format(" {\n Vec%d%s res = {0};", n, vec_suffix)); + for (int32_t i = 0; i < n; ++i) { + cb_gen_push(gen, cb_format("\n res.values[%d] = start.values[%d] * (1 - t) + end.values[%d] * t;", i, i, i)); + } + cb_gen_push(gen, "\n return res;" + "\n}\n\n"); +} + +static inline void +cb_linagen_defun_vec3_cross(CB_Generator *gen, char *type, + bool implementation) { + char *vec_suffix = strdup(type); + *vec_suffix = char_toupper(*type); + cb_gen_push_func_begin(gen, cb_format("linagen_fn Vec3%s vec3%s_cross", + vec_suffix, type)); + cb_gen_push_func_arg(gen, cb_format("Vec3%s v1", vec_suffix)); + cb_gen_push_func_arg(gen, cb_format("Vec3%s v2", vec_suffix)); + cb_gen_push_func_end(gen, implementation); + if (!implementation) { return; } + + cb_gen_push(gen, cb_format(" {" "\n Vec3%s res = {0};", vec_suffix)); + cb_gen_push(gen, "\n res.values[0] = v1.values[1]*v2.values[2] - v1.values[2]*v2.values[1];"); + cb_gen_push(gen, "\n res.values[1] = v1.values[2]*v2.values[0] - v1.values[0]*v2.values[2];"); + cb_gen_push(gen, "\n res.values[2] = v1.values[0]*v2.values[1] - v1.values[1]*v2.values[0];"); + cb_gen_push(gen, "\n return res;" + "\n}\n\n"); +} + static void cb_linagen_defun_vecn_scale(CB_Generator *gen, char *type, int32_t n, bool implementation) { @@ -173,11 +273,22 @@ cb_linagen_defun_vecn_normalize(CB_Generator *gen, char *type, cb_gen_push_func_end(gen, implementation); if (!implementation) { return; } - // NOTE(lb): should generated function use other generated functions, - // or should they completely independent from each other? - cb_gen_push(gen, cb_format(" {" - "\n Vec%d%s res = vec%d%s_scale(v1, ((%s)1) / vec%d%s_magnitude(v1));", - n, vec_suffix, n, type, type, n, type)); + cb_gen_push(gen, cb_format(" {\n %s dot = {0};", type)); + for (int32_t i = 0; i < n; ++i) { + cb_gen_push(gen, cb_format("\n dot += v1.values[%d] * v1.values[%d];", i, i, i)); + } + + cb_gen_push(gen, cb_format("\n float magnitude = sqrtf((float)dot);" , + n, type)); + + cb_gen_push(gen, cb_format("\n Vec%d%s res = {0};" + "\n if (magnitude == 0.f) { return res; }", + n, vec_suffix)); + for (int32_t i = 0; i < n; ++i) { + cb_gen_push(gen, cb_format("\n res.values[%d] = v1.values[%d] / magnitude;", + i, i, type)); + } + cb_gen_push(gen, "\n return res;" "\n}\n\n"); } @@ -238,6 +349,59 @@ cb_linagen_defun_vecn_magnitude64(CB_Generator *gen, char *type, "\n}\n\n"); } +static void +cb_linagen_defun_vecn_distance(CB_Generator *gen, char *type, + int32_t n, bool implementation) { + char *vec_suffix = strdup(type); + *vec_suffix = char_toupper(*type); + cb_gen_push_func_begin(gen, cb_format("linagen_fn float vec%d%s_distance", + n, type)); + cb_gen_push_func_arg(gen, cb_format("Vec%d%s v1", n, vec_suffix)); + cb_gen_push_func_arg(gen, cb_format("Vec%d%s v2", n, vec_suffix)); + cb_gen_push_func_end(gen, implementation); + if (!implementation) { return; } + + cb_gen_push(gen, " {"); + for (int32_t i = 0; i < n; ++i) { + cb_gen_push(gen, cb_format("\n v1.values[%d] -= v2.values[%d];", i, i)); + } + + cb_gen_push(gen, cb_format("\n %s dot = {0};", type)); + for (int32_t i = 0; i < n; ++i) { + cb_gen_push(gen, cb_format("\n dot += v1.values[%d] * v1.values[%d];", + i, i)); + } + cb_gen_push(gen, "\n float res = sqrtf(dot);" + "\n return res;" + "\n}\n\n"); +} + +static void +cb_linagen_defun_vecn_distance2(CB_Generator *gen, char *type, + int32_t n, bool implementation) { + char *vec_suffix = strdup(type); + *vec_suffix = char_toupper(*type); + cb_gen_push_func_begin(gen, cb_format("linagen_fn float vec%d%s_distance2", + n, type)); + cb_gen_push_func_arg(gen, cb_format("Vec%d%s v1", n, vec_suffix)); + cb_gen_push_func_arg(gen, cb_format("Vec%d%s v2", n, vec_suffix)); + cb_gen_push_func_end(gen, implementation); + if (!implementation) { return; } + + cb_gen_push(gen, " {"); + for (int32_t i = 0; i < n; ++i) { + cb_gen_push(gen, cb_format("\n v1.values[%d] -= v2.values[%d];", i, i)); + } + + cb_gen_push(gen, cb_format("\n %s res = {0};", type)); + for (int32_t i = 0; i < n; ++i) { + cb_gen_push(gen, cb_format("\n res += v1.values[%d] * v1.values[%d];", + i, i)); + } + cb_gen_push(gen, "\n return res;" + "\n}\n\n"); +} + static inline void cb_linagen_defun_vecn_add_assign(CB_Generator *gen, char *type, int32_t n, bool implementation) { @@ -291,16 +455,25 @@ cb_linagen_defun_vecn_normalize_assign(CB_Generator *gen, char *type, int32_t n, bool implementation) { char *vec_suffix = strdup(type); *vec_suffix = char_toupper(*type); - cb_gen_push_func_begin(gen, cb_format("linagen_fn Vec%d%s vec%d%s_normalize_assign", - n, vec_suffix, n, type)); + cb_gen_push_func_begin(gen, cb_format("linagen_fn void vec%d%s_normalize_assign", + n, type)); cb_gen_push_func_arg(gen, cb_format("Vec%d%s *v1", n, vec_suffix)); cb_gen_push_func_end(gen, implementation); if (!implementation) { return; } - cb_gen_push(gen, cb_format(" {" - "\n vec%d%s_scale_assign(v1, ((%s)1) / vec%d%s_magnitude(*v1));" - "\n}\n\n", - n, type, type, n, type)); + cb_gen_push(gen, cb_format(" {\n %s dot = {0};", type)); + for (int32_t i = 0; i < n; ++i) { + cb_gen_push(gen, cb_format("\n dot += v1->values[%d] * v1->values[%d];", + i, i)); + } + cb_gen_push(gen, "\n float magnitude = sqrtf((float)dot);" + "\n if (magnitude == 0.f) { return; }"); + + for (int32_t i = 0; i < n; ++i) { + cb_gen_push(gen, cb_format("\n v1->values[%d] /= magnitude;", + i, type)); + } + cb_gen_push(gen, "\n}\n\n"); } -- 2.52.0