diff --git a/doc/source/changelog.md b/doc/source/changelog.md index 924bae96..d7ea2458 100644 --- a/doc/source/changelog.md +++ b/doc/source/changelog.md @@ -61,6 +61,7 @@ Ongoing development - `master` - `VoxelStreamBlockFiles`: fixed warning about channels always shown in the scene tree - `VoxelStreamSQLite`: fixed blocks above LOD0 being saved at wrong locations, causing them to be reloaded often floating in the air - Fix some crashes occurring when all PoolVector allocs are in use (Godot 3.x limitation). It will print errors instead, but crashes can still occur inside Godot's code as it's not often checking for this + - Fix some crashes occurring when negative sizes are sent to AABB function parameters 09/05/2021 - `godot3.3` diff --git a/edition/voxel_tool_lod_terrain.cpp b/edition/voxel_tool_lod_terrain.cpp index 318b3209..33adb512 100644 --- a/edition/voxel_tool_lod_terrain.cpp +++ b/edition/voxel_tool_lod_terrain.cpp @@ -597,6 +597,7 @@ static Array separate_floating_chunks(VoxelTool &voxel_tool, Box3i world_box, No Array VoxelToolLodTerrain::separate_floating_chunks(AABB world_box, Node *parent_node) { ERR_FAIL_COND_V(_terrain == nullptr, Array()); + ERR_FAIL_COND_V(!is_valid_size(world_box.size), Array()); Ref mesher = _terrain->get_mesher(); Array materials; materials.append(_terrain->get_material()); diff --git a/edition/voxel_tool_terrain.cpp b/edition/voxel_tool_terrain.cpp index eccb4d62..17637f11 100644 --- a/edition/voxel_tool_terrain.cpp +++ b/edition/voxel_tool_terrain.cpp @@ -229,6 +229,7 @@ void VoxelToolTerrain::run_blocky_random_tick(AABB voxel_area, int voxel_count, ERR_FAIL_COND(callback.is_null()); ERR_FAIL_COND(batch_count <= 0); ERR_FAIL_COND(voxel_count < 0); + ERR_FAIL_COND(!is_valid_size(voxel_area.size)); if (voxel_count == 0) { return; @@ -327,6 +328,7 @@ void VoxelToolTerrain::run_blocky_random_tick(AABB voxel_area, int voxel_count, void VoxelToolTerrain::for_each_voxel_metadata_in_area(AABB voxel_area, Ref callback) { ERR_FAIL_COND(_terrain == nullptr); ERR_FAIL_COND(callback.is_null()); + ERR_FAIL_COND(!is_valid_size(voxel_area.size)); const Box3i voxel_box = Box3i(Vector3i(voxel_area.position), Vector3i(voxel_area.size)); ERR_FAIL_COND(!is_area_editable(voxel_box)); diff --git a/terrain/voxel_lod_terrain.cpp b/terrain/voxel_lod_terrain.cpp index a223112b..15a7034c 100644 --- a/terrain/voxel_lod_terrain.cpp +++ b/terrain/voxel_lod_terrain.cpp @@ -2253,6 +2253,7 @@ void VoxelLodTerrain::_b_save_modified_blocks() { } void VoxelLodTerrain::_b_set_voxel_bounds(AABB aabb) { + ERR_FAIL_COND(!is_valid_size(aabb.size)); // TODO Please Godot, have an integer AABB! set_voxel_bounds(Box3i(aabb.position.round(), aabb.size.round())); } diff --git a/terrain/voxel_terrain.cpp b/terrain/voxel_terrain.cpp index 95bcd91d..2b0a9511 100644 --- a/terrain/voxel_terrain.cpp +++ b/terrain/voxel_terrain.cpp @@ -1353,6 +1353,7 @@ void VoxelTerrain::_b_save_block(Vector3 p_block_pos) { } void VoxelTerrain::_b_set_bounds(AABB aabb) { + ERR_FAIL_COND(!is_valid_size(aabb.size)); // TODO Please Godot, have an integer AABB! set_bounds(Box3i(aabb.position.round(), aabb.size.round())); } diff --git a/util/math/funcs.h b/util/math/funcs.h index 304a69c4..ce87e210 100644 --- a/util/math/funcs.h +++ b/util/math/funcs.h @@ -154,6 +154,10 @@ inline Vector3 fract(const Vector3 &p) { return Vector3(fract(p.x), fract(p.y), fract(p.z)); } +inline bool is_valid_size(const Vector3 &s) { + return s.x >= 0 && s.y >= 0 && s.z >= 0; +} + // inline bool is_power_of_two(int i) { // return i & (i - 1); // }