1
0
Fork 0
Univerxel/src/core/world/iterators.cpp

59 lines
1.3 KiB
C++

#include "iterators.hpp"
using namespace world::iterator;
std::unique_ptr<Abstract> world::iterator::Get(world::action::Shape shape, uint16_t radius) {
switch (shape) {
case world::action::Shape::Cube:
return std::make_unique<Cube>(radius);
case world::action::Shape::RawSphere:
return std::make_unique<RawSphere>(radius);
default:
return std::unique_ptr<Abstract>(nullptr);
}
}
bool Cube::next(pair& out) {
if (pos.z > radius)
return false;
out.first = pos;
out.second = 1;
// MAYBE: use linear idx to make branch less
if (pos.x < radius) {
pos.x++;
} else {
pos.x = -radius;
if (pos.y < radius) {
pos.y++;
} else {
pos.y = -radius;
pos.z++;
}
}
return true;
}
bool RawSphere::next(pair& out) {
if (pos.x > radius)
return false;
out.first = pos;
out.second = 1;
if (pos.z < dz) {
pos.z++;
} else {
if (pos.y < dy) {
pos.y++;
} else {
pos.x++;
dy = floor(sqrt(radius * radius - pos.x * pos.x));
pos.y = -dy;
}
dz = floor(sqrt(dy * dy - pos.y * pos.y));
pos.z = -dz;
}
return true;
}