diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 9c943bcae..92c9d9fd6 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -36,7 +36,7 @@ jobs: sudo ln -s /usr/lib/x86_64-linux-gnu/libluajit-5.1.a /usr/lib/x86_64-linux-gnu/liblua5.1.a sudo ln -s /usr/include/luajit-2.1 /usr/include/lua # install EnTT - git clone https://github.com/skypjack/entt.git + git clone --branch v3.16.0 https://github.com/skypjack/entt.git cd entt/build cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_BUILD_TYPE=Release -DENTT_INSTALL=on .. sudo make install diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index ddaa95f8a..652cc26f9 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -44,7 +44,7 @@ jobs: sudo ln -s /usr/lib/x86_64-linux-gnu/libluajit-5.1.a /usr/lib/x86_64-linux-gnu/liblua-5.1.a sudo ln -s /usr/include/luajit-2.1 /usr/include/lua # install EnTT - git clone https://github.com/skypjack/entt.git + git clone --branch v3.16.0 https://github.com/skypjack/entt.git cd entt/build cmake -DCMAKE_BUILD_TYPE=Release -DENTT_INSTALL=on .. sudo make install diff --git a/Dockerfile b/Dockerfile index 9d0005f59..e067b92d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,8 +37,8 @@ RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cm rm cmake-${CMAKE_VERSION}-linux-x86_64.sh -# Install EnTT -RUN git clone https://github.com/skypjack/entt.git && \ +# Install specific EnTT version (the latest version that supports C++17). +RUN git clone --branch v3.16.0 https://github.com/skypjack/entt.git && \ cd entt/build && \ cmake -DCMAKE_BUILD_TYPE=Release -DENTT_INSTALL=on .. && \ make install && \ diff --git a/README.md b/README.md index 894432638..1221148c3 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,10 @@ #### Install EnTT +Installing last version that supports C++17. + ```sh -git clone https://github.com/skypjack/entt.git +git clone --branch v3.16.0 https://github.com/skypjack/entt.git cd entt mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release -DENTT_INSTALL=ON .. diff --git a/src/logic/scripting/lua/libs/lib__transform.cpp b/src/logic/scripting/lua/libs/lib__transform.cpp index 1edbaa5c2..7cf7bed62 100644 --- a/src/logic/scripting/lua/libs/lib__transform.cpp +++ b/src/logic/scripting/lua/libs/lib__transform.cpp @@ -1,5 +1,24 @@ #include "libentity.hpp" +#include "maths/util.hpp" + +static void check_valid(const glm::vec3& vec) { + if (util::is_nan_or_inf(vec)) { + throw std::invalid_argument( + "invalid vector: " + std::to_string(vec.x) + ", " + + std::to_string(vec.y) + ", " + std::to_string(vec.z) + ); + } +} + +static void check_valid(const glm::mat3& vec) { + if (util::is_nan_or_inf(vec)) { + throw std::invalid_argument( + "invalid matrix (contains nan or inf values)" + ); + } +} + static int l_get_pos(lua::State* L) { if (auto entity = get_entity(L, 1)) { return lua::pushvec3(L, entity->getTransform().pos); @@ -10,6 +29,7 @@ static int l_get_pos(lua::State* L) { static int l_set_pos(lua::State* L) { if (auto entity = get_entity(L, 1)) { auto vec = lua::tovec3(L, 2); + check_valid(vec); entity->getTransform().setPos(vec); entity->getRigidbody().hitbox.position = vec; } @@ -25,7 +45,9 @@ static int l_get_size(lua::State* L) { static int l_set_size(lua::State* L) { if (auto entity = get_entity(L, 1)) { - entity->getTransform().setSize(lua::tovec3(L, 2)); + auto vec = lua::tovec3(L, 2); + check_valid(vec); + entity->getTransform().setSize(vec); } return 0; } @@ -39,7 +61,9 @@ static int l_get_rot(lua::State* L) { static int l_set_rot(lua::State* L) { if (auto entity = get_entity(L, 1)) { - entity->getTransform().setRot(lua::tomat4(L, 2)); + auto matrix = lua::tomat4(L, 2); + check_valid(matrix); + entity->getTransform().setRot(matrix); } return 0; } diff --git a/src/maths/util.hpp b/src/maths/util.hpp index 92d02d826..cb58212eb 100644 --- a/src/maths/util.hpp +++ b/src/maths/util.hpp @@ -162,4 +162,19 @@ namespace util { return a + glm::ivec3(glm::round(glm::vec3(vec) * t)); } + + template + bool is_nan_or_inf(const glm::vec& vector) { + return glm::any(glm::isnan(vector)) || glm::any(glm::isinf(vector)); + } + + template + bool is_nan_or_inf(const glm::mat& matrix) { + for (int i = 0; i < n; i++) { + if (is_nan_or_inf(matrix[i])) { + return true; + } + } + return false; + } } diff --git a/src/objects/Transform.cpp b/src/objects/Transform.cpp index 8779e2201..da876b81e 100644 --- a/src/objects/Transform.cpp +++ b/src/objects/Transform.cpp @@ -1,9 +1,13 @@ #include "Transform.hpp" #include "data/dv_util.hpp" +#include "debug/Logger.hpp" +#include "maths/util.hpp" #include +static debug::Logger logger("entity-transform"); + void Transform::refresh() { combined = glm::mat4(1.0f); combined = glm::translate(combined, pos); @@ -31,3 +35,34 @@ void Transform::deserialize(const dv::value& root) { dv::get_vec(root, "size", size); dv::get_mat(root, "rot", rot); } + +bool Transform::checkValue(const glm::vec3& vector, std::string_view name) { + if (util::is_nan_or_inf(vector)) { + auto message = "invalid vector attempted set to " + std::string(name) + + " : " + std::to_string(vector.x) + ", " + + std::to_string(vector.y) + ", " + + std::to_string(vector.z); +#ifndef NDEBUG + throw std::invalid_argument(message); +#else + logger.warning() << message; + return false; +#endif + } + return true; +} + +bool Transform::checkValue(const glm::mat3& matrix, std::string_view name) { + if (util::is_nan_or_inf(matrix)) { + auto message = + "invalid matrix (contains nan or inf) attempted set to " + + std::string(name); +#ifndef NDEBUG + throw std::invalid_argument(message); +#else + logger.warning() << message; + return false; +#endif + } + return true; +} diff --git a/src/objects/Transform.hpp b/src/objects/Transform.hpp index b948bd297..8c49d6859 100644 --- a/src/objects/Transform.hpp +++ b/src/objects/Transform.hpp @@ -2,6 +2,7 @@ #define GLM_ENABLE_EXPERIMENTAL +#include #include #include #include @@ -24,11 +25,17 @@ struct Transform { void refresh(); inline void setRot(const glm::mat3& m) { + if (!checkValue(m, "rotation")) { + return; + } rot = m; dirty = true; } inline void setSize(const glm::vec3& v) { + if (!checkValue(v, "size")) { + return; + } if (glm::distance2(displaySize, v) >= EPSILON) { dirty = true; } @@ -36,9 +43,15 @@ struct Transform { } inline void setPos(const glm::vec3& v) { + if (!checkValue(v, "position")) { + return; + } if (glm::distance2(displayPos, v) >= EPSILON) { dirty = true; } pos = v; } + + static bool checkValue(const glm::vec3& v, std::string_view name); + static bool checkValue(const glm::mat3& v, std::string_view name); };