diff --git a/src/maths/util.hpp b/src/maths/util.hpp index a5302980..5f08253f 100644 --- a/src/maths/util.hpp +++ b/src/maths/util.hpp @@ -78,12 +78,24 @@ namespace util { (b.z - a.z) * (b.z - a.z); } + /// @return integer square of distance between two points + inline int distance2(int ax, int ay, int az, int bx, int by, int bz) { + return (bx - ax) * (bx - ax) + + (by - ay) * (by - ay) + + (bz - az) * (bz - az); + } + /// @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; } + /// @return integer square of vector length + inline int length2(int x, int y, int z) { + return x * x + y * y + z * z; + } + /// @brief Find nearest point on segment to given /// @param a segment point A /// @param b segment point B diff --git a/src/world/generator/WorldGenerator.cpp b/src/world/generator/WorldGenerator.cpp index 301049b7..b29914c7 100644 --- a/src/world/generator/WorldGenerator.cpp +++ b/src/world/generator/WorldGenerator.cpp @@ -380,24 +380,30 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) { } } } + generateLines(prototype, voxels, chunkX, chunkZ); +} + +void WorldGenerator::generateLines( + const ChunkPrototype& prototype, voxel* voxels, int chunkX, int chunkZ +) { for (const auto& line : prototype.lines) { int cgx = chunkX * CHUNK_W; int cgz = chunkZ * CHUNK_D; int radius = line.radius; - int minX = std::max(0, std::min(line.a.x-radius-cgx, line.b.x-radius-cgx)); - int maxX = std::min(CHUNK_W, std::max(line.a.x+radius-cgx, line.b.x+radius-cgx)); - - int minZ = std::max(0, std::min(line.a.z-radius-cgz, line.b.z-radius-cgz)); - int maxZ = std::min(CHUNK_D, std::max(line.a.z+radius-cgz, line.b.z+radius-cgz)); - - int minY = std::max(0, std::min(line.a.y-radius, line.b.y-radius)); - int maxY = std::min(CHUNK_H, std::max(line.a.y+radius, line.b.y+radius)); - auto a = line.a; auto b = line.b; + int minX = std::max(0, std::min(a.x-radius-cgx, b.x-radius-cgx)); + int maxX = std::min(CHUNK_W, std::max(a.x+radius-cgx, b.x+radius-cgx)); + + int minZ = std::max(0, std::min(a.z-radius-cgz, b.z-radius-cgz)); + int maxZ = std::min(CHUNK_D, std::max(a.z+radius-cgz, b.z+radius-cgz)); + + int minY = std::max(0, std::min(a.y-radius, b.y-radius)); + int maxY = std::min(CHUNK_H, std::max(a.y+radius, b.y+radius)); + for (int y = minY; y < maxY; y++) { for (int z = minZ; z < maxZ; z++) { for (int x = minX; x < maxX; x++) { @@ -405,7 +411,8 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) { int gz = z + cgz; glm::ivec3 point {gx, y, gz}; glm::ivec3 closest = util::closest_point_on_segment( - a, b, point); + a, b, point + ); if (util::distance2(closest, point) <= radius*radius) { voxels[vox_index(x, y, z)] = {line.block, {}}; } diff --git a/src/world/generator/WorldGenerator.hpp b/src/world/generator/WorldGenerator.hpp index a503c312..784b4329 100644 --- a/src/world/generator/WorldGenerator.hpp +++ b/src/world/generator/WorldGenerator.hpp @@ -76,6 +76,10 @@ class WorldGenerator { ); void placeLine(const LinePlacement& line); + + void generateLines( + const ChunkPrototype& prototype, voxel* voxels, int x, int z + ); public: WorldGenerator( const GeneratorDef& def,