From 91090342bf6d0660de191eccb5ac0bc76a1c3f9d Mon Sep 17 00:00:00 2001 From: Orange Date: Wed, 29 Jul 2026 12:54:51 +0300 Subject: [PATCH] Auto stash before checking out "origin/main" --- source/lua/lua_engine_cry.cpp | 13 ++ source/lua/lua_engine_frostbite.cpp | 13 ++ source/lua/lua_engine_iw.cpp | 13 ++ source/lua/lua_engine_opengl.cpp | 13 ++ source/lua/lua_engine_rage.cpp | 13 ++ source/lua/lua_engine_source.cpp | 13 ++ source/lua/lua_engine_unity.cpp | 13 ++ source/lua/lua_engine_unreal.cpp | 13 ++ source/lua/lua_engines.cpp | 290 +++++----------------------- source/lua/lua_engines_detail.hpp | 142 ++++++++++++++ 10 files changed, 294 insertions(+), 242 deletions(-) create mode 100644 source/lua/lua_engine_cry.cpp create mode 100644 source/lua/lua_engine_frostbite.cpp create mode 100644 source/lua/lua_engine_iw.cpp create mode 100644 source/lua/lua_engine_opengl.cpp create mode 100644 source/lua/lua_engine_rage.cpp create mode 100644 source/lua/lua_engine_source.cpp create mode 100644 source/lua/lua_engine_unity.cpp create mode 100644 source/lua/lua_engine_unreal.cpp create mode 100644 source/lua/lua_engines_detail.hpp diff --git a/source/lua/lua_engine_cry.cpp b/source/lua/lua_engine_cry.cpp new file mode 100644 index 0000000..fbd33d6 --- /dev/null +++ b/source/lua/lua_engine_cry.cpp @@ -0,0 +1,13 @@ +#ifdef OMATH_ENABLE_LUA +#include "lua_engines_detail.hpp" +#include + +namespace omath::lua::detail +{ + void register_cry_engine(sol::table& omath_table) + { + register_engine( + omath_table, "cry"); + } +} // namespace omath::lua::detail +#endif diff --git a/source/lua/lua_engine_frostbite.cpp b/source/lua/lua_engine_frostbite.cpp new file mode 100644 index 0000000..a46ab2e --- /dev/null +++ b/source/lua/lua_engine_frostbite.cpp @@ -0,0 +1,13 @@ +#ifdef OMATH_ENABLE_LUA +#include "lua_engines_detail.hpp" +#include + +namespace omath::lua::detail +{ + void register_frostbite_engine(sol::table& omath_table) + { + register_engine(omath_table, "frostbite"); + } +} // namespace omath::lua::detail +#endif diff --git a/source/lua/lua_engine_iw.cpp b/source/lua/lua_engine_iw.cpp new file mode 100644 index 0000000..ad4e8e7 --- /dev/null +++ b/source/lua/lua_engine_iw.cpp @@ -0,0 +1,13 @@ +#ifdef OMATH_ENABLE_LUA +#include "lua_engines_detail.hpp" +#include + +namespace omath::lua::detail +{ + void register_iw_engine(sol::table& omath_table) + { + register_engine( + omath_table, "iw"); + } +} // namespace omath::lua::detail +#endif diff --git a/source/lua/lua_engine_opengl.cpp b/source/lua/lua_engine_opengl.cpp new file mode 100644 index 0000000..14f77ff --- /dev/null +++ b/source/lua/lua_engine_opengl.cpp @@ -0,0 +1,13 @@ +#ifdef OMATH_ENABLE_LUA +#include "lua_engines_detail.hpp" +#include + +namespace omath::lua::detail +{ + void register_opengl_engine(sol::table& omath_table) + { + register_engine(omath_table, "opengl"); + } +} // namespace omath::lua::detail +#endif diff --git a/source/lua/lua_engine_rage.cpp b/source/lua/lua_engine_rage.cpp new file mode 100644 index 0000000..26a12bd --- /dev/null +++ b/source/lua/lua_engine_rage.cpp @@ -0,0 +1,13 @@ +#ifdef OMATH_ENABLE_LUA +#include "lua_engines_detail.hpp" +#include + +namespace omath::lua::detail +{ + void register_rage_engine(sol::table& omath_table) + { + register_engine( + omath_table, "rage"); + } +} // namespace omath::lua::detail +#endif diff --git a/source/lua/lua_engine_source.cpp b/source/lua/lua_engine_source.cpp new file mode 100644 index 0000000..50a89de --- /dev/null +++ b/source/lua/lua_engine_source.cpp @@ -0,0 +1,13 @@ +#ifdef OMATH_ENABLE_LUA +#include "lua_engines_detail.hpp" +#include + +namespace omath::lua::detail +{ + void register_source_engine(sol::table& omath_table) + { + register_engine(omath_table, "source"); + } +} // namespace omath::lua::detail +#endif diff --git a/source/lua/lua_engine_unity.cpp b/source/lua/lua_engine_unity.cpp new file mode 100644 index 0000000..d135d5b --- /dev/null +++ b/source/lua/lua_engine_unity.cpp @@ -0,0 +1,13 @@ +#ifdef OMATH_ENABLE_LUA +#include "lua_engines_detail.hpp" +#include + +namespace omath::lua::detail +{ + void register_unity_engine(sol::table& omath_table) + { + register_engine(omath_table, "unity"); + } +} // namespace omath::lua::detail +#endif diff --git a/source/lua/lua_engine_unreal.cpp b/source/lua/lua_engine_unreal.cpp new file mode 100644 index 0000000..894c1e8 --- /dev/null +++ b/source/lua/lua_engine_unreal.cpp @@ -0,0 +1,13 @@ +#ifdef OMATH_ENABLE_LUA +#include "lua_engines_detail.hpp" +#include + +namespace omath::lua::detail +{ + void register_unreal_engine(sol::table& omath_table) + { + register_engine(omath_table, "unreal"); + } +} // namespace omath::lua::detail +#endif diff --git a/source/lua/lua_engines.cpp b/source/lua/lua_engines.cpp index f64cae2..b9754c4 100644 --- a/source/lua/lua_engines.cpp +++ b/source/lua/lua_engines.cpp @@ -2,269 +2,75 @@ // Created by orange on 07.03.2026. // #ifdef OMATH_ENABLE_LUA -#include "omath/lua/lua.hpp" -#include "omath/omath.hpp" -#include "omath/projection/error_codes.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace -{ - // ---- Canonical shared C++ type aliases ---------------------------------- - // Each unique template instantiation must be registered exactly once. - - using PitchAngle90 = omath::Angle; - using PitchAngle89 = omath::Angle; - using SharedYawRoll = omath::Angle; - using SharedFoV = omath::Angle; - using ViewAngles90 = omath::ViewAngles; - using ViewAngles89 = omath::ViewAngles; - - std::string projection_error_to_string(omath::projection::Error e) - { - switch (e) - { - case omath::projection::Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS: - return "world position is out of screen bounds"; - case omath::projection::Error::INV_VIEW_PROJ_MAT_DET_EQ_ZERO: - return "inverse view-projection matrix determinant is zero"; - case omath::projection::Error::PERSPECTIVE_DIVIDER_LESS_EQ_ZERO: - return "perspective divider is less or equal to zero"; - } - return "unknown error"; - } - - template - void register_angle(sol::table& table, const char* name) - { - table.new_usertype( - name, sol::no_constructor, "from_degrees", &AngleType::from_degrees, "from_radians", - &AngleType::from_radians, "as_degrees", &AngleType::as_degrees, "as_radians", &AngleType::as_radians, - "sin", &AngleType::sin, "cos", &AngleType::cos, "tan", &AngleType::tan, "cot", &AngleType::cot, - sol::meta_function::addition, [](const AngleType& a, const AngleType& b) - { return AngleType::from_degrees(a.as_degrees() + b.as_degrees()); }, sol::meta_function::subtraction, - [](const AngleType& a, const AngleType& b) - { return AngleType::from_degrees(a.as_degrees() - b.as_degrees()); }, sol::meta_function::unary_minus, - [](const AngleType& a) { return AngleType::from_degrees(-a.as_degrees()); }, - sol::meta_function::equal_to, [](const AngleType& a, const AngleType& b) { return a == b; }, - sol::meta_function::to_string, [](const AngleType& a) { return std::format("{}deg", a.as_degrees()); }); - } - - // Set aliases in an engine subtable pointing to the already-registered shared types - template - void set_engine_aliases(sol::table& engine_table, sol::table& types) - { - if constexpr (std::is_same_v) - engine_table["PitchAngle"] = types["PitchAngle90"]; - else - engine_table["PitchAngle"] = types["PitchAngle89"]; - - engine_table["YawAngle"] = types["YawRoll"]; - engine_table["RollAngle"] = types["YawRoll"]; - engine_table["FieldOfView"] = types["FieldOfView"]; - engine_table["ViewPort"] = types["ViewPort"]; - - if constexpr (std::is_same_v) - engine_table["ViewAngles"] = types["ViewAngles90"]; - else - engine_table["ViewAngles"] = types["ViewAngles89"]; - } - - // Register an engine: alias shared types, register unique Camera - template - requires std::is_arithmetic_v - void register_engine(sol::table& omath_table, const char* subtable_name) - { - using PitchAngle = typename EngineTraits::PitchAngle; - using ViewAngles = typename EngineTraits::ViewAngles; - using Camera = typename EngineTraits::Camera; - using Mat4X4 = std::remove_cvref_t().get_view_matrix())>; - - auto engine_table = omath_table[subtable_name].get_or_create(); - auto types = omath_table["_types"].get(); - - set_engine_aliases(engine_table, types); - - auto camera_type = engine_table.new_usertype( - "Camera", - sol::constructors&, const ViewAngles&, - const omath::projection::ViewPort&, const omath::projection::FieldOfView&, - ArithmeticType, ArithmeticType)>()); - - camera_type["look_at"] = &Camera::look_at; - camera_type["get_forward"] = &Camera::get_forward; - camera_type["get_right"] = &Camera::get_right; - camera_type["get_up"] = &Camera::get_up; - camera_type["get_origin"] = &Camera::get_origin; - camera_type["get_view_angles"] = &Camera::get_view_angles; - camera_type["get_near_plane"] = &Camera::get_near_plane; - camera_type["get_far_plane"] = &Camera::get_far_plane; - camera_type["get_field_of_view"] = &Camera::get_field_of_view; - camera_type["set_origin"] = &Camera::set_origin; - camera_type["set_view_angles"] = &Camera::set_view_angles; - camera_type["set_view_port"] = &Camera::set_view_port; - camera_type["set_field_of_view"] = &Camera::set_field_of_view; - camera_type["set_near_plane"] = &Camera::set_near_plane; - camera_type["set_far_plane"] = &Camera::set_far_plane; - - camera_type["get_view_matrix"] = [](const Camera& cam) -> Mat4X4 - { - return cam.get_view_matrix(); - }; - camera_type["get_projection_matrix"] = [](const Camera& cam) -> Mat4X4 - { - return cam.get_projection_matrix(); - }; - camera_type["get_view_projection_matrix"] = [](const Camera& cam) -> Mat4X4 - { - return cam.get_view_projection_matrix(); - }; - camera_type["extract_projection_params"] = [](const Mat4X4& projection_matrix) - { - const auto params = Camera::extract_projection_params(projection_matrix); - return std::make_tuple(params.fov, params.aspect_ratio); - }; - camera_type["calc_view_angles_from_view_matrix"] = &Camera::calc_view_angles_from_view_matrix; - camera_type["calc_origin_from_view_matrix"] = &Camera::calc_origin_from_view_matrix; - - camera_type["world_to_screen"] = [](const Camera& cam, const omath::Vector3& pos) - -> std::tuple>, sol::optional> - { - auto result = cam.world_to_screen(pos); - if (result) - return {*result, sol::nullopt}; - return {sol::nullopt, projection_error_to_string(result.error())}; - }; - - camera_type["screen_to_world"] = [](const Camera& cam, const omath::Vector3& pos) - -> std::tuple>, sol::optional> - { - auto result = cam.screen_to_world(pos); - if (result) - return {*result, sol::nullopt}; - return {sol::nullopt, projection_error_to_string(result.error())}; - }; - } - - // ---- Engine trait structs ----------------------------------------------- - - struct OpenGLEngineTraits - { - using PitchAngle = omath::opengl_engine::PitchAngle; - using ViewAngles = omath::opengl_engine::ViewAngles; - using Camera = omath::opengl_engine::Camera; - }; - struct FrostbiteEngineTraits - { - using PitchAngle = omath::frostbite_engine::PitchAngle; - using ViewAngles = omath::frostbite_engine::ViewAngles; - using Camera = omath::frostbite_engine::Camera; - }; - struct IWEngineTraits - { - using PitchAngle = omath::iw_engine::PitchAngle; - using ViewAngles = omath::iw_engine::ViewAngles; - using Camera = omath::iw_engine::Camera; - }; - struct SourceEngineTraits - { - using PitchAngle = omath::source_engine::PitchAngle; - using ViewAngles = omath::source_engine::ViewAngles; - using Camera = omath::source_engine::Camera; - }; - struct RageEngineTraits - { - using PitchAngle = omath::rage_engine::PitchAngle; - using ViewAngles = omath::rage_engine::ViewAngles; - using Camera = omath::rage_engine::Camera; - }; - struct UnityEngineTraits - { - using PitchAngle = omath::unity_engine::PitchAngle; - using ViewAngles = omath::unity_engine::ViewAngles; - using Camera = omath::unity_engine::Camera; - }; - struct UnrealEngineTraits - { - using PitchAngle = omath::unreal_engine::PitchAngle; - using ViewAngles = omath::unreal_engine::ViewAngles; - using Camera = omath::unreal_engine::Camera; - }; - struct CryEngineTraits - { - using PitchAngle = omath::cry_engine::PitchAngle; - using ViewAngles = omath::cry_engine::ViewAngles; - using Camera = omath::cry_engine::Camera; - }; -} // namespace +#include "lua_engines_detail.hpp" namespace omath::lua { void LuaInterpreter::register_shared_types(sol::table& omath_table) { - auto t = omath_table["_types"].get_or_create(); + auto types = omath_table["_types"].get_or_create(); - register_angle(t, "PitchAngle90"); - register_angle(t, "PitchAngle89"); - register_angle(t, "YawRoll"); - register_angle(t, "FieldOfView"); + detail::register_angle(types, "PitchAngle90"); + detail::register_angle(types, "PitchAngle89"); + detail::register_angle(types, "YawRoll"); + detail::register_angle(types, "FieldOfView"); - t.new_usertype( - "ViewPort", sol::factories([](float w, float h) { return omath::projection::ViewPort{w, h}; }), "width", - sol::property([](const omath::projection::ViewPort& vp) { return vp.m_width; }, - [](omath::projection::ViewPort& vp, float val) { vp.m_width = val; }), + types.new_usertype( + "ViewPort", + sol::factories([](float width, float height) { return projection::ViewPort{width, height}; }), + "width", + sol::property([](const projection::ViewPort& view_port) { return view_port.m_width; }, + [](projection::ViewPort& view_port, float value) { view_port.m_width = value; }), "height", - sol::property([](const omath::projection::ViewPort& vp) { return vp.m_height; }, - [](omath::projection::ViewPort& vp, float val) { vp.m_height = val; }), - "aspect_ratio", &omath::projection::ViewPort::aspect_ratio); + sol::property([](const projection::ViewPort& view_port) { return view_port.m_height; }, + [](projection::ViewPort& view_port, float value) { view_port.m_height = value; }), + "aspect_ratio", &projection::ViewPort::aspect_ratio); - t.new_usertype( + types.new_usertype( "ViewAngles90", - sol::factories([](PitchAngle90 p, SharedYawRoll y, SharedYawRoll r) { return ViewAngles90{p, y, r}; }), + sol::factories([](detail::PitchAngle90 pitch, detail::SharedYawRoll yaw, detail::SharedYawRoll roll) + { return detail::ViewAngles90{pitch, yaw, roll}; }), "pitch", - sol::property([](const ViewAngles90& va) { return va.pitch; }, - [](ViewAngles90& va, const PitchAngle90& val) { va.pitch = val; }), + sol::property([](const detail::ViewAngles90& view_angles) { return view_angles.pitch; }, + [](detail::ViewAngles90& view_angles, const detail::PitchAngle90& value) + { view_angles.pitch = value; }), "yaw", - sol::property([](const ViewAngles90& va) { return va.yaw; }, - [](ViewAngles90& va, const SharedYawRoll& val) { va.yaw = val; }), + sol::property([](const detail::ViewAngles90& view_angles) { return view_angles.yaw; }, + [](detail::ViewAngles90& view_angles, const detail::SharedYawRoll& value) + { view_angles.yaw = value; }), "roll", - sol::property([](const ViewAngles90& va) { return va.roll; }, - [](ViewAngles90& va, const SharedYawRoll& val) { va.roll = val; })); + sol::property([](const detail::ViewAngles90& view_angles) { return view_angles.roll; }, + [](detail::ViewAngles90& view_angles, const detail::SharedYawRoll& value) + { view_angles.roll = value; })); - t.new_usertype( + types.new_usertype( "ViewAngles89", - sol::factories([](PitchAngle89 p, SharedYawRoll y, SharedYawRoll r) { return ViewAngles89{p, y, r}; }), + sol::factories([](detail::PitchAngle89 pitch, detail::SharedYawRoll yaw, detail::SharedYawRoll roll) + { return detail::ViewAngles89{pitch, yaw, roll}; }), "pitch", - sol::property([](const ViewAngles89& va) { return va.pitch; }, - [](ViewAngles89& va, const PitchAngle89& val) { va.pitch = val; }), + sol::property([](const detail::ViewAngles89& view_angles) { return view_angles.pitch; }, + [](detail::ViewAngles89& view_angles, const detail::PitchAngle89& value) + { view_angles.pitch = value; }), "yaw", - sol::property([](const ViewAngles89& va) { return va.yaw; }, - [](ViewAngles89& va, const SharedYawRoll& val) { va.yaw = val; }), + sol::property([](const detail::ViewAngles89& view_angles) { return view_angles.yaw; }, + [](detail::ViewAngles89& view_angles, const detail::SharedYawRoll& value) + { view_angles.yaw = value; }), "roll", - sol::property([](const ViewAngles89& va) { return va.roll; }, - [](ViewAngles89& va, const SharedYawRoll& val) { va.roll = val; })); + sol::property([](const detail::ViewAngles89& view_angles) { return view_angles.roll; }, + [](detail::ViewAngles89& view_angles, const detail::SharedYawRoll& value) + { view_angles.roll = value; })); } void LuaInterpreter::register_engines(sol::table& omath_table) { - register_engine(omath_table, "opengl"); - register_engine(omath_table, "frostbite"); - register_engine(omath_table, "iw"); - register_engine(omath_table, "source"); - register_engine(omath_table, "rage"); - register_engine(omath_table, "unity"); - register_engine(omath_table, "unreal"); - register_engine(omath_table, "cry"); + detail::register_opengl_engine(omath_table); + detail::register_frostbite_engine(omath_table); + detail::register_iw_engine(omath_table); + detail::register_source_engine(omath_table); + detail::register_rage_engine(omath_table); + detail::register_unity_engine(omath_table); + detail::register_unreal_engine(omath_table); + detail::register_cry_engine(omath_table); } -} // namespace omath::lua::detail +} // namespace omath::lua #endif diff --git a/source/lua/lua_engines_detail.hpp b/source/lua/lua_engines_detail.hpp new file mode 100644 index 0000000..5262676 --- /dev/null +++ b/source/lua/lua_engines_detail.hpp @@ -0,0 +1,142 @@ +#pragma once + +#include "omath/lua/lua.hpp" +#include "omath/projection/camera.hpp" +#include "omath/projection/error_codes.hpp" +#include "omath/trigonometry/view_angles.hpp" +#include +#include +#include +#include +#include +#include + +namespace omath::lua::detail +{ + using PitchAngle90 = Angle; + using PitchAngle89 = Angle; + using SharedYawRoll = Angle; + using SharedFoV = Angle; + using ViewAngles90 = ViewAngles; + using ViewAngles89 = ViewAngles; + + inline std::string projection_error_to_string(projection::Error error) + { + switch (error) + { + case projection::Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS: + return "world position is out of screen bounds"; + case projection::Error::INV_VIEW_PROJ_MAT_DET_EQ_ZERO: + return "inverse view-projection matrix determinant is zero"; + case projection::Error::PERSPECTIVE_DIVIDER_LESS_EQ_ZERO: + return "perspective divider is less or equal to zero"; + } + return "unknown error"; + } + + template + void register_angle(sol::table& table, const char* name) + { + table.new_usertype( + name, sol::no_constructor, "from_degrees", &AngleType::from_degrees, "from_radians", + &AngleType::from_radians, "as_degrees", &AngleType::as_degrees, "as_radians", &AngleType::as_radians, + "sin", &AngleType::sin, "cos", &AngleType::cos, "tan", &AngleType::tan, "cot", &AngleType::cot, + sol::meta_function::addition, [](const AngleType& a, const AngleType& b) + { return AngleType::from_degrees(a.as_degrees() + b.as_degrees()); }, sol::meta_function::subtraction, + [](const AngleType& a, const AngleType& b) + { return AngleType::from_degrees(a.as_degrees() - b.as_degrees()); }, sol::meta_function::unary_minus, + [](const AngleType& a) { return AngleType::from_degrees(-a.as_degrees()); }, + sol::meta_function::equal_to, [](const AngleType& a, const AngleType& b) { return a == b; }, + sol::meta_function::to_string, [](const AngleType& a) { return std::format("{}deg", a.as_degrees()); }); + } + + template + void set_engine_aliases(sol::table& engine_table, sol::table& types) + { + if constexpr (std::is_same_v) + engine_table["PitchAngle"] = types["PitchAngle90"]; + else + engine_table["PitchAngle"] = types["PitchAngle89"]; + + engine_table["YawAngle"] = types["YawRoll"]; + engine_table["RollAngle"] = types["YawRoll"]; + engine_table["FieldOfView"] = types["FieldOfView"]; + engine_table["ViewPort"] = types["ViewPort"]; + + if constexpr (std::is_same_v) + engine_table["ViewAngles"] = types["ViewAngles90"]; + else + engine_table["ViewAngles"] = types["ViewAngles89"]; + } + + template + requires std::is_arithmetic_v + void register_engine(sol::table& omath_table, const char* subtable_name) + { + using Mat4X4 = std::remove_cvref_t().get_view_matrix())>; + + auto engine_table = omath_table[subtable_name].get_or_create(); + auto types = omath_table["_types"].get(); + + set_engine_aliases(engine_table, types); + + auto camera_type = engine_table.new_usertype( + "Camera", + sol::constructors&, const ViewAnglesType&, + const projection::ViewPort&, const projection::FieldOfView&, ArithmeticType, + ArithmeticType)>()); + + camera_type["look_at"] = &Camera::look_at; + camera_type["get_forward"] = &Camera::get_forward; + camera_type["get_right"] = &Camera::get_right; + camera_type["get_up"] = &Camera::get_up; + camera_type["get_origin"] = &Camera::get_origin; + camera_type["get_view_angles"] = &Camera::get_view_angles; + camera_type["get_near_plane"] = &Camera::get_near_plane; + camera_type["get_far_plane"] = &Camera::get_far_plane; + camera_type["get_field_of_view"] = &Camera::get_field_of_view; + camera_type["set_origin"] = &Camera::set_origin; + camera_type["set_view_angles"] = &Camera::set_view_angles; + camera_type["set_view_port"] = &Camera::set_view_port; + camera_type["set_field_of_view"] = &Camera::set_field_of_view; + camera_type["set_near_plane"] = &Camera::set_near_plane; + camera_type["set_far_plane"] = &Camera::set_far_plane; + camera_type["get_view_matrix"] = [](const Camera& camera) -> Mat4X4 { return camera.get_view_matrix(); }; + camera_type["get_projection_matrix"] = [](const Camera& camera) -> Mat4X4 + { return camera.get_projection_matrix(); }; + camera_type["get_view_projection_matrix"] = [](const Camera& camera) -> Mat4X4 + { return camera.get_view_projection_matrix(); }; + camera_type["extract_projection_params"] = [](const Mat4X4& projection_matrix) + { + const auto params = Camera::extract_projection_params(projection_matrix); + return std::make_tuple(params.fov, params.aspect_ratio); + }; + camera_type["calc_view_angles_from_view_matrix"] = &Camera::calc_view_angles_from_view_matrix; + camera_type["calc_origin_from_view_matrix"] = &Camera::calc_origin_from_view_matrix; + camera_type["world_to_screen"] = [](const Camera& camera, const Vector3& position) + -> std::tuple>, sol::optional> + { + auto result = camera.world_to_screen(position); + if (result) + return {*result, sol::nullopt}; + return {sol::nullopt, projection_error_to_string(result.error())}; + }; + camera_type["screen_to_world"] = [](const Camera& camera, const Vector3& position) + -> std::tuple>, sol::optional> + { + auto result = camera.screen_to_world(position); + if (result) + return {*result, sol::nullopt}; + return {sol::nullopt, projection_error_to_string(result.error())}; + }; + } + + void register_opengl_engine(sol::table& omath_table); + void register_frostbite_engine(sol::table& omath_table); + void register_iw_engine(sol::table& omath_table); + void register_source_engine(sol::table& omath_table); + void register_rage_engine(sol::table& omath_table); + void register_unity_engine(sol::table& omath_table); + void register_unreal_engine(sol::table& omath_table); + void register_cry_engine(sol::table& omath_table); +} // namespace omath::lua::detail