diff options
author | Yuri Roubinsky <chaosus89@gmail.com> | 2021-11-25 10:26:31 +0300 |
---|---|---|
committer | Yuri Roubinsky <chaosus89@gmail.com> | 2021-11-26 16:07:09 +0300 |
commit | 93bb34cfb4665765e56dbb411ced68a91e3605d8 (patch) | |
tree | 2be65c1e27d3e5e20db6b8192bccf1a78e9b0cf0 /scene/resources | |
parent | ab6e370a9e6ccefba10179c0ae3ab0c15b28a45c (diff) |
Prevent crash when passing empty array to MeshEmitter
Diffstat (limited to 'scene/resources')
-rw-r--r-- | scene/resources/visual_shader_particle_nodes.cpp | 157 | ||||
-rw-r--r-- | scene/resources/visual_shader_particle_nodes.h | 1 |
2 files changed, 94 insertions, 64 deletions
diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp index 1a829968e3..a7c20b2cb9 100644 --- a/scene/resources/visual_shader_particle_nodes.cpp +++ b/scene/resources/visual_shader_particle_nodes.cpp @@ -318,26 +318,24 @@ String VisualShaderNodeParticleMeshEmitter::get_input_port_name(int p_port) cons String VisualShaderNodeParticleMeshEmitter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { String code; - if (mesh.is_valid()) { - if (is_output_port_connected(0)) { // position - code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_vx") + ";\n"; - } + if (is_output_port_connected(0)) { // position + code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_vx") + ";\n"; + } - if (is_output_port_connected(1)) { // normal - code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_nm") + ";\n"; - } + if (is_output_port_connected(1)) { // normal + code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_nm") + ";\n"; + } - if (is_output_port_connected(2) || is_output_port_connected(3)) { // color & alpha - code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_col") + ";\n"; - } + if (is_output_port_connected(2) || is_output_port_connected(3)) { // color & alpha + code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_col") + ";\n"; + } - if (is_output_port_connected(4)) { // uv - code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv") + ";\n"; - } + if (is_output_port_connected(4)) { // uv + code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv") + ";\n"; + } - if (is_output_port_connected(5)) { // uv2 - code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv2") + ";\n"; - } + if (is_output_port_connected(5)) { // uv2 + code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv2") + ";\n"; } return code; @@ -503,67 +501,97 @@ void VisualShaderNodeParticleMeshEmitter::_update_textures() { Vector<Vector2> uvs; Vector<Vector2> uvs2; + const int surface_count = mesh->get_surface_count(); + if (use_all_surfaces) { - for (int i = 0; i < max_surface_index; i++) { + for (int i = 0; i < surface_count; i++) { + const Array surface_arrays = mesh->surface_get_arrays(i); + const int surface_arrays_size = surface_arrays.size(); + // position - Array vertex_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_VERTEX]; - for (int j = 0; j < vertex_array.size(); j++) { - vertices.push_back((Vector3)vertex_array[j]); + if (surface_arrays_size > Mesh::ARRAY_VERTEX) { + Array vertex_array = surface_arrays[Mesh::ARRAY_VERTEX]; + for (int j = 0; j < vertex_array.size(); j++) { + vertices.push_back((Vector3)vertex_array[j]); + } } // normal - Array normal_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_NORMAL]; - for (int j = 0; j < normal_array.size(); j++) { - normals.push_back((Vector3)normal_array[j]); + if (surface_arrays_size > Mesh::ARRAY_NORMAL) { + Array normal_array = surface_arrays[Mesh::ARRAY_NORMAL]; + for (int j = 0; j < normal_array.size(); j++) { + normals.push_back((Vector3)normal_array[j]); + } } // color - Array color_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_COLOR]; - for (int j = 0; j < color_array.size(); j++) { - colors.push_back((Color)color_array[j]); + if (surface_arrays_size > Mesh::ARRAY_COLOR) { + Array color_array = surface_arrays[Mesh::ARRAY_COLOR]; + for (int j = 0; j < color_array.size(); j++) { + colors.push_back((Color)color_array[j]); + } } // uv - Array uv_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_TEX_UV]; - for (int j = 0; j < uv_array.size(); j++) { - uvs.push_back((Vector2)uv_array[j]); + if (surface_arrays_size > Mesh::ARRAY_TEX_UV) { + Array uv_array = surface_arrays[Mesh::ARRAY_TEX_UV]; + for (int j = 0; j < uv_array.size(); j++) { + uvs.push_back((Vector2)uv_array[j]); + } } // uv2 - Array uv2_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_TEX_UV2]; - for (int j = 0; j < uv2_array.size(); j++) { - uvs2.push_back((Vector2)uv2_array[j]); + if (surface_arrays_size > Mesh::ARRAY_TEX_UV2) { + Array uv2_array = surface_arrays[Mesh::ARRAY_TEX_UV2]; + for (int j = 0; j < uv2_array.size(); j++) { + uvs2.push_back((Vector2)uv2_array[j]); + } } } } else { - // position - Array vertex_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_VERTEX]; - for (int i = 0; i < vertex_array.size(); i++) { - vertices.push_back((Vector3)vertex_array[i]); - } + if (surface_index >= 0 && surface_index < surface_count) { + const Array surface_arrays = mesh->surface_get_arrays(surface_index); + const int surface_arrays_size = surface_arrays.size(); - // normal - Array normal_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_NORMAL]; - for (int i = 0; i < normal_array.size(); i++) { - normals.push_back((Vector3)normal_array[i]); - } + // position + if (surface_arrays_size > Mesh::ARRAY_VERTEX) { + Array vertex_array = surface_arrays[Mesh::ARRAY_VERTEX]; + for (int i = 0; i < vertex_array.size(); i++) { + vertices.push_back((Vector3)vertex_array[i]); + } + } - // color - Array color_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_COLOR]; - for (int i = 0; i < color_array.size(); i++) { - colors.push_back((Color)color_array[i]); - } + // normal + if (surface_arrays_size > Mesh::ARRAY_NORMAL) { + Array normal_array = surface_arrays[Mesh::ARRAY_NORMAL]; + for (int i = 0; i < normal_array.size(); i++) { + normals.push_back((Vector3)normal_array[i]); + } + } - // uv - Array uv_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_TEX_UV]; - for (int j = 0; j < uv_array.size(); j++) { - uvs.push_back((Vector2)uv_array[j]); - } + // color + if (surface_arrays_size > Mesh::ARRAY_COLOR) { + Array color_array = surface_arrays[Mesh::ARRAY_COLOR]; + for (int i = 0; i < color_array.size(); i++) { + colors.push_back((Color)color_array[i]); + } + } + + // uv + if (surface_arrays_size > Mesh::ARRAY_TEX_UV) { + Array uv_array = surface_arrays[Mesh::ARRAY_TEX_UV]; + for (int j = 0; j < uv_array.size(); j++) { + uvs.push_back((Vector2)uv_array[j]); + } + } - // uv2 - Array uv2_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_TEX_UV2]; - for (int j = 0; j < uv2_array.size(); j++) { - uvs2.push_back((Vector2)uv2_array[j]); + // uv2 + if (surface_arrays_size > Mesh::ARRAY_TEX_UV2) { + Array uv2_array = surface_arrays[Mesh::ARRAY_TEX_UV2]; + for (int j = 0; j < uv2_array.size(); j++) { + uvs2.push_back((Vector2)uv2_array[j]); + } + } } } @@ -579,12 +607,6 @@ void VisualShaderNodeParticleMeshEmitter::set_mesh(Ref<Mesh> p_mesh) { return; } - if (p_mesh.is_valid()) { - max_surface_index = p_mesh->get_surface_count(); - } else { - max_surface_index = 0; - } - if (mesh.is_valid()) { Callable callable = callable_mp(this, &VisualShaderNodeParticleMeshEmitter::_update_textures); @@ -623,7 +645,16 @@ bool VisualShaderNodeParticleMeshEmitter::is_use_all_surfaces() const { } void VisualShaderNodeParticleMeshEmitter::set_surface_index(int p_surface_index) { - if (p_surface_index == surface_index || p_surface_index < 0 || p_surface_index >= max_surface_index) { + if (mesh.is_valid()) { + if (mesh->get_surface_count() > 0) { + p_surface_index = CLAMP(p_surface_index, 0, mesh->get_surface_count() - 1); + } else { + p_surface_index = 0; + } + } else if (p_surface_index < 0) { + p_surface_index = 0; + } + if (surface_index == p_surface_index) { return; } surface_index = p_surface_index; diff --git a/scene/resources/visual_shader_particle_nodes.h b/scene/resources/visual_shader_particle_nodes.h index 79459432f1..ae7ea69225 100644 --- a/scene/resources/visual_shader_particle_nodes.h +++ b/scene/resources/visual_shader_particle_nodes.h @@ -111,7 +111,6 @@ class VisualShaderNodeParticleMeshEmitter : public VisualShaderNodeParticleEmitt Ref<Mesh> mesh; bool use_all_surfaces = true; int surface_index = 0; - int max_surface_index = 0; Ref<ImageTexture> position_texture; Ref<ImageTexture> normal_texture; |