diff --git a/Makefile b/Makefile index e2a1064..c9a6c3f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CXX= clang++-8 -CXXFLAGS= --std=c++17 -O0 -pthread -DGP_TESTS -DFUZZ_STRENGTH=500 -pedantic -Werror \ +CXXFLAGS= --std=c++17 -O3 -pthread -DGP_TESTS -DFUZZ_STRENGTH=500 -pedantic -Werror \ -Wno-unknown-attributes \ -g -fprofile-instr-generate -fcoverage-mapping # -fsanitize=address -fno-omit-frame-pointer diff --git a/include/gp/math.hpp b/include/gp/math.hpp index 93af11a..8a0910b 100644 --- a/include/gp/math.hpp +++ b/include/gp/math.hpp @@ -6,8 +6,14 @@ # include "gp/math/fp_math.hpp" #endif #include "gp/algorithm/repeat.hpp" +#include "gp/algorithm/min_max.hpp" namespace gp { + template + T lerp(T input, T low, T high) { + return low + (high - low) * input; + } + template T fixed_sqrt(T value) { if(value == 0) return 0; @@ -101,6 +107,10 @@ namespace gp { T ilen = fast_isqrt(x*x+y*y); return {x*ilen, y*ilen}; } + + T length() { + return fixed_sqrt(x*x+y*y); + } }; template @@ -175,6 +185,10 @@ namespace gp { T ilen = fast_isqrt(x*x+y*y+z*z); return {x*ilen, y*ilen, z*ilen}; } + + T length() { + return fixed_sqrt(x*x+y*y+z*z); + } }; template @@ -260,8 +274,41 @@ namespace gp { T ilen = fast_isqrt(x*x+y*y+z*z+w*w); return {x*ilen, y*ilen, z*ilen, w*ilen}; } + + T length() { + return fixed_sqrt(x*x+y*y+z*z+w*w); + } }; + template + auto sphere_sdf(vec3_g center, T radius) { + return [=](vec3_g position) -> T const { + auto p = position - center; + return p.length() - radius; + }; + } + + template + auto union_sdf(lhs _l, rhs _r) { + return [=](vec3_g position) -> T const { + return gp::min(_l(position), _r(position)); + }; + } + + template + auto intersect_sdf(lhs _l, rhs _r) { + return [=](vec3_g position) -> T const { + return gp::max(_l(position), _r(position)); + }; + } + + template + auto difference_sdf(lhs _l, rhs _r) { + return [=](vec3_g position) -> T const { + return gp::max(_l(position), -_r(position)); + }; + } + template vec2_g operator*(vec2_g p, T v) { return {p.x*v, p.y*v}; diff --git a/tests/math.cpp b/tests/math.cpp index 7639ae3..048592f 100644 --- a/tests/math.cpp +++ b/tests/math.cpp @@ -46,14 +46,31 @@ struct render_test : public test_scaffold { int res = 0; renderer a; a._resolution = vec2{128,64}; - a.passes = 6; - a.projection_end = 4; + a.passes = 5; + a.projection_end = 3; - a.sky_box = [](vec3) -> color_t {return {0,0,0,0};}; - auto v = a.materials.push( + a.sky_box = [](vec3) -> color_t { + color_t ret; + ret.r() = 0.5; + ret.g() = 0.5; + ret.b() = 1; + ret.a() = 1; + return ret; + }; + auto red = a.materials.push( [&](vec3 p) -> color_t { color_t ret; ret.r() = 1; + ret.g() = 0; + ret.b() = 0; + ret.a() = 1; + return ret; + } + ); + auto green = a.materials.push( + [&](vec3 p) -> color_t { + color_t ret; + ret.r() = 0; ret.g() = 1; ret.b() = 0; ret.a() = 1; @@ -64,8 +81,22 @@ struct render_test : public test_scaffold { auto sphere = a.scene_elements.push( [=](vec3 pos) -> render_point { render_point ret; - ret.distance = gp::fixed_sqrt(pos.x*pos.x + pos.y*pos.y + pos.z*pos.z) - 1.0; - ret.material = v; + const auto l_sdf = gp::difference_sdf( + gp::sphere_sdf({0.0,0.0,0.0}, 1.0), + gp::sphere_sdf({-0.75,0.0,0.0}, 1.0) + ); + ret.distance = l_sdf(pos); + ret.material = red; + return ret; + } + ); + + auto sphere2 = a.scene_elements.push( + [=](vec3 pos) -> render_point { + render_point ret; + const auto l_sdf = gp::sphere_sdf({-0.75,0.0,0.0}, 1.0); + ret.distance = l_sdf(pos); + ret.material = green; return ret; } );