From 72d84e8780e009a922e55b3abbba3812d4e04c6c Mon Sep 17 00:00:00 2001 From: Adrian Samoticha <86920182+Adrian-Samoticha@users.noreply.github.com> Date: Mon, 24 Jun 2024 14:36:45 +0200 Subject: [PATCH 1/3] Infer array length from custom array if no vertex array is provided While the `RenderingServer::mesh_create_surface_data_from_arrays` method does support vertexless meshes (see #62046 and #83446), it enforces that the size of custom arrays is dependent on the size of the vertex array. This effectively means that custom arrays cannot be used in vertexless meshes. This commit changes the way the array length is computed so that if no vertex array is provided, its length will be inferred from the custom arrays, if provided. It therefore adds support for custom arrays in vertexless meshes. --- servers/rendering_server.cpp | 31 +++++++++++++++++++++++++++++++ servers/rendering_server.h | 1 + 2 files changed, 32 insertions(+) diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index dd3491f62ce..c9159160dff 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1239,6 +1239,13 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa // Include custom array format type. if (format & (1ULL << (ARRAY_CUSTOM0 + i))) { format |= (RS::ARRAY_FORMAT_CUSTOM_MASK << (RS::ARRAY_FORMAT_CUSTOM_BASE + i * RS::ARRAY_FORMAT_CUSTOM_BITS)) & p_compress_format; + + // If the mesh contains no vertex array, infer the array length from the custom array. + if (array_len == 0) { + Vector custom_array = p_arrays[RS::ARRAY_CUSTOM0 + i]; + uint32_t factor_reciprocal = _get_vertex_to_custom_array_length_factor(format, RS::ARRAY_CUSTOM0 + i); + array_len = custom_array.size() / factor_reciprocal; + } } } @@ -1374,6 +1381,30 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa return OK; } +int32_t RenderingServer::_get_vertex_to_custom_array_length_factor(uint32_t p_format, int p_array_index) { + uint32_t type = (p_format >> (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * (p_array_index - RS::ARRAY_CUSTOM0))) & ARRAY_FORMAT_CUSTOM_MASK; + switch (type) { + case ARRAY_CUSTOM_RGBA8_UNORM: + case ARRAY_CUSTOM_RGBA8_SNORM: + case ARRAY_CUSTOM_RG_HALF: { + return 4; + } break; + case ARRAY_CUSTOM_RGBA_HALF: { + return 8; + } break; + case ARRAY_CUSTOM_R_FLOAT: + case ARRAY_CUSTOM_RG_FLOAT: + case ARRAY_CUSTOM_RGB_FLOAT: + case ARRAY_CUSTOM_RGBA_FLOAT: { + int32_t s = type - ARRAY_CUSTOM_R_FLOAT + 1; + + return s; + } break; + default: { + } + } +} + void RenderingServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, BitField p_compress_format) { SurfaceData sd; Error err = mesh_create_surface_data_from_arrays(&sd, p_primitive, p_arrays, p_blend_shapes, p_lods, p_compress_format); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index e15dba43536..f1a02016631 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -388,6 +388,7 @@ class RenderingServer : public Object { /// Returns stride virtual void mesh_surface_make_offsets_from_format(uint64_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets, uint32_t &r_vertex_element_size, uint32_t &r_normal_element_size, uint32_t &r_attrib_element_size, uint32_t &r_skin_element_size) const; virtual Error mesh_create_surface_data_from_arrays(SurfaceData *r_surface_data, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint64_t p_compress_format = 0); + int32_t _get_vertex_to_custom_array_length_factor(uint32_t p_format, int p_array_index); Array mesh_create_arrays_from_surface_data(const SurfaceData &p_data) const; Array mesh_surface_get_arrays(RID p_mesh, int p_surface) const; TypedArray mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_surface) const; From b5e969e50fa6927624222506f089d0d1c4159a49 Mon Sep 17 00:00:00 2001 From: Adrian Samoticha <86920182+Adrian-Samoticha@users.noreply.github.com> Date: Mon, 24 Jun 2024 14:50:56 +0200 Subject: [PATCH 2/3] Update servers/rendering_server.cpp Co-authored-by: A Thousand Ships (she/her) <96648715+AThousandShips@users.noreply.github.com> --- servers/rendering_server.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index c9159160dff..a0d5a600b4c 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1401,6 +1401,7 @@ int32_t RenderingServer::_get_vertex_to_custom_array_length_factor(uint32_t p_fo return s; } break; default: { + ERR_FAIL_V_MSG(0, "Invalid texture type."); } } } From 8b46e58947a5ee0b41a67dd0af333632213bb96a Mon Sep 17 00:00:00 2001 From: Adrian Samoticha <86920182+Adrian-Samoticha@users.noreply.github.com> Date: Mon, 24 Jun 2024 14:52:45 +0200 Subject: [PATCH 3/3] Change error message when receiving invalid custom format type in `_get_vertex_to_custom_array_length_factor` --- servers/rendering_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index a0d5a600b4c..69a5e1ace05 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1401,7 +1401,7 @@ int32_t RenderingServer::_get_vertex_to_custom_array_length_factor(uint32_t p_fo return s; } break; default: { - ERR_FAIL_V_MSG(0, "Invalid texture type."); + ERR_FAIL_V_MSG(0, "Invalid custom format type."); } } }