@@ -66,6 +66,14 @@ static void readAccessor(std::vector<Attr>& data, const cgltf_accessor* accessor
6666 }
6767}
6868
69+ static void readAccessor (std::vector<Attr>& data, const cgltf_accessor* accessor, const std::vector<unsigned int >& sparse)
70+ {
71+ data.resize (sparse.size ());
72+
73+ for (size_t i = 0 ; i < sparse.size (); ++i)
74+ cgltf_accessor_read_float (accessor, sparse[i], &data[i].f [0 ], 4 );
75+ }
76+
6977static void fixupIndices (std::vector<unsigned int >& indices, cgltf_primitive_type& type)
7078{
7179 if (type == cgltf_primitive_type_line_loop)
@@ -177,11 +185,8 @@ static void parseMeshesGltf(cgltf_data* data, std::vector<Mesh>& meshes, std::ve
177185 Mesh& result = meshes.back ();
178186
179187 result.scene = -1 ;
180-
181188 result.material = primitive.material ;
182-
183189 result.extras = primitive.extras ;
184-
185190 result.type = primitive.type ;
186191
187192 result.streams .reserve (primitive.attributes_count );
@@ -199,14 +204,27 @@ static void parseMeshesGltf(cgltf_data* data, std::vector<Mesh>& meshes, std::ve
199204 }
200205 else if (primitive.type != cgltf_primitive_type_points)
201206 {
202- // note, while we could generate a good index buffer, reindexMesh will take care of this
207+ // note, while we could generate a good index buffer here, mesh will be reindexed during processing
203208 result.indices .resize (vertex_count);
204209 for (size_t i = 0 ; i < vertex_count; ++i)
205210 result.indices [i] = unsigned (i);
206211 }
207212
213+ // convert line loops and line/triangle strips to lists
208214 fixupIndices (result.indices , result.type );
209215
216+ std::vector<unsigned int > sparse;
217+
218+ // if the index data is very sparse, switch to deindexing on the fly to avoid the excessive cost of reading large accessors
219+ if (!result.indices .empty () && result.indices .size () < vertex_count / 2 )
220+ {
221+ sparse = result.indices ;
222+
223+ // mesh will be reindexed during processing
224+ for (size_t i = 0 ; i < result.indices .size (); ++i)
225+ result.indices [i] = unsigned (i);
226+ }
227+
210228 for (size_t ai = 0 ; ai < primitive.attributes_count ; ++ai)
211229 {
212230 const cgltf_attribute& attr = primitive.attributes [ai];
@@ -232,7 +250,10 @@ static void parseMeshesGltf(cgltf_data* data, std::vector<Mesh>& meshes, std::ve
232250 if (attr.type == cgltf_attribute_type_custom)
233251 s.custom_name = attr.name ;
234252
235- readAccessor (s.data , attr.data );
253+ if (sparse.empty ())
254+ readAccessor (s.data , attr.data );
255+ else
256+ readAccessor (s.data , attr.data , sparse);
236257
237258 if (attr.type == cgltf_attribute_type_color && attr.data ->type == cgltf_type_vec3)
238259 {
@@ -262,7 +283,10 @@ static void parseMeshesGltf(cgltf_data* data, std::vector<Mesh>& meshes, std::ve
262283 s.index = attr.index ;
263284 s.target = int (ti + 1 );
264285
265- readAccessor (s.data , attr.data );
286+ if (sparse.empty ())
287+ readAccessor (s.data , attr.data );
288+ else
289+ readAccessor (s.data , attr.data , sparse);
266290 }
267291 }
268292
@@ -312,11 +336,11 @@ static void parseMeshInstancesGltf(std::vector<Transform>& instances, cgltf_node
312336 for (size_t i = 0 ; i < count; ++i)
313337 {
314338 if (translation)
315- cgltf_accessor_read_float (translation, i, instance.translation , sizeof ( float ) );
339+ cgltf_accessor_read_float (translation, i, instance.translation , 4 );
316340 if (rotation)
317- cgltf_accessor_read_float (rotation, i, instance.rotation , sizeof ( float ) );
341+ cgltf_accessor_read_float (rotation, i, instance.rotation , 4 );
318342 if (scale)
319- cgltf_accessor_read_float (scale, i, instance.scale , sizeof ( float ) );
343+ cgltf_accessor_read_float (scale, i, instance.scale , 4 );
320344
321345 Transform xf;
322346 cgltf_node_transform_world (&instance, xf.data );
0 commit comments