From ba3ac11b4154669693c73b8de1c84ceb2b585bb6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 8 Oct 2024 16:26:26 +0300 Subject: [PATCH] optimize lines generation --- src/maths/util.hpp | 36 ++++++++++++++++++++++++-- src/world/generator/WorldGenerator.cpp | 10 +------ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/maths/util.hpp b/src/maths/util.hpp index ddedb855..a5302980 100644 --- a/src/maths/util.hpp +++ b/src/maths/util.hpp @@ -69,14 +69,28 @@ namespace util { rand(); } }; - + + /// @return integer square of distance between two points + /// @note glm::distance2 does not support integer vectors + inline int distance2(const glm::ivec3& a, const glm::ivec3& b) { + return (b.x - a.x) * (b.x - a.x) + + (b.y - a.y) * (b.y - a.y) + + (b.z - a.z) * (b.z - a.z); + } + + /// @return integer square of vector length + /// @note glm::length2 does not support integer vectors + inline int length2(const glm::ivec3& a) { + return a.x * a.x + a.y * a.y + a.z * a.z; + } + /// @brief Find nearest point on segment to given /// @param a segment point A /// @param b segment point B /// @param point given point (may be anywhere) /// @return nearest point on the segment to given point inline glm::vec3 closest_point_on_segment( - glm::vec3 a, glm::vec3 b, const glm::vec3& point + const glm::vec3& a, const glm::vec3& b, const glm::vec3& point ) { auto vec = b - a; float da = glm::distance2(point, a); @@ -86,4 +100,22 @@ namespace util { t = std::min(1.0f, std::max(0.0f, t)); return a + vec * t; } + + /// @brief Find nearest point on segment to given + /// @param a segment point A + /// @param b segment point B + /// @param point given point (may be anywhere) + /// @note this overload is actually faster (comment out method to compare) + /// @return nearest point on the segment to given point + inline glm::ivec3 closest_point_on_segment( + const glm::ivec3& a, const glm::ivec3& b, const glm::ivec3& point + ) { + auto vec = b - a; + float da = distance2(point, a); + float db = distance2(point, b); + float len = length2(vec); + float t = (((da - db) / len) * 0.5f + 0.5f); + t = std::min(1.0f, std::max(0.0f, t)); + return a + glm::ivec3(glm::vec3(vec) * t); + } } diff --git a/src/world/generator/WorldGenerator.cpp b/src/world/generator/WorldGenerator.cpp index f1157343..301049b7 100644 --- a/src/world/generator/WorldGenerator.cpp +++ b/src/world/generator/WorldGenerator.cpp @@ -305,14 +305,6 @@ void WorldGenerator::update(int centerX, int centerY, int loadDistance) { surroundMap.setCenter(centerX, centerY); } -/// @return integer square of distance between two points -/// @note glm::distance2 does not support integer vectors -static inline int distance2(const glm::ivec3& a, const glm::ivec3& b) { - return (b.x - a.x) * (b.x - a.x) + - (b.y - a.y) * (b.y - a.y) + - (b.z - a.z) * (b.z - a.z); -} - void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) { surroundMap.completeAt(chunkX, chunkZ); @@ -414,7 +406,7 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) { glm::ivec3 point {gx, y, gz}; glm::ivec3 closest = util::closest_point_on_segment( a, b, point); - if (distance2(closest, point) <= radius*radius) { + if (util::distance2(closest, point) <= radius*radius) { voxels[vox_index(x, y, z)] = {line.block, {}}; } }