Moved some Vector3i function specializations to math:: namespace

master
Marc Gilleron 2022-04-29 23:25:04 +01:00
parent c0ca89a797
commit a5e429de6f
18 changed files with 85 additions and 76 deletions

View File

@ -182,7 +182,7 @@ inline float sdf_blend(float src_value, float dst_value, VoxelTool::Mode mode) {
void VoxelTool::do_sphere(Vector3 center, float radius) {
ZN_PROFILE_SCOPE();
const Box3i box(Vector3iUtil::from_floored(center) - Vector3iUtil::create(Math::floor(radius)),
const Box3i box(math::floor(center) - Vector3iUtil::create(Math::floor(radius)),
Vector3iUtil::create(Math::ceil(radius) * 2));
if (!is_area_editable(box)) {

View File

@ -188,10 +188,10 @@ private:
do_point(pos);
}
void _b_do_line(Vector3 begin, Vector3 end) {
do_line(Vector3iUtil::from_floored(begin), Vector3iUtil::from_floored(end));
do_line(math::floor(begin), math::floor(end));
}
void _b_do_circle(Vector3 pos, float radius, Vector3 direction) {
do_circle(Vector3iUtil::from_floored(pos), radius, Vector3iUtil::from_floored(direction));
do_circle(math::floor(pos), radius, math::floor(direction));
}
void _b_do_sphere(Vector3 pos, float radius) {
do_sphere(pos, radius);
@ -210,7 +210,7 @@ private:
}
bool _b_is_area_editable(AABB box) const {
return is_area_editable(Box3i(Vector3iUtil::from_floored(box.position), Vector3iUtil::from_floored(box.size)));
return is_area_editable(Box3i(math::floor(box.position), math::floor(box.size)));
}
protected:

View File

@ -26,7 +26,7 @@ void VoxelToolBuffer::do_sphere(Vector3 center, float radius) {
ZN_PROFILE_SCOPE();
Box3i box(Vector3iUtil::from_floored(center) - Vector3iUtil::create(Math::floor(radius)),
Box3i box(math::floor(center) - Vector3iUtil::create(Math::floor(radius)),
Vector3iUtil::create(Math::ceil(radius) * 2));
box.clip(Box3i(Vector3i(), _buffer->get_buffer().get_size()));

View File

@ -29,7 +29,7 @@ bool VoxelToolLodTerrain::is_area_editable(const Box3i &box) const {
template <typename Volume_F>
float get_sdf_interpolated(const Volume_F &f, Vector3 pos) {
const Vector3i c = Vector3iUtil::from_floored(pos);
const Vector3i c = math::floor(pos);
const float s000 = f(Vector3i(c.x, c.y, c.z));
const float s100 = f(Vector3i(c.x + 1, c.y, c.z));
@ -222,7 +222,7 @@ void VoxelToolLodTerrain::do_sphere(Vector3 center, float radius) {
ZN_PROFILE_SCOPE();
ERR_FAIL_COND(_terrain == nullptr);
const Box3i box = Box3i(Vector3iUtil::from_floored(center) - Vector3iUtil::create(Math::floor(radius)),
const Box3i box = Box3i(math::floor(center) - Vector3iUtil::create(Math::floor(radius)),
Vector3iUtil::create(Math::ceil(radius) * 2))
.clipped(_terrain->get_voxel_bounds());
@ -294,7 +294,7 @@ private:
void VoxelToolLodTerrain::do_sphere_async(Vector3 center, float radius) {
ERR_FAIL_COND(_terrain == nullptr);
const Box3i box = Box3i(Vector3iUtil::from_floored(center) - Vector3iUtil::create(Math::floor(radius)),
const Box3i box = Box3i(math::floor(center) - Vector3iUtil::create(Math::floor(radius)),
Vector3iUtil::create(Math::ceil(radius) * 2))
.clipped(_terrain->get_voxel_bounds());
@ -716,8 +716,7 @@ Array VoxelToolLodTerrain::separate_floating_chunks(AABB world_box, Node *parent
Ref<VoxelMesher> mesher = _terrain->get_mesher();
Array materials;
materials.append(_terrain->get_material());
const Box3i int_world_box(
Vector3iUtil::from_floored(world_box.position), Vector3iUtil::from_ceiled(world_box.size));
const Box3i int_world_box(math::floor(world_box.position), math::ceil(world_box.size));
return zylann::voxel::separate_floating_chunks(
*this, int_world_box, parent_node, _terrain->get_global_transform(), mesher, materials);
}

View File

@ -167,7 +167,7 @@ void VoxelToolTerrain::do_sphere(Vector3 center, float radius) {
ZN_PROFILE_SCOPE();
const Box3i box(Vector3iUtil::from_floored(center) - Vector3iUtil::create(Math::floor(radius)),
const Box3i box(math::floor(center) - Vector3iUtil::create(Math::floor(radius)),
Vector3iUtil::create(Math::ceil(radius) * 2));
if (!is_area_editable(box)) {
@ -350,7 +350,7 @@ void VoxelToolTerrain::run_blocky_random_tick(
const VoxelBlockyLibrary &lib = **_terrain->get_voxel_library();
VoxelDataMap &map = _terrain->get_storage();
const Box3i voxel_box(Vector3iUtil::from_floored(voxel_area.position), Vector3iUtil::from_floored(voxel_area.size));
const Box3i voxel_box(math::floor(voxel_area.position), math::floor(voxel_area.size));
run_blocky_random_tick_static(
map, voxel_box, lib, voxel_count, batch_count, &cb_self, [](void *self, Vector3i pos, int64_t val) {
@ -376,8 +376,7 @@ void VoxelToolTerrain::for_each_voxel_metadata_in_area(AABB voxel_area, const Ca
ERR_FAIL_COND(callback.is_null());
ERR_FAIL_COND(!math::is_valid_size(voxel_area.size));
const Box3i voxel_box =
Box3i(Vector3iUtil::from_floored(voxel_area.position), Vector3iUtil::from_floored(voxel_area.size));
const Box3i voxel_box = Box3i(math::floor(voxel_area.position), math::floor(voxel_area.size));
ERR_FAIL_COND(!is_area_editable(voxel_box));
const Box3i data_block_box = voxel_box.downscaled(_terrain->get_data_block_size());

View File

@ -645,8 +645,7 @@ void VoxelGraphEditor::update_range_analysis_previews() {
ERR_FAIL_COND(!_graph->is_good());
const AABB aabb = _range_analysis_dialog->get_aabb();
_graph->debug_analyze_range(
Vector3iUtil::from_floored(aabb.position), Vector3iUtil::from_floored(aabb.position + aabb.size), true);
_graph->debug_analyze_range(math::floor(aabb.position), math::floor(aabb.position + aabb.size), true);
const VoxelGraphRuntime::State &state = _graph->get_last_state_from_current_thread();

View File

@ -94,7 +94,7 @@ Error for_each_model_instance_in_scene_graph(const Data &data, int node_id, Tran
const ShapeNode *vox_shape_node = reinterpret_cast<const ShapeNode *>(vox_node);
ForEachModelInstanceArgs args;
args.model = &data.get_model(vox_shape_node->model_id);
args.position = Vector3iUtil::from_rounded(transform.origin);
args.position = math::round(transform.origin);
args.basis = transform.basis;
f(args);
} break;

View File

@ -1833,15 +1833,14 @@ void VoxelGeneratorGraph::_b_set_node_name(int node_id, String name) {
}
float VoxelGeneratorGraph::_b_generate_single(Vector3 pos) {
return generate_single(Vector3iUtil::from_floored(pos), VoxelBufferInternal::CHANNEL_SDF).f;
return generate_single(math::floor(pos), VoxelBufferInternal::CHANNEL_SDF).f;
}
Vector2 VoxelGeneratorGraph::_b_debug_analyze_range(Vector3 min_pos, Vector3 max_pos) const {
ERR_FAIL_COND_V(min_pos.x > max_pos.x, Vector2());
ERR_FAIL_COND_V(min_pos.y > max_pos.y, Vector2());
ERR_FAIL_COND_V(min_pos.z > max_pos.z, Vector2());
const math::Interval r =
debug_analyze_range(Vector3iUtil::from_floored(min_pos), Vector3iUtil::from_floored(max_pos), false);
const math::Interval r = debug_analyze_range(math::floor(min_pos), math::floor(max_pos), false);
return Vector2(r.min, r.max);
}

View File

@ -161,7 +161,7 @@ VoxelStreamRegionFiles::EmergeResult VoxelStreamRegionFiles::_load_block(
return EMERGE_OK_FALLBACK;
}
const Vector3i block_rpos = Vector3iUtil::wrap(block_pos, region_size);
const Vector3i block_rpos = math::wrap(block_pos, region_size);
const Error err = cache->region.load_block(block_rpos, out_buffer);
switch (err) {
@ -214,7 +214,7 @@ void VoxelStreamRegionFiles::_save_block(VoxelBufferInternal &voxel_buffer, Vect
const Vector3i region_size = Vector3iUtil::create(1 << _meta.region_size_po2);
Vector3i block_pos = get_block_position_from_voxels(origin_in_voxels) >> lod;
Vector3i region_pos = get_region_position_from_blocks(block_pos);
Vector3i block_rpos = Vector3iUtil::wrap(block_pos, region_size);
Vector3i block_rpos = math::wrap(block_pos, region_size);
CachedRegion *cache = open_region(region_pos, lod, true);
ERR_FAIL_COND_MSG(cache == nullptr, "Could not save region file data");

View File

@ -1086,7 +1086,7 @@ void VoxelTerrain::process_viewers() {
const Vector3 local_position = world_to_local_transform.xform(viewer.world_position);
state.view_distance_voxels = math::min(view_distance_voxels, self._max_view_distance_voxels);
state.local_position_voxels = Vector3iUtil::from_floored(local_position);
state.local_position_voxels = math::floor(local_position);
state.requires_collisions = VoxelServer::get_singleton().is_viewer_requiring_collisions(viewer_id);
state.requires_meshes = VoxelServer::get_singleton().is_viewer_requiring_visuals(viewer_id);
@ -1101,8 +1101,7 @@ void VoxelTerrain::process_viewers() {
if (state.requires_meshes || state.requires_collisions) {
const int view_distance_mesh_blocks = math::ceildiv(state.view_distance_voxels, mesh_block_size);
const int render_to_data_factor = (mesh_block_size / data_block_size);
const Vector3i mesh_block_pos =
Vector3iUtil::floordiv(state.local_position_voxels, mesh_block_size);
const Vector3i mesh_block_pos = math::floordiv(state.local_position_voxels, mesh_block_size);
// Adding one block of padding because meshing requires neighbors
view_distance_data_blocks = view_distance_mesh_blocks * render_to_data_factor + 1;
@ -1115,7 +1114,7 @@ void VoxelTerrain::process_viewers() {
} else {
view_distance_data_blocks = math::ceildiv(state.view_distance_voxels, data_block_size);
data_block_pos = Vector3iUtil::floordiv(state.local_position_voxels, data_block_size);
data_block_pos = math::floordiv(state.local_position_voxels, data_block_size);
state.mesh_box = Box3i();
}
@ -1608,7 +1607,7 @@ Box3i VoxelTerrain::get_bounds() const {
}
Vector3i VoxelTerrain::_b_voxel_to_data_block(Vector3 pos) const {
return _data_map.voxel_to_block(Vector3iUtil::from_floored(pos));
return _data_map.voxel_to_block(math::floor(pos));
}
Vector3i VoxelTerrain::_b_data_block_to_voxel(Vector3i pos) const {
@ -1621,7 +1620,7 @@ void VoxelTerrain::_b_save_modified_blocks() {
// Explicitely ask to save a block if it was modified
void VoxelTerrain::_b_save_block(Vector3i p_block_pos) {
const Vector3i block_pos(Vector3iUtil::from_floored(p_block_pos));
const Vector3i block_pos(math::floor(p_block_pos));
VoxelDataBlock *block = _data_map.get_block(block_pos);
ERR_FAIL_COND(block == nullptr);
@ -1635,7 +1634,7 @@ void VoxelTerrain::_b_save_block(Vector3i p_block_pos) {
void VoxelTerrain::_b_set_bounds(AABB aabb) {
ERR_FAIL_COND(!math::is_valid_size(aabb.size));
set_bounds(Box3i(Vector3iUtil::from_rounded(aabb.position), Vector3iUtil::from_rounded(aabb.size)));
set_bounds(Box3i(math::round(aabb.position), math::round(aabb.size)));
}
AABB VoxelTerrain::_b_get_bounds() const {

View File

@ -814,7 +814,7 @@ VoxelInstancer::SceneInstance VoxelInstancer::create_scene_instance(const VoxelI
instance.component->attach(this);
instance.component->set_instance_index(instance_index);
instance.component->set_render_block_index(block_index);
instance.component->set_data_block_position(Vector3iUtil::from_floored(transform.origin) >> data_block_size_po2);
instance.component->set_data_block_position(math::floor(transform.origin) >> data_block_size_po2);
instance.root->set_transform(transform);
@ -918,8 +918,7 @@ void VoxelInstancer::update_block_from_transforms(int block_index, Span<const Tr
body->attach(this);
body->set_instance_index(instance_index);
body->set_render_block_index(block_index);
body->set_data_block_position(
Vector3iUtil::from_floored(body_transform.origin) >> data_block_size_po2);
body->set_data_block_position(math::floor(body_transform.origin) >> data_block_size_po2);
for (unsigned int i = 0; i < collision_shapes.size(); ++i) {
const VoxelInstanceLibraryMultiMeshItem::CollisionShapeInfo &shape_info = collision_shapes[i];
@ -1119,7 +1118,7 @@ void VoxelInstancer::save_block(Vector3i data_grid_pos, int lod_index) const {
ERR_FAIL_COND_MSG(render_to_data_factor < 1 || render_to_data_factor > 2, "Unsupported block size");
const int half_render_block_size = (1 << _parent_mesh_block_size_po2) / 2;
const Vector3i render_block_pos = Vector3iUtil::floordiv(data_grid_pos, render_to_data_factor);
const Vector3i render_block_pos = math::floordiv(data_grid_pos, render_to_data_factor);
const int octant_index = (data_grid_pos.x & 1) | ((data_grid_pos.y & 1) << 1) | ((data_grid_pos.z & 1) << 1);
@ -1255,7 +1254,7 @@ void VoxelInstancer::remove_floating_multimesh_instances(Block &block, const Tra
for (int instance_index = 0; instance_index < instance_count; ++instance_index) {
// TODO Optimize: This is terrible in MT mode! Think about keeping a local copy...
const Transform3D mm_transform = multimesh->get_instance_transform(instance_index);
const Vector3i voxel_pos(Vector3iUtil::from_floored(mm_transform.origin + block_global_transform.origin));
const Vector3i voxel_pos(math::floor(mm_transform.origin + block_global_transform.origin));
if (!p_voxel_box.contains(voxel_pos)) {
continue;
@ -1336,7 +1335,7 @@ void VoxelInstancer::remove_floating_scene_instances(Block &block, const Transfo
SceneInstance instance = block.scene_instances[instance_index];
ERR_CONTINUE(instance.root == nullptr);
const Transform3D scene_transform = instance.root->get_transform();
const Vector3i voxel_pos(Vector3iUtil::from_floored(scene_transform.origin + block_global_transform.origin));
const Vector3i voxel_pos(math::floor(scene_transform.origin + block_global_transform.origin));
if (!p_voxel_box.contains(voxel_pos)) {
continue;

View File

@ -953,7 +953,7 @@ Vector3i VoxelLodTerrain::voxel_to_data_block_position(Vector3 vpos, int lod_ind
ERR_FAIL_COND_V(lod_index < 0, Vector3i());
ERR_FAIL_COND_V(lod_index >= get_lod_count(), Vector3i());
const VoxelDataLodMap::Lod &lod = _data->lods[lod_index];
const Vector3i bpos = lod.map.voxel_to_block(Vector3iUtil::from_floored(vpos)) >> lod_index;
const Vector3i bpos = lod.map.voxel_to_block(math::floor(vpos)) >> lod_index;
return bpos;
}
@ -961,7 +961,7 @@ Vector3i VoxelLodTerrain::voxel_to_mesh_block_position(Vector3 vpos, int lod_ind
ERR_FAIL_COND_V(lod_index < 0, Vector3i());
ERR_FAIL_COND_V(lod_index >= get_lod_count(), Vector3i());
const unsigned int mesh_block_size_po2 = _update_data->settings.mesh_block_size_po2;
const Vector3i bpos = (Vector3iUtil::from_floored(vpos) >> mesh_block_size_po2) >> lod_index;
const Vector3i bpos = (math::floor(vpos) >> mesh_block_size_po2) >> lod_index;
return bpos;
}
@ -1795,7 +1795,7 @@ void VoxelLodTerrain::_b_save_modified_blocks() {
void VoxelLodTerrain::_b_set_voxel_bounds(AABB aabb) {
ERR_FAIL_COND(!math::is_valid_size(aabb.size));
set_voxel_bounds(Box3i(Vector3iUtil::from_rounded(aabb.position), Vector3iUtil::from_rounded(aabb.size)));
set_voxel_bounds(Box3i(math::round(aabb.position), math::round(aabb.size)));
}
AABB VoxelLodTerrain::_b_get_voxel_bounds() const {
@ -1817,7 +1817,7 @@ Array VoxelLodTerrain::debug_raycast_mesh_block(Vector3 world_origin, Vector3 wo
Array hits;
while (distance < max_distance && hits.size() == 0) {
const Vector3i posi = Vector3iUtil::from_floored(pos);
const Vector3i posi = math::floor(pos);
for (unsigned int lod_index = 0; lod_index < lod_count; ++lod_index) {
const VoxelMeshMap<VoxelMeshBlockVLT> &mesh_map = _mesh_maps_per_lod[lod_index];
const Vector3i bpos = (posi << mesh_block_size_po2) >> lod_index;
@ -1844,7 +1844,7 @@ Dictionary VoxelLodTerrain::debug_get_data_block_info(Vector3 fbpos, int lod_ind
const VoxelLodTerrainUpdateData::Lod &lod = _update_data->state.lods[lod_index];
const VoxelDataLodMap::Lod &data_lod = _data->lods[lod_index];
Vector3i bpos = Vector3iUtil::from_floored(fbpos);
Vector3i bpos = math::floor(fbpos);
int loading_state = 0;
@ -1872,7 +1872,7 @@ Dictionary VoxelLodTerrain::debug_get_mesh_block_info(Vector3 fbpos, int lod_ind
const int lod_count = get_lod_count();
ERR_FAIL_COND_V(lod_index >= lod_count, d);
const Vector3i bpos = Vector3iUtil::from_floored(fbpos);
const Vector3i bpos = math::floor(fbpos);
bool loaded = false;
bool meshed = false;

View File

@ -55,7 +55,7 @@ void VoxelLodTerrainUpdateTask::flush_pending_lod_edits(VoxelLodTerrainUpdateDat
ERR_CONTINUE(data_block == nullptr);
data_block->set_needs_lodding(false);
const Vector3i mesh_block_pos = Vector3iUtil::floordiv(data_block_pos, data_to_mesh_factor);
const Vector3i mesh_block_pos = math::floordiv(data_block_pos, data_to_mesh_factor);
auto mesh_block_it = lod0.mesh_map_state.map.find(mesh_block_pos);
if (mesh_block_it != lod0.mesh_map_state.map.end()) {
// If a mesh exists here, it will need an update.
@ -124,7 +124,7 @@ void VoxelLodTerrainUpdateTask::flush_pending_lod_edits(VoxelLodTerrainUpdateDat
//CRASH_COND(dst_block == nullptr);
{
const Vector3i mesh_block_pos = Vector3iUtil::floordiv(dst_bpos, data_to_mesh_factor);
const Vector3i mesh_block_pos = math::floordiv(dst_bpos, data_to_mesh_factor);
auto mesh_block_it = dst_lod.mesh_map_state.map.find(mesh_block_pos);
if (mesh_block_it != dst_lod.mesh_map_state.map.end()) {
schedule_mesh_update(mesh_block_it->second, mesh_block_pos, dst_lod.blocks_pending_update);
@ -229,7 +229,7 @@ static void process_unload_data_blocks_sliding_box(VoxelLodTerrainUpdateData::St
const unsigned int block_size_po2 = data_block_size_po2 + lod_index;
const Vector3i viewer_block_pos_within_lod =
VoxelDataMap::voxel_to_block_b(Vector3iUtil::from_floored(p_viewer_pos), block_size_po2);
VoxelDataMap::voxel_to_block_b(math::floor(p_viewer_pos), block_size_po2);
const Box3i bounds_in_blocks = Box3i( //
settings.bounds_in_voxels.pos >> block_size_po2, //
@ -310,7 +310,7 @@ static void process_unload_mesh_blocks_sliding_box(VoxelLodTerrainUpdateData::St
VoxelLodTerrainUpdateData::Lod &lod = state.lods[lod_index];
unsigned int block_size_po2 = mesh_block_size_po2 + lod_index;
const Vector3i viewer_block_pos_within_lod = Vector3iUtil::from_floored(p_viewer_pos) >> block_size_po2;
const Vector3i viewer_block_pos_within_lod = math::floor(p_viewer_pos) >> block_size_po2;
const Box3i bounds_in_blocks = Box3i( //
settings.bounds_in_voxels.pos >> block_size_po2, //
@ -365,7 +365,7 @@ void process_octrees_sliding_box(VoxelLodTerrainUpdateData::State &state, Vector
const unsigned int octree_region_extent = 1 + settings.view_distance_voxels / (1 << octree_size_po2);
const Vector3i viewer_octree_pos =
(Vector3iUtil::from_floored(p_viewer_pos) + Vector3iUtil::create(octree_size / 2)) >> octree_size_po2;
(math::floor(p_viewer_pos) + Vector3iUtil::create(octree_size / 2)) >> octree_size_po2;
const Box3i bounds_in_octrees = settings.bounds_in_voxels.downscaled(octree_size);

View File

@ -23,7 +23,7 @@ void test_octree_update() {
// Testing as an octree forest, as it is the way they are used in VoxelLodTerrain
Map<Vector3i, LodOctree> octrees;
const Box3i viewer_box_voxels =
Box3i::from_center_extents(Vector3iUtil::from_floored(viewer_pos), Vector3iUtil::create(view_distance));
Box3i::from_center_extents(math::floor(viewer_pos), Vector3iUtil::create(view_distance));
const Box3i viewer_box_octrees = viewer_box_voxels.downscaled(octree_size);
viewer_box_octrees.for_each_cell([&octrees](Vector3i pos) {
Map<Vector3i, LodOctree>::Element *e = octrees.insert(pos, LodOctree());

View File

@ -274,9 +274,9 @@ public:
// rounding outwards of the area covered by the original rectangle if divided coordinates have remainders.
inline Box3i downscaled(int step_size) const {
Box3i o;
o.pos = Vector3iUtil::floordiv(pos, step_size);
o.pos = math::floordiv(pos, step_size);
// TODO Is that ceildiv?
Vector3i max_pos = Vector3iUtil::floordiv(pos + size - Vector3i(1, 1, 1), step_size);
Vector3i max_pos = math::floordiv(pos + size - Vector3i(1, 1, 1), step_size);
o.size = max_pos - o.pos + Vector3i(1, 1, 1);
return o;
}
@ -286,8 +286,7 @@ public:
// This is such that the result is included in the original rectangle (assuming a common coordinate system).
// The result can be an empty rectangle.
inline Box3i downscaled_inner(int step_size) const {
return Box3i::from_min_max(
Vector3iUtil::ceildiv(pos, step_size), Vector3iUtil::floordiv(pos + size, step_size));
return Box3i::from_min_max(math::ceildiv(pos, step_size), math::floordiv(pos + size, step_size));
}
static inline void clip_range(int &pos, int &size, int lim_pos, int lim_size) {

View File

@ -68,6 +68,7 @@ inline double maxf(double a, double b) {
template <typename T>
inline T clamp(const T x, const T min_value, const T max_value) {
// TODO Optimization: clang can optimize a min/max implementation. Worth changing to that?
// TODO Enforce T as being numeric
if (x < min_value) {
return min_value;
}

View File

@ -269,7 +269,8 @@ _FORCE_INLINE_ int64_t Vector3i::distance_sq(const Vector3i &other) const {
#else
namespace zylann::Vector3iUtil {
namespace zylann {
namespace Vector3iUtil {
constexpr int AXIS_COUNT = 3;
@ -277,18 +278,6 @@ inline Vector3i create(int xyz) {
return Vector3i(xyz, xyz, xyz);
}
inline Vector3i from_floored(const Vector3 &f) {
return Vector3i(Math::floor(f.x), Math::floor(f.y), Math::floor(f.z));
}
inline Vector3i from_rounded(const Vector3 &f) {
return Vector3i(Math::round(f.x), Math::round(f.y), Math::round(f.z));
}
inline Vector3i from_ceiled(const Vector3 &f) {
return Vector3i(Math::ceil(f.x), Math::ceil(f.y), Math::ceil(f.z));
}
inline Vector3i from_cast(const Vector3 &f) {
return Vector3i(f.x, f.y, f.z);
}
@ -320,6 +309,34 @@ inline Vector3i from_zxy_index(unsigned int i, const Vector3i area_size) {
return pos;
}
inline bool all_members_equal(const Vector3i v) {
return v.x == v.y && v.y == v.z;
}
inline bool is_unit_vector(const Vector3i v) {
return Math::abs(v.x) + Math::abs(v.y) + Math::abs(v.z) == 1;
}
inline bool is_valid_size(const Vector3i &s) {
return s.x >= 0 && s.y >= 0 && s.z >= 0;
}
} // namespace Vector3iUtil
namespace math {
inline Vector3i floor(const Vector3 &f) {
return Vector3i(Math::floor(f.x), Math::floor(f.y), Math::floor(f.z));
}
inline Vector3i round(const Vector3 &f) {
return Vector3i(Math::round(f.x), Math::round(f.y), Math::round(f.z));
}
inline Vector3i ceil(const Vector3 &f) {
return Vector3i(Math::ceil(f.x), Math::ceil(f.y), Math::ceil(f.z));
}
inline Vector3i floordiv(const Vector3i v, const Vector3i d) {
return Vector3i(
zylann::math::floordiv(v.x, d.x), zylann::math::floordiv(v.y, d.y), zylann::math::floordiv(v.z, d.z));
@ -333,23 +350,21 @@ inline Vector3i ceildiv(const Vector3i v, const int d) {
return Vector3i(zylann::math::ceildiv(v.x, d), zylann::math::ceildiv(v.y, d), zylann::math::ceildiv(v.z, d));
}
inline Vector3i ceildiv(const Vector3i v, const Vector3i d) {
return Vector3i(zylann::math::ceildiv(v.x, d.x), zylann::math::ceildiv(v.y, d.y), zylann::math::ceildiv(v.z, d.z));
}
inline Vector3i wrap(const Vector3i v, const Vector3i d) {
return Vector3i(zylann::math::wrap(v.x, d.x), zylann::math::wrap(v.y, d.y), zylann::math::wrap(v.z, d.z));
}
inline bool all_members_equal(const Vector3i v) {
return v.x == v.y && v.y == v.z;
inline Vector3i clamp(const Vector3i a, const Vector3i minv, const Vector3i maxv) {
return Vector3i(
math::clamp(a.x, minv.x, maxv.x), math::clamp(a.y, minv.y, maxv.y), math::clamp(a.z, minv.z, maxv.z));
}
inline bool is_unit_vector(const Vector3i v) {
return Math::abs(v.x) + Math::abs(v.y) + Math::abs(v.z) == 1;
}
inline bool is_valid_size(const Vector3i &s) {
return s.x >= 0 && s.y >= 0 && s.z >= 0;
}
} // namespace zylann::Vector3iUtil
} // namespace math
} // namespace zylann
inline Vector3i operator<<(const Vector3i &a, int b) {
#ifdef DEBUG_ENABLED

View File

@ -32,7 +32,7 @@ bool voxel_raycast(Vector3 ray_origin, Vector3 ray_direction, Predicate_F predic
/* Initialisation */
// Voxel position
Vector3i hit_pos = Vector3iUtil::from_floored(ray_origin);
Vector3i hit_pos = math::floor(ray_origin);
Vector3i hit_prev_pos = hit_pos;
// Voxel step