From f6f3c13fcd287774a458730722854baab8a17366 Mon Sep 17 00:00:00 2001 From: skal Date: Thu, 5 Feb 2026 16:40:27 +0100 Subject: 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. --- src/3d/sdf_cpu.h | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/3d/sdf_cpu.h (limited to 'src/3d/sdf_cpu.h') 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 +#include + +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 +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 -- cgit v1.2.3