Able to load uint8_t type Joint + Able to animate 0 duration animation 61/286361/6
authorEunki, Hong <eunkiki.hong@samsung.com>
Wed, 4 Jan 2023 15:17:46 +0000 (00:17 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Wed, 18 Jan 2023 03:51:21 +0000 (03:51 +0000)
This patch try to resolve 2 kind of unsupported feature.

1. There was possible to set JOINT_0 accessor type as unsigend byte.
Make it supported.

2. If duration of gltf was 0, the keyframe's progress value become -nan.
It may occure some problems.

Change-Id: I166be7d31880c04b9e819e9cd1acd843538c927a
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
dali-scene3d/public-api/loader/gltf2-loader.cpp
dali-scene3d/public-api/loader/mesh-definition.cpp
dali-scene3d/public-api/loader/mesh-definition.h

index 6d209d2..90002b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -426,9 +426,9 @@ SamplerFlags::Type ConvertSampler(const gt::Ref<gt::Sampler>& s)
 {
   if(s)
   {
-    return ((s->mMinFilter < gt::Filter::NEAREST_MIPMAP_NEAREST) ? (s->mMinFilter - gt::Filter::NEAREST) : ((s->mMinFilter - gt::Filter::NEAREST_MIPMAP_NEAREST) + 2)) | 
-           ((s->mMagFilter - gt::Filter::NEAREST) << SamplerFlags::FILTER_MAG_SHIFT) | 
-           (ConvertWrapMode(s->mWrapS) << SamplerFlags::WRAP_S_SHIFT) | 
+    return ((s->mMinFilter < gt::Filter::NEAREST_MIPMAP_NEAREST) ? (s->mMinFilter - gt::Filter::NEAREST) : ((s->mMinFilter - gt::Filter::NEAREST_MIPMAP_NEAREST) + 2)) |
+           ((s->mMagFilter - gt::Filter::NEAREST) << SamplerFlags::FILTER_MAG_SHIFT) |
+           (ConvertWrapMode(s->mWrapS) << SamplerFlags::WRAP_S_SHIFT) |
            (ConvertWrapMode(s->mWrapT) << SamplerFlags::WRAP_T_SHIFT);
   }
   else
@@ -670,7 +670,8 @@ void ConvertMeshes(const gt::Document& doc, ConversionContext& context)
           if(iFind->first == gt::Attribute::JOINTS_0)
           {
             meshDefinition.mFlags |= (iFind->second->mComponentType == gt::Component::UNSIGNED_SHORT) * MeshDefinition::U16_JOINT_IDS;
-            DALI_ASSERT_DEBUG(MaskMatch(meshDefinition.mFlags, MeshDefinition::U16_JOINT_IDS) || iFind->second->mComponentType == gt::Component::FLOAT);
+            meshDefinition.mFlags |= (iFind->second->mComponentType == gt::Component::UNSIGNED_BYTE) * MeshDefinition::U8_JOINT_IDS;
+            DALI_ASSERT_DEBUG(MaskMatch(meshDefinition.mFlags, MeshDefinition::U16_JOINT_IDS) || MaskMatch(meshDefinition.mFlags, MeshDefinition::U8_JOINT_IDS) || iFind->second->mComponentType == gt::Component::FLOAT);
           }
         }
         else if(needNormalsTangents)
@@ -954,7 +955,7 @@ float LoadKeyFrames(const std::string& path, const gt::Animation::Channel& chann
   Vector<float> inputDataBuffer;
   Vector<T>     outputDataBuffer;
 
-  const float duration = LoadDataFromAccessors<T>(path, input, output, inputDataBuffer, outputDataBuffer);
+  const float duration = std::max(LoadDataFromAccessors<T>(path, input, output, inputDataBuffer, outputDataBuffer), AnimationDefinition::MIN_DURATION_SECONDS);
 
   for(uint32_t i = 0; i < input.mCount; ++i)
   {
@@ -1030,8 +1031,8 @@ void ConvertAnimations(const gt::Document& doc, ConversionContext& context)
     Index propertyIndex = 0u;
     for(const auto& channel : animation.mChannels)
     {
-      Index nodeIndex    = context.mNodeIndices.GetRuntimeId(channel.mTarget.mNode.GetIndex());
-      float duration = 0.f;
+      Index nodeIndex = context.mNodeIndices.GetRuntimeId(channel.mTarget.mNode.GetIndex());
+      float duration  = 0.f;
 
       switch(channel.mTarget.mPath)
       {
index 5c9655a..35835b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,8 +31,6 @@ namespace Loader
 {
 namespace
 {
-using Uint16Vector4 = uint16_t[4];
-
 class IndexProvider
 {
 public:
@@ -175,6 +173,40 @@ bool ReadAccessor(const MeshDefinition::Accessor& accessor, std::istream& source
   return success;
 }
 
+template<typename T>
+void ReadJointAccessor(MeshDefinition::RawData& raw, const MeshDefinition::Accessor& accessor, std::ifstream& binFile, const std::string& meshPath)
+{
+  constexpr auto sizeofBlobUnit = sizeof(T) * 4;
+
+  DALI_ASSERT_ALWAYS(((accessor.mBlob.mLength % sizeofBlobUnit == 0) ||
+                      accessor.mBlob.mStride >= sizeofBlobUnit) &&
+                     "Joints buffer length not a multiple of element size");
+  const auto inBufferSize  = accessor.mBlob.GetBufferSize();
+  const auto outBufferSize = (sizeof(Vector4) / sizeofBlobUnit) * inBufferSize;
+
+  std::vector<uint8_t> buffer(outBufferSize);
+  auto                 inBuffer = buffer.data() + outBufferSize - inBufferSize;
+  if(!ReadAccessor(accessor, binFile, inBuffer))
+  {
+    ExceptionFlinger(ASSERT_LOCATION) << "Failed to read joints from '" << meshPath << "'.";
+  }
+
+  if constexpr(sizeofBlobUnit != sizeof(Vector4))
+  {
+    auto       floats = reinterpret_cast<float*>(buffer.data());
+    const auto end    = inBuffer + inBufferSize;
+    while(inBuffer != end)
+    {
+      const auto value = *reinterpret_cast<T*>(inBuffer);
+      *floats          = static_cast<float>(value);
+
+      inBuffer += sizeof(T);
+      ++floats;
+    }
+  }
+  raw.mAttribs.push_back({"aJoints", Property::VECTOR4, static_cast<uint32_t>(outBufferSize / sizeof(Vector4)), std::move(buffer)});
+}
+
 void GenerateNormals(MeshDefinition::RawData& raw)
 {
   auto& attribs = raw.mAttribs;
@@ -773,42 +805,15 @@ MeshDefinition::LoadRaw(const std::string& modelsPath)
   {
     if(MaskMatch(mFlags, U16_JOINT_IDS))
     {
-      DALI_ASSERT_ALWAYS(((mJoints0.mBlob.mLength % sizeof(Uint16Vector4) == 0) ||
-                          mJoints0.mBlob.mStride >= sizeof(Uint16Vector4)) &&
-                         "Joints buffer length not a multiple of element size");
-      const auto           inBufferSize = mJoints0.mBlob.GetBufferSize();
-      std::vector<uint8_t> buffer(inBufferSize * 2);
-      auto                 u16s = buffer.data() + inBufferSize;
-      if(!ReadAccessor(mJoints0, binFile, u16s))
-      {
-        ExceptionFlinger(ASSERT_LOCATION) << "Failed to read joints from '" << meshPath << "'.";
-      }
-
-      auto floats = reinterpret_cast<float*>(buffer.data());
-      auto end    = u16s + inBufferSize;
-      while(u16s != end)
-      {
-        auto value = *reinterpret_cast<uint16_t*>(u16s);
-        *floats    = static_cast<float>(value);
-
-        u16s += sizeof(uint16_t);
-        ++floats;
-      }
-      raw.mAttribs.push_back({"aJoints", Property::VECTOR4, static_cast<uint32_t>(buffer.size() / sizeof(Vector4)), std::move(buffer)});
+      ReadJointAccessor<uint16_t>(raw, mJoints0, binFile, meshPath);
+    }
+    else if(MaskMatch(mFlags, U8_JOINT_IDS))
+    {
+      ReadJointAccessor<uint8_t>(raw, mJoints0, binFile, meshPath);
     }
     else
     {
-      DALI_ASSERT_ALWAYS(((mJoints0.mBlob.mLength % sizeof(Vector4) == 0) ||
-                          mJoints0.mBlob.mStride >= sizeof(Vector4)) &&
-                         "Joints buffer length not a multiple of element size");
-      const auto           bufferSize = mJoints0.mBlob.GetBufferSize();
-      std::vector<uint8_t> buffer(bufferSize);
-      if(!ReadAccessor(mJoints0, binFile, buffer.data()))
-      {
-        ExceptionFlinger(ASSERT_LOCATION) << "Failed to read joints from '" << meshPath << "'.";
-      }
-
-      raw.mAttribs.push_back({"aJoints", Property::VECTOR4, static_cast<uint32_t>(bufferSize / sizeof(Vector4)), std::move(buffer)});
+      ReadJointAccessor<float>(raw, mJoints0, binFile, meshPath);
     }
 
     DALI_ASSERT_ALWAYS(((mWeights0.mBlob.mLength % sizeof(Vector4) == 0) ||
index 1030c7c..4e72719 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_SCENE3D_LOADER_MESH_DEFINITION_H
 #define DALI_SCENE3D_LOADER_MESH_DEFINITION_H
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -53,6 +53,7 @@ struct DALI_SCENE3D_API MeshDefinition
     FLIP_UVS_VERTICAL = NthBit(0),
     U32_INDICES       = NthBit(1), // default is unsigned short
     U16_JOINT_IDS     = NthBit(2), // default is floats
+    U8_JOINT_IDS      = NthBit(3),
   };
 
   enum Attributes