]> git.leonardobizzoni.com Git - CBuild/commitdiff
More linagen functions
authorLeonardoBizzoni <leo2002714@gmail.com>
Sat, 18 Oct 2025 09:14:49 +0000 (11:14 +0200)
committerLeonardoBizzoni <leo2002714@gmail.com>
Sat, 18 Oct 2025 09:14:49 +0000 (11:14 +0200)
extra/code_generation.h
extra/linear_algebra.h

index 916d8fc71d4d5b804031cd8a94bbcbace8f7ab3b..f9202c51292726d07061dcb33879686b9fce0c92 100644 (file)
@@ -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) {
index 098a4b2139024ad16fedc0b1a8327a6ef90948e1..5a91f99af4b321eb0d1ea46a63b4517509777efe 100644 (file)
@@ -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");
 }