// 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