MeshInstance3D::get_active_material() causes out-of-bounds error when surface_override_materials is empty
Tested versions
Reproducible in Godot 4.7.2.stable
System information
Windows 10 - Godot v4.7.2.stable - Vulkan (Forward+) - dedicated RX 580
Issue description
Bug: MeshInstance3D get_active_material() can access an empty surface_override_materials array
Description
MeshInstance3D::get_active_material(int p_surface) calls get_surface_override_material(p_surface) after checking that the Mesh has at least one surface.
However, surface_override_materials can have size 0 at the time of the call.
This results in:
ERROR: scene/3d/mesh_instance_3d.cpp:388 - Index p_surface = 0 is out of bounds (surface_override_materials.size() = 0)Relevant code
Ref<Material> MeshInstance3D::get_active_material(int p_surface) const {
Ref<Material> mat_override = get_material_override();
if (mat_override.is_valid()) {
return mat_override;
}
Ref<Mesh> m = get_mesh();
if (m.is_null() || m->get_surface_count() == 0) {
return Ref<Material>();
}
Ref<Material> surface_material = get_surface_override_material(p_surface);
if (surface_material.is_valid()) {
return surface_material;
}
return m->surface_get_material(p_surface);
}get_surface_override_material() performs:
ERR_FAIL_INDEX_V(p_surface, surface_override_materials.size(), Ref<Material>());At the time of the error:
p_surface = 0
surface_override_materials.size() = 0Expected behavior
get_active_material(0) should safely return the mesh's material when there is no surface override, without producing an out-of-bounds error.
Actual behavior
An out-of-bounds error is printed because get_active_material() calls get_surface_override_material() while the override-material array is empty.
Steps to reproduce
- [ضع الخطوات الدقيقة هنا]
- [ضع الـ Mesh/Scene المستخدم هنا]
- [ضع العملية التي تؤدي إلى استدعاء get_active_material() هنا]
- Error appears in
mesh_instance_3d.cpp.
Additional information
The surface_override_materials array is resized in _mesh_changed():
surface_override_materials.resize(surface_count);This suggests the issue may involve a timing/state synchronization case where get_active_material() is called before the override array has been initialized or synchronized with the Mesh surface count.
A defensive bounds check inside get_active_material() may prevent the error, but the underlying cause of the array being empty should also be investigated.
Steps to reproduce
/
Minimal reproduction project (MRP)
/
Source: godotengine/godot