From ff4917825f778a28748eba59d5c7db293d32eeb9 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Sun, 23 Oct 2022 21:29:58 +0800 Subject: [PATCH] Make source compatible with latest version of MSVC. Add compile-time math header --- CMakeLists.txt | 1 - src/ai/bt/node.hpp | 64 ++++---- src/animation/spring.hpp | 2 + src/animation/tween.hpp | 1 + src/color/xyy.hpp | 2 +- src/color/xyz.hpp | 2 +- src/config.hpp.in | 2 +- src/game/ant/swarm.cpp | 2 +- src/game/system/astronomy.cpp | 4 +- src/game/system/terrain.cpp | 14 +- src/game/system/terrain.hpp | 4 +- src/genetics/base.cpp | 4 +- src/geom/hyperoctree.hpp | 172 +++++++++------------- src/geom/octree.hpp | 12 +- src/geom/quadtree.hpp | 12 +- src/math/compile.hpp | 61 ++++++++ src/math/matrix.hpp | 4 +- src/math/transform-type.hpp | 2 +- src/math/vector.hpp | 8 +- src/resources/behavior-tree-loader.cpp | 4 +- src/resources/entity-archetype-loader.cpp | 6 +- src/resources/resource-manager.hpp | 2 +- 22 files changed, 208 insertions(+), 177 deletions(-) create mode 100644 src/math/compile.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 74f34e5..a8b55b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,6 @@ set(STATIC_LIBS stb tinyexr glad - EnTT SDL2::SDL2-static SDL2::SDL2main OpenAL::OpenAL diff --git a/src/ai/bt/node.hpp b/src/ai/bt/node.hpp index 9697057..6ada8e5 100644 --- a/src/ai/bt/node.hpp +++ b/src/ai/bt/node.hpp @@ -51,98 +51,98 @@ using leaf_node = node; /// A node with exactly one child. template -struct decorator_node: node +struct decorator_node: public node { - node* child; + node* child; }; /// A node that can have one or more children. template -struct composite_node: node +struct composite_node: public node { - std::list children; + std::list*> children; }; /// Executes a function on a context and returns the status. template -struct action: leaf_node +struct action: public leaf_node { - virtual status execute(context_type& context) const final; - typedef std::function function_type; + virtual status execute(node::context_type& context) const final; + typedef std::function::context_type&)> function_type; function_type function; }; /// Evaluates a boolean condition (predicate) and returns either `status::success` or `status::failure`. template -struct condition: leaf_node +struct condition: public leaf_node { - virtual status execute(context_type& context) const final; - typedef std::function predicate_type; + virtual status execute(node::context_type& context) const final; + typedef std::function::context_type&)> predicate_type; predicate_type predicate; }; /// Executes a child node and returns its inverted status. If the child returns `status::success`, then `status::failure` will be returned. Otherwise if the child returns `status::failure`, then `status::success` will be returned. template -struct inverter: decorator_node +struct inverter: public decorator_node { - virtual status execute(context_type& context) const final; + virtual status execute(node::context_type& context) const final; }; /// Attempts to execute a child node `n` times or until the child fails. template -struct repeater: decorator_node +struct repeater: public decorator_node { - virtual status execute(context_type& context) const final; + virtual status execute(node::context_type& context) const final; int n; }; /// Executes a child node and returns `status::success` regardless of the child node status. template -struct succeeder: decorator_node +struct succeeder: public decorator_node { - virtual status execute(context_type& context) const final; + virtual status execute(node::context_type& context) const final; }; /// Attempts to execute each child node sequentially until one fails. If all children are executed successfully, `status::success` will be returned. Otherwise if any children fail, `status::failure` will be returned. template -struct sequence: composite_node +struct sequence: public composite_node { - virtual status execute(context_type& context) const final; + virtual status execute(node::context_type& context) const final; }; /// Attempts to execute each child node sequentially until one succeeds. If a child succeeds, `status::success` will be returned. Otherwise if all children fail, `status::failure` will be returned. template -struct selector: composite_node +struct selector: public composite_node { - virtual status execute(context_type& context) const final; + virtual status execute(node::context_type& context) const final; }; template -status action::execute(context_type& context) const +status action::execute(node::context_type& context) const { return function(context); } template -status condition::execute(context_type& context) const +status condition::execute(node::context_type& context) const { return (predicate(context)) ? status::success : status::failure; } template -status inverter::execute(context_type& context) const +status inverter::execute(node::context_type& context) const { - status child_status = child->execute(context); + status child_status = decorator_node::child->execute(context); return (child_status == status::success) ? status::failure : (child_status == status::failure) ? status::success : child_status; } template -status repeater::execute(context_type& context) const +status repeater::execute(node::context_type& context) const { status child_status; for (int i = 0; i < n; ++i) { - child_status = child->execute(context); + child_status = decorator_node::child->execute(context); if (child_status == status::failure) break; } @@ -150,16 +150,16 @@ status repeater::execute(context_type& context) const } template -status succeeder::execute(context_type& context) const +status succeeder::execute(node::context_type& context) const { - child->execute(context); + decorator_node::child->execute(context); return status::success; } template -status sequence::execute(context_type& context) const +status sequence::execute(node::context_type& context) const { - for (const node* child: children) + for (const node* child: composite_node::children) { status child_status = child->execute(context); if (child_status != status::success) @@ -169,9 +169,9 @@ status sequence::execute(context_type& context) const } template -status selector::execute(context_type& context) const +status selector::execute(node::context_type& context) const { - for (const node* child: children) + for (const node* child: composite_node::children) { status child_status = child->execute(context); if (child_status != status::failure) diff --git a/src/animation/spring.hpp b/src/animation/spring.hpp index 1cd80ea..84d2fbb 100644 --- a/src/animation/spring.hpp +++ b/src/animation/spring.hpp @@ -20,6 +20,8 @@ #ifndef ANTKEEPER_SPRING_HPP #define ANTKEEPER_SPRING_HPP +#include "math/constants.hpp" + /** * Contains the variables required for numeric springing. * diff --git a/src/animation/tween.hpp b/src/animation/tween.hpp index 18359ed..e1a857c 100644 --- a/src/animation/tween.hpp +++ b/src/animation/tween.hpp @@ -22,6 +22,7 @@ #include #include +#include #include /** diff --git a/src/color/xyy.hpp b/src/color/xyy.hpp index 2f8dc02..c81e644 100644 --- a/src/color/xyy.hpp +++ b/src/color/xyy.hpp @@ -48,7 +48,7 @@ constexpr inline T luminance(const math::vector3& x) template constexpr math::vector2 to_ucs(const math::vector3& x) { - const T d = T({1} / (T{-2} * x[0] + T{12} * x[1] + T{3})); + const T d = (T{1} / (T{-2} * x[0] + T{12} * x[1] + T{3})); return math::vector2{(T{4} * x[0]) * d, (T{6} * x[1]) * d}; } diff --git a/src/color/xyz.hpp b/src/color/xyz.hpp index 0601f59..ad7ff24 100644 --- a/src/color/xyz.hpp +++ b/src/color/xyz.hpp @@ -53,7 +53,7 @@ template constexpr math::vector3 to_xyy(const math::vector3& x) { const T sum = x[0] + x[1] + x[2]; - return math::vector3{x[0] / sum, x[1] / sum, x[1]} + return math::vector3{x[0] / sum, x[1] / sum, x[1]}; } /** diff --git a/src/config.hpp.in b/src/config.hpp.in index bf78091..425b4d6 100644 --- a/src/config.hpp.in +++ b/src/config.hpp.in @@ -28,7 +28,7 @@ namespace config { constexpr int version_major = @PROJECT_VERSION_MAJOR@; constexpr int version_minor = @PROJECT_VERSION_MINOR@; constexpr int version_patch = @PROJECT_VERSION_PATCH@; -constexpr char* version_string = "@PROJECT_VERSION@"; +constexpr const char* version_string = "@PROJECT_VERSION@"; constexpr math::vector global_forward = {0.0f, 0.0f, -1.0f}; constexpr math::vector global_up = {0.0f, 1.0f, 0.0f}; diff --git a/src/game/ant/swarm.cpp b/src/game/ant/swarm.cpp index 2ffdfe5..300cc1f 100644 --- a/src/game/ant/swarm.cpp +++ b/src/game/ant/swarm.cpp @@ -39,7 +39,7 @@ namespace ant { template static math::vector3 sphere_random(Generator& rng) { - const std::uniform_real_distribution distribution(T{-1}, T{1}); + std::uniform_real_distribution distribution(T{-1}, T{1}); math::vector3 position; for (std::size_t i = 0; i < 3; ++i) diff --git a/src/game/system/astronomy.cpp b/src/game/system/astronomy.cpp index 955fc60..e50fdc7 100644 --- a/src/game/system/astronomy.cpp +++ b/src/game/system/astronomy.cpp @@ -168,7 +168,7 @@ void astronomy::update(double t, double dt) // Update blackbody lighting registry.view().each( - [&](entity::id entity_id, const auto& blackbody_body, const auto& blackbody_orbit, const auto& blackbody) + [&, bounce_normal](entity::id entity_id, const auto& blackbody_body, const auto& blackbody_orbit, const auto& blackbody) { // Transform blackbody position from ICRF frame to EUS frame const double3 blackbody_position_eus = icrf_to_eus * blackbody_orbit.position; @@ -248,7 +248,7 @@ void astronomy::update(double t, double dt) // Update diffuse reflectors this->registry.view().each( - [&](entity::id entity_id, const auto& reflector_body, const auto& reflector_orbit, const auto& reflector, const auto& transform) + [&, bounce_normal](entity::id entity_id, const auto& reflector_body, const auto& reflector_orbit, const auto& reflector, const auto& transform) { // Transform reflector position from ICRF frame to EUS frame const double3 reflector_position_eus = icrf_to_eus * reflector_orbit.position; diff --git a/src/game/system/terrain.cpp b/src/game/system/terrain.cpp index 5e996e6..7264c18 100644 --- a/src/game/system/terrain.cpp +++ b/src/game/system/terrain.cpp @@ -56,6 +56,8 @@ terrain::terrain(entity::registry& registry): for (std::size_t i = 0; i <= quadtree_type::max_depth; ++i) quadtree_node_size[i] = 0.0f; + std::cout << "quadtree cap: " << quadtree.max_size() << std::endl; + registry.on_construct().connect<&terrain::on_terrain_construct>(this); registry.on_update().connect<&terrain::on_terrain_update>(this); registry.on_destroy().connect<&terrain::on_terrain_destroy>(this); @@ -119,7 +121,7 @@ void terrain::update(double t, double dt) geom::sphere sphere; sphere.center = cam.get_translation(); - sphere.radius = cam.get_clip_far() * 0.25; + sphere.radius = patch_side_length; //visit_quadtree(cam.get_view_frustum().get_bounds(), quadtree_type::root); visit_quadtree(sphere, quadtree_type::root); @@ -275,14 +277,14 @@ void terrain::visit_quadtree(const geom::bounding_volume& volume, quadtre node_bounds.min_point = { node_center.x() - node_size * 0.5f, - quadtree_node_size[quadtree_type::max_depth] * -0.5f, + -std::numeric_limits::infinity(), node_center.z() - node_size * 0.5f }; node_bounds.max_point = { - node_bounds.min_point[0] + node_size, - node_bounds.min_point[1] + quadtree_node_size[quadtree_type::max_depth], - node_bounds.min_point[2] + node_size + node_bounds.min_point.x() + node_size, + std::numeric_limits::infinity(), + node_bounds.min_point.z() + node_size }; // If volume intersects node @@ -664,6 +666,8 @@ geom::mesh* terrain::generate_patch_mesh(quadtree_node_type node) const // Set patch model bounds patch_model->set_bounds(patch_bounds); + //std::cout << "depth: " << quadtree_type::depth(node) << "; size: " << (patch_bounds.max_point + patch_bounds.min_point) * 0.5f << std::endl; + return patch_model; } diff --git a/src/game/system/terrain.hpp b/src/game/system/terrain.hpp index fb32ed3..f54eaea 100644 --- a/src/game/system/terrain.hpp +++ b/src/game/system/terrain.hpp @@ -82,7 +82,7 @@ public: void set_scene_collection(scene::collection* collection); private: - typedef geom::quadtree32 quadtree_type; + typedef geom::quadtree16 quadtree_type; typedef quadtree_type::node_type quadtree_node_type; struct patch @@ -105,8 +105,6 @@ private: void visit_quadtree(const geom::bounding_volume& volume, quadtree_node_type node); - - /** * Generates a mesh for a terrain patch given the patch's quadtree node */ diff --git a/src/genetics/base.cpp b/src/genetics/base.cpp index 003c51d..6565a8c 100644 --- a/src/genetics/base.cpp +++ b/src/genetics/base.cpp @@ -81,7 +81,7 @@ namespace dna { char complement(char symbol) { - static constexpr char* complements = "TVGHZZCDZZMZKNZZZYSAABWZR"; + constexpr const char* complements = "TVGHZZCDZZMZKNZZZYSAABWZR"; return (symbol < 'A' || symbol >= 'Z') ? 'Z' : complements[symbol - 'A']; } } @@ -90,7 +90,7 @@ namespace rna { char complement(char symbol) { - static constexpr char* complements = "UVGHZZCDZZMZKNZZZYSAABWZR"; + constexpr const char* complements = "UVGHZZCDZZMZKNZZZYSAABWZR"; return (symbol < 'A' || symbol >= 'Z') ? 'Z' : complements[symbol - 'A']; } } diff --git a/src/geom/hyperoctree.hpp b/src/geom/hyperoctree.hpp index 29b93e2..295ce15 100644 --- a/src/geom/hyperoctree.hpp +++ b/src/geom/hyperoctree.hpp @@ -20,6 +20,8 @@ #ifndef ANTKEEPER_GEOM_HYPEROCTREE_HPP #define ANTKEEPER_GEOM_HYPEROCTREE_HPP +#include "math/compile.hpp" +#include #include #include #include @@ -31,9 +33,7 @@ namespace geom { /** * Hashed linear hyperoctree. * - * @see http://codervil.blogspot.com/2015/10/octree-node-identifiers.html - * @see https://geidav.wordpress.com/2014/08/18/advanced-octrees-2-node-representations/ - * + * @tparam T Integer node type. * @tparam N Number of dimensions. * @tparam D Max depth. * @@ -46,7 +46,6 @@ namespace geom { * 64 bit ( 8 byte) = max depth 28 ( 58 loc bits, 5 depth bits, 1 divider bit) = 64 bits * 128 bit (16 byte) = max depth 59 (120 loc bits, 6 depth bits, 1 divider bit) = 127 bits * 256 bit (32 byte) = max depth 123 (248 loc bits, 7 depth bits, 1 divider bit) = 256 bits - * * @see https://oeis.org/A173009 * * 3D: @@ -56,18 +55,14 @@ namespace geom { * 64 bit ( 8 byte) = max depth 18 ( 57 loc bits, 5 depth bits, 1 divider bit) = 63 bits * 128 bit (16 byte) = max depth 39 (120 loc bits, 6 depth bits, 1 divider bit) = 127 bits * 256 bit (32 byte) = max depth 81 (243 loc bits, 7 depth bits, 1 divider bit) = 251 bits - * * @see https://oeis.org/A178420 * - * @tparam T Integer node type. + * @see http://codervil.blogspot.com/2015/10/octree-node-identifiers.html + * @see https://geidav.wordpress.com/2014/08/18/advanced-octrees-2-node-representations/ */ -template +template class hyperoctree { -private: - /// Compile-time calculation of the minimum bits required to represent `n` state changes. - static constexpr T ceil_log2(T n); - public: /// Integral node type. typedef T node_type; @@ -79,8 +74,8 @@ public: static constexpr std::size_t max_depth = D; /// Number of bits required to encode the depth of a node. - static constexpr T depth_bits = ceil_log2(max_depth + 1); - + static constexpr T depth_bits = math::compile::ceil_log2(max_depth + 1); + /// Number of bits required to encode the location of a node. static constexpr T location_bits = (max_depth + 1) * N; @@ -89,7 +84,7 @@ public: // Ensure the node type has enough bits static_assert(depth_bits + location_bits + 1 <= node_bits, "Size of hyperoctree node type is insufficient to encode the maximum depth"); - + /// Number of children per node. static constexpr T children_per_node = (N) ? (2 << (N - 1)) : 1; @@ -98,7 +93,7 @@ public: /// Root node which is always guaranteed to exist. static constexpr node_type root = 0; - + /** * Accesses nodes in their internal hashmap order. */ @@ -116,7 +111,7 @@ public: inline explicit unordered_iterator(const typename std::unordered_set::const_iterator& it): set_iterator(it) {}; typename std::unordered_set::const_iterator set_iterator; }; - + /** * Accesses nodes in z-order. * @@ -136,7 +131,7 @@ public: const hyperoctree* hyperoctree; std::stack stack; }; - + /** * Returns the depth of a node. * @@ -144,7 +139,7 @@ public: * @return Depth of the node. */ static T depth(node_type node); - + /** * Returns the Morton code location of a node. * @@ -152,7 +147,7 @@ public: * @return Morton code location of the node. */ static T location(node_type node); - + /** * Returns the node at the given depth and location. * @@ -250,24 +245,24 @@ public: /// Returns the number of nodes in the hyperoctree. std::size_t size() const; + + /// Returns the total number of nodes the hyperoctree is capable of containing. + static consteval std::size_t max_size() noexcept + { + return (math::compile::pow(children_per_node, max_depth + 1) - 1) / (children_per_node - 1); + } private: - /// Compile-time pow() - static constexpr T pow(T x, T exponent); - - /// Count leading zeros - static T clz(T x); - std::unordered_set nodes; }; -template -typename hyperoctree::iterator& hyperoctree::iterator::operator++() +template +typename hyperoctree::iterator& hyperoctree::iterator::operator++() { // Get next node from top of stack node_type node = stack.top(); stack.pop(); - + // If the node has children if (!hyperoctree->is_leaf(node)) { @@ -275,54 +270,48 @@ typename hyperoctree::iterator& hyperoctree::iterator::operato for (T i = 0; i < children_per_node; ++i) stack.push(child(node, siblings_per_node - i)); } - + if (stack.empty()) stack.push(std::numeric_limits::max()); - + return *this; } -template -constexpr T hyperoctree::ceil_log2(T n) -{ - return (n <= 1) ? 0 : ceil_log2((n + 1) / 2) + 1; -} - -template -inline T hyperoctree::depth(node_type node) +template +inline T hyperoctree::depth(node_type node) { // Extract depth using a bit mask - constexpr T mask = pow(2, depth_bits) - 1; + constexpr T mask = math::compile::pow(2, depth_bits) - 1; return node & mask; } -template -inline T hyperoctree::location(node_type node) +template +inline T hyperoctree::location(node_type node) { return node >> ((node_bits - 1) - depth(node) * N); } -template -inline typename hyperoctree::node_type hyperoctree::node(T depth, T location) +template +inline typename hyperoctree::node_type hyperoctree::node(T depth, T location) { return (location << ((node_bits - 1) - depth * N)) | depth; } -template -inline typename hyperoctree::node_type hyperoctree::ancestor(node_type node, T depth) +template +inline typename hyperoctree::node_type hyperoctree::ancestor(node_type node, T depth) { const T mask = std::numeric_limits::max() << ((node_bits - 1) - depth * N); return (node & mask) | depth; } -template -inline typename hyperoctree::node_type hyperoctree::parent(node_type node) +template +inline typename hyperoctree::node_type hyperoctree::parent(node_type node) { return ancestor(node, depth(node) - 1); } -template -inline typename hyperoctree::node_type hyperoctree::sibling(node_type node, T n) +template +inline typename hyperoctree::node_type hyperoctree::sibling(node_type node, T n) { constexpr T mask = (1 << N) - 1; @@ -332,28 +321,28 @@ inline typename hyperoctree::node_type hyperoctree::sibling(no return hyperoctree::node(depth, (location & (~mask)) | ((location + n) & mask)); } -template -inline typename hyperoctree::node_type hyperoctree::child(node_type node, T n) +template +inline typename hyperoctree::node_type hyperoctree::child(node_type node, T n) { return sibling(node + 1, n); } -template -inline typename hyperoctree::node_type hyperoctree::common_ancestor(node_type a, node_type b) +template +inline typename hyperoctree::node_type hyperoctree::common_ancestor(node_type a, node_type b) { T bits = std::min(depth(a), depth(b)) * N; T marker = (T(1) << (node_bits - 1)) >> bits; - T depth = clz((a ^ b) | marker) / N; + T depth = T(std::countl_zero((a ^ b) | marker) / N); return ancestor(a, depth); } -template -inline hyperoctree::hyperoctree(): +template +inline hyperoctree::hyperoctree(): nodes({0}) {} -template -void hyperoctree::insert(node_type node) +template +void hyperoctree::insert(node_type node) { if (contains(node)) return; @@ -371,8 +360,8 @@ void hyperoctree::insert(node_type node) insert(parent); } -template -void hyperoctree::erase(node_type node) +template +void hyperoctree::erase(node_type node) { // Don't erase the root! if (node == root) @@ -396,87 +385,60 @@ void hyperoctree::erase(node_type node) } } -template -void hyperoctree::clear() +template +void hyperoctree::clear() { nodes = {0}; } -template -inline bool hyperoctree::contains(node_type node) const +template +inline bool hyperoctree::contains(node_type node) const { return nodes.count(node); } -template -inline bool hyperoctree::is_leaf(node_type node) const +template +inline bool hyperoctree::is_leaf(node_type node) const { return !contains(child(node, 0)); } -template -inline std::size_t hyperoctree::size() const +template +inline std::size_t hyperoctree::size() const { return nodes.size(); } -template -typename hyperoctree::iterator hyperoctree::begin() const +template +typename hyperoctree::iterator hyperoctree::begin() const { return iterator(this, hyperoctree::root); } -template -typename hyperoctree::iterator hyperoctree::end() const +template +typename hyperoctree::iterator hyperoctree::end() const { return iterator(this, std::numeric_limits::max()); } -template -typename hyperoctree::iterator hyperoctree::find(node_type node) const +template +typename hyperoctree::iterator hyperoctree::find(node_type node) const { return contains(node) ? iterator(node) : end(); } -template -typename hyperoctree::unordered_iterator hyperoctree::unordered_begin() const +template +typename hyperoctree::unordered_iterator hyperoctree::unordered_begin() const { return unordered_iterator(nodes.begin()); } -template -typename hyperoctree::unordered_iterator hyperoctree::unordered_end() const +template +typename hyperoctree::unordered_iterator hyperoctree::unordered_end() const { return unordered_iterator(nodes.end()); } -template -constexpr T hyperoctree::pow(T x, T exponent) -{ - return (exponent == 0) ? 1 : x * pow(x, exponent - 1); -} - -template -T hyperoctree::clz(T x) -{ - if (!x) - return sizeof(T) * 8; - - #if defined(__GNU__) - return __builtin_clz(x); - #else - T n = 0; - - while ((x & (T(1) << (8 * sizeof(x) - 1))) == 0) - { - x <<= 1; - ++n; - } - - return n; - #endif -} - } // namespace geom #endif // ANTKEEPER_GEOM_HYPEROCTREE_HPP diff --git a/src/geom/octree.hpp b/src/geom/octree.hpp index b9605e1..18f32d7 100644 --- a/src/geom/octree.hpp +++ b/src/geom/octree.hpp @@ -25,20 +25,20 @@ namespace geom { /// An octree, or 3-dimensional hyperoctree. -template -using octree = hyperoctree<3, D, T>; +template +using octree = hyperoctree; /// Octree with an 8-bit node type (2 depth levels). -typedef octree<1, std::uint8_t> octree8; +typedef octree octree8; /// Octree with a 16-bit node type (4 depth levels). -typedef octree<3, std::uint16_t> octree16; +typedef octree octree16; /// Octree with a 32-bit node type (9 depth levels). -typedef octree<8, std::uint32_t> octree32; +typedef octree octree32; /// Octree with a 64-bit node type (19 depth levels). -typedef octree<18, std::uint64_t> octree64; +typedef octree octree64; } // namespace geom diff --git a/src/geom/quadtree.hpp b/src/geom/quadtree.hpp index 62c5f7c..646e836 100644 --- a/src/geom/quadtree.hpp +++ b/src/geom/quadtree.hpp @@ -25,20 +25,20 @@ namespace geom { /// A quadtree, or 2-dimensional hyperoctree. -template -using quadtree = hyperoctree<2, D, T>; +template +using quadtree = hyperoctree; /// Quadtree with an 8-bit node type (2 depth levels). -typedef quadtree<1, std::uint8_t> quadtree8; +typedef quadtree quadtree8; /// Quadtree with a 16-bit node type (6 depth levels). -typedef quadtree<5, std::uint16_t> quadtree16; +typedef quadtree quadtree16; /// Quadtree with a 32-bit node type (13 depth levels). -typedef quadtree<12, std::uint32_t> quadtree32; +typedef quadtree quadtree32; /// Quadtree with a 64-bit node type (29 depth levels). -typedef quadtree<28, std::uint64_t> quadtree64; +typedef quadtree quadtree64; } // namespace geom diff --git a/src/math/compile.hpp b/src/math/compile.hpp new file mode 100644 index 0000000..8280668 --- /dev/null +++ b/src/math/compile.hpp @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2021 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_MATH_COMPILE_HPP +#define ANTKEEPER_MATH_COMPILE_HPP + +#include + +namespace math { + +/// Compile-time mathematical functions. +namespace compile { + +/** + * Compile-time `pow` for unsigned integrals. + * + * @param x Base value. + * @param e Integral exponent. + * + * @return `x^e`. + */ +template +consteval T pow(T x, T e) noexcept +{ + return (e == 0) ? T(1) : (x * pow(x, e - 1)); +} + +/** + * Compile-time `ceil(log2(x))` for unsigned integrals. + * + * @param x Input value. + * + * @return `ceil(log2(x))`. + */ +template +consteval T ceil_log2(T x) noexcept +{ + return (x <= T(1)) ? T(0) : ceil_log2((x + T(1)) / T(2)) + T(1); +} + +} // namespace compile + +} // namespace math + +#endif // ANTKEEPER_MATH_COMPILE_HPP diff --git a/src/math/matrix.hpp b/src/math/matrix.hpp index 4881e2d..22d8328 100644 --- a/src/math/matrix.hpp +++ b/src/math/matrix.hpp @@ -123,11 +123,11 @@ struct matrix /// @{ constexpr inline column_vector_type& back() noexcept { - return elements[column_count - 1]; + return columns[column_count - 1]; } constexpr inline const column_vector_type& back() const noexcept { - return elements[column_count - 1]; + return columns[column_count - 1]; } /// @} diff --git a/src/math/transform-type.hpp b/src/math/transform-type.hpp index e6d00f9..22a7f7f 100644 --- a/src/math/transform-type.hpp +++ b/src/math/transform-type.hpp @@ -47,7 +47,7 @@ struct transform }; template -constexpr transform transform::identity = +const transform transform::identity = { vector::zero(), quaternion::identity(), diff --git a/src/math/vector.hpp b/src/math/vector.hpp index 5b1056e..fb18685 100644 --- a/src/math/vector.hpp +++ b/src/math/vector.hpp @@ -633,7 +633,7 @@ vector normalize(const vector& x); * @return Logically inverted vector. */ template -constexpr vector not(const vector& x) noexcept; +constexpr vector logical_not(const vector& x) noexcept; /** * Compares two vectors for inequality @@ -1189,15 +1189,15 @@ inline vector normalize(const vector& x) /// @private template -constexpr inline vector not(const vector& x, std::index_sequence) noexcept +constexpr inline vector logical_not(const vector& x, std::index_sequence) noexcept { return {!x[I]...}; } template -constexpr inline vector not(const vector& x) noexcept +constexpr inline vector logical_not(const vector& x) noexcept { - return not(x, std::make_index_sequence{}); + return logical_not(x, std::make_index_sequence{}); } /// @private diff --git a/src/resources/behavior-tree-loader.cpp b/src/resources/behavior-tree-loader.cpp index 8438618..bcc75e7 100644 --- a/src/resources/behavior-tree-loader.cpp +++ b/src/resources/behavior-tree-loader.cpp @@ -29,6 +29,8 @@ #include #include +/* + template void parse_argument(T& value, const std::string& string) { @@ -160,4 +162,4 @@ entity::ebt::node* resource_loader::load(resource_manager* re return load_node(json.cbegin(), resource_manager); } - +*/ diff --git a/src/resources/entity-archetype-loader.cpp b/src/resources/entity-archetype-loader.cpp index 131dc3e..4c20269 100644 --- a/src/resources/entity-archetype-loader.cpp +++ b/src/resources/entity-archetype-loader.cpp @@ -87,6 +87,7 @@ static bool load_component_atmosphere(entity::archetype& archetype, const json& return true; } +/* static bool load_component_behavior(entity::archetype& archetype, resource_manager& resource_manager, const json& element) { game::component::behavior component; @@ -107,6 +108,7 @@ static bool load_component_behavior(entity::archetype& archetype, resource_manag return (component.behavior_tree != nullptr); } +*/ static bool load_component_blackbody(entity::archetype& archetype, const json& element) { @@ -306,8 +308,8 @@ static bool load_component(entity::archetype& archetype, resource_manager& resou { if (element.key() == "atmosphere") return load_component_atmosphere(archetype, element.value()); - if (element.key() == "behavior") - return load_component_behavior(archetype, resource_manager, element.value()); + // if (element.key() == "behavior") + // return load_component_behavior(archetype, resource_manager, element.value()); if (element.key() == "blackbody") return load_component_blackbody(archetype, element.value()); if (element.key() == "celestial_body") diff --git a/src/resources/resource-manager.hpp b/src/resources/resource-manager.hpp index 54912c8..1e8a460 100644 --- a/src/resources/resource-manager.hpp +++ b/src/resources/resource-manager.hpp @@ -225,7 +225,7 @@ void resource_manager::save(const T* resource, const std::filesystem::path& path status = EXIT_FAILURE; } - logger->pop_task(status) + logger->pop_task(status); } inline entt::registry& resource_manager::get_archetype_registry()