summaryrefslogtreecommitdiff
path: root/src/3d/sdf_cpu.h
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-05 16:40:27 +0100
committerskal <pascal.massimino@gmail.com>2026-02-05 16:40:27 +0100
commitf6f3c13fcd287774a458730722854baab8a17366 (patch)
tree44420eecdd2e2dd84d68be12cb12641064eb1c5a /src/3d/sdf_cpu.h
parent93a65b43094641b4c188b4fc260b8ed44c883728 (diff)
feat(physics): Implement SDF-based physics engine and BVH
Completed Task #49. - Implemented CPU-side SDF library (sphere, box, torus, plane). - Implemented Dynamic BVH construction (rebuilt every frame). - Implemented PhysicsSystem with semi-implicit Euler integration and collision resolution. - Added visual debugging for BVH nodes. - Created test_3d_physics interactive test and test_physics unit tests. - Updated project docs and triaged new tasks.
Diffstat (limited to 'src/3d/sdf_cpu.h')
-rw-r--r--src/3d/sdf_cpu.h55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/3d/sdf_cpu.h b/src/3d/sdf_cpu.h
new file mode 100644
index 0000000..1e461f6
--- /dev/null
+++ b/src/3d/sdf_cpu.h
@@ -0,0 +1,55 @@
+// This file is part of the 64k demo project.
+// It implements CPU-side Signed Distance Field (SDF) primitives
+// and utilities for physics and collision detection.
+
+#pragma once
+
+#include "util/mini_math.h"
+#include <algorithm>
+#include <cmath>
+
+namespace sdf {
+
+inline float sdSphere(vec3 p, float r) {
+ return p.len() - r;
+}
+
+inline float sdBox(vec3 p, vec3 b) {
+ vec3 q;
+ q.x = std::abs(p.x) - b.x;
+ q.y = std::abs(p.y) - b.y;
+ q.z = std::abs(p.z) - b.z;
+
+ vec3 max_q_0;
+ max_q_0.x = std::max(q.x, 0.0f);
+ max_q_0.y = std::max(q.y, 0.0f);
+ max_q_0.z = std::max(q.z, 0.0f);
+
+ return max_q_0.len() + std::min(std::max(q.x, std::max(q.y, q.z)), 0.0f);
+}
+
+inline float sdTorus(vec3 p, vec2 t) {
+ vec2 p_xz(p.x, p.z);
+ vec2 q(p_xz.len() - t.x, p.y);
+ return q.len() - t.y;
+}
+
+inline float sdPlane(vec3 p, vec3 n, float h) {
+ return vec3::dot(p, n) + h;
+}
+
+/**
+ * Calculates the normal of an SDF at point p using numerical differentiation.
+ * sdf_func must be a callable: float sdf_func(vec3 p)
+ */
+template <typename F>
+inline vec3 calc_normal(vec3 p, F sdf_func, float e = 0.001f) {
+ const float d2e = 2.0f * e;
+ return vec3(
+ sdf_func(vec3(p.x + e, p.y, p.z)) - sdf_func(vec3(p.x - e, p.y, p.z)),
+ sdf_func(vec3(p.x, p.y + e, p.z)) - sdf_func(vec3(p.x, p.y - e, p.z)),
+ sdf_func(vec3(p.x, p.y, p.z + e)) - sdf_func(vec3(p.x, p.y, p.z - e)))
+ .normalize();
+}
+
+} // namespace sdf