#pragma once #include "array" #include "ChunkDimensions.hpp" #include "../Math/Common.hpp" #include "../Math/Vector.hpp" namespace MC::Position { #define MC_POSITION_MAKE_DEFAULT_CONSTRUCTORS(name, t) \ name() = default; \ template = 0> \ name(Args... args) : Vector{ static_cast(args)... } {} \ name(Vector v) : Vector(v) {} // Offset between block positions within single chunk. class BlockLocalOffset : public Vector<3, I16> { public: MC_POSITION_MAKE_DEFAULT_CONSTRUCTORS(BlockLocalOffset, I16) Bool fits_within_chunk() const { using namespace MC::World::ChunkDimensions; return x() >= 0 && x() < Width && y() >= 0 && y() < Height && z() >= 0 && z() < Width; } }; // Position of a block within single chunk. class BlockLocal : public Vector<3, U8> { public: MC_POSITION_MAKE_DEFAULT_CONSTRUCTORS(BlockLocal, U8) BlockLocal(BlockLocalOffset offset) : BlockLocal(offset.x(), offset.y(), offset.z()) {} BlockLocalOffset offset(BlockLocalOffset by) { return { static_cast(x() + by.x()), static_cast(y() + by.y()), static_cast(z() + by.z()) }; } }; // Offset between block positions within entire world. class BlockWorldOffset : public Vector<3, I64> { public: MC_POSITION_MAKE_DEFAULT_CONSTRUCTORS(BlockWorldOffset, I64) }; // Position of a block within entire world. class BlockWorld : public Vector<3, I64> { public: MC_POSITION_MAKE_DEFAULT_CONSTRUCTORS(BlockWorld, I64) BlockLocal to_local() const { using namespace MC::World::ChunkDimensions; return {Math::mod(x(), Width), std::clamp(y(), 0, Height), Math::mod(z(), Width)}; } }; const std::array axis_directions = {{ {1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}, }}; // Offset between two world positions. class WorldOffset : public Vector<3> { public: MC_POSITION_MAKE_DEFAULT_CONSTRUCTORS(WorldOffset, Real) }; // Position within entire world. class World : public Vector<3> { public: MC_POSITION_MAKE_DEFAULT_CONSTRUCTORS(World, Real) BlockWorld round_to_block() const { auto rounded = map([](auto x) { return std::floor(x); }); return {rounded.x(), rounded.y(), rounded.z()}; } }; }