@@ -202,8 +202,8 @@ static void ProcessNode(const tinygltf::Model& gltf,
202
202
if (in_node.translation .size () == 3 ) {
203
203
transform = transform * Matrix::MakeTranslation (
204
204
{static_cast <Scalar>(in_node.translation [0 ]),
205
- static_cast <Scalar>(in_node.translation [0 ]),
206
- static_cast <Scalar>(in_node.translation [0 ])});
205
+ static_cast <Scalar>(in_node.translation [1 ]),
206
+ static_cast <Scalar>(in_node.translation [2 ])});
207
207
}
208
208
if (in_node.rotation .size () == 4 ) {
209
209
transform = transform * Matrix::MakeRotation (Quaternion (
@@ -226,7 +226,7 @@ static void ProcessNode(const tinygltf::Model& gltf,
226
226
}
227
227
transform = ToMatrix (in_node.matrix );
228
228
}
229
- out_node.transform = ToFBMatrix (transform);
229
+ out_node.transform = ToFBMatrixUniquePtr (transform);
230
230
231
231
// ---------------------------------------------------------------------------
232
232
// / Static meshes.
@@ -242,13 +242,42 @@ static void ProcessNode(const tinygltf::Model& gltf,
242
242
out_node.mesh_primitives .push_back (std::move (mesh_primitive));
243
243
}
244
244
}
245
+
246
+ // ---------------------------------------------------------------------------
247
+ // / Skin.
248
+ // /
249
+
250
+ if (WithinRange (in_node.skin , gltf.skins .size ())) {
251
+ auto & skin = gltf.skins [in_node.skin ];
252
+
253
+ auto ipskin = std::make_unique<fb::SkinT>();
254
+ ipskin->joints = skin.joints ;
255
+ {
256
+ std::vector<fb::Matrix> matrices;
257
+ auto & matrix_accessor = gltf.accessors [skin.inverseBindMatrices ];
258
+ auto & matrix_view = gltf.bufferViews [matrix_accessor.bufferView ];
259
+ auto & matrix_buffer = gltf.buffers [matrix_view.buffer ];
260
+ for (size_t matrix_i = 0 ; matrix_i < matrix_accessor.count ; matrix_i++) {
261
+ auto * s = reinterpret_cast <const float *>(
262
+ matrix_buffer.data .data () + matrix_view.byteOffset +
263
+ matrix_accessor.ByteStride (matrix_view) * matrix_i);
264
+ Matrix m (s[0 ], s[1 ], s[2 ], s[3 ], //
265
+ s[4 ], s[5 ], s[6 ], s[7 ], //
266
+ s[8 ], s[9 ], s[10 ], s[11 ], //
267
+ s[12 ], s[13 ], s[14 ], s[15 ]);
268
+ matrices.push_back (ToFBMatrix (m));
269
+ }
270
+ ipskin->inverse_bind_matrices = std::move (matrices);
271
+ }
272
+ ipskin->skeleton = skin.skeleton ;
273
+ out_node.skin = std::move (ipskin);
274
+ }
245
275
}
246
276
247
277
static void ProcessTexture (const tinygltf::Model& gltf,
248
278
const tinygltf::Texture& in_texture,
249
279
fb::TextureT& out_texture) {
250
- if (in_texture.source < 0 ||
251
- in_texture.source >= static_cast <int >(gltf.images .size ())) {
280
+ if (!WithinRange (in_texture.source , gltf.images .size ())) {
252
281
return ;
253
282
}
254
283
auto & image = gltf.images [in_texture.source ];
@@ -283,6 +312,128 @@ static void ProcessTexture(const tinygltf::Model& gltf,
283
312
out_texture.uri = image.uri ;
284
313
}
285
314
315
+ static void ProcessAnimation (const tinygltf::Model& gltf,
316
+ const tinygltf::Animation& in_animation,
317
+ fb::AnimationT& out_animation) {
318
+ out_animation.name = in_animation.name ;
319
+
320
+ std::vector<std::unique_ptr<impeller::fb::ChannelT>> channels;
321
+ for (auto & in_channel : in_animation.channels ) {
322
+ auto out_channel = std::make_unique<fb::ChannelT>();
323
+
324
+ out_channel->node = in_channel.target_node ;
325
+ auto & sampler = in_animation.samplers [in_channel.sampler ];
326
+
327
+ // / Keyframe times.
328
+ auto & times_accessor = gltf.accessors [sampler.input ];
329
+ if (times_accessor.count <= 0 ) {
330
+ continue ; // Nothing to record.
331
+ }
332
+ {
333
+ auto & times_bufferview = gltf.bufferViews [times_accessor.bufferView ];
334
+ auto & times_buffer = gltf.buffers [times_bufferview.buffer ];
335
+ if (times_accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
336
+ std::cerr << " Unexpected component type \" "
337
+ << times_accessor.componentType
338
+ << " \" for animation channel times accessor. Skipping."
339
+ << std::endl;
340
+ continue ;
341
+ }
342
+ if (times_accessor.type != TINYGLTF_TYPE_SCALAR) {
343
+ std::cerr << " Unexpected type \" " << times_accessor.type
344
+ << " \" for animation channel times accessor. Skipping."
345
+ << std::endl;
346
+ continue ;
347
+ }
348
+ for (size_t time_i = 0 ; time_i < times_accessor.count ; time_i++) {
349
+ const float * time_p = reinterpret_cast <const float *>(
350
+ times_buffer.data .data () + times_bufferview.byteOffset +
351
+ times_accessor.ByteStride (times_bufferview) * time_i);
352
+ out_channel->timeline .push_back (*time_p);
353
+ }
354
+ }
355
+
356
+ // / Keyframe values.
357
+ auto & values_accessor = gltf.accessors [sampler.output ];
358
+ if (values_accessor.count != times_accessor.count ) {
359
+ std::cerr << " Mismatch between time and value accessors for animation "
360
+ " channel. Skipping."
361
+ << std::endl;
362
+ continue ;
363
+ }
364
+ {
365
+ auto & values_bufferview = gltf.bufferViews [values_accessor.bufferView ];
366
+ auto & values_buffer = gltf.buffers [values_bufferview.buffer ];
367
+ if (values_accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
368
+ std::cerr << " Unexpected component type \" "
369
+ << values_accessor.componentType
370
+ << " \" for animation channel values accessor. Skipping."
371
+ << std::endl;
372
+ continue ;
373
+ }
374
+ if (in_channel.target_path == " translation" ) {
375
+ if (values_accessor.type != TINYGLTF_TYPE_VEC3) {
376
+ std::cerr << " Unexpected type \" " << values_accessor.type
377
+ << " \" for animation channel \" translation\" accessor. "
378
+ " Skipping."
379
+ << std::endl;
380
+ continue ;
381
+ }
382
+ fb::TranslationKeyframesT keyframes;
383
+ for (size_t value_i = 0 ; value_i < values_accessor.count ; value_i++) {
384
+ const float * value_p = reinterpret_cast <const float *>(
385
+ values_buffer.data .data () + values_bufferview.byteOffset +
386
+ values_accessor.ByteStride (values_bufferview) * value_i);
387
+ keyframes.values .push_back (
388
+ fb::Vec3 (value_p[0 ], value_p[1 ], value_p[2 ]));
389
+ }
390
+ out_channel->keyframes .Set (std::move (keyframes));
391
+ } else if (in_channel.target_path == " rotation" ) {
392
+ if (values_accessor.type != TINYGLTF_TYPE_VEC4) {
393
+ std::cerr << " Unexpected type \" " << values_accessor.type
394
+ << " \" for animation channel \" rotation\" accessor. "
395
+ " Skipping."
396
+ << std::endl;
397
+ continue ;
398
+ }
399
+ fb::RotationKeyframesT keyframes;
400
+ for (size_t value_i = 0 ; value_i < values_accessor.count ; value_i++) {
401
+ const float * value_p = reinterpret_cast <const float *>(
402
+ values_buffer.data .data () + values_bufferview.byteOffset +
403
+ values_accessor.ByteStride (values_bufferview) * value_i);
404
+ keyframes.values .push_back (
405
+ fb::Vec4 (value_p[0 ], value_p[1 ], value_p[2 ], value_p[3 ]));
406
+ }
407
+ out_channel->keyframes .Set (std::move (keyframes));
408
+ } else if (in_channel.target_path == " scale" ) {
409
+ if (values_accessor.type != TINYGLTF_TYPE_VEC3) {
410
+ std::cerr << " Unexpected type \" " << values_accessor.type
411
+ << " \" for animation channel \" scale\" accessor. "
412
+ " Skipping."
413
+ << std::endl;
414
+ continue ;
415
+ }
416
+ fb::ScaleKeyframesT keyframes;
417
+ for (size_t value_i = 0 ; value_i < values_accessor.count ; value_i++) {
418
+ const float * value_p = reinterpret_cast <const float *>(
419
+ values_buffer.data .data () + values_bufferview.byteOffset +
420
+ values_accessor.ByteStride (values_bufferview) * value_i);
421
+ keyframes.values .push_back (
422
+ fb::Vec3 (value_p[0 ], value_p[1 ], value_p[2 ]));
423
+ }
424
+ out_channel->keyframes .Set (std::move (keyframes));
425
+ } else {
426
+ std::cerr << " Unsupported animation channel target path \" "
427
+ << in_channel.target_path << " \" . Skipping." << std::endl;
428
+ continue ;
429
+ }
430
+ }
431
+
432
+ channels.push_back (std::move (out_channel));
433
+ }
434
+ out_animation.channels = std::move (channels);
435
+ }
436
+
286
437
bool ParseGLTF (const fml::Mapping& source_mapping, fb::SceneT& out_scene) {
287
438
tinygltf::Model gltf;
288
439
@@ -319,6 +470,13 @@ bool ParseGLTF(const fml::Mapping& source_mapping, fb::SceneT& out_scene) {
319
470
out_scene.nodes .push_back (std::move (node));
320
471
}
321
472
473
+ for (size_t animation_i = 0 ; animation_i < gltf.animations .size ();
474
+ animation_i++) {
475
+ auto animation = std::make_unique<fb::AnimationT>();
476
+ ProcessAnimation (gltf, gltf.animations [animation_i], *animation);
477
+ out_scene.animations .push_back (std::move (animation));
478
+ }
479
+
322
480
return true ;
323
481
}
324
482
0 commit comments