Skip to content

Commit 72d84e8

Browse files
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 godotengine#62046 and godotengine#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.
1 parent e78dc83 commit 72d84e8

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

servers/rendering_server.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,13 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
12391239
// Include custom array format type.
12401240
if (format & (1ULL << (ARRAY_CUSTOM0 + i))) {
12411241
format |= (RS::ARRAY_FORMAT_CUSTOM_MASK << (RS::ARRAY_FORMAT_CUSTOM_BASE + i * RS::ARRAY_FORMAT_CUSTOM_BITS)) & p_compress_format;
1242+
1243+
// If the mesh contains no vertex array, infer the array length from the custom array.
1244+
if (array_len == 0) {
1245+
Vector<Variant> custom_array = p_arrays[RS::ARRAY_CUSTOM0 + i];
1246+
uint32_t factor_reciprocal = _get_vertex_to_custom_array_length_factor(format, RS::ARRAY_CUSTOM0 + i);
1247+
array_len = custom_array.size() / factor_reciprocal;
1248+
}
12421249
}
12431250
}
12441251

@@ -1374,6 +1381,30 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
13741381
return OK;
13751382
}
13761383

1384+
int32_t RenderingServer::_get_vertex_to_custom_array_length_factor(uint32_t p_format, int p_array_index) {
1385+
uint32_t type = (p_format >> (ARRAY_FORMAT_CUSTOM_BASE + ARRAY_FORMAT_CUSTOM_BITS * (p_array_index - RS::ARRAY_CUSTOM0))) & ARRAY_FORMAT_CUSTOM_MASK;
1386+
switch (type) {
1387+
case ARRAY_CUSTOM_RGBA8_UNORM:
1388+
case ARRAY_CUSTOM_RGBA8_SNORM:
1389+
case ARRAY_CUSTOM_RG_HALF: {
1390+
return 4;
1391+
} break;
1392+
case ARRAY_CUSTOM_RGBA_HALF: {
1393+
return 8;
1394+
} break;
1395+
case ARRAY_CUSTOM_R_FLOAT:
1396+
case ARRAY_CUSTOM_RG_FLOAT:
1397+
case ARRAY_CUSTOM_RGB_FLOAT:
1398+
case ARRAY_CUSTOM_RGBA_FLOAT: {
1399+
int32_t s = type - ARRAY_CUSTOM_R_FLOAT + 1;
1400+
1401+
return s;
1402+
} break;
1403+
default: {
1404+
}
1405+
}
1406+
}
1407+
13771408
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<ArrayFormat> p_compress_format) {
13781409
SurfaceData sd;
13791410
Error err = mesh_create_surface_data_from_arrays(&sd, p_primitive, p_arrays, p_blend_shapes, p_lods, p_compress_format);

servers/rendering_server.h

+1
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ class RenderingServer : public Object {
388388
/// Returns stride
389389
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;
390390
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);
391+
int32_t _get_vertex_to_custom_array_length_factor(uint32_t p_format, int p_array_index);
391392
Array mesh_create_arrays_from_surface_data(const SurfaceData &p_data) const;
392393
Array mesh_surface_get_arrays(RID p_mesh, int p_surface) const;
393394
TypedArray<Array> mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_surface) const;

0 commit comments

Comments
 (0)