Add 0.0f progress data if given data don't have it 75/315575/3
authorEunki Hong <eunkiki.hong@samsung.com>
Sat, 3 Aug 2024 12:55:26 +0000 (21:55 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Tue, 6 Aug 2024 01:20:35 +0000 (10:20 +0900)
gltf spec support that if their is nothing define 0'th timestamp data then
they will use the smallest timestamp value.

For dali case, we don't do anything if the animation progress is not define at
given keyframes frame range.
So it might not be matched with normal gltf viewer's behavior at 0'th frame.

Currrently we copy 0th frame data at model inside definition animations, and
bvh file. But facial animation doesnt.
We need to support it.

Change-Id: I435847f33ff60aec6bc03c7f7633b09cd5dc43cc
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali-scene3d/utc-Dali-FacialAnimation.cpp
dali-scene3d/public-api/loader/facial-animation-loader.cpp

index 3d122089dc70b516f312fe8b9ad7c63b7c175e63..9038bbb1542865c6c5971b299edeec1fbabdde45 100644 (file)
@@ -15,6 +15,7 @@
  *
  */
 
+#include <dali/devel-api/animation/key-frames-devel.h>
 #include <dali-scene3d/public-api/loader/animation-definition.h>
 #include <dali-scene3d/public-api/loader/facial-animation-loader.h>
 #include <dali-test-suite-utils.h>
@@ -170,5 +171,61 @@ int UtcDaliLoadFacialAnimationFailed03(void)
     AnimationDefinition animDef = LoadFacialAnimation(oss.str());
     DALI_TEST_EQUALS(0u, animDef.GetPropertyCount(), TEST_LOCATION);
   }
+  END_TEST;
+}
+
+int UtcDaliLoadFacialAnimationLoadFirstFrameData(void)
+{
+  TestApplication application;
+
+  tet_infoline("parse json which don't define times zero");
+  std::string rawData = R"(
+  {
+    "name": "Facial_Blendshape_Animation",
+    "version": "1.2.3",
+    "blendShapes": [
+      {
+        "name": "GEO_1",
+        "fullName": "Facial_Blendshape_Animation:GEO_1",
+        "blendShapeVersion": "3.0",
+        "morphtarget": 1,
+        "morphname": [
+          "EyeBlink_Left"
+        ],
+        "key": [
+          [
+            0.5
+          ],
+          [
+            1.0
+          ]
+        ]
+      }
+    ],
+    "shapesAmount": 1,
+    "time": [
+      50,
+      100
+    ],
+    "frames": 2
+  }
+  )";
+  AnimationDefinition animDef = LoadFacialAnimationFromBuffer(reinterpret_cast<uint8_t*>(rawData.data()), static_cast<int>(rawData.length()));
+
+  DALI_TEST_EQUALS(1u, animDef.GetPropertyCount(), TEST_LOCATION);
+
+  DALI_TEST_EQUAL(animDef.GetPropertyAt(0).mNodeName, "GEO_1");
+  DALI_TEST_EQUAL(animDef.GetPropertyAt(0).mPropertyName, "uBlendShapeWeight[0]");
+
+  // Let we ensure 0'th keyframe progress is 0.0f.
+  auto keyFrames = animDef.GetPropertyAt(0).mKeyFrames;
+  DALI_TEST_EQUAL(keyFrames.GetType(), Property::Type::FLOAT);
+  DALI_TEST_EQUALS(Dali::DevelKeyFrames::GetKeyFrameCount(keyFrames), 3, TEST_LOCATION);
+
+  float progress = -1.0f;
+  Property::Value value = Property::Value(10.0f);
+  Dali::DevelKeyFrames::GetKeyFrame(keyFrames, 0u, progress, value);
+  DALI_TEST_EQUALS(progress, 0.0f, TEST_LOCATION);
+
   END_TEST;
 }
\ No newline at end of file
index 1f830073b7e09919f0c93243d93519f4a0e54934..0691c3544d5652151fbd4212ffe7b27cfd4d4b4e 100644 (file)
@@ -165,6 +165,12 @@ Dali::Scene3D::Loader::AnimationDefinition LoadFacialAnimationInternal(json::uni
       animatedProperty.mPropertyName = weightPropertyStream.str();\r
 \r
       animatedProperty.mKeyFrames = Dali::KeyFrames::New();\r
+      // Make initial progress value follow the first parameter, if their is nothing defined at 0'th duration.\r
+      if(DALI_UNLIKELY(facialAnimation.mNumberOfFrames > 0 && facialAnimation.mTime[0] != 0))\r
+      {\r
+        animatedProperty.mKeyFrames.Add(0.0f, blendShape.mKeys[0][0]);\r
+      }\r
+\r
       for(uint32_t timeIndex = 0u; timeIndex < facialAnimation.mNumberOfFrames; ++timeIndex)\r
       {\r
         const float progress = Dali::EqualsZero(animationDefinition.GetDuration()) ? 0.0f : MILLISECONDS_TO_SECONDS * static_cast<float>(facialAnimation.mTime[timeIndex]) / animationDefinition.GetDuration();\r