@@ -202,8 +202,8 @@ static void ProcessNode(const tinygltf::Model& gltf,
202202 if (in_node.translation .size () == 3 ) {
203203 transform = transform * Matrix::MakeTranslation (
204204 {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 ])});
207207 }
208208 if (in_node.rotation .size () == 4 ) {
209209 transform = transform * Matrix::MakeRotation (Quaternion (
@@ -226,7 +226,7 @@ static void ProcessNode(const tinygltf::Model& gltf,
226226 }
227227 transform = ToMatrix (in_node.matrix );
228228 }
229- out_node.transform = ToFBMatrix (transform);
229+ out_node.transform = ToFBMatrixUniquePtr (transform);
230230
231231 // ---------------------------------------------------------------------------
232232 // / Static meshes.
@@ -242,13 +242,42 @@ static void ProcessNode(const tinygltf::Model& gltf,
242242 out_node.mesh_primitives .push_back (std::move (mesh_primitive));
243243 }
244244 }
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+ }
245275}
246276
247277static void ProcessTexture (const tinygltf::Model& gltf,
248278 const tinygltf::Texture& in_texture,
249279 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 ())) {
252281 return ;
253282 }
254283 auto & image = gltf.images [in_texture.source ];
@@ -283,6 +312,128 @@ static void ProcessTexture(const tinygltf::Model& gltf,
283312 out_texture.uri = image.uri ;
284313}
285314
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+
286437bool ParseGLTF (const fml::Mapping& source_mapping, fb::SceneT& out_scene) {
287438 tinygltf::Model gltf;
288439
@@ -319,6 +470,13 @@ bool ParseGLTF(const fml::Mapping& source_mapping, fb::SceneT& out_scene) {
319470 out_scene.nodes .push_back (std::move (node));
320471 }
321472
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+
322480 return true ;
323481}
324482
0 commit comments