diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index dd3491f62ce..69a5e1ace05 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,31 @@ 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: { + ERR_FAIL_V_MSG(0, "Invalid custom format type."); + } + } +} + 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;