Skip to content

Commit

Permalink
Fix crash when using the Image graph node with an empty image
Browse files Browse the repository at this point in the history
  • Loading branch information
Zylann committed Nov 7, 2024
1 parent d291ef1 commit eca2aaa
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 2 deletions.
1 change: 1 addition & 0 deletions doc/source/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Primarily developped with Godot 4.3.
- Fixed wrong values when using `OutputWeight` with optimized execution map enabled, when weights are determined to be locally constant
- Fixed occasional holes in terrain when using `FastNoise3D` nodes with the `OpenSimplex2S` noise type
- Fixed shader generation error when using the `Distance3D` node (vec2 instead of vec3, thanks to scwich)
- Fixed crash when assigning an empty image to the `Image` node
- `VoxelMesherTransvoxel`: revert texturing logic that attempted to prevent air voxels from contributing, but was lowering quality. It is now optional as an experimental property.
- `VoxelStreamSQLite`: Fixed "empty size" errors when loading areas with edited `VoxelInstancer` data
- `.vox` scene importer: disabled threaded import to workaround the editor freezing when saving meshes
Expand Down
4 changes: 4 additions & 0 deletions generators/graph/image_range_grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ void ImageRangeGrid::generate(const Image &im) {

clear();

if (im.is_empty()) {
return;
}

const int lod_base = 4; // Start at 16

// Compute first lod
Expand Down
10 changes: 10 additions & 0 deletions generators/graph/nodes/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ void register_image_nodes(Span<NodeType> types) {
.format(varray(Image::get_class_static())));
return;
}
if (image->is_empty()) {
ctx.make_error(String(ZN_TTR("{0} is empty").format(varray(Image::get_class_static()))));
return;
}
ImageRangeGrid *im_range = ZN_NEW(ImageRangeGrid);
im_range->generate(**image);
Params p;
Expand All @@ -167,6 +171,12 @@ void register_image_nodes(Span<NodeType> types) {
// Cache image size to reduce API calls in GDExtension
const int w = im.get_width();
const int h = im.get_height();
#ifdef DEBUG_ENABLED
if (w == 0 || h == 0) {
ZN_PRINT_ERROR_ONCE("Image is empty");
return;
}
#endif
// TODO Optimized path for most used formats, `get_pixel` is kinda slow
if (p.filter == FILTER_NEAREST) {
for (uint32_t i = 0; i < out.size; ++i) {
Expand Down
4 changes: 2 additions & 2 deletions generators/graph/voxel_generator_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1665,7 +1665,7 @@ VoxelSingleValue VoxelGeneratorGraph::generate_single(Vector3i position, unsigne
RWLockRead rlock(_runtime_lock);
runtime_ptr = _runtime;
}
ERR_FAIL_COND_V(runtime_ptr == nullptr, v);
ERR_FAIL_COND_V_MSG(runtime_ptr == nullptr, v, "no compiled graph available");
if (runtime_ptr->sdf_output_buffer_index == -1) {
return v;
}
Expand All @@ -1688,7 +1688,7 @@ VoxelSingleValue VoxelGeneratorGraph::generate_single(Vector3i position, unsigne
RWLockRead rlock(_runtime_lock);
runtime_ptr = _runtime;
}
ERR_FAIL_COND_V(runtime_ptr == nullptr, v);
ERR_FAIL_COND_V_MSG(runtime_ptr == nullptr, v, "no compiled graph available");
if (runtime_ptr->single_texture_output_buffer_index == -1) {
return v;
}
Expand Down
1 change: 1 addition & 0 deletions tests/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ void run_voxel_tests() {
VOXEL_TEST(test_voxel_graph_many_weight_outputs);
VOXEL_TEST(test_voxel_graph_many_subdivisions);
VOXEL_TEST(test_voxel_graph_non_square_image);
VOXEL_TEST(test_voxel_graph_empty_image);
VOXEL_TEST(test_voxel_graph_4_default_weights);
VOXEL_TEST(test_island_finder);
VOXEL_TEST(test_unordered_remove_if);
Expand Down
29 changes: 29 additions & 0 deletions tests/voxel/test_voxel_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2329,4 +2329,33 @@ void test_voxel_graph_4_default_weights() { // Related to issue #686
L::test(0.5, 0.2, 0.4, 0.8);
}

void test_voxel_graph_empty_image() {
// This used to crash

Ref<VoxelGeneratorGraph> generator;
generator.instantiate();

VoxelGraphFunction &g = **generator->get_main_function();

const uint32_t n_x = g.create_node(VoxelGraphFunction::NODE_INPUT_X);
const uint32_t n_z = g.create_node(VoxelGraphFunction::NODE_INPUT_Z);
const uint32_t n_image = g.create_node(VoxelGraphFunction::NODE_IMAGE_2D);
const uint32_t n_out_sdf = g.create_node(VoxelGraphFunction::NODE_OUTPUT_SDF);

Ref<Image> image;
image.instantiate();
g.set_node_param(n_image, 0, image);

g.add_connection(n_x, 0, n_image, 0);
g.add_connection(n_z, 0, n_image, 1);
g.add_connection(n_image, 0, n_out_sdf, 0);

CompilationResult result = generator->compile(false);

// Try to generate before asserting compilation result. It should fail without crashing.
generator->generate_single(Vector3i(405, 2, 305), VoxelBuffer::CHANNEL_SDF);

ZN_TEST_ASSERT(result.success == false);
}

} // namespace zylann::voxel::tests
1 change: 1 addition & 0 deletions tests/voxel/test_voxel_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void test_image_range_grid();
void test_voxel_graph_many_subdivisions();
void test_voxel_graph_non_square_image();
void test_voxel_graph_4_default_weights();
void test_voxel_graph_empty_image();

} // namespace zylann::voxel::tests

Expand Down
9 changes: 9 additions & 0 deletions util/io/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@
#define ZN_PRINT_WARNING(msg) zylann::print_warning(msg, __FUNCTION__, __FILE__, __LINE__)
#define ZN_PRINT_ERROR(msg) zylann::print_error(msg, __FUNCTION__, __FILE__, __LINE__)

#define ZN_PRINT_ERROR_ONCE(msg) \
{ \
static bool s_first_print = true; \
if (s_first_print) { \
s_first_print = false; \
zylann::print_error(msg, __FUNCTION__, __FILE__, __LINE__); \
} \
}

namespace zylann {

bool is_verbose_output_enabled();
Expand Down

0 comments on commit eca2aaa

Please sign in to comment.