From feac21cad695bd91534aa152852d24035dbb4e40 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 3 Dec 2019 07:35:10 +0700 Subject: [PATCH] math: string format and binds for ray2 and ray3 --- headers/enduro2d/utils/strfmts.hpp | 90 +++++++++++++++++++ .../bin/library/scripts/emmy/math/ray2.lua | 38 ++++++++ .../bin/library/scripts/emmy/math/ray3.lua | 41 +++++++++ .../high/bindings/math_binds/_math_binds.hpp | 6 ++ .../high/bindings/math_binds/ray2_binds.cpp | 64 +++++++++++++ .../high/bindings/math_binds/ray3_binds.cpp | 65 ++++++++++++++ untests/sources/untests_math/ray2.cpp | 8 +- untests/sources/untests_math/ray3.cpp | 8 +- untests/sources/untests_utils/strfmts.cpp | 10 +++ 9 files changed, 322 insertions(+), 8 deletions(-) create mode 100644 samples/bin/library/scripts/emmy/math/ray2.lua create mode 100644 samples/bin/library/scripts/emmy/math/ray3.lua create mode 100644 sources/enduro2d/high/bindings/math_binds/ray2_binds.cpp create mode 100644 sources/enduro2d/high/bindings/math_binds/ray3_binds.cpp diff --git a/headers/enduro2d/utils/strfmts.hpp b/headers/enduro2d/utils/strfmts.hpp index eaecda72..b6c6bbcd 100644 --- a/headers/enduro2d/utils/strfmts.hpp +++ b/headers/enduro2d/utils/strfmts.hpp @@ -181,6 +181,96 @@ namespace e2d::strings } }; + // + // ray2 + // + + template < typename T > + class format_arg, std::enable_if_t>> { + ray2 value_; + u8 width_; + public: + template < typename U > + explicit format_arg(U&& value, u8 width = 0) noexcept + : value_(std::forward(value)), width_(width) {} + + std::ptrdiff_t write(char* dst, size_t size) const { + return math::numeric_cast( + format(dst, size, "(%0,%1,%2,%3)", + make_format_arg(value_.origin.x, width_), + make_format_arg(value_.origin.y, width_), + make_format_arg(value_.direction.x, width_), + make_format_arg(value_.direction.y, width_))); + } + }; + + template < typename T > + class format_arg, std::enable_if_t>> { + ray2 value_; + u8 width_; + u8 precision_; + public: + template < typename U > + explicit format_arg(U&& value, u8 width = 0, u8 precision = 6) noexcept + : value_(std::forward(value)), width_(width), precision_(precision) {} + + std::ptrdiff_t write(char* dst, size_t size) const { + return math::numeric_cast( + format(dst, size, "(%0,%1,%2,%3)", + make_format_arg(value_.origin.x, width_, precision_), + make_format_arg(value_.origin.y, width_, precision_), + make_format_arg(value_.direction.x, width_, precision_), + make_format_arg(value_.direction.y, width_, precision_))); + } + }; + + // + // ray3 + // + + template < typename T > + class format_arg, std::enable_if_t>> { + ray3 value_; + u8 width_; + public: + template < typename U > + explicit format_arg(U&& value, u8 width = 0) noexcept + : value_(std::forward(value)), width_(width) {} + + std::ptrdiff_t write(char* dst, size_t size) const { + return math::numeric_cast( + format(dst, size, "(%0,%1,%2,%3,%4,%5)", + make_format_arg(value_.origin.x, width_), + make_format_arg(value_.origin.y, width_), + make_format_arg(value_.origin.z, width_), + make_format_arg(value_.direction.x, width_), + make_format_arg(value_.direction.y, width_), + make_format_arg(value_.direction.z, width_))); + } + }; + + template < typename T > + class format_arg, std::enable_if_t>> { + ray3 value_; + u8 width_; + u8 precision_; + public: + template < typename U > + explicit format_arg(U&& value, u8 width = 0, u8 precision = 6) noexcept + : value_(std::forward(value)), width_(width), precision_(precision) {} + + std::ptrdiff_t write(char* dst, size_t size) const { + return math::numeric_cast( + format(dst, size, "(%0,%1,%2,%3,%4,%5)", + make_format_arg(value_.origin.x, width_, precision_), + make_format_arg(value_.origin.y, width_, precision_), + make_format_arg(value_.origin.z, width_, precision_), + make_format_arg(value_.direction.x, width_, precision_), + make_format_arg(value_.direction.y, width_, precision_), + make_format_arg(value_.direction.z, width_, precision_))); + } + }; + // // rect // diff --git a/samples/bin/library/scripts/emmy/math/ray2.lua b/samples/bin/library/scripts/emmy/math/ray2.lua new file mode 100644 index 00000000..6f197255 --- /dev/null +++ b/samples/bin/library/scripts/emmy/math/ray2.lua @@ -0,0 +1,38 @@ +---@class ray2 +local ray2 = { + ---@type v2f + origin = v2f.zero(), + + ---@type v2f + direction = v2f.zero() +} + +---@overload fun(): ray2 +---@overload fun(r: ray2): ray2 +---@overload fun(dx: number, dy: number): ray2 +---@overload fun(ox: number, oy: number, dx: number, dy: number): ray2 +---@overload fun(d: v2f): ray2 +---@overload fun(o: v2f, d: v2f): ray2 +---@return ray2 +function ray2.new(...) end + +---@return ray2 +function ray2.zero() end + +---@return ray2 +function ray2.unit_x() end + +---@return ray2 +function ray2.unit_y() end + +---@param l ray2 +---@param r ray2 +---@return boolean +function ray2.approximately(l, r) end + +---@param r ray2 +---@return boolean +function ray2.contains_nan(r) end + +---@type ray2 +_G.ray2 = _G.ray2 or ray2 diff --git a/samples/bin/library/scripts/emmy/math/ray3.lua b/samples/bin/library/scripts/emmy/math/ray3.lua new file mode 100644 index 00000000..b13ddc26 --- /dev/null +++ b/samples/bin/library/scripts/emmy/math/ray3.lua @@ -0,0 +1,41 @@ +---@class ray3 +local ray3 = { + ---@type v3f + origin = v3f.zero(), + + ---@type v3f + direction = v3f.zero() +} + +---@overload fun(): ray3 +---@overload fun(r: ray3): ray3 +---@overload fun(dx: number, dy: number, dz: number): ray2 +---@overload fun(ox: number, oy: number, oz: number, dx: number, dy: number, dz: number): ray2 +---@overload fun(d: v3f): ray3 +---@overload fun(o: v3f, d: v3f): ray3 +---@return ray3 +function ray3.new(...) end + +---@return ray3 +function ray3.zero() end + +---@return ray3 +function ray3.unit_x() end + +---@return ray3 +function ray3.unit_y() end + +---@return ray3 +function ray3.unit_z() end + +---@param l ray3 +---@param r ray3 +---@return boolean +function ray3.approximately(l, r) end + +---@param r ray3 +---@return boolean +function ray3.contains_nan(r) end + +---@type ray3 +_G.ray3 = _G.ray3 or ray3 diff --git a/sources/enduro2d/high/bindings/math_binds/_math_binds.hpp b/sources/enduro2d/high/bindings/math_binds/_math_binds.hpp index e86a8e2d..a9c3f503 100644 --- a/sources/enduro2d/high/bindings/math_binds/_math_binds.hpp +++ b/sources/enduro2d/high/bindings/math_binds/_math_binds.hpp @@ -20,6 +20,9 @@ namespace e2d::bindings::math void bind_quat(sol::state& l); + void bind_ray2(sol::state& l); + void bind_ray3(sol::state& l); + void bind_rect(sol::state& l); void bind_aabb(sol::state& l); @@ -40,6 +43,9 @@ namespace e2d::bindings math::bind_quat(l); + math::bind_ray2(l); + math::bind_ray3(l); + math::bind_rect(l); math::bind_aabb(l); diff --git a/sources/enduro2d/high/bindings/math_binds/ray2_binds.cpp b/sources/enduro2d/high/bindings/math_binds/ray2_binds.cpp new file mode 100644 index 00000000..c76652cf --- /dev/null +++ b/sources/enduro2d/high/bindings/math_binds/ray2_binds.cpp @@ -0,0 +1,64 @@ +/******************************************************************************* + * This file is part of the "Enduro2D" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#include "_math_binds.hpp" + +namespace +{ + using namespace e2d; + + template < typename T > + void bind_ray2_t(const str& name, sol::state& l) { + l.new_usertype>(name, + sol::constructors< + ray2(), + ray2(ray2), + ray2(T,T), + ray2(T,T,T,T), + ray2(vec2), + ray2(vec2,vec2)>(), + + "zero", &ray2::zero, + "unit_x", &ray2::unit_x, + "unit_y", &ray2::unit_y, + + "origin", &ray2::origin, + "direction", &ray2::direction, + + sol::meta_function::to_string, [](const ray2& v){ + return strings::rformat("%0", v); + }, + + sol::meta_function::equal_to, sol::resolve&, const ray2&)>(::operator==), + + sol::meta_function::addition, sol::overload( + sol::resolve(const ray2&, T)>(::operator+), + sol::resolve(const ray2&, const vec2&)>(::operator+)), + + sol::meta_function::subtraction, sol::overload( + sol::resolve(const ray2&, T)>(::operator-), + sol::resolve(const ray2&, const vec2&)>(::operator-)), + + sol::meta_function::multiplication, sol::overload( + sol::resolve(const ray2&, T)>(::operator*), + sol::resolve(const ray2&, const vec2&)>(::operator*)), + + sol::meta_function::division, sol::overload( + sol::resolve(const ray2&, T)>(::operator/), + sol::resolve(const ray2&, const vec2&)>(::operator/)), + + "approximately", [](const ray2& l, const ray2& r){ return math::approximately(l,r); }, + + "contains_nan", sol::resolve&)>(&math::contains_nan)); + } +} + +namespace e2d::bindings::math +{ + void bind_ray2(sol::state& l) { + bind_ray2_t("r2f", l); + } +} diff --git a/sources/enduro2d/high/bindings/math_binds/ray3_binds.cpp b/sources/enduro2d/high/bindings/math_binds/ray3_binds.cpp new file mode 100644 index 00000000..1f39e0af --- /dev/null +++ b/sources/enduro2d/high/bindings/math_binds/ray3_binds.cpp @@ -0,0 +1,65 @@ +/******************************************************************************* + * This file is part of the "Enduro2D" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2018-2019, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#include "_math_binds.hpp" + +namespace +{ + using namespace e2d; + + template < typename T > + void bind_ray3_t(const str& name, sol::state& l) { + l.new_usertype>(name, + sol::constructors< + ray3(), + ray3(ray3), + ray3(T,T,T), + ray3(T,T,T,T,T,T), + ray3(vec3), + ray3(vec3,vec3)>(), + + "zero", &ray3::zero, + "unit", &ray3::unit_x, + "unit_y", &ray3::unit_y, + "unit_z", &ray3::unit_z, + + "origin", &ray3::origin, + "direction", &ray3::direction, + + sol::meta_function::to_string, [](const ray3& v){ + return strings::rformat("%0", v); + }, + + sol::meta_function::equal_to, sol::resolve&, const ray3&)>(::operator==), + + sol::meta_function::addition, sol::overload( + sol::resolve(const ray3&, T)>(::operator+), + sol::resolve(const ray3&, const vec3&)>(::operator+)), + + sol::meta_function::subtraction, sol::overload( + sol::resolve(const ray3&, T)>(::operator-), + sol::resolve(const ray3&, const vec3&)>(::operator-)), + + sol::meta_function::multiplication, sol::overload( + sol::resolve(const ray3&, T)>(::operator*), + sol::resolve(const ray3&, const vec3&)>(::operator*)), + + sol::meta_function::division, sol::overload( + sol::resolve(const ray3&, T)>(::operator/), + sol::resolve(const ray3&, const vec3&)>(::operator/)), + + "approximately", [](const ray3& l, const ray3& r){ return math::approximately(l,r); }, + + "contains_nan", sol::resolve&)>(&math::contains_nan)); + } +} + +namespace e2d::bindings::math +{ + void bind_ray3(sol::state& l) { + bind_ray3_t("r3f", l); + } +} diff --git a/untests/sources/untests_math/ray2.cpp b/untests/sources/untests_math/ray2.cpp index e11c495b..bf0e560a 100644 --- a/untests/sources/untests_math/ray2.cpp +++ b/untests/sources/untests_math/ray2.cpp @@ -47,8 +47,8 @@ TEST_CASE("ray2") { REQUIRE(r2i(1,2).origin == v2i(0,0)); REQUIRE(r2i(1,2).direction == v2i(1,2)); - REQUIRE(r2i({1,2}).origin == v2i(0,0)); - REQUIRE(r2i({1,2}).direction == v2i(1,2)); + REQUIRE(r2i(v2i{1,2}).origin == v2i(0,0)); + REQUIRE(r2i(v2i{1,2}).direction == v2i(1,2)); REQUIRE(r2i(1,2,3,4).origin == v2i(1,2)); REQUIRE(r2i(1,2,3,4).direction == v2i(3,4)); @@ -140,7 +140,7 @@ TEST_CASE("ray2") { { REQUIRE_FALSE(math::contains_nan(r2i({1,2},{3,4}))); REQUIRE_FALSE(math::contains_nan(r2f({1.f,2.f},{3.f,4.f}))); - REQUIRE(math::contains_nan(r2f({1.f,std::numeric_limits::quiet_NaN()}))); - REQUIRE(math::contains_nan(r2f({std::numeric_limits::infinity(), 1.f}))); + REQUIRE(math::contains_nan(r2f(1.f,std::numeric_limits::quiet_NaN()))); + REQUIRE(math::contains_nan(r2f(std::numeric_limits::infinity(), 1.f))); } } diff --git a/untests/sources/untests_math/ray3.cpp b/untests/sources/untests_math/ray3.cpp index e73c474a..c25a3341 100644 --- a/untests/sources/untests_math/ray3.cpp +++ b/untests/sources/untests_math/ray3.cpp @@ -48,8 +48,8 @@ TEST_CASE("ray3") { REQUIRE(r3i(1,2,3).origin == v3i(0,0,0)); REQUIRE(r3i(1,2,3).direction == v3i(1,2,3)); - REQUIRE(r3i({1,2,3}).origin == v3i(0,0,0)); - REQUIRE(r3i({1,2,3}).direction == v3i(1,2,3)); + REQUIRE(r3i(v3i{1,2,3}).origin == v3i(0,0,0)); + REQUIRE(r3i(v3i{1,2,3}).direction == v3i(1,2,3)); REQUIRE(r3i(1,2,3,3,4,5).origin == v3i(1,2,3)); REQUIRE(r3i(1,2,3,3,4,5).direction == v3i(3,4,5)); @@ -149,7 +149,7 @@ TEST_CASE("ray3") { { REQUIRE_FALSE(math::contains_nan(r3i({1,2,3},{3,4,5}))); REQUIRE_FALSE(math::contains_nan(r3f({1.f,2.f,3.f},{3.f,4.f,5.f}))); - REQUIRE(math::contains_nan(r3f({1.f,2.f,std::numeric_limits::quiet_NaN()}))); - REQUIRE(math::contains_nan(r3f({std::numeric_limits::infinity(), 1.f,2.f}))); + REQUIRE(math::contains_nan(r3f(1.f,2.f,std::numeric_limits::quiet_NaN()))); + REQUIRE(math::contains_nan(r3f(std::numeric_limits::infinity(), 1.f,2.f))); } } diff --git a/untests/sources/untests_utils/strfmts.cpp b/untests/sources/untests_utils/strfmts.cpp index 4cb1a41d..5ebbbd76 100644 --- a/untests/sources/untests_utils/strfmts.cpp +++ b/untests/sources/untests_utils/strfmts.cpp @@ -156,10 +156,20 @@ TEST_CASE("strfmts") { " 4.00us"); } { + REQUIRE(strings::rformat("%0", make_ray2(v2i{1,2},v2i{3,4})) == "(1,2,3,4)"); + REQUIRE(strings::rformat("%0", make_ray3(v3i{1,2,3},v3i{4,5,6})) == "(1,2,3,4,5,6)"); + REQUIRE(strings::rformat("%0", make_rect(1,2,3,4)) == "(1,2,3,4)"); REQUIRE(strings::rformat("%0", make_quat(1,2,3,4)) == "(1,2,3,4)"); REQUIRE(strings::rformat("%0", make_aabb(1,2,3,4,5,6)) == "(1,2,3,4,5,6)"); + REQUIRE(strings::rformat( + "%0", + strings::make_format_arg(make_ray2(v2f{1.f,2.f},v2f{3.f,4.f}), u8(5), u8(2))) == "( 1.00, 2.00, 3.00, 4.00)"); + REQUIRE(strings::rformat( + "%0", + strings::make_format_arg(make_ray3(v3f{1.f,2.f,3.f},v3f{4.f,5.f,6.f}), u8(5), u8(2))) == "( 1.00, 2.00, 3.00, 4.00, 5.00, 6.00)"); + REQUIRE(strings::rformat( "%0", strings::make_format_arg(make_rect(1.f,2.f,3.f,4.f), u8(5), u8(2))) == "( 1.00, 2.00, 3.00, 4.00)");