Prevent crash when passing empty array to MeshEmitter
This commit is contained in:
parent
ab6e370a9e
commit
93bb34cfb4
2 changed files with 94 additions and 64 deletions
|
@ -318,7 +318,6 @@ 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 VisualShaderNodeParticleMeshEmitter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
|
||||||
String code;
|
String code;
|
||||||
|
|
||||||
if (mesh.is_valid()) {
|
|
||||||
if (is_output_port_connected(0)) { // position
|
if (is_output_port_connected(0)) { // position
|
||||||
code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_vx") + ";\n";
|
code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_vx") + ";\n";
|
||||||
}
|
}
|
||||||
|
@ -338,7 +337,6 @@ String VisualShaderNodeParticleMeshEmitter::generate_global(Shader::Mode p_mode,
|
||||||
if (is_output_port_connected(5)) { // uv2
|
if (is_output_port_connected(5)) { // uv2
|
||||||
code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv2") + ";\n";
|
code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv2") + ";\n";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -503,69 +501,99 @@ void VisualShaderNodeParticleMeshEmitter::_update_textures() {
|
||||||
Vector<Vector2> uvs;
|
Vector<Vector2> uvs;
|
||||||
Vector<Vector2> uvs2;
|
Vector<Vector2> uvs2;
|
||||||
|
|
||||||
|
const int surface_count = mesh->get_surface_count();
|
||||||
|
|
||||||
if (use_all_surfaces) {
|
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
|
// position
|
||||||
Array vertex_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_VERTEX];
|
if (surface_arrays_size > Mesh::ARRAY_VERTEX) {
|
||||||
|
Array vertex_array = surface_arrays[Mesh::ARRAY_VERTEX];
|
||||||
for (int j = 0; j < vertex_array.size(); j++) {
|
for (int j = 0; j < vertex_array.size(); j++) {
|
||||||
vertices.push_back((Vector3)vertex_array[j]);
|
vertices.push_back((Vector3)vertex_array[j]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// normal
|
// normal
|
||||||
Array normal_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_NORMAL];
|
if (surface_arrays_size > Mesh::ARRAY_NORMAL) {
|
||||||
|
Array normal_array = surface_arrays[Mesh::ARRAY_NORMAL];
|
||||||
for (int j = 0; j < normal_array.size(); j++) {
|
for (int j = 0; j < normal_array.size(); j++) {
|
||||||
normals.push_back((Vector3)normal_array[j]);
|
normals.push_back((Vector3)normal_array[j]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// color
|
// color
|
||||||
Array color_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_COLOR];
|
if (surface_arrays_size > Mesh::ARRAY_COLOR) {
|
||||||
|
Array color_array = surface_arrays[Mesh::ARRAY_COLOR];
|
||||||
for (int j = 0; j < color_array.size(); j++) {
|
for (int j = 0; j < color_array.size(); j++) {
|
||||||
colors.push_back((Color)color_array[j]);
|
colors.push_back((Color)color_array[j]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// uv
|
// uv
|
||||||
Array uv_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_TEX_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++) {
|
for (int j = 0; j < uv_array.size(); j++) {
|
||||||
uvs.push_back((Vector2)uv_array[j]);
|
uvs.push_back((Vector2)uv_array[j]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// uv2
|
// uv2
|
||||||
Array uv2_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_TEX_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++) {
|
for (int j = 0; j < uv2_array.size(); j++) {
|
||||||
uvs2.push_back((Vector2)uv2_array[j]);
|
uvs2.push_back((Vector2)uv2_array[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
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();
|
||||||
|
|
||||||
// position
|
// position
|
||||||
Array vertex_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_VERTEX];
|
if (surface_arrays_size > Mesh::ARRAY_VERTEX) {
|
||||||
|
Array vertex_array = surface_arrays[Mesh::ARRAY_VERTEX];
|
||||||
for (int i = 0; i < vertex_array.size(); i++) {
|
for (int i = 0; i < vertex_array.size(); i++) {
|
||||||
vertices.push_back((Vector3)vertex_array[i]);
|
vertices.push_back((Vector3)vertex_array[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// normal
|
// normal
|
||||||
Array normal_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_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++) {
|
for (int i = 0; i < normal_array.size(); i++) {
|
||||||
normals.push_back((Vector3)normal_array[i]);
|
normals.push_back((Vector3)normal_array[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// color
|
// color
|
||||||
Array color_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_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++) {
|
for (int i = 0; i < color_array.size(); i++) {
|
||||||
colors.push_back((Color)color_array[i]);
|
colors.push_back((Color)color_array[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// uv
|
// uv
|
||||||
Array uv_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_TEX_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++) {
|
for (int j = 0; j < uv_array.size(); j++) {
|
||||||
uvs.push_back((Vector2)uv_array[j]);
|
uvs.push_back((Vector2)uv_array[j]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// uv2
|
// uv2
|
||||||
Array uv2_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_TEX_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++) {
|
for (int j = 0; j < uv2_array.size(); j++) {
|
||||||
uvs2.push_back((Vector2)uv2_array[j]);
|
uvs2.push_back((Vector2)uv2_array[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_update_texture(vertices, position_texture);
|
_update_texture(vertices, position_texture);
|
||||||
_update_texture(normals, normal_texture);
|
_update_texture(normals, normal_texture);
|
||||||
|
@ -579,12 +607,6 @@ void VisualShaderNodeParticleMeshEmitter::set_mesh(Ref<Mesh> p_mesh) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_mesh.is_valid()) {
|
|
||||||
max_surface_index = p_mesh->get_surface_count();
|
|
||||||
} else {
|
|
||||||
max_surface_index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mesh.is_valid()) {
|
if (mesh.is_valid()) {
|
||||||
Callable callable = callable_mp(this, &VisualShaderNodeParticleMeshEmitter::_update_textures);
|
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) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
surface_index = p_surface_index;
|
surface_index = p_surface_index;
|
||||||
|
|
|
@ -111,7 +111,6 @@ class VisualShaderNodeParticleMeshEmitter : public VisualShaderNodeParticleEmitt
|
||||||
Ref<Mesh> mesh;
|
Ref<Mesh> mesh;
|
||||||
bool use_all_surfaces = true;
|
bool use_all_surfaces = true;
|
||||||
int surface_index = 0;
|
int surface_index = 0;
|
||||||
int max_surface_index = 0;
|
|
||||||
|
|
||||||
Ref<ImageTexture> position_texture;
|
Ref<ImageTexture> position_texture;
|
||||||
Ref<ImageTexture> normal_texture;
|
Ref<ImageTexture> normal_texture;
|
||||||
|
|
Loading…
Reference in a new issue