diff options
Diffstat (limited to 'src/3d/sdf_cpu.h')
| -rw-r--r-- | src/3d/sdf_cpu.h | 55 |
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 |
