utc-Dali-AnimationDefinition.cpp
utc-Dali-AnimatedProperty.cpp
utc-Dali-BvhLoader.cpp
+ utc-Dali-BlendShapeIndex.cpp
utc-Dali-CameraParameters.cpp
utc-Dali-EnvironmentMapLoader.cpp
utc-Dali-EnvironmentDefinition.cpp
utc-Dali-Model.cpp
utc-Dali-ModelNode.cpp
utc-Dali-ModelPrimitive.cpp
+ utc-Dali-MotionData.cpp
+ utc-Dali-MotionIndex.cpp
+ utc-Dali-MotionPropertyIndex.cpp
+ utc-Dali-MotionTransformIndex.cpp
+ utc-Dali-MotionValue.cpp
utc-Dali-SceneView.cpp
utc-Dali-MatrixStack.cpp
utc-Dali-MeshDefinition.cpp
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <stdlib.h>
+#include <iostream>
+
+#include <dali-scene3d/public-api/model-motion/motion-index/blend-shape-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-index.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+using namespace Dali::Scene3D;
+
+void model_motion_blend_shape_index_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void model_motion_blend_shape_index_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+namespace
+{
+const char* const WEIGHTS_UNIFORM = "uBlendShapeWeight";
+
+std::string GetPropertyNameFromIndex(int index)
+{
+ if(index >= 0)
+ {
+ char weightNameBuffer[32];
+
+ // Get return value of snprintf to avoid SVACE.
+ [[maybe_unused]] auto prefixSize = snprintf(weightNameBuffer, sizeof(weightNameBuffer), "%s[%d]", WEIGHTS_UNIFORM, index);
+
+ return weightNameBuffer;
+ }
+ return "";
+}
+} // namespace
+
+// Positive test case for a method
+int UtcDaliBlendShapeIndexNew(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliBlendShapeIndexNew");
+
+ BlendShapeIndex blendShapeIndex = BlendShapeIndex::New();
+ DALI_TEST_CHECK(blendShapeIndex);
+ DALI_TEST_EQUALS(blendShapeIndex.GetModelNodeId().stringKey, "", TEST_LOCATION);
+ DALI_TEST_EQUALS(blendShapeIndex.GetBlendShapeId().indexKey, Property::INVALID_INDEX, TEST_LOCATION);
+
+ blendShapeIndex = BlendShapeIndex::New("dummy", 3u);
+ DALI_TEST_CHECK(blendShapeIndex);
+ DALI_TEST_EQUALS(blendShapeIndex.GetModelNodeId().stringKey, "dummy", TEST_LOCATION);
+ DALI_TEST_EQUALS(blendShapeIndex.GetBlendShapeId().indexKey, 3u, TEST_LOCATION);
+ END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliBlendShapeIndexDownCast(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliBlendShapeIndexDownCast");
+
+ BlendShapeIndex blendShapeIndex = BlendShapeIndex::New();
+ BaseHandle handle(blendShapeIndex);
+
+ BlendShapeIndex blendShapeIndex2 = BlendShapeIndex::DownCast(handle);
+ DALI_TEST_CHECK(blendShapeIndex);
+ DALI_TEST_CHECK(blendShapeIndex2);
+ DALI_TEST_CHECK(blendShapeIndex2 == blendShapeIndex);
+ END_TEST;
+}
+
+int UtcDaliBlendShapeIndexTypeRegistry(void)
+{
+ ToolkitTestApplication application;
+
+ TypeRegistry typeRegistry = TypeRegistry::Get();
+ DALI_TEST_CHECK(typeRegistry);
+
+ TypeInfo typeInfo = typeRegistry.GetTypeInfo("BlendShapeIndex");
+ DALI_TEST_CHECK(typeInfo);
+
+ BaseHandle handle = typeInfo.CreateInstance();
+ DALI_TEST_CHECK(handle);
+
+ BlendShapeIndex blendShapeIndex = BlendShapeIndex::DownCast(handle);
+ DALI_TEST_CHECK(blendShapeIndex);
+
+ END_TEST;
+}
+
+int UtcDaliBlendShapeIndexCopyAndAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ BlendShapeIndex blendShapeIndex = BlendShapeIndex::New();
+ DALI_TEST_CHECK(blendShapeIndex);
+
+ BlendShapeIndex copy(blendShapeIndex);
+ DALI_TEST_CHECK(blendShapeIndex == copy);
+
+ BlendShapeIndex assign;
+ DALI_TEST_CHECK(!assign);
+
+ assign = copy;
+ DALI_TEST_CHECK(assign == blendShapeIndex);
+
+ END_TEST;
+}
+
+int UtcDaliBlendShapeIndexMoveConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ BlendShapeIndex blendShapeIndex = BlendShapeIndex::New();
+ DALI_TEST_EQUALS(1, blendShapeIndex.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ BlendShapeIndex moved = std::move(blendShapeIndex);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_CHECK(!blendShapeIndex);
+
+ END_TEST;
+}
+
+int UtcDaliBlendShapeIndexMoveAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ BlendShapeIndex blendShapeIndex = BlendShapeIndex::New();
+ DALI_TEST_EQUALS(1, blendShapeIndex.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ BlendShapeIndex moved;
+ moved = std::move(blendShapeIndex);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ END_TEST;
+}
+
+// Method test
+
+int UtcDaliBlendShapeIndexGetPropertyName(void)
+{
+ std::string expectPropertyName = "";
+ Property::Index expectPropertyIndex = Property::INVALID_INDEX;
+
+ uint32_t blendShapeIndex;
+
+ MotionIndex index = BlendShapeIndex::New();
+
+ // Invalid motion index return empty string, invalid index
+ DALI_TEST_EQUALS(expectPropertyName, index.GetPropertyName(), TEST_LOCATION);
+ DALI_TEST_EQUALS(expectPropertyIndex, index.GetPropertyIndex(), TEST_LOCATION);
+
+ blendShapeIndex = 0u;
+ index = BlendShapeIndex::New("", blendShapeIndex);
+ expectPropertyName = GetPropertyNameFromIndex(blendShapeIndex);
+ DALI_TEST_EQUALS(expectPropertyName, index.GetPropertyName(), TEST_LOCATION);
+
+ blendShapeIndex = 45u;
+ index = BlendShapeIndex::New("", blendShapeIndex);
+ expectPropertyName = GetPropertyNameFromIndex(blendShapeIndex);
+ DALI_TEST_EQUALS(expectPropertyName, index.GetPropertyName(), TEST_LOCATION);
+
+ blendShapeIndex = 109u;
+ index = BlendShapeIndex::New("", blendShapeIndex);
+ expectPropertyName = GetPropertyNameFromIndex(blendShapeIndex);
+ DALI_TEST_EQUALS(expectPropertyName, index.GetPropertyName(), TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliBlendShapeIndexSetGetBlendShapeId(void)
+{
+ Property::Index expectPropertyIndex = 0u;
+
+ BlendShapeIndex index = BlendShapeIndex::New("", expectPropertyIndex);
+
+ // Invalid motion index return empty string, invalid index
+ DALI_TEST_CHECK(index.GetBlendShapeId().type == Property::Key::Type::INDEX);
+ DALI_TEST_EQUALS(expectPropertyIndex, index.GetBlendShapeId().indexKey, TEST_LOCATION);
+
+ std::string expectPropertyName = "hello";
+ index.SetBlendShapeId(expectPropertyName);
+ DALI_TEST_CHECK(index.GetBlendShapeId().type == Property::Key::Type::STRING);
+ DALI_TEST_EQUALS(expectPropertyName, index.GetBlendShapeId().stringKey, TEST_LOCATION);
+
+ expectPropertyIndex = 100u;
+ index.SetBlendShapeId(expectPropertyIndex);
+ DALI_TEST_CHECK(index.GetBlendShapeId().type == Property::Key::Type::INDEX);
+ DALI_TEST_EQUALS(expectPropertyIndex, index.GetBlendShapeId().indexKey, TEST_LOCATION);
+
+ END_TEST;
+}
\ No newline at end of file
#include <dali-scene3d/public-api/controls/model/model.h>
#include <dali-scene3d/public-api/model-components/model-node.h>
+#include <dali-scene3d/public-api/model-motion/motion-data.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/blend-shape-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-transform-index.h>
+
#include <dali/devel-api/actors/camera-actor-devel.h>
using namespace Dali;
const char* TEST_GLTF_ANIMATION_TEST_FILE_NAME = TEST_RESOURCE_DIR "/animationTest.gltf";
const char* TEST_GLTF_EXTRAS_FILE_NAME = TEST_RESOURCE_DIR "/AnimatedMorphCubeAnimateNonZeroFrame.gltf";
const char* TEST_GLTF_MULTIPLE_PRIMITIVE_FILE_NAME = TEST_RESOURCE_DIR "/simpleMultiplePrimitiveTest.gltf";
+const char* TEST_GLTF_MORPH_FILE_NAME = TEST_RESOURCE_DIR "/AnimatedMorphCube.gltf";
const char* TEST_DLI_FILE_NAME = TEST_RESOURCE_DIR "/arc.dli";
const char* TEST_DLI_EXERCISE_FILE_NAME = TEST_RESOURCE_DIR "/exercise.dli";
END_TEST;
}
+
+int UtcDaliModelGenerateMotionDataAnimation01(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_MORPH_FILE_NAME);
+ model.SetProperty(Dali::Actor::Property::SIZE, Vector2(50, 50));
+ application.GetScene().Add(model);
+
+ gResourceReadyCalled = false;
+ model.ResourceReadySignal().Connect(&OnResourceReady);
+ DALI_TEST_EQUALS(gResourceReadyCalled, false, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(gResourceReadyCalled, true, TEST_LOCATION);
+
+ KeyFrames floatKeyFrames = KeyFrames::New();
+ floatKeyFrames.Add(0.0f, 1.0f);
+ floatKeyFrames.Add(1.0f, 0.5f);
+
+ float duration = 3.0f;
+ Scene3D::MotionData motionData = Scene3D::MotionData::New(duration);
+ motionData.Add(Scene3D::MotionTransformIndex::New("AnimatedMorphCube", Scene3D::MotionTransformIndex::TransformType::SCALE_Y), Scene3D::MotionValue::New(2.0f));
+ motionData.Add(Scene3D::MotionTransformIndex::New("AnimatedMorphCube", Scene3D::MotionTransformIndex::TransformType::SCALE_Z), Scene3D::MotionValue::New(floatKeyFrames));
+ motionData.Add(Scene3D::BlendShapeIndex::New("AnimatedMorphCube", 0), Scene3D::MotionValue::New(0.5f));
+ motionData.Add(Scene3D::BlendShapeIndex::New("AnimatedMorphCube", 1), Scene3D::MotionValue::New(floatKeyFrames));
+
+ Animation generatedAnimation = model.GenerateMotionDataAnimation(motionData);
+ DALI_TEST_CHECK(generatedAnimation);
+ DALI_TEST_EQUALS(generatedAnimation.GetDuration(), duration, TEST_LOCATION);
+
+ Scene3D::MotionData invalidMotionData = Scene3D::MotionData::New(duration);
+ invalidMotionData.Add(Scene3D::MotionTransformIndex::New("NotAnimatedMorphCube", Scene3D::MotionTransformIndex::TransformType::SCALE_Y), Scene3D::MotionValue::New(2.0f));
+ invalidMotionData.Add(Scene3D::MotionTransformIndex::New("NotAnimatedMorphCube", Scene3D::MotionTransformIndex::TransformType::SCALE_Z), Scene3D::MotionValue::New(floatKeyFrames));
+ invalidMotionData.Add(Scene3D::BlendShapeIndex::New("NotAnimatedMorphCube", 0), Scene3D::MotionValue::New(0.5f));
+ invalidMotionData.Add(Scene3D::BlendShapeIndex::New("NotAnimatedMorphCube", 1), Scene3D::MotionValue::New(floatKeyFrames));
+
+ generatedAnimation = model.GenerateMotionDataAnimation(invalidMotionData);
+ DALI_TEST_CHECK(!generatedAnimation); // Animation should be empty if motion data have invalid index.
+
+ END_TEST;
+}
+
+int UtcDaliModelSetMotionData(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_MORPH_FILE_NAME);
+ model.SetProperty(Dali::Actor::Property::SIZE, Vector2(50, 50));
+ application.GetScene().Add(model);
+
+ gResourceReadyCalled = false;
+ model.ResourceReadySignal().Connect(&OnResourceReady);
+ DALI_TEST_EQUALS(gResourceReadyCalled, false, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(gResourceReadyCalled, true, TEST_LOCATION);
+
+ KeyFrames floatKeyFrames = KeyFrames::New();
+ floatKeyFrames.Add(0.0f, 1.0f);
+ floatKeyFrames.Add(1.0f, 0.5f);
+
+ float duration = 3.0f;
+ Scene3D::MotionData motionData = Scene3D::MotionData::New(duration);
+ motionData.Add(Scene3D::MotionTransformIndex::New("AnimatedMorphCube", Scene3D::MotionTransformIndex::TransformType::SCALE_Y), Scene3D::MotionValue::New(2.0f));
+ motionData.Add(Scene3D::MotionTransformIndex::New("AnimatedMorphCube", Scene3D::MotionTransformIndex::TransformType::SCALE_Z), Scene3D::MotionValue::New(floatKeyFrames));
+ motionData.Add(Scene3D::BlendShapeIndex::New("AnimatedMorphCube", 0), Scene3D::MotionValue::New(0.5f));
+ motionData.Add(Scene3D::BlendShapeIndex::New("AnimatedMorphCube", 1), Scene3D::MotionValue::New(floatKeyFrames));
+
+ auto cubeModelNode = model.FindChildModelNodeByName("AnimatedMorphCube");
+
+ float expectScaleX = cubeModelNode.GetProperty<float>(Actor::Property::SCALE_X);
+
+ model.SetMotionData(motionData);
+
+ DALI_TEST_EQUALS(cubeModelNode.GetProperty<float>(Actor::Property::SCALE_X), expectScaleX, TEST_LOCATION);
+ DALI_TEST_EQUALS(cubeModelNode.GetProperty<float>(Actor::Property::SCALE_Y), 2.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(cubeModelNode.GetProperty<float>(Actor::Property::SCALE_Z), 0.5f, TEST_LOCATION); ///< Last value of keyframes
+
+ END_TEST;
+}
+
+int UtcDaliModelBlendShapeMotionDataByName(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_EXTRAS_FILE_NAME);
+ model.SetProperty(Dali::Actor::Property::SIZE, Vector2(50, 50));
+ application.GetScene().Add(model);
+
+ gResourceReadyCalled = false;
+ model.ResourceReadySignal().Connect(&OnResourceReady);
+ DALI_TEST_EQUALS(gResourceReadyCalled, false, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(gResourceReadyCalled, true, TEST_LOCATION);
+
+ KeyFrames floatKeyFrames = KeyFrames::New();
+ floatKeyFrames.Add(0.0f, 0.5f);
+ floatKeyFrames.Add(1.0f, 1.0f);
+
+ float duration = 3.0f;
+ Scene3D::MotionData motionData = Scene3D::MotionData::New(duration);
+ motionData.Add(Scene3D::BlendShapeIndex::New("Target_0"), Scene3D::MotionValue::New(0.5f));
+ motionData.Add(Scene3D::BlendShapeIndex::New("Target_1"), Scene3D::MotionValue::New(floatKeyFrames));
+
+ Animation generatedAnimation = model.GenerateMotionDataAnimation(motionData);
+ DALI_TEST_CHECK(generatedAnimation);
+ DALI_TEST_EQUALS(generatedAnimation.GetDuration(), duration, TEST_LOCATION);
+
+ model.SetMotionData(motionData);
+
+ // Get target ModelNode that has extras
+ Scene3D::ModelNode expectNode = model.FindChildModelNodeByName("AnimatedMorphCube");
+ auto propertyIndex = expectNode.GetPropertyIndex(motionData.GetIndex(0u).GetPropertyName(expectNode));
+
+ DALI_TEST_CHECK(propertyIndex != Property::INVALID_INDEX);
+ DALI_TEST_EQUALS(expectNode.GetProperty<float>(propertyIndex), 0.5f, TEST_LOCATION);
+
+ propertyIndex = expectNode.GetPropertyIndex(motionData.GetIndex(1u).GetPropertyName(expectNode));
+ DALI_TEST_CHECK(propertyIndex != Property::INVALID_INDEX);
+ DALI_TEST_EQUALS(expectNode.GetProperty<float>(propertyIndex), 1.0f, TEST_LOCATION);
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <stdlib.h>
+#include <fstream>
+#include <iostream>
+
+#include <toolkit-event-thread-callback.h>
+
+#include <dali-scene3d/public-api/model-motion/motion-data.h>
+#include <dali-scene3d/public-api/model-motion/motion-value.h>
+
+#include <dali-scene3d/public-api/model-motion/motion-index/blend-shape-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-transform-index.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+using namespace Dali::Scene3D;
+
+void model_motion_motion_data_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void model_motion_motion_data_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+namespace
+{
+const char* TEST_BVH_FILE_NAME = TEST_RESOURCE_DIR "/test.bvh";
+const char* TEST_FACIAL_FILE_NAME = TEST_RESOURCE_DIR "/facial-blendshape-animation.json";
+
+std::string ReadBufferFromFile(const std::string& url)
+{
+ std::string rawString;
+ std::fstream fileStream;
+
+ fileStream.open(url, std::ios::in | std::ios::binary);
+ if(!fileStream.is_open())
+ {
+ DALI_LOG_WARNING("stream open failed for: \"%s\", in mode: \"%d\".\n", url.c_str(), static_cast<int>(std::ios::in | std::ios::binary));
+ }
+
+ // get length of file:
+ fileStream.seekg(0, std::ios::end);
+ auto length = fileStream.tellg();
+ fileStream.seekg(0, std::ios::beg);
+
+ rawString.resize(length);
+ fileStream.read(rawString.data(), length);
+
+ fileStream.close();
+
+ return rawString;
+}
+
+// For LoadCompleted
+static bool gLoadCompleted = false;
+void OnLoadCompleted(MotionData data)
+{
+ gLoadCompleted = true;
+}
+} // namespace
+
+// Positive test case for a method
+int UtcDaliMotionDataNew(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliMotionDataNew");
+
+ float expectDuration = 0.0f;
+ MotionData motionData = MotionData::New();
+ DALI_TEST_CHECK(motionData);
+ DALI_TEST_EQUALS(motionData.GetDuration(), expectDuration, TEST_LOCATION);
+
+ expectDuration = 10.0f;
+ motionData = MotionData::New(expectDuration);
+ DALI_TEST_CHECK(motionData);
+ DALI_TEST_EQUALS(motionData.GetDuration(), expectDuration, TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliMotionDataDownCast(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliMotionDataDownCast");
+
+ MotionData motionData = MotionData::New();
+ BaseHandle handle(motionData);
+
+ MotionData motionData2 = MotionData::DownCast(handle);
+ DALI_TEST_CHECK(motionData);
+ DALI_TEST_CHECK(motionData2);
+ DALI_TEST_CHECK(motionData2 == motionData);
+ END_TEST;
+}
+
+int UtcDaliMotionDataTypeRegistry(void)
+{
+ ToolkitTestApplication application;
+
+ TypeRegistry typeRegistry = TypeRegistry::Get();
+ DALI_TEST_CHECK(typeRegistry);
+
+ TypeInfo typeInfo = typeRegistry.GetTypeInfo("MotionData");
+ DALI_TEST_CHECK(typeInfo);
+
+ BaseHandle handle = typeInfo.CreateInstance();
+ DALI_TEST_CHECK(handle);
+
+ MotionData motionData = MotionData::DownCast(handle);
+ DALI_TEST_CHECK(motionData);
+
+ END_TEST;
+}
+
+int UtcDaliMotionDataCopyAndAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ MotionData motionData = MotionData::New();
+ DALI_TEST_CHECK(motionData);
+
+ MotionData copy(motionData);
+ DALI_TEST_CHECK(motionData == copy);
+
+ MotionData assign;
+ DALI_TEST_CHECK(!assign);
+
+ assign = copy;
+ DALI_TEST_CHECK(assign == motionData);
+
+ END_TEST;
+}
+
+int UtcDaliMotionDataMoveConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ MotionData motionData = MotionData::New();
+ DALI_TEST_EQUALS(1, motionData.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ MotionData moved = std::move(motionData);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_CHECK(!motionData);
+
+ END_TEST;
+}
+
+int UtcDaliMotionDataMoveAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ MotionData motionData = MotionData::New();
+ DALI_TEST_EQUALS(1, motionData.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ MotionData moved;
+ moved = std::move(motionData);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ END_TEST;
+}
+
+// Method test
+
+int UtcDaliMotionDataAddMotion(void)
+{
+ ToolkitTestApplication application;
+
+ MotionData motionData = MotionData::New(3.0f);
+
+ const uint32_t countMax = 4;
+ MotionIndex index[countMax];
+ MotionValue value[countMax];
+ for(uint32_t i = 0u; i < countMax; ++i)
+ {
+ // Generate index
+ if(i & 1)
+ {
+ index[i] = BlendShapeIndex::New("node", 0);
+ }
+ else
+ {
+ index[i] = MotionTransformIndex::New("node", MotionTransformIndex::TransformType::POSITION_X);
+ }
+
+ // Generate value
+ if(i & 2)
+ {
+ value[i] = MotionValue::New(3.0f);
+ }
+ else
+ {
+ KeyFrames keyFrames = KeyFrames::New();
+ keyFrames.Add(0.0f, 9.0f);
+ keyFrames.Add(1.0f, 5.0f);
+ value[i] = MotionValue::New(keyFrames);
+ }
+
+ DALI_TEST_CHECK(index[i]);
+ DALI_TEST_CHECK(value[i]);
+ motionData.Add(index[i], value[i]);
+
+ DALI_TEST_EQUALS(i + 1, motionData.GetMotionCount(), TEST_LOCATION);
+ }
+
+ for(uint32_t i = 0u; i < countMax; ++i)
+ {
+ DALI_TEST_EQUALS(index[i], motionData.GetIndex(i), TEST_LOCATION);
+ DALI_TEST_EQUALS(value[i], motionData.GetValue(i), TEST_LOCATION);
+ }
+
+ DALI_TEST_CHECK(!motionData.GetIndex(countMax));
+ DALI_TEST_CHECK(!motionData.GetValue(countMax));
+
+ motionData.Clear();
+
+ DALI_TEST_EQUALS(0u, motionData.GetMotionCount(), TEST_LOCATION);
+ DALI_TEST_CHECK(!motionData.GetIndex(0u));
+ DALI_TEST_CHECK(!motionData.GetValue(0u));
+
+ END_TEST;
+}
+
+int UtcDaliMotionDataSetGetDuration(void)
+{
+ ToolkitTestApplication application;
+
+ float expectDuration = 3.0f;
+ MotionData motionData = MotionData::New(expectDuration);
+ DALI_TEST_EQUALS(motionData.GetDuration(), expectDuration, TEST_LOCATION);
+
+ expectDuration = 7.0f;
+ motionData.SetDuration(expectDuration);
+ DALI_TEST_EQUALS(motionData.GetDuration(), expectDuration, TEST_LOCATION);
+
+ expectDuration = 1.0f;
+ motionData.SetDuration(expectDuration);
+ DALI_TEST_EQUALS(motionData.GetDuration(), expectDuration, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliMotionDataLoadBvhAndFacialAsync(void)
+{
+ ToolkitTestApplication application;
+
+ for(uint32_t tc = 0; tc < 4; ++tc)
+ {
+ MotionData motionData = MotionData::New();
+ gLoadCompleted = false;
+ motionData.LoadCompletedSignal().Connect(&OnLoadCompleted);
+
+ switch(tc)
+ {
+ case 0:
+ default:
+ {
+ motionData.LoadBvh(TEST_BVH_FILE_NAME);
+ break;
+ }
+ case 1:
+ {
+ motionData.LoadFacialAnimation(TEST_FACIAL_FILE_NAME);
+ break;
+ }
+ case 2:
+ {
+ std::string rawString = ReadBufferFromFile(TEST_BVH_FILE_NAME);
+ motionData.LoadBvhFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()));
+ break;
+ }
+ case 3:
+ {
+ std::string rawString = ReadBufferFromFile(TEST_FACIAL_FILE_NAME);
+ motionData.LoadFacialAnimationFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()));
+ break;
+ }
+ }
+
+ DALI_TEST_EQUALS(gLoadCompleted, false, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ application.SendNotification();
+ application.Render();
+
+ // Check LoadCompletedSignal emitted.
+ DALI_TEST_EQUALS(gLoadCompleted, true, TEST_LOCATION);
+
+ // Check MotionData load successfully.
+ DALI_TEST_GREATER(motionData.GetMotionCount(), 0u, TEST_LOCATION);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliMotionDataLoadBvhAndFacialSync(void)
+{
+ ToolkitTestApplication application;
+
+ for(uint32_t tc = 0; tc < 4; ++tc)
+ {
+ MotionData motionData = MotionData::New();
+ gLoadCompleted = false;
+ motionData.LoadCompletedSignal().Connect(&OnLoadCompleted);
+
+ switch(tc)
+ {
+ case 0:
+ default:
+ {
+ motionData.LoadBvh(TEST_BVH_FILE_NAME, Vector3::ONE, true);
+ break;
+ }
+ case 1:
+ {
+ motionData.LoadFacialAnimation(TEST_FACIAL_FILE_NAME, true);
+ break;
+ }
+ case 2:
+ {
+ std::string rawString = ReadBufferFromFile(TEST_BVH_FILE_NAME);
+ motionData.LoadBvhFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()), Vector3::ONE, true);
+ break;
+ }
+ case 3:
+ {
+ std::string rawString = ReadBufferFromFile(TEST_FACIAL_FILE_NAME);
+ motionData.LoadFacialAnimationFromBuffer(reinterpret_cast<uint8_t*>(rawString.data()), static_cast<int>(rawString.length()), true);
+ break;
+ }
+ }
+
+ // Check LoadCompletedSignal emitted.
+ DALI_TEST_EQUALS(gLoadCompleted, true, TEST_LOCATION);
+
+ // Check MotionData load successfully.
+ DALI_TEST_GREATER(motionData.GetMotionCount(), 0u, TEST_LOCATION);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliMotionDataLoadAsyncMultiple(void)
+{
+ ToolkitTestApplication application;
+
+ MotionData motionData = MotionData::New();
+ gLoadCompleted = false;
+ motionData.LoadCompletedSignal().Connect(&OnLoadCompleted);
+
+ auto tryCount = 10u;
+ for(auto i = 0u; i < tryCount; ++i)
+ {
+ motionData.LoadBvh(TEST_BVH_FILE_NAME);
+ }
+
+ DALI_TEST_EQUALS(gLoadCompleted, false, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(gLoadCompleted, true, TEST_LOCATION);
+
+ // Check MotionData load successfully.
+ DALI_TEST_GREATER(motionData.GetMotionCount(), 0u, TEST_LOCATION);
+
+ // Check if completed request comes only 1 time.
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, 1), false, TEST_LOCATION);
+
+ END_TEST;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <stdlib.h>
+#include <iostream>
+
+#include <dali-scene3d/public-api/model-motion/motion-index/blend-shape-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-property-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-transform-index.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+using namespace Dali::Scene3D;
+
+void model_motion_motion_index_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void model_motion_motion_index_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+namespace
+{
+} // namespace
+
+// Positive test case for a method
+int UtcDaliMotionIndexDownCast(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliMotionIndexDownCast");
+
+ MotionIndex blendShapeIndex = BlendShapeIndex::New();
+ BaseHandle handle(blendShapeIndex);
+
+ MotionIndex blendShapeIndex2 = MotionIndex::DownCast(handle);
+ DALI_TEST_CHECK(blendShapeIndex);
+ DALI_TEST_CHECK(blendShapeIndex2);
+ DALI_TEST_CHECK(blendShapeIndex2 == blendShapeIndex);
+ END_TEST;
+}
+
+int UtcDaliMotionIndexDownCastNotMatchedType(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliMotionIndexDownCastNotMatchedType");
+
+ {
+ MotionIndex baseIndex = BlendShapeIndex::New();
+ DALI_TEST_CHECK(baseIndex);
+
+ BaseHandle handle(baseIndex);
+
+ MotionIndex motionPropertyIndex = MotionPropertyIndex::DownCast(handle);
+ DALI_TEST_CHECK(!motionPropertyIndex);
+
+ MotionIndex motionTransformIndex = MotionTransformIndex::DownCast(handle);
+ DALI_TEST_CHECK(!motionTransformIndex);
+
+ MotionIndex blendShapeIndex = BlendShapeIndex::DownCast(handle);
+ DALI_TEST_CHECK(blendShapeIndex);
+ DALI_TEST_CHECK(blendShapeIndex == baseIndex);
+ }
+ END_TEST;
+}
+
+int UtcDaliMotionIndexCopyAndAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ MotionIndex blendShapeIndex = BlendShapeIndex::New();
+ DALI_TEST_CHECK(blendShapeIndex);
+
+ MotionIndex copy(blendShapeIndex);
+ DALI_TEST_CHECK(blendShapeIndex == copy);
+
+ MotionIndex assign;
+ DALI_TEST_CHECK(!assign);
+
+ assign = copy;
+ DALI_TEST_CHECK(assign == blendShapeIndex);
+
+ END_TEST;
+}
+
+int UtcDaliMotionIndexMoveConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ MotionIndex blendShapeIndex = MotionTransformIndex::New();
+ DALI_TEST_EQUALS(1, blendShapeIndex.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ MotionIndex moved = std::move(blendShapeIndex);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_CHECK(!blendShapeIndex);
+
+ END_TEST;
+}
+
+int UtcDaliMotionIndexMoveAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ MotionIndex blendShapeIndex = BlendShapeIndex::New();
+ DALI_TEST_EQUALS(1, blendShapeIndex.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ MotionIndex moved;
+ moved = std::move(blendShapeIndex);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ END_TEST;
+}
+
+// Method test
+
+int UtcDaliMotionIndexSetGetModelNodeId(void)
+{
+ std::string expectModelNodeStringId = "nodeId";
+ MotionIndex index = MotionTransformIndex::New(expectModelNodeStringId, MotionTransformIndex::TransformType::POSITION);
+
+ auto propertyKey = index.GetModelNodeId();
+ DALI_TEST_CHECK(propertyKey.type == Property::Key::Type::STRING);
+ DALI_TEST_EQUALS(expectModelNodeStringId, propertyKey.stringKey, TEST_LOCATION);
+
+ expectModelNodeStringId = "anotherId";
+ index.SetModelNodeId(expectModelNodeStringId);
+
+ propertyKey = index.GetModelNodeId();
+ DALI_TEST_CHECK(propertyKey.type == Property::Key::Type::STRING);
+ DALI_TEST_EQUALS(expectModelNodeStringId, propertyKey.stringKey, TEST_LOCATION);
+
+ Property::Index expectModelNodeIndexId = 193u;
+ index.SetModelNodeId(expectModelNodeIndexId);
+
+ propertyKey = index.GetModelNodeId();
+ DALI_TEST_CHECK(propertyKey.type == Property::Key::Type::INDEX);
+ DALI_TEST_EQUALS(expectModelNodeIndexId, propertyKey.indexKey, TEST_LOCATION);
+
+ END_TEST;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <stdlib.h>
+#include <iostream>
+
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-property-index.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+using namespace Dali::Scene3D;
+
+void model_motion_motion_property_index_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void model_motion_motion_property_index_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+namespace
+{
+} // namespace
+
+// Positive test case for a method
+int UtcDaliMotionPropertyIndexNew(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliMotionPropertyIndexNew");
+
+ MotionPropertyIndex motionPropertyIndex = MotionPropertyIndex::New();
+ DALI_TEST_CHECK(motionPropertyIndex);
+ DALI_TEST_EQUALS(motionPropertyIndex.GetModelNodeId().stringKey, "", TEST_LOCATION);
+ DALI_TEST_EQUALS(motionPropertyIndex.GetPropertyId().indexKey, Property::INVALID_INDEX, TEST_LOCATION);
+
+ motionPropertyIndex = MotionPropertyIndex::New("dummy", 3u);
+ DALI_TEST_CHECK(motionPropertyIndex);
+ DALI_TEST_EQUALS(motionPropertyIndex.GetModelNodeId().stringKey, "dummy", TEST_LOCATION);
+ DALI_TEST_EQUALS(motionPropertyIndex.GetPropertyId().indexKey, 3u, TEST_LOCATION);
+ END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliMotionPropertyIndexDownCast(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliMotionPropertyIndexDownCast");
+
+ MotionPropertyIndex motionPropertyIndex = MotionPropertyIndex::New();
+ BaseHandle handle(motionPropertyIndex);
+
+ MotionPropertyIndex motionPropertyIndex2 = MotionPropertyIndex::DownCast(handle);
+ DALI_TEST_CHECK(motionPropertyIndex);
+ DALI_TEST_CHECK(motionPropertyIndex2);
+ DALI_TEST_CHECK(motionPropertyIndex2 == motionPropertyIndex);
+ END_TEST;
+}
+
+int UtcDaliMotionPropertyIndexTypeRegistry(void)
+{
+ ToolkitTestApplication application;
+
+ TypeRegistry typeRegistry = TypeRegistry::Get();
+ DALI_TEST_CHECK(typeRegistry);
+
+ TypeInfo typeInfo = typeRegistry.GetTypeInfo("MotionPropertyIndex");
+ DALI_TEST_CHECK(typeInfo);
+
+ BaseHandle handle = typeInfo.CreateInstance();
+ DALI_TEST_CHECK(handle);
+
+ MotionPropertyIndex motionPropertyIndex = MotionPropertyIndex::DownCast(handle);
+ DALI_TEST_CHECK(motionPropertyIndex);
+
+ END_TEST;
+}
+
+int UtcDaliMotionPropertyIndexCopyAndAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ MotionPropertyIndex motionPropertyIndex = MotionPropertyIndex::New();
+ DALI_TEST_CHECK(motionPropertyIndex);
+
+ MotionPropertyIndex copy(motionPropertyIndex);
+ DALI_TEST_CHECK(motionPropertyIndex == copy);
+
+ MotionPropertyIndex assign;
+ DALI_TEST_CHECK(!assign);
+
+ assign = copy;
+ DALI_TEST_CHECK(assign == motionPropertyIndex);
+
+ END_TEST;
+}
+
+int UtcDaliMotionPropertyIndexMoveConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ MotionPropertyIndex motionPropertyIndex = MotionPropertyIndex::New();
+ DALI_TEST_EQUALS(1, motionPropertyIndex.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ MotionPropertyIndex moved = std::move(motionPropertyIndex);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_CHECK(!motionPropertyIndex);
+
+ END_TEST;
+}
+
+int UtcDaliMotionPropertyIndexMoveAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ MotionPropertyIndex motionPropertyIndex = MotionPropertyIndex::New();
+ DALI_TEST_EQUALS(1, motionPropertyIndex.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ MotionPropertyIndex moved;
+ moved = std::move(motionPropertyIndex);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ END_TEST;
+}
+
+// Method test
+
+int UtcDaliMotionPropertyIndexGetPropertyName(void)
+{
+ std::string expectPropertyName = "";
+ Property::Index expectPropertyIndex = Property::INVALID_INDEX;
+
+ MotionIndex index = MotionPropertyIndex::New();
+
+ // Invalid motion index return empty string, invalid index
+ DALI_TEST_EQUALS(expectPropertyName, index.GetPropertyName(), TEST_LOCATION);
+ DALI_TEST_EQUALS(expectPropertyIndex, index.GetPropertyIndex(), TEST_LOCATION);
+
+ expectPropertyIndex = 0u;
+ index = MotionPropertyIndex::New("", expectPropertyIndex);
+ DALI_TEST_EQUALS(expectPropertyIndex, index.GetPropertyIndex(), TEST_LOCATION);
+
+ expectPropertyIndex = 45u;
+ index = MotionPropertyIndex::New("", expectPropertyIndex);
+ DALI_TEST_EQUALS(expectPropertyIndex, index.GetPropertyIndex(), TEST_LOCATION);
+
+ expectPropertyName = "name";
+ index = MotionPropertyIndex::New("", expectPropertyName);
+ DALI_TEST_EQUALS(expectPropertyName, index.GetPropertyName(), TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliMotionPropertyIndexSetGetPropertyId(void)
+{
+ Property::Index expectPropertyIndex = 0u;
+
+ MotionPropertyIndex index = MotionPropertyIndex::New("", expectPropertyIndex);
+
+ // Invalid motion index return empty string, invalid index
+ DALI_TEST_CHECK(index.GetPropertyId().type == Property::Key::Type::INDEX);
+ DALI_TEST_EQUALS(expectPropertyIndex, index.GetPropertyId().indexKey, TEST_LOCATION);
+
+ std::string expectPropertyName = "hello";
+ index.SetPropertyId(expectPropertyName);
+ DALI_TEST_CHECK(index.GetPropertyId().type == Property::Key::Type::STRING);
+ DALI_TEST_EQUALS(expectPropertyName, index.GetPropertyId().stringKey, TEST_LOCATION);
+
+ expectPropertyIndex = 100u;
+ index.SetPropertyId(expectPropertyIndex);
+ DALI_TEST_CHECK(index.GetPropertyId().type == Property::Key::Type::INDEX);
+ DALI_TEST_EQUALS(expectPropertyIndex, index.GetPropertyId().indexKey, TEST_LOCATION);
+
+ END_TEST;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <stdlib.h>
+#include <iostream>
+
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-transform-index.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+using namespace Dali::Scene3D;
+
+void model_motion_motion_transform_index_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void model_motion_motion_transform_index_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+namespace
+{
+struct PropertyStringIndex
+{
+ const MotionTransformIndex::TransformType type;
+
+ const char* const name;
+ const Property::Index index;
+};
+const PropertyStringIndex PROPERTY_TABLE[] =
+ {
+ {MotionTransformIndex::TransformType::POSITION, "position", Actor::Property::POSITION},
+ {MotionTransformIndex::TransformType::POSITION_X, "positionX", Actor::Property::POSITION_X},
+ {MotionTransformIndex::TransformType::POSITION_Y, "positionY", Actor::Property::POSITION_Y},
+ {MotionTransformIndex::TransformType::POSITION_Z, "positionZ", Actor::Property::POSITION_Z},
+ {MotionTransformIndex::TransformType::ORIENTATION, "orientation", Actor::Property::ORIENTATION},
+ {MotionTransformIndex::TransformType::SCALE, "scale", Actor::Property::SCALE},
+ {MotionTransformIndex::TransformType::SCALE_X, "scaleX", Actor::Property::SCALE_X},
+ {MotionTransformIndex::TransformType::SCALE_Y, "scaleY", Actor::Property::SCALE_Y},
+ {MotionTransformIndex::TransformType::SCALE_Z, "scaleZ", Actor::Property::SCALE_Z},
+};
+} // namespace
+
+// Positive test case for a method
+int UtcDaliMotionTransformIndexNew(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliMotionTransformIndexNew");
+
+ MotionTransformIndex motionTransformIndex = MotionTransformIndex::New();
+ DALI_TEST_CHECK(motionTransformIndex);
+ DALI_TEST_EQUALS(motionTransformIndex.GetModelNodeId().stringKey, "", TEST_LOCATION);
+ DALI_TEST_EQUALS(motionTransformIndex.GetTransformType(), MotionTransformIndex::TransformType::INVALID, TEST_LOCATION);
+
+ motionTransformIndex = MotionTransformIndex::New("dummy", MotionTransformIndex::TransformType::SCALE);
+ DALI_TEST_CHECK(motionTransformIndex);
+ DALI_TEST_EQUALS(motionTransformIndex.GetModelNodeId().stringKey, "dummy", TEST_LOCATION);
+ DALI_TEST_EQUALS(motionTransformIndex.GetTransformType(), MotionTransformIndex::TransformType::SCALE, TEST_LOCATION);
+ END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliMotionTransformIndexDownCast(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliMotionTransformIndexDownCast");
+
+ MotionTransformIndex motionTransformIndex = MotionTransformIndex::New();
+ BaseHandle handle(motionTransformIndex);
+
+ MotionTransformIndex motionTransformIndex2 = MotionTransformIndex::DownCast(handle);
+ DALI_TEST_CHECK(motionTransformIndex);
+ DALI_TEST_CHECK(motionTransformIndex2);
+ DALI_TEST_CHECK(motionTransformIndex2 == motionTransformIndex);
+ END_TEST;
+}
+
+int UtcDaliMotionTransformIndexTypeRegistry(void)
+{
+ ToolkitTestApplication application;
+
+ TypeRegistry typeRegistry = TypeRegistry::Get();
+ DALI_TEST_CHECK(typeRegistry);
+
+ TypeInfo typeInfo = typeRegistry.GetTypeInfo("MotionTransformIndex");
+ DALI_TEST_CHECK(typeInfo);
+
+ BaseHandle handle = typeInfo.CreateInstance();
+ DALI_TEST_CHECK(handle);
+
+ MotionTransformIndex motionTransformIndex = MotionTransformIndex::DownCast(handle);
+ DALI_TEST_CHECK(motionTransformIndex);
+
+ END_TEST;
+}
+
+int UtcDaliMotionTransformIndexCopyAndAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ MotionTransformIndex motionTransformIndex = MotionTransformIndex::New();
+ DALI_TEST_CHECK(motionTransformIndex);
+
+ MotionTransformIndex copy(motionTransformIndex);
+ DALI_TEST_CHECK(motionTransformIndex == copy);
+
+ MotionTransformIndex assign;
+ DALI_TEST_CHECK(!assign);
+
+ assign = copy;
+ DALI_TEST_CHECK(assign == motionTransformIndex);
+
+ END_TEST;
+}
+
+int UtcDaliMotionTransformIndexMoveConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ MotionTransformIndex motionTransformIndex = MotionTransformIndex::New();
+ DALI_TEST_EQUALS(1, motionTransformIndex.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ MotionTransformIndex moved = std::move(motionTransformIndex);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_CHECK(!motionTransformIndex);
+
+ END_TEST;
+}
+
+int UtcDaliMotionTransformIndexMoveAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ MotionTransformIndex motionTransformIndex = MotionTransformIndex::New();
+ DALI_TEST_EQUALS(1, motionTransformIndex.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ MotionTransformIndex moved;
+ moved = std::move(motionTransformIndex);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+
+ END_TEST;
+}
+
+// Method test
+
+int UtcDaliMotionTransformIndexGetPropertyNameAndIndex(void)
+{
+ auto transfromTypeCount = sizeof(PROPERTY_TABLE) / sizeof(PROPERTY_TABLE[0]);
+ for(auto i = 0u; i < transfromTypeCount; i++)
+ {
+ auto type = PROPERTY_TABLE[i].type;
+
+ std::string expectPropertyName = PROPERTY_TABLE[i].name;
+ Property::Index expectPropertyIndex = PROPERTY_TABLE[i].index;
+
+ MotionIndex index = MotionTransformIndex::New("", type);
+
+ DALI_TEST_EQUALS(expectPropertyName, index.GetPropertyName(), TEST_LOCATION);
+ DALI_TEST_EQUALS(expectPropertyIndex, index.GetPropertyIndex(), TEST_LOCATION);
+ }
+ END_TEST;
+}
+
+int UtcDaliMotionTransformIndexGetPropertyInvalid(void)
+{
+ std::string expectPropertyName = "";
+ Property::Index expectPropertyIndex = Property::INVALID_INDEX;
+
+ MotionIndex index = MotionTransformIndex::New();
+
+ // Invalid motion index return empty string, invalid index
+ DALI_TEST_EQUALS(expectPropertyName, index.GetPropertyName(), TEST_LOCATION);
+ DALI_TEST_EQUALS(expectPropertyIndex, index.GetPropertyIndex(), TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliMotionTransformIndexSetGetPropertType(void)
+{
+ auto expectType = MotionTransformIndex::TransformType::POSITION;
+ MotionTransformIndex index = MotionTransformIndex::New("", expectType);
+
+ // Invalid motion index return empty string, invalid index
+ DALI_TEST_EQUALS(expectType, index.GetTransformType(), TEST_LOCATION);
+
+ expectType = MotionTransformIndex::TransformType::ORIENTATION;
+ index.SetTransformType(expectType);
+ DALI_TEST_EQUALS(expectType, index.GetTransformType(), TEST_LOCATION);
+
+ END_TEST;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <stdlib.h>
+#include <iostream>
+
+#include <dali-scene3d/public-api/model-motion/motion-value.h>
+#include <dali/devel-api/animation/key-frames-devel.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+using namespace Dali::Scene3D;
+
+void model_motion_motion_value_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void model_motion_motion_value_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+namespace
+{
+} // namespace
+
+// Positive test case for a method
+int UtcDaliMotionValueNew(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliMotionValueNew");
+
+ MotionValue motionValue = MotionValue::New();
+ DALI_TEST_CHECK(motionValue);
+ END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliMotionValueDownCast(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliMotionValueDownCast");
+
+ MotionValue motionValue = MotionValue::New();
+ BaseHandle handle(motionValue);
+
+ MotionValue motionValue2 = MotionValue::DownCast(handle);
+ DALI_TEST_CHECK(motionValue);
+ DALI_TEST_CHECK(motionValue2);
+ DALI_TEST_CHECK(motionValue2 == motionValue);
+ END_TEST;
+}
+
+int UtcDaliMotionValueTypeRegistry(void)
+{
+ ToolkitTestApplication application;
+
+ TypeRegistry typeRegistry = TypeRegistry::Get();
+ DALI_TEST_CHECK(typeRegistry);
+
+ TypeInfo typeInfo = typeRegistry.GetTypeInfo("MotionValue");
+ DALI_TEST_CHECK(typeInfo);
+
+ BaseHandle handle = typeInfo.CreateInstance();
+ DALI_TEST_CHECK(handle);
+
+ MotionValue motionValue = MotionValue::DownCast(handle);
+ DALI_TEST_CHECK(motionValue);
+
+ END_TEST;
+}
+
+int UtcDaliMotionValueCopyAndAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ MotionValue motionValue = MotionValue::New(1);
+ DALI_TEST_CHECK(motionValue);
+ DALI_TEST_CHECK(motionValue.GetValueType() == MotionValue::ValueType::PROPERTY_VALUE);
+
+ MotionValue copy(motionValue);
+ DALI_TEST_CHECK(motionValue == copy);
+ DALI_TEST_CHECK(copy.GetValueType() == MotionValue::ValueType::PROPERTY_VALUE);
+
+ MotionValue assign;
+ DALI_TEST_CHECK(!assign);
+
+ assign = copy;
+ DALI_TEST_CHECK(assign == motionValue);
+ DALI_TEST_CHECK(assign.GetValueType() == MotionValue::ValueType::PROPERTY_VALUE);
+
+ END_TEST;
+}
+
+int UtcDaliMotionValueMoveConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ MotionValue motionValue = MotionValue::New(3.0f);
+ DALI_TEST_EQUALS(1, motionValue.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_CHECK(motionValue.GetValueType() == MotionValue::ValueType::PROPERTY_VALUE);
+
+ MotionValue moved = std::move(motionValue);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_CHECK(moved.GetValueType() == MotionValue::ValueType::PROPERTY_VALUE);
+ DALI_TEST_CHECK(!motionValue);
+
+ END_TEST;
+}
+
+int UtcDaliMotionValueMoveAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ MotionValue motionValue = MotionValue::New(KeyFrames::New());
+ DALI_TEST_EQUALS(1, motionValue.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_CHECK(motionValue.GetValueType() == MotionValue::ValueType::KEY_FRAMES);
+
+ MotionValue moved;
+ moved = std::move(motionValue);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_CHECK(moved.GetValueType() == MotionValue::ValueType::KEY_FRAMES);
+
+ END_TEST;
+}
+
+// Method test
+
+int UtcDaliMotionValueGetSetValue(void)
+{
+ ToolkitTestApplication application;
+
+ MotionValue motionValue = MotionValue::New();
+ DALI_TEST_CHECK(motionValue.GetValueType() == MotionValue::ValueType::INVALID);
+ DALI_TEST_CHECK(motionValue.GetPropertyValue().GetType() == Property::Type::NONE);
+ DALI_TEST_CHECK(!motionValue.GetKeyFrames());
+
+ float expectValue = 3.0f;
+ motionValue.SetValue(expectValue);
+ DALI_TEST_CHECK(motionValue.GetValueType() == MotionValue::ValueType::PROPERTY_VALUE);
+ DALI_TEST_CHECK(motionValue.GetPropertyValue().GetType() == Property::Type::FLOAT);
+ DALI_TEST_CHECK(motionValue.GetPropertyValue().Get<float>() == expectValue);
+
+ // Check the converted KeyFrames
+ auto convertedKeyFrames = motionValue.GetKeyFrames();
+ DALI_TEST_CHECK(convertedKeyFrames);
+ auto convertedKeyFrameCount = DevelKeyFrames::GetKeyFrameCount(convertedKeyFrames);
+ for(auto i = 0u; i < convertedKeyFrameCount; ++i)
+ {
+ float progress;
+ Property::Value value;
+ DevelKeyFrames::GetKeyFrame(convertedKeyFrames, i, progress, value);
+
+ // Check all value has same as expect property.
+ DALI_TEST_EQUALS(value.Get<float>(), expectValue, TEST_LOCATION);
+ }
+
+ KeyFrames expectKeyFrames = KeyFrames::New();
+ expectValue = 2.0f;
+ expectKeyFrames.Add(0.0f, expectValue - 1.0f);
+ expectKeyFrames.Add(1.0f, expectValue);
+ motionValue.SetValue(expectKeyFrames);
+
+ DALI_TEST_CHECK(motionValue.GetValueType() == MotionValue::ValueType::KEY_FRAMES);
+ DALI_TEST_CHECK(motionValue.GetKeyFrames() == expectKeyFrames);
+
+ // Check property value return last frame value.
+ DALI_TEST_CHECK(motionValue.GetPropertyValue().GetType() == Property::Type::FLOAT);
+ DALI_TEST_EQUALS(motionValue.GetPropertyValue().Get<float>(), expectValue, TEST_LOCATION);
+
+ // Check invalidate value.
+ motionValue.Invalidate();
+ DALI_TEST_CHECK(motionValue.GetValueType() == MotionValue::ValueType::INVALID);
+ DALI_TEST_CHECK(motionValue.GetPropertyValue().GetType() == Property::Type::NONE);
+ DALI_TEST_CHECK(!motionValue.GetKeyFrames());
+
+ motionValue.SetValue(expectKeyFrames);
+ DALI_TEST_CHECK(motionValue.GetValueType() == MotionValue::ValueType::KEY_FRAMES);
+ DALI_TEST_CHECK(motionValue.GetKeyFrames() == expectKeyFrames);
+
+ // Check invalidate value by Clear().
+ motionValue.Clear();
+ DALI_TEST_CHECK(motionValue.GetValueType() == MotionValue::ValueType::INVALID);
+ DALI_TEST_CHECK(motionValue.GetPropertyValue().GetType() == Property::Type::NONE);
+ DALI_TEST_CHECK(!motionValue.GetKeyFrames());
+
+ END_TEST;
+}
\ No newline at end of file
#include <dali-scene3d/public-api/model-components/model-node.h>
#include <dali-scene3d/public-api/model-components/model-primitive.h>
+#include <dali-scene3d/public-api/model-motion/motion-data.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/blend-shape-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-property-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-transform-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-value.h>
+
#endif // DALI_SCENE3D_H
\ No newline at end of file
#include <dali-scene3d/public-api/loader/node-definition.h>
#include <dali-scene3d/public-api/loader/scene-definition.h>
#include <dali-scene3d/public-api/loader/shader-definition-factory.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/blend-shape-index.h>
using namespace Dali;
}
}
+Dali::Animation Model::GenerateMotionDataAnimation(Scene3D::MotionData motionData)
+{
+ Dali::Animation animation;
+
+ // TODO : Need to collect duplicated codes with SetMotionData()
+
+ if(motionData)
+ {
+ const uint32_t motionCount = motionData.GetMotionCount();
+ for(uint32_t i = 0u; i < motionCount; ++i)
+ {
+ auto motionIndex = motionData.GetIndex(i);
+ auto motionValue = motionData.GetValue(i);
+ if(motionIndex && motionValue)
+ {
+ if(motionIndex.GetModelNodeId() != Property::INVALID_KEY)
+ {
+ Scene3D::ModelNode modelNode;
+ if(motionIndex.GetModelNodeId().type == Property::Key::Type::STRING)
+ {
+ modelNode = FindChildModelNodeByName(motionIndex.GetModelNodeId().stringKey);
+ }
+ else if(motionIndex.GetModelNodeId().type == Property::Key::Type::INDEX)
+ {
+ // TODO : Not implement yet.
+ }
+
+ if(modelNode)
+ {
+ KeyFrames keyFrames = motionValue.GetKeyFrames();
+
+ if(keyFrames)
+ {
+ // Try to use index first. If failed, try to use name
+ Property::Index animatedPropertyIndex = motionIndex.GetPropertyIndex(modelNode);
+ if(animatedPropertyIndex != Property::INVALID_INDEX)
+ {
+ if(DALI_UNLIKELY(!animation))
+ {
+ animation = Animation::New(motionData.GetDuration());
+ }
+ animation.AnimateBetween(Dali::Property(modelNode, animatedPropertyIndex), keyFrames);
+ }
+ else
+ {
+ std::string animatedPropertyName = motionIndex.GetPropertyName(modelNode);
+ Dali::Property property(modelNode, animatedPropertyName);
+ if(property.propertyIndex != Property::INVALID_INDEX)
+ {
+ if(DALI_UNLIKELY(!animation))
+ {
+ animation = Animation::New(motionData.GetDuration());
+ }
+ animation.AnimateBetween(property, keyFrames);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ Scene3D::BlendShapeIndex blendShapeIndex = Scene3D::BlendShapeIndex::DownCast(motionIndex);
+ if(blendShapeIndex && blendShapeIndex.GetBlendShapeId().type == Property::Key::Type::STRING)
+ {
+ // Special case : For BlendShapeIndex that doesn't have ModelNodeId and has string BlendShapeId,
+ // we need to animate all kind of blendshapes
+
+ KeyFrames keyFrames = motionValue.GetKeyFrames();
+
+ if(keyFrames)
+ {
+ std::vector<Scene3D::ModelNode> modelNodes;
+ RetrieveModelNodesByBlendShapeName(blendShapeIndex.GetBlendShapeId().stringKey, modelNodes);
+
+ for(auto& modelNode : modelNodes)
+ {
+ // Try to use index first. If failed, try to use name
+ Property::Index animatedPropertyIndex = motionIndex.GetPropertyIndex(modelNode);
+ if(animatedPropertyIndex != Property::INVALID_INDEX)
+ {
+ if(DALI_UNLIKELY(!animation))
+ {
+ animation = Animation::New(motionData.GetDuration());
+ }
+ animation.AnimateBetween(Dali::Property(modelNode, animatedPropertyIndex), keyFrames);
+ }
+ else
+ {
+ std::string animatedPropertyName = motionIndex.GetPropertyName(modelNode);
+ Dali::Property property(modelNode, animatedPropertyName);
+
+ if(property.propertyIndex != Property::INVALID_INDEX)
+ {
+ if(DALI_UNLIKELY(!animation))
+ {
+ animation = Animation::New(motionData.GetDuration());
+ }
+ animation.AnimateBetween(property, keyFrames);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return animation;
+}
+
+void Model::SetMotionData(Scene3D::MotionData motionData)
+{
+ // TODO : Need to collect duplicated codes with GenerateMotionDataAnimation()
+
+ if(motionData)
+ {
+ const uint32_t motionCount = motionData.GetMotionCount();
+ for(uint32_t i = 0u; i < motionCount; ++i)
+ {
+ auto motionIndex = motionData.GetIndex(i);
+ auto motionValue = motionData.GetValue(i);
+ if(motionIndex && motionValue)
+ {
+ if(motionIndex.GetModelNodeId() != Property::INVALID_KEY)
+ {
+ Scene3D::ModelNode modelNode;
+ if(motionIndex.GetModelNodeId().type == Property::Key::Type::STRING)
+ {
+ modelNode = FindChildModelNodeByName(motionIndex.GetModelNodeId().stringKey);
+ }
+ else if(motionIndex.GetModelNodeId().type == Property::Key::Type::INDEX)
+ {
+ // TODO : Not implement yet.
+ }
+
+ if(modelNode)
+ {
+ Property::Value value = motionValue.GetPropertyValue();
+
+ if(value.GetType() != Property::Type::NONE)
+ {
+ // Try to use index first. If failed, try to use name
+ Property::Index propertyIndex = motionIndex.GetPropertyIndex(modelNode);
+ if(propertyIndex != Property::INVALID_INDEX)
+ {
+ modelNode.SetProperty(propertyIndex, value);
+ }
+ else
+ {
+ std::string propertyName = motionIndex.GetPropertyName(modelNode);
+ Dali::Property property(modelNode, propertyName);
+ if(property.propertyIndex != Property::INVALID_INDEX)
+ {
+ modelNode.SetProperty(property.propertyIndex, value);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ Scene3D::BlendShapeIndex blendShapeIndex = Scene3D::BlendShapeIndex::DownCast(motionIndex);
+ if(blendShapeIndex && blendShapeIndex.GetBlendShapeId().type == Property::Key::Type::STRING)
+ {
+ // Special case : For BlendShapeIndex that doesn't have ModelNodeId and has string BlendShapeId,
+ // we need to animate all kind of blendshapes
+
+ Property::Value value = motionValue.GetPropertyValue();
+
+ if(value.GetType() != Property::Type::NONE)
+ {
+ std::vector<Scene3D::ModelNode> modelNodes;
+ RetrieveModelNodesByBlendShapeName(blendShapeIndex.GetBlendShapeId().stringKey, modelNodes);
+
+ for(auto& modelNode : modelNodes)
+ {
+ // Try to use index first. If failed, try to use name
+ Property::Index propertyIndex = motionIndex.GetPropertyIndex(modelNode);
+ if(propertyIndex != Property::INVALID_INDEX)
+ {
+ modelNode.SetProperty(propertyIndex, value);
+ }
+ else
+ {
+ std::string propertyName = motionIndex.GetPropertyName(modelNode);
+ Dali::Property property(modelNode, propertyName);
+ if(property.propertyIndex != Property::INVALID_INDEX)
+ {
+ modelNode.SetProperty(property.propertyIndex, value);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
///////////////////////////////////////////////////////////
//
// Private methods
*/
void RetrieveModelNodesByBlendShapeName(std::string_view blendShapeName, std::vector<Scene3D::ModelNode>& modelNodes) const;
+ /**
+ * @copydoc Model::GenerateMotionDataAnimation()
+ */
+ Dali::Animation GenerateMotionDataAnimation(Scene3D::MotionData motionData);
+
+ /**
+ * @copydoc Model::SetMotionData()
+ */
+ void SetMotionData(Scene3D::MotionData motionData);
+
protected:
/**
* @brief Constructs a new Model.
${scene3d_internal_dir}/model-components/material-impl.cpp
${scene3d_internal_dir}/model-components/model-node-impl.cpp
${scene3d_internal_dir}/model-components/model-primitive-impl.cpp
+ ${scene3d_internal_dir}/model-motion/motion-data-impl.cpp
+ ${scene3d_internal_dir}/model-motion/motion-data-load-task.cpp
+ ${scene3d_internal_dir}/model-motion/motion-index/blend-shape-index-impl.cpp
+ ${scene3d_internal_dir}/model-motion/motion-index/motion-index-impl.cpp
+ ${scene3d_internal_dir}/model-motion/motion-index/motion-property-index-impl.cpp
+ ${scene3d_internal_dir}/model-motion/motion-index/motion-transform-index-impl.cpp
+ ${scene3d_internal_dir}/model-motion/motion-value-impl.cpp
)
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/internal/model-motion/motion-data-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/public-api/adaptor-framework/async-task-manager.h>
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/object/type-registry.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-property-index.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+namespace
+{
+/**
+ * Creates control through type registry
+ */
+BaseHandle Create()
+{
+ return Scene3D::MotionData::New();
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN(Scene3D::MotionData, Dali::BaseHandle, Create);
+DALI_TYPE_REGISTRATION_END()
+
+} // unnamed namespace
+
+MotionDataPtr MotionData::New()
+{
+ MotionDataPtr motionData = new MotionData();
+
+ motionData->Initialize();
+
+ return motionData;
+}
+
+MotionData::MotionData()
+{
+}
+
+MotionData::~MotionData()
+{
+ if(Dali::Adaptor::IsAvailable())
+ {
+ CancelMotionDataLoad();
+ }
+}
+
+void MotionData::Initialize()
+{
+}
+
+uint32_t MotionData::GetMotionCount() const
+{
+ return static_cast<uint32_t>(mMotions.size());
+}
+
+Scene3D::MotionIndex MotionData::GetIndex(uint32_t index) const
+{
+ if(index < mMotions.size())
+ {
+ return mMotions[index].first;
+ }
+ return Scene3D::MotionIndex();
+}
+
+Scene3D::MotionValue MotionData::GetValue(uint32_t index) const
+{
+ if(index < mMotions.size())
+ {
+ return mMotions[index].second;
+ }
+ return Scene3D::MotionValue();
+}
+
+void MotionData::Add(Scene3D::MotionIndex index, Scene3D::MotionValue value)
+{
+ mMotions.emplace_back(index, value);
+}
+
+void MotionData::Clear()
+{
+ mMotions.clear();
+}
+
+void MotionData::SetDuration(float durationSeconds)
+{
+ mDurationSeconds = durationSeconds;
+}
+
+float MotionData::GetDuration() const
+{
+ return mDurationSeconds;
+}
+
+void MotionData::LoadBvh(const std::string& path, const Vector3& scale, bool synchronousLoad)
+{
+ CancelMotionDataLoad();
+ mMotionDataLoadTask = new MotionDataLoadTask(path, scale, MakeCallback(this, &MotionData::OnLoadCompleted));
+ RequestMotionDataLoad(synchronousLoad);
+}
+
+void MotionData::LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, const Vector3& scale, bool synchronousLoad)
+{
+ CancelMotionDataLoad();
+ mMotionDataLoadTask = new MotionDataLoadTask(rawBuffer, rawBufferLength, scale, MakeCallback(this, &MotionData::OnLoadCompleted));
+ RequestMotionDataLoad(synchronousLoad);
+}
+
+void MotionData::LoadFacialAnimation(const std::string& url, bool synchronousLoad)
+{
+ CancelMotionDataLoad();
+ mMotionDataLoadTask = new MotionDataLoadTask(url, MakeCallback(this, &MotionData::OnLoadCompleted));
+ RequestMotionDataLoad(synchronousLoad);
+}
+
+void MotionData::LoadFacialAnimationFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, bool synchronousLoad)
+{
+ CancelMotionDataLoad();
+ mMotionDataLoadTask = new MotionDataLoadTask(rawBuffer, rawBufferLength, MakeCallback(this, &MotionData::OnLoadCompleted));
+ RequestMotionDataLoad(synchronousLoad);
+}
+
+// Private method
+void MotionData::RequestMotionDataLoad(bool synchronousLoad)
+{
+ if(mMotionDataLoadTask)
+ {
+ if(synchronousLoad)
+ {
+ mMotionDataLoadTask->Process();
+ OnLoadCompleted(mMotionDataLoadTask);
+ }
+ else
+ {
+ Dali::AsyncTaskManager::Get().AddTask(mMotionDataLoadTask);
+ }
+ }
+}
+
+void MotionData::CancelMotionDataLoad()
+{
+ if(mMotionDataLoadTask)
+ {
+ Dali::AsyncTaskManager::Get().RemoveTask(mMotionDataLoadTask);
+ mMotionDataLoadTask.Reset();
+ }
+}
+
+// Called from MotionDataLoadTask
+void MotionData::OnLoadCompleted(MotionDataLoadTaskPtr task)
+{
+ if(mMotionDataLoadTask == task)
+ {
+ const Scene3D::Loader::AnimationDefinition& animationDefinition = mMotionDataLoadTask->GetAnimationDefinition();
+
+ mDurationSeconds = animationDefinition.GetDuration();
+
+ auto animatedPropertyCount = animationDefinition.GetPropertyCount();
+
+ mMotions.clear();
+ mMotions.reserve(animatedPropertyCount);
+
+ for(uint32_t i = 0u; i < animatedPropertyCount; ++i)
+ {
+ const auto& animatedProperty = animationDefinition.GetPropertyAt(i);
+
+ // TODO : Currently, we only support KeyFrames without alpha function and time period now.
+ if(animatedProperty.mKeyFrames)
+ {
+ Add(Scene3D::MotionPropertyIndex::New(animatedProperty.mNodeName, animatedProperty.mPropertyName), Scene3D::MotionValue::New(animatedProperty.mKeyFrames));
+ }
+ }
+
+ // Reset task before emit load competed signal.
+ mMotionDataLoadTask.Reset();
+ {
+ Scene3D::MotionData handle(this); ///< Keep handle for lifecycle.
+ LoadCompletedSignal().Emit(handle);
+ }
+ }
+}
+
+} // namespace Internal
+
+} // namespace Scene3D
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_SCENE3D_MODEL_MOTION_MOTION_DATA_IMPL_H
+#define DALI_SCENE3D_MODEL_MOTION_MOTION_DATA_IMPL_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/base-object.h>
+
+#include <dali/public-api/common/vector-wrapper.h>
+#include <utility> ///< for std::pair
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/model-motion/motion-data-load-task.h>
+#include <dali-scene3d/public-api/loader/animation-definition.h>
+#include <dali-scene3d/public-api/model-motion/motion-data.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+using MotionDataPtr = IntrusivePtr<MotionData>;
+
+/**
+ * @brief Internal data for Scene3D::MotionData.
+ */
+class MotionData : public BaseObject
+{
+public: // Creation & Destruction
+ /**
+ * @brief Create a new MotionData object.
+ * @return A smart-pointer to the newly allocated MotionData.
+ */
+ static MotionDataPtr New();
+
+protected:
+ /**
+ * @brief Construct a new MotionData.
+ */
+ MotionData();
+
+ /**
+ * @brief Second-phase constructor.
+ */
+ void Initialize();
+
+ /**
+ * @brief Virtual destructor.
+ */
+ virtual ~MotionData();
+
+public: // Public Method
+ /**
+ * @copydoc Dali::Scene3D::MotionData::GetMotionCount()
+ */
+ uint32_t GetMotionCount() const;
+
+ /**
+ * @copydoc Dali::Scene3D::MotionData::GetIndex()
+ */
+ Scene3D::MotionIndex GetIndex(uint32_t index) const;
+
+ /**
+ * @copydoc Dali::Scene3D::MotionData::GetValue()
+ */
+ Scene3D::MotionValue GetValue(uint32_t index) const;
+
+ /**
+ * @copydoc Dali::Scene3D::MotionData::Add()
+ */
+ void Add(Scene3D::MotionIndex index, Scene3D::MotionValue value);
+
+ /**
+ * @copydoc Dali::Scene3D::MotionData::Clear()
+ */
+ void Clear();
+
+ /**
+ * @copydoc Dali::Scene3D::MotionData::SetDuration()
+ */
+ void SetDuration(float durationSeconds);
+
+ /**
+ * @copydoc Dali::Scene3D::MotionData::GetDuration()
+ */
+ float GetDuration() const;
+
+ /**
+ * @copydoc Dali::Scene3D::MotionData::LoadBvh()
+ */
+ void LoadBvh(const std::string& path, const Vector3& scale = Vector3::ONE, bool synchronousLoad = false);
+
+ /**
+ * @copydoc Dali::Scene3D::MotionData::LoadBvhFromBuffer()
+ */
+ void LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, const Vector3& scale = Vector3::ONE, bool synchronousLoad = false);
+
+ /**
+ * @copydoc Dali::Scene3D::MotionData::LoadFacialAnimation()
+ */
+ void LoadFacialAnimation(const std::string& url, bool synchronousLoad = false);
+
+ /**
+ * @copydoc Dali::Scene3D::MotionData::LoadFacialAnimationFromBuffer()
+ */
+ void LoadFacialAnimationFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, bool synchronousLoad = false);
+
+public:
+ /**
+ * @copydoc Dali::Scene3D::MotionData::LoadCompletedSignal()
+ */
+ Scene3D::MotionData::LoadCompletedSignalType& LoadCompletedSignal()
+ {
+ return mLoadCompletedSignal;
+ }
+
+private:
+ /**
+ * @brief Request motion data load task process.
+ *
+ * @param[in] synchronousLoad True if we want to load result synchronously.
+ */
+ void RequestMotionDataLoad(bool synchronousLoad);
+
+ /**
+ * @brief Cancel requested motion data load task process.
+ */
+ void CancelMotionDataLoad();
+
+private:
+ /**
+ * @brief Called when async load task completed.
+ *
+ * @param[in] task Completed tasks
+ */
+ void OnLoadCompleted(MotionDataLoadTaskPtr task);
+
+private:
+ // Asynchronous loading variable
+ MotionDataLoadTaskPtr mMotionDataLoadTask{nullptr};
+ Scene3D::MotionData::LoadCompletedSignalType mLoadCompletedSignal;
+
+ std::vector<std::pair<Scene3D::MotionIndex, Scene3D::MotionValue>> mMotions{};
+
+ float mDurationSeconds{0.0f}; ///< Duration of animation if we generate this motion data as Dali::Animation.
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Internal::MotionData& GetImplementation(Dali::Scene3D::MotionData& motionData)
+{
+ DALI_ASSERT_ALWAYS(motionData && "MotionData handle is empty");
+
+ BaseObject& handle = motionData.GetBaseObject();
+
+ return static_cast<Internal::MotionData&>(handle);
+}
+
+inline const Internal::MotionData& GetImplementation(const Dali::Scene3D::MotionData& motionData)
+{
+ DALI_ASSERT_ALWAYS(motionData && "MotionData handle is empty");
+
+ const BaseObject& handle = motionData.GetBaseObject();
+
+ return static_cast<const Internal::MotionData&>(handle);
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_MODEL_MOTION_MOTION_DATA_IMPL_H
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/internal/model-motion/motion-data-load-task.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/loader/bvh-loader.h>
+#include <dali-scene3d/public-api/loader/facial-animation-loader.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+MotionDataLoadTask::MotionDataLoadTask(const std::string& path, const Vector3& scale, CallbackBase* callback)
+: AsyncTask(callback),
+ mFileUrl(path),
+ mRawBuffer(nullptr),
+ mRawBufferLength(0),
+ mScale(scale),
+ mAnimationDefinition{},
+ mLoadMethod(MotionDataLoadTask::LoadMethod::BVH_FILE)
+{
+}
+
+MotionDataLoadTask::MotionDataLoadTask(const uint8_t* rawBuffer, int rawBufferLength, const Vector3& scale, CallbackBase* callback)
+: AsyncTask(callback),
+ mFileUrl(),
+ mRawBuffer(nullptr),
+ mRawBufferLength(rawBufferLength),
+ mScale(scale),
+ mAnimationDefinition{},
+ mLoadMethod(MotionDataLoadTask::LoadMethod::BVH_BUFFER)
+{
+ // To keep life of raw buffer, let us copy data now.
+ mRawBuffer = new uint8_t[mRawBufferLength];
+ memcpy(mRawBuffer, rawBuffer, sizeof(uint8_t) * mRawBufferLength);
+}
+
+MotionDataLoadTask::MotionDataLoadTask(const std::string& url, CallbackBase* callback)
+: AsyncTask(callback),
+ mFileUrl(url),
+ mRawBuffer(nullptr),
+ mRawBufferLength(0),
+ mScale(),
+ mAnimationDefinition{},
+ mLoadMethod(MotionDataLoadTask::LoadMethod::FACIAL_FILE)
+{
+}
+
+MotionDataLoadTask::MotionDataLoadTask(const uint8_t* rawBuffer, int rawBufferLength, CallbackBase* callback)
+: AsyncTask(callback),
+ mFileUrl(),
+ mRawBuffer(nullptr),
+ mRawBufferLength(rawBufferLength),
+ mScale(),
+ mAnimationDefinition{},
+ mLoadMethod(MotionDataLoadTask::LoadMethod::FACIAL_BUFFER)
+{
+ // To keep life of raw buffer, let us copy data now.
+ mRawBuffer = new uint8_t[mRawBufferLength];
+ memcpy(mRawBuffer, rawBuffer, sizeof(uint8_t) * mRawBufferLength);
+}
+
+MotionDataLoadTask::~MotionDataLoadTask()
+{
+ if(mRawBuffer)
+ {
+ delete[] mRawBuffer;
+ }
+}
+
+void MotionDataLoadTask::Process()
+{
+ switch(mLoadMethod)
+ {
+ case LoadMethod::BVH_FILE:
+ {
+ mAnimationDefinition = std::move(Loader::LoadBvh(mFileUrl, "LoadedBvhMotionData", mScale));
+ break;
+ }
+ case LoadMethod::BVH_BUFFER:
+ {
+ mAnimationDefinition = std::move(Loader::LoadBvhFromBuffer(mRawBuffer, mRawBufferLength, "LoadedBvhMotionData", mScale));
+ break;
+ }
+ case LoadMethod::FACIAL_FILE:
+ {
+ mAnimationDefinition = std::move(Loader::LoadFacialAnimation(mFileUrl));
+ break;
+ }
+ case LoadMethod::FACIAL_BUFFER:
+ {
+ mAnimationDefinition = std::move(Loader::LoadFacialAnimationFromBuffer(mRawBuffer, mRawBufferLength));
+ break;
+ }
+ }
+}
+
+bool MotionDataLoadTask::IsReady()
+{
+ return true;
+}
+
+const Scene3D::Loader::AnimationDefinition& MotionDataLoadTask::GetAnimationDefinition() const
+{
+ return mAnimationDefinition;
+}
+
+} // namespace Internal
+
+} // namespace Scene3D
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_SCENE3D_MODEL_MOTION_MOTION_DATA_LOAD_TASK_H
+#define DALI_SCENE3D_MODEL_MOTION_MOTION_DATA_LOAD_TASK_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/adaptor-framework/async-task-manager.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/loader/animation-definition.h>
+#include <dali-scene3d/public-api/model-motion/motion-data.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+class MotionDataLoadTask;
+typedef IntrusivePtr<MotionDataLoadTask> MotionDataLoadTaskPtr;
+
+/**
+ * @brief AsyncTask for load MotionData from various type.
+ * After load finished, it will keep result as Loader::AnimationDefinition.
+ */
+class MotionDataLoadTask : public AsyncTask
+{
+public:
+ enum class LoadMethod
+ {
+ BVH_FILE,
+ BVH_BUFFER,
+ FACIAL_FILE,
+ FACIAL_BUFFER,
+ };
+
+public:
+ /**
+ * Constructor for load bvh from file.
+ */
+ MotionDataLoadTask(const std::string& path, const Vector3& scale, CallbackBase* callback);
+
+ /**
+ * Constructor for load bvh from buffer.
+ */
+ MotionDataLoadTask(const uint8_t* rawBuffer, int rawBufferLength, const Vector3& scale, CallbackBase* callback);
+
+ /**
+ * Constructor for load facial from file.
+ */
+ MotionDataLoadTask(const std::string& url, CallbackBase* callback);
+
+ /**
+ * Constructor for load facial from buffer.
+ */
+ MotionDataLoadTask(const uint8_t* rawBuffer, int rawBufferLength, CallbackBase* callback);
+
+ /**
+ * Destructor.
+ */
+ ~MotionDataLoadTask();
+
+ /**
+ * Process the task
+ */
+ void Process() override;
+
+ /**
+ * Whether the task is ready to process.
+ * @return True if the task is ready to process.
+ */
+ bool IsReady() override;
+
+public:
+ const Scene3D::Loader::AnimationDefinition& GetAnimationDefinition() const;
+
+private:
+ // Undefined
+ MotionDataLoadTask(const MotionDataLoadTask& task) = delete;
+
+ // Undefined
+ MotionDataLoadTask& operator=(const MotionDataLoadTask& task) = delete;
+
+private:
+ std::string mFileUrl;
+ uint8_t* mRawBuffer;
+ int mRawBufferLength;
+ Vector3 mScale;
+
+ Scene3D::Loader::AnimationDefinition mAnimationDefinition;
+ LoadMethod mLoadMethod;
+};
+
+} // namespace Internal
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_MODEL_MOTION_MOTION_DATA_LOAD_TASK_H
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/internal/model-motion/motion-index/blend-shape-index-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/object/type-registry.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/loader/blend-shape-details.h> ///< For BlendShapes::WEIGHTS_UNIFORM
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+namespace
+{
+/**
+ * Creates control through type registry
+ */
+BaseHandle Create()
+{
+ return Scene3D::BlendShapeIndex::New();
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN(Scene3D::BlendShapeIndex, Dali::BaseHandle, Create);
+DALI_TYPE_REGISTRATION_END()
+
+std::string GetBlendShapePropertyNameFromIndex(int index)
+{
+ if(index >= 0)
+ {
+ char weightNameBuffer[32];
+
+ // Get return value of snprintf to avoid SVACE.
+ [[maybe_unused]] auto prefixSize = snprintf(weightNameBuffer, sizeof(weightNameBuffer), "%s[%d]", Loader::BlendShapes::WEIGHTS_UNIFORM, index);
+
+ return weightNameBuffer;
+ }
+ return "";
+}
+
+} // namespace
+
+BlendShapeIndexPtr BlendShapeIndex::New()
+{
+ BlendShapeIndexPtr blendShapeIndex = new BlendShapeIndex();
+
+ blendShapeIndex->Initialize();
+
+ return blendShapeIndex;
+}
+
+BlendShapeIndex::BlendShapeIndex()
+{
+}
+
+BlendShapeIndex::~BlendShapeIndex()
+{
+}
+
+void BlendShapeIndex::Initialize()
+{
+}
+
+void BlendShapeIndex::SetBlendShapeId(Property::Key blendShapeId)
+{
+ mBlendShapeId = blendShapeId;
+}
+
+Property::Key BlendShapeIndex::GetBlendShapeId() const
+{
+ return mBlendShapeId;
+}
+
+std::string BlendShapeIndex::GetPropertyName(Scene3D::ModelNode node)
+{
+ if(mBlendShapeId.type == Property::Key::Type::INDEX)
+ {
+ if(mBlendShapeId.indexKey != Property::INVALID_INDEX)
+ {
+ return GetBlendShapePropertyNameFromIndex(mBlendShapeId.indexKey);
+ }
+ }
+ else if(mBlendShapeId.type == Property::Key::Type::STRING)
+ {
+ if(node)
+ {
+ auto index = node.GetBlendShapeIndexByName(mBlendShapeId.stringKey);
+ if(index != Scene3D::Loader::BlendShapes::INVALID_INDEX)
+ {
+ return GetBlendShapePropertyNameFromIndex(index);
+ }
+ }
+ }
+ return "";
+}
+
+Property::Index BlendShapeIndex::GetPropertyIndex(Scene3D::ModelNode node)
+{
+ // Not surport now
+ return Property::INVALID_INDEX;
+}
+
+} // namespace Internal
+
+} // namespace Scene3D
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_SCENE3D_MODEL_MOTION_BLEND_SHAPE_INDEX_IMPL_H
+#define DALI_SCENE3D_MODEL_MOTION_BLEND_SHAPE_INDEX_IMPL_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/base-object.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/model-motion/motion-index/motion-index-impl.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/blend-shape-index.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+using BlendShapeIndexPtr = IntrusivePtr<BlendShapeIndex>;
+
+/**
+ * @brief Internal data for Scene3D::BlendShapeIndex.
+ */
+class BlendShapeIndex : public MotionIndex
+{
+public: // Creation & Destruction
+ /**
+ * @brief Create a new BlendShapeIndex object.
+ * @return A smart-pointer to the newly allocated BlendShapeIndex.
+ */
+ static BlendShapeIndexPtr New();
+
+protected:
+ /**
+ * @brief Construct a new BlendShapeIndex.
+ */
+ BlendShapeIndex();
+
+ /**
+ * @brief Second-phase constructor.
+ */
+ void Initialize();
+
+ /**
+ * @brief Virtual destructor.
+ */
+ virtual ~BlendShapeIndex();
+
+public: // Public Method
+ /**
+ * @copydoc Dali::Scene3D::BlendShapeIndex::SetBlendShapeId()
+ */
+ void SetBlendShapeId(Property::Key blendShapeId);
+
+ /**
+ * @copydoc Dali::Scene3D::BlendShapeIndex::GetBlendShapeId()
+ */
+ Property::Key GetBlendShapeId() const;
+
+public: // MotionIndex Override Method
+ /**
+ * @copydoc Dali::Scene3D::Internal::MotionIndex::GetPropertyName()
+ */
+ std::string GetPropertyName(Scene3D::ModelNode node = Scene3D::ModelNode()) override;
+
+ /**
+ * @copydoc Dali::Scene3D::Internal::MotionIndex::GetPropertyIndex()
+ */
+ Property::Index GetPropertyIndex(Scene3D::ModelNode node = Scene3D::ModelNode()) override;
+
+protected:
+ Property::Key mBlendShapeId{Property::INVALID_KEY}; ///< The id of blend shape
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Internal::BlendShapeIndex& GetImplementation(Dali::Scene3D::BlendShapeIndex& blendShapeIndex)
+{
+ DALI_ASSERT_ALWAYS(blendShapeIndex && "BlendShapeIndex handle is empty");
+
+ BaseObject& handle = blendShapeIndex.GetBaseObject();
+
+ return static_cast<Internal::BlendShapeIndex&>(handle);
+}
+
+inline const Internal::BlendShapeIndex& GetImplementation(const Dali::Scene3D::BlendShapeIndex& blendShapeIndex)
+{
+ DALI_ASSERT_ALWAYS(blendShapeIndex && "BlendShapeIndex handle is empty");
+
+ const BaseObject& handle = blendShapeIndex.GetBaseObject();
+
+ return static_cast<const Internal::BlendShapeIndex&>(handle);
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_MODEL_MOTION_BLEND_SHAPE_INDEX_IMPL_H
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/internal/model-motion/motion-index/motion-index-impl.h>
+
+// EXTERNAL INCLUDES
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+namespace
+{
+} // unnamed namespace
+
+MotionIndex::MotionIndex()
+{
+}
+
+MotionIndex::~MotionIndex()
+{
+}
+
+void MotionIndex::SetModelNodeId(Property::Key modelNodeId)
+{
+ mModelNodeId = modelNodeId;
+}
+
+Property::Key MotionIndex::GetModelNodeId() const
+{
+ return mModelNodeId;
+}
+
+} // namespace Internal
+
+} // namespace Scene3D
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_SCENE3D_MODEL_MOTION_MOTION_INDEX_IMPL_H
+#define DALI_SCENE3D_MODEL_MOTION_MOTION_INDEX_IMPL_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/base-object.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-index.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+using MotionIndexPtr = IntrusivePtr<MotionIndex>;
+
+/**
+ * @brief Internal abstract data for Scene3D::MotionIndex.
+ * The drived class can implemet there own GetPropertyIndex() and GetPropertyName() API.
+ */
+class MotionIndex : public BaseObject
+{
+protected:
+ /**
+ * @brief Construct a new MotionIndex.
+ */
+ MotionIndex();
+
+ /**
+ * @brief Virtual destructor.
+ */
+ virtual ~MotionIndex();
+
+public: // Public Method
+ /**
+ * @copydoc Dali::Scene3D::MotionIndex::SetModelNodeId()
+ */
+ void SetModelNodeId(Property::Key modelNodeId);
+
+ /**
+ * @copydoc Dali::Scene3D::MotionIndex::GetModelNodeId()
+ */
+ Property::Key GetModelNodeId() const;
+
+public: // Virtual Method
+ /**
+ * @copydoc Dali::Scene3D::MotionIndex::GetPropertyName()
+ */
+ virtual std::string GetPropertyName(Scene3D::ModelNode node = Scene3D::ModelNode()) = 0;
+
+ /**
+ * @copydoc Dali::Scene3D::MotionIndex::GetPropertyIndex()
+ */
+ virtual Property::Index GetPropertyIndex(Scene3D::ModelNode node = Scene3D::ModelNode()) = 0;
+
+protected:
+ Property::Key mModelNodeId{Property::INVALID_KEY}; ///< The id of model node
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Internal::MotionIndex& GetImplementation(Dali::Scene3D::MotionIndex& motionIndex)
+{
+ DALI_ASSERT_ALWAYS(motionIndex && "MotionIndex handle is empty");
+
+ BaseObject& handle = motionIndex.GetBaseObject();
+
+ return static_cast<Internal::MotionIndex&>(handle);
+}
+
+inline const Internal::MotionIndex& GetImplementation(const Dali::Scene3D::MotionIndex& motionIndex)
+{
+ DALI_ASSERT_ALWAYS(motionIndex && "MotionIndex handle is empty");
+
+ const BaseObject& handle = motionIndex.GetBaseObject();
+
+ return static_cast<const Internal::MotionIndex&>(handle);
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_MODEL_MOTION_MOTION_INDEX_IMPL_H
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/internal/model-motion/motion-index/motion-property-index-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/object/type-registry.h>
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+namespace
+{
+/**
+ * Creates control through type registry
+ */
+BaseHandle Create()
+{
+ return Scene3D::MotionPropertyIndex::New();
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN(Scene3D::MotionPropertyIndex, Dali::BaseHandle, Create);
+DALI_TYPE_REGISTRATION_END()
+
+} // namespace
+
+MotionPropertyIndexPtr MotionPropertyIndex::New()
+{
+ MotionPropertyIndexPtr motionPropertyIndex = new MotionPropertyIndex();
+
+ motionPropertyIndex->Initialize();
+
+ return motionPropertyIndex;
+}
+
+MotionPropertyIndex::MotionPropertyIndex()
+{
+}
+
+MotionPropertyIndex::~MotionPropertyIndex()
+{
+}
+
+void MotionPropertyIndex::Initialize()
+{
+}
+
+void MotionPropertyIndex::SetPropertyId(Property::Key propertyId)
+{
+ mPropertyId = propertyId;
+}
+
+Property::Key MotionPropertyIndex::GetPropertyId() const
+{
+ return mPropertyId;
+}
+
+std::string MotionPropertyIndex::GetPropertyName(Scene3D::ModelNode node)
+{
+ if(mPropertyId.type == Property::Key::Type::STRING)
+ {
+ return mPropertyId.stringKey;
+ }
+ return "";
+}
+
+Property::Index MotionPropertyIndex::GetPropertyIndex(Scene3D::ModelNode node)
+{
+ if(mPropertyId.type == Property::Key::Type::INDEX)
+ {
+ return mPropertyId.indexKey;
+ }
+ return Property::INVALID_INDEX;
+}
+
+} // namespace Internal
+
+} // namespace Scene3D
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_SCENE3D_MODEL_MOTION_MOTION_PROPERTY_INDEX_IMPL_H
+#define DALI_SCENE3D_MODEL_MOTION_MOTION_PROPERTY_INDEX_IMPL_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/base-object.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/model-motion/motion-index/motion-index-impl.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-property-index.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+using MotionPropertyIndexPtr = IntrusivePtr<MotionPropertyIndex>;
+
+/**
+ * @brief Internal data for Scene3D::MotionPropertyIndex.
+ */
+class MotionPropertyIndex : public MotionIndex
+{
+public: // Creation & Destruction
+ /**
+ * @brief Create a new MotionPropertyIndex object.
+ * @return A smart-pointer to the newly allocated MotionPropertyIndex.
+ */
+ static MotionPropertyIndexPtr New();
+
+protected:
+ /**
+ * @brief Construct a new MotionPropertyIndex.
+ */
+ MotionPropertyIndex();
+
+ /**
+ * @brief Second-phase constructor.
+ */
+ void Initialize();
+
+ /**
+ * @brief Virtual destructor.
+ */
+ virtual ~MotionPropertyIndex();
+
+public: // Public Method
+ /**
+ * @copydoc Dali::Scene3D::MotionPropertyIndex::SetPropertyId()
+ */
+ void SetPropertyId(Property::Key propertyId);
+
+ /**
+ * @copydoc Dali::Scene3D::MotionPropertyIndex::GetPropertyId()
+ */
+ Property::Key GetPropertyId() const;
+
+public: // MotionIndex Override Method
+ /**
+ * @copydoc Dali::Scene3D::Internal::MotionIndex::GetPropertyName()
+ */
+ std::string GetPropertyName(Scene3D::ModelNode node = Scene3D::ModelNode()) override;
+
+ /**
+ * @copydoc Dali::Scene3D::Internal::MotionIndex::GetPropertyIndex()
+ */
+ Property::Index GetPropertyIndex(Scene3D::ModelNode node = Scene3D::ModelNode()) override;
+
+protected:
+ Property::Key mPropertyId{Property::INVALID_KEY}; ///< The id of blend shape
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Internal::MotionPropertyIndex& GetImplementation(Dali::Scene3D::MotionPropertyIndex& motionPropertyIndex)
+{
+ DALI_ASSERT_ALWAYS(motionPropertyIndex && "MotionPropertyIndex handle is empty");
+
+ BaseObject& handle = motionPropertyIndex.GetBaseObject();
+
+ return static_cast<Internal::MotionPropertyIndex&>(handle);
+}
+
+inline const Internal::MotionPropertyIndex& GetImplementation(const Dali::Scene3D::MotionPropertyIndex& motionPropertyIndex)
+{
+ DALI_ASSERT_ALWAYS(motionPropertyIndex && "MotionPropertyIndex handle is empty");
+
+ const BaseObject& handle = motionPropertyIndex.GetBaseObject();
+
+ return static_cast<const Internal::MotionPropertyIndex&>(handle);
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_MODEL_MOTION_MOTION_PROPERTY_INDEX_IMPL_H
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/internal/model-motion/motion-index/motion-transform-index-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/object/type-registry.h>
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+namespace
+{
+/**
+ * Creates control through type registry
+ */
+BaseHandle Create()
+{
+ return Scene3D::MotionTransformIndex::New();
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN(Scene3D::MotionTransformIndex, Dali::BaseHandle, Create);
+DALI_TYPE_REGISTRATION_END()
+} // namespace
+
+MotionTransformIndexPtr MotionTransformIndex::New()
+{
+ MotionTransformIndexPtr motionTransformIndex = new MotionTransformIndex();
+
+ motionTransformIndex->Initialize();
+
+ return motionTransformIndex;
+}
+
+MotionTransformIndex::MotionTransformIndex()
+{
+}
+
+MotionTransformIndex::~MotionTransformIndex()
+{
+}
+
+void MotionTransformIndex::Initialize()
+{
+}
+
+void MotionTransformIndex::SetTransformType(Scene3D::MotionTransformIndex::TransformType type)
+{
+ mTransformType = type;
+}
+
+Scene3D::MotionTransformIndex::TransformType MotionTransformIndex::GetTransformType() const
+{
+ return mTransformType;
+}
+
+std::string MotionTransformIndex::GetPropertyName(Scene3D::ModelNode node)
+{
+ using TransformType = Scene3D::MotionTransformIndex::TransformType;
+
+ switch(mTransformType)
+ {
+ case TransformType::POSITION:
+ {
+ return "position";
+ }
+ case TransformType::POSITION_X:
+ {
+ return "positionX";
+ }
+ case TransformType::POSITION_Y:
+ {
+ return "positionY";
+ }
+ case TransformType::POSITION_Z:
+ {
+ return "positionZ";
+ }
+ case TransformType::ORIENTATION:
+ {
+ return "orientation";
+ }
+ case TransformType::SCALE:
+ {
+ return "scale";
+ }
+ case TransformType::SCALE_X:
+ {
+ return "scaleX";
+ }
+ case TransformType::SCALE_Y:
+ {
+ return "scaleY";
+ }
+ case TransformType::SCALE_Z:
+ {
+ return "scaleZ";
+ }
+ default:
+ {
+ DALI_LOG_ERROR("Invalid transform type used\n");
+ return "";
+ }
+ }
+}
+
+Property::Index MotionTransformIndex::GetPropertyIndex(Scene3D::ModelNode node)
+{
+ using TransformType = Scene3D::MotionTransformIndex::TransformType;
+
+ switch(mTransformType)
+ {
+ case TransformType::POSITION:
+ {
+ return Dali::Actor::Property::POSITION;
+ }
+ case TransformType::POSITION_X:
+ {
+ return Dali::Actor::Property::POSITION_X;
+ }
+ case TransformType::POSITION_Y:
+ {
+ return Dali::Actor::Property::POSITION_Y;
+ }
+ case TransformType::POSITION_Z:
+ {
+ return Dali::Actor::Property::POSITION_Z;
+ }
+ case TransformType::ORIENTATION:
+ {
+ return Dali::Actor::Property::ORIENTATION;
+ }
+ case TransformType::SCALE:
+ {
+ return Dali::Actor::Property::SCALE;
+ }
+ case TransformType::SCALE_X:
+ {
+ return Dali::Actor::Property::SCALE_X;
+ }
+ case TransformType::SCALE_Y:
+ {
+ return Dali::Actor::Property::SCALE_Y;
+ }
+ case TransformType::SCALE_Z:
+ {
+ return Dali::Actor::Property::SCALE_Z;
+ }
+ default:
+ {
+ DALI_LOG_ERROR("Invalid transform type used\n");
+ return Property::INVALID_INDEX;
+ }
+ }
+}
+
+} // namespace Internal
+
+} // namespace Scene3D
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_SCENE3D_MODEL_MOTION_MOTION_TRANSFORM_INDEX_IMPL_H
+#define DALI_SCENE3D_MODEL_MOTION_MOTION_TRANSFORM_INDEX_IMPL_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/base-object.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/model-motion/motion-index/motion-index-impl.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-transform-index.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+using MotionTransformIndexPtr = IntrusivePtr<MotionTransformIndex>;
+
+/**
+ * @brief Internal data for Scene3D::MotionTransformIndex.
+ */
+class MotionTransformIndex : public MotionIndex
+{
+public: // Creation & Destruction
+ /**
+ * @brief Create a new MotionTransformIndex object.
+ * @return A smart-pointer to the newly allocated MotionTransformIndex.
+ */
+ static MotionTransformIndexPtr New();
+
+protected:
+ /**
+ * @brief Construct a new MotionTransformIndex.
+ */
+ MotionTransformIndex();
+
+ /**
+ * @brief Second-phase constructor.
+ */
+ void Initialize();
+
+ /**
+ * @brief Virtual destructor.
+ */
+ virtual ~MotionTransformIndex();
+
+public: // Public Method
+ /**
+ * @copydoc Dali::Scene3D::MotionTransformIndex::SetTransformType()
+ */
+ void SetTransformType(Scene3D::MotionTransformIndex::TransformType type);
+
+ /**
+ * @copydoc Dali::Scene3D::BlendShapeIndex::GetTransformType()
+ */
+ Scene3D::MotionTransformIndex::TransformType GetTransformType() const;
+
+public: // MotionIndex Override Method
+ /**
+ * @copydoc Dali::Scene3D::Internal::MotionIndex::GetPropertyName()
+ */
+ std::string GetPropertyName(Scene3D::ModelNode node = Scene3D::ModelNode()) override;
+
+ /**
+ * @copydoc Dali::Scene3D::Internal::MotionIndex::GetPropertyIndex()
+ */
+ Property::Index GetPropertyIndex(Scene3D::ModelNode node = Scene3D::ModelNode()) override;
+
+protected:
+ Scene3D::MotionTransformIndex::TransformType mTransformType{Scene3D::MotionTransformIndex::TransformType::INVALID}; ///< The type of transform
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Internal::MotionTransformIndex& GetImplementation(Dali::Scene3D::MotionTransformIndex& motionTransformIndex)
+{
+ DALI_ASSERT_ALWAYS(motionTransformIndex && "MotionTransformIndex handle is empty");
+
+ BaseObject& handle = motionTransformIndex.GetBaseObject();
+
+ return static_cast<Internal::MotionTransformIndex&>(handle);
+}
+
+inline const Internal::MotionTransformIndex& GetImplementation(const Dali::Scene3D::MotionTransformIndex& motionTransformIndex)
+{
+ DALI_ASSERT_ALWAYS(motionTransformIndex && "MotionTransformIndex handle is empty");
+
+ const BaseObject& handle = motionTransformIndex.GetBaseObject();
+
+ return static_cast<const Internal::MotionTransformIndex&>(handle);
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_MODEL_MOTION_MOTION_TRANSFORM_INDEX_IMPL_H
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/internal/model-motion/motion-value-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/animation/key-frames-devel.h>
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/object/type-registry.h>
+
+// INTERNAL INCLUDES
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+namespace
+{
+/**
+ * Creates control through type registry
+ */
+BaseHandle Create()
+{
+ return Scene3D::MotionValue::New();
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN(Scene3D::MotionValue, Dali::BaseHandle, Create);
+DALI_TYPE_REGISTRATION_END()
+
+} // unnamed namespace
+
+MotionValuePtr MotionValue::New()
+{
+ MotionValuePtr motionValue = new MotionValue();
+
+ motionValue->Initialize();
+
+ return motionValue;
+}
+
+MotionValue::MotionValue()
+{
+}
+
+MotionValue::~MotionValue()
+{
+}
+
+void MotionValue::Initialize()
+{
+}
+
+// Public Method
+
+Scene3D::MotionValue::ValueType MotionValue::GetValueType() const
+{
+ return mType;
+}
+
+void MotionValue::SetValue(Property::Value propertyValue)
+{
+ mType = Scene3D::MotionValue::ValueType::PROPERTY_VALUE;
+
+ mKeyFrames.Reset();
+ mPropertyValue = propertyValue;
+}
+
+void MotionValue::SetValue(Dali::KeyFrames keyFrames)
+{
+ mType = Scene3D::MotionValue::ValueType::KEY_FRAMES;
+
+ mKeyFrames = keyFrames;
+ mPropertyValue = Property::Value();
+}
+
+void MotionValue::Clear()
+{
+ mType = Scene3D::MotionValue::ValueType::INVALID;
+
+ mKeyFrames.Reset();
+ mPropertyValue = Property::Value();
+}
+
+Property::Value MotionValue::GetPropertyValue() const
+{
+ if(mType == Scene3D::MotionValue::ValueType::PROPERTY_VALUE)
+ {
+ return mPropertyValue;
+ }
+ else if(mType == Scene3D::MotionValue::ValueType::KEY_FRAMES)
+ {
+ // Get last value of keyframes
+ auto keyFrameCount = DevelKeyFrames::GetKeyFrameCount(mKeyFrames);
+ if(keyFrameCount > 0u)
+ {
+ float dummyProgress;
+ Property::Value propertyValue;
+ DevelKeyFrames::GetKeyFrame(mKeyFrames, keyFrameCount - 1u, dummyProgress, propertyValue);
+
+ return propertyValue;
+ }
+ }
+ return Property::Value();
+}
+
+KeyFrames MotionValue::GetKeyFrames() const
+{
+ if(mType == Scene3D::MotionValue::ValueType::KEY_FRAMES)
+ {
+ return mKeyFrames;
+ }
+ else if(mType == Scene3D::MotionValue::ValueType::PROPERTY_VALUE)
+ {
+ // Generate stable keyframe animation here.
+ // TODO : Should we check property value is animatable type or not?
+ KeyFrames keyFrames = KeyFrames::New();
+ keyFrames.Add(0.0f, mPropertyValue);
+ keyFrames.Add(1.0f, mPropertyValue);
+ return keyFrames;
+ }
+ return Dali::KeyFrames();
+}
+
+} // namespace Internal
+
+} // namespace Scene3D
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_SCENE3D_MODEL_MOTION_MOTION_VALUE_IMPL_H
+#define DALI_SCENE3D_MODEL_MOTION_MOTION_VALUE_IMPL_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/common/intrusive-ptr.h>
+#include <dali/public-api/object/base-object.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/model-motion/motion-value.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+using MotionValuePtr = IntrusivePtr<MotionValue>;
+
+/**
+ * @brief Internal data for Scene3D::MotionValue.
+ */
+class MotionValue : public BaseObject
+{
+public: // Creation & Destruction
+ /**
+ * @brief Create a new MotionValue object.
+ * @return A smart-pointer to the newly allocated MotionValue.
+ */
+ static MotionValuePtr New();
+
+protected:
+ /**
+ * @brief Construct a new MotionValue.
+ */
+ MotionValue();
+
+ /**
+ * @brief Second-phase constructor.
+ */
+ void Initialize();
+
+ /**
+ * @brief Virtual destructor.
+ */
+ virtual ~MotionValue();
+
+public: // Public Method
+ /**
+ * @copydoc Dali::Scene3D::MotionValue::GetValueType()
+ */
+ Scene3D::MotionValue::ValueType GetValueType() const;
+
+ /**
+ * @copydoc Dali::Scene3D::MotionValue::SetValue()
+ */
+ void SetValue(Property::Value propertyValue);
+
+ /**
+ * @copydoc Dali::Scene3D::MotionValue::SetValue()
+ */
+ void SetValue(Dali::KeyFrames keyFrames);
+
+ /**
+ * @copydoc Dali::Scene3D::MotionValue::Clear()
+ */
+ void Clear();
+
+ /**
+ * @copydoc Dali::Scene3D::MotionValue::GetPropertyValue()
+ */
+ Property::Value GetPropertyValue() const;
+
+ /**
+ * @copydoc Dali::Scene3D::MotionValue::GetKeyFrames()
+ */
+ KeyFrames GetKeyFrames() const;
+
+private:
+ Scene3D::MotionValue::ValueType mType{Scene3D::MotionValue::ValueType::INVALID};
+
+ Property::Value mPropertyValue{};
+ Dali::KeyFrames mKeyFrames{};
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Internal::MotionValue& GetImplementation(Dali::Scene3D::MotionValue& motionValue)
+{
+ DALI_ASSERT_ALWAYS(motionValue && "MotionValue handle is empty");
+
+ BaseObject& handle = motionValue.GetBaseObject();
+
+ return static_cast<Internal::MotionValue&>(handle);
+}
+
+inline const Internal::MotionValue& GetImplementation(const Dali::Scene3D::MotionValue& motionValue)
+{
+ DALI_ASSERT_ALWAYS(motionValue && "MotionValue handle is empty");
+
+ const BaseObject& handle = motionValue.GetBaseObject();
+
+ return static_cast<const Internal::MotionValue&>(handle);
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_MODEL_MOTION_MOTION_VALUE_IMPL_H
\ No newline at end of file
GetImpl(*this).RetrieveModelNodesByBlendShapeName(blendShapeName, modelNodes);
}
+Dali::Animation Model::GenerateMotionDataAnimation(MotionData motionData)
+{
+ return GetImpl(*this).GenerateMotionDataAnimation(motionData);
+}
+
+void Model::SetMotionData(MotionData motionData)
+{
+ GetImpl(*this).SetMotionData(motionData);
+}
+
} // namespace Scene3D
} // namespace Dali
// INTERNAL INCLUDES
#include <dali-scene3d/public-api/api.h>
#include <dali-scene3d/public-api/model-components/model-node.h>
+#include <dali-scene3d/public-api/model-motion/motion-data.h>
namespace Dali
{
*/
void RetrieveModelNodesByBlendShapeName(std::string_view blendShapeName, std::vector<ModelNode>& modelNodes) const;
+ /**
+ * @brief Generate specific animation of this Model by inputed MotionData.
+ *
+ * @SINCE_2_2.34
+ * @param[in] motionData the data of motion animation.
+ * @return Animation that be generated by MotionData. Or empty handle if there is no valid animation generated.
+ * @note This method should be called after Model load finished.
+ */
+ Dali::Animation GenerateMotionDataAnimation(MotionData motionData);
+
+ /**
+ * @brief Set specific values of this Model by inputed MotionData.
+ * @note If MotionValue's ValueType is ValueType::KEY_FRAMES, the last value will be set.
+ *
+ * @SINCE_2_2.34
+ * @param[in] motionData the data of motion to be set.
+ * @note This method should be called after Model load finished.
+ */
+ void SetMotionData(Scene3D::MotionData motionData);
+
public: // Not intended for application developers
/// @cond internal
/**
${scene3d_public_api_dir}/model-components/material.cpp
${scene3d_public_api_dir}/model-components/model-node.cpp
${scene3d_public_api_dir}/model-components/model-primitive.cpp
+ ${scene3d_public_api_dir}/model-motion/motion-data.cpp
+ ${scene3d_public_api_dir}/model-motion/motion-index/blend-shape-index.cpp
+ ${scene3d_public_api_dir}/model-motion/motion-index/motion-index.cpp
+ ${scene3d_public_api_dir}/model-motion/motion-index/motion-property-index.cpp
+ ${scene3d_public_api_dir}/model-motion/motion-index/motion-transform-index.cpp
+ ${scene3d_public_api_dir}/model-motion/motion-value.cpp
)
\ No newline at end of file
namespace Dali::Scene3D::Loader
{
-void AnimatedProperty::Animate(Animation& anim, GetActor getActor)
+void AnimatedProperty::Animate(Animation& anim, GetActor getActor) const
{
if(Actor actor = getActor(*this))
{
/**
* @return The Property object (of the given @a actor) whose value is being animated.
*/
- Property GetProperty(Actor& actor)
+ Property GetProperty(Actor& actor) const
{
auto idx = actor.GetPropertyIndex(mPropertyName);
return Property(actor, idx);
/**
* @brief The type of the Property (of the given @a actor) that is being animated.
*/
- Property::Type GetPropertyType(Actor& actor)
+ Property::Type GetPropertyType(Actor& actor) const
{
auto idx = actor.GetPropertyIndex(mPropertyName);
return actor.GetPropertyType(idx);
* Failing to find the actor purely means that this property will not be
* animated.
*/
- void Animate(Animation& anim, GetActor getActor);
+ void Animate(Animation& anim, GetActor getActor) const;
public: // DATA
struct Value
mProperties.reserve(size);
}
-uint32_t AnimationDefinition::GetPropertyCount()
+uint32_t AnimationDefinition::GetPropertyCount() const
{
- return mProperties.size();
+ return static_cast<uint32_t>(mProperties.size());
}
void AnimationDefinition::SetProperty(uint32_t index, AnimatedProperty&& property)
return mProperties[index];
}
+const AnimatedProperty& AnimationDefinition::GetPropertyAt(uint32_t index) const
+{
+ return mProperties[index];
+}
+
} // namespace Dali::Scene3D::Loader
*
* @return The count of animated properties.
*/
- uint32_t GetPropertyCount();
+ uint32_t GetPropertyCount() const;
/**
* @brief Add a property that will be animated by this AnimationDefinition
*/
AnimatedProperty& GetPropertyAt(uint32_t index);
+ /**
+ * @brief Retrieves animated property at the index
+ *
+ * @param[in] index The index of property to be retrieved.
+ */
+ const AnimatedProperty& GetPropertyAt(uint32_t index) const;
+
private: // DATA
std::string mName;
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/public-api/model-motion/motion-data.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/model-motion/motion-data-impl.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+MotionData MotionData::New()
+{
+ Internal::MotionDataPtr internal = Internal::MotionData::New();
+
+ return MotionData(internal.Get());
+}
+
+MotionData MotionData::New(float durationSeconds)
+{
+ Internal::MotionDataPtr internal = Internal::MotionData::New();
+
+ internal->SetDuration(durationSeconds);
+
+ return MotionData(internal.Get());
+}
+
+MotionData::MotionData()
+{
+}
+
+MotionData::MotionData(const MotionData& motionData) = default;
+
+MotionData::MotionData(MotionData&& rhs) noexcept = default;
+
+MotionData::~MotionData()
+{
+}
+
+MotionData& MotionData::operator=(const MotionData& handle) = default;
+
+MotionData& MotionData::operator=(MotionData&& rhs) noexcept = default;
+
+MotionData MotionData::DownCast(BaseHandle handle)
+{
+ return MotionData(dynamic_cast<Dali::Scene3D::Internal::MotionData*>(handle.GetObjectPtr()));
+}
+
+MotionData::MotionData(Dali::Scene3D::Internal::MotionData* internal)
+: BaseHandle(internal)
+{
+}
+
+// Public Method
+
+uint32_t MotionData::GetMotionCount() const
+{
+ return GetImplementation(*this).GetMotionCount();
+}
+
+MotionIndex MotionData::GetIndex(uint32_t index) const
+{
+ return GetImplementation(*this).GetIndex(index);
+}
+
+MotionValue MotionData::GetValue(uint32_t index) const
+{
+ return GetImplementation(*this).GetValue(index);
+}
+
+void MotionData::Add(MotionIndex index, MotionValue value)
+{
+ GetImplementation(*this).Add(index, value);
+}
+
+void MotionData::Clear()
+{
+ GetImplementation(*this).Clear();
+}
+
+void MotionData::SetDuration(float durationSeconds)
+{
+ GetImplementation(*this).SetDuration(durationSeconds);
+}
+
+float MotionData::GetDuration() const
+{
+ return GetImplementation(*this).GetDuration();
+}
+
+void MotionData::LoadBvh(const std::string& path, const Vector3& scale, bool synchronousLoad)
+{
+ GetImplementation(*this).LoadBvh(path, scale, synchronousLoad);
+}
+
+void MotionData::LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, const Vector3& scale, bool synchronousLoad)
+{
+ GetImplementation(*this).LoadBvhFromBuffer(rawBuffer, rawBufferLength, scale, synchronousLoad);
+}
+
+void MotionData::LoadFacialAnimation(const std::string& url, bool synchronousLoad)
+{
+ GetImplementation(*this).LoadFacialAnimation(url, synchronousLoad);
+}
+
+void MotionData::LoadFacialAnimationFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, bool synchronousLoad)
+{
+ GetImplementation(*this).LoadFacialAnimationFromBuffer(rawBuffer, rawBufferLength, synchronousLoad);
+}
+
+MotionData::LoadCompletedSignalType& MotionData::LoadCompletedSignal()
+{
+ return GetImplementation(*this).LoadCompletedSignal();
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_SCENE3D_MODEL_MOTION_MOTION_DATA_H
+#define DALI_SCENE3D_MODEL_MOTION_MOTION_DATA_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/object/base-handle.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-index.h>
+#include <dali-scene3d/public-api/model-motion/motion-value.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+//Forward declarations.
+namespace Internal
+{
+class MotionData;
+} // namespace Internal
+
+/**
+ * @addtogroup dali_scene3d_model_motion_motion_data
+ * @{
+ */
+
+/**
+ * @brief List of model motion definitions.
+ * Each motion has pair of MotionIndex and MotionValue.
+ * MotionIndex is abstract class that specify the target of motion.
+ * MotionValue is target value of motion. It can be KeyFrames.
+ *
+ * We can generate list of motions by MotionIndex and MotionValue classes.
+ *
+ * @code
+ *
+ * MotionData motionData = MotionData::New(3.0f);
+ *
+ * // Make MotionIndex with MotionPropertyIndex
+ * // Make MotionValue with Dali::Property::Value
+ * motionData.Add(MotionPropertyIndex::New("nodeName", "color"), MotionValue::New(Color::RED));
+ *
+ * // Make MotionIndex with MotionTransformIndex
+ * // Make MotionValue with Dali::KeyFrames
+ * KeyFrames keyFrames = KeyFrames::New();
+ * keyFrames.Add(0.0f, 0.0f);
+ * keyFrames.Add(0.0f, 1.0f);
+ * motionData.Add(MotionTransformIndex::New("nodeName", MotionTransformIndex::TransformType::POSITION_X), MotionValue::New(keyFrames));
+ *
+ * // Make MotionIndex with BlendShapeIndex
+ * motionData.Add(BlendShapeIndex::New("nodeName", 0u), motionData.GetValue(1u));
+ *
+ * @endcode
+ *
+ * We can request to load MotionData from file or buffer asynchronously.
+ * If load completed, LoadCompetedSignal will be emmited.
+ *
+ * @code
+ *
+ * MotionData motionData = MotionData::New();
+ * motionData.LoadCompletedSignal().Connect(&OnLoadCompleted);
+ * motionData.LoadBvh("bvhFilename.bvh", Vector3::ONE);
+ *
+ * @endcode
+ *
+ * We can generate animation of Scene3D::Model from MotionData class.
+ * Or, just set values.
+ *
+ * @code
+ *
+ * // Generate animation from loaded Model
+ * Dali::Animation animation = model.GenerateMotionDataAnimation(motionData);
+ * animation.Play();
+ *
+ * // Set values from loaded Model.
+ * model2.SetMotionData(motionData);
+ *
+ * @endcode
+ * @note We don't check duplicated MotionIndex internally.
+ * @SINCE_2_2.34
+ */
+class DALI_SCENE3D_API MotionData : public Dali::BaseHandle
+{
+public:
+ /// @brief LoadCompleted signal type. @SINCE_2_2.34
+ typedef Signal<void(MotionData)> LoadCompletedSignalType;
+
+public: // Creation & Destruction
+ /**
+ * @brief Create an initialized MotionData.
+ *
+ * @SINCE_2_2.34
+ * @return A handle to a newly allocated Dali resource
+ */
+ static MotionData New();
+
+ /**
+ * @brief Create an initialized MotionData with duration.
+ *
+ * @SINCE_2_2.34
+ * @param[in] durationSeconds Duration of animation as seconds.
+ * @return A handle to a newly allocated Dali resource
+ */
+ static MotionData New(float durationSeconds);
+
+ /**
+ * @brief Creates an uninitialized MotionData.
+ *
+ * Only derived versions can be instantiated. Calling member
+ * functions with an uninitialized Dali::Object is not allowed.
+ *
+ * @SINCE_2_2.34
+ */
+ MotionData();
+
+ /**
+ * @brief Destructor.
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ *
+ * @SINCE_2_2.34
+ */
+ ~MotionData();
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @SINCE_2_2.34
+ * @param[in] motionData Handle to an object
+ */
+ MotionData(const MotionData& motionData);
+
+ /**
+ * @brief Move constructor
+ *
+ * @SINCE_2_2.34
+ * @param[in] rhs A reference to the moved handle
+ */
+ MotionData(MotionData&& rhs) noexcept;
+
+ /**
+ * @brief Assignment operator.
+ *
+ * @SINCE_2_2.34
+ * @param[in] motionData Handle to an object
+ * @return reference to this
+ */
+ MotionData& operator=(const MotionData& motionData);
+
+ /**
+ * @brief Move assignment
+ *
+ * @SINCE_2_2.34
+ * @param[in] rhs A reference to the moved handle
+ * @return A reference to this
+ */
+ MotionData& operator=(MotionData&& rhs) noexcept;
+
+ /**
+ * @brief Downcasts an Object handle to MotionData.
+ *
+ * If handle points to a MotionData, the downcast produces valid handle.
+ * If not, the returned handle is left uninitialized.
+ *
+ * @SINCE_2_2.34
+ * @param[in] handle Handle to an object
+ * @return Handle to a MotionData or an uninitialized handle
+ */
+ static MotionData DownCast(BaseHandle handle);
+
+public: // Public Method
+ /**
+ * @brief Get the number of motions what we added
+ *
+ * @SINCE_2_2.34
+ * @return The number of motions
+ */
+ uint32_t GetMotionCount() const;
+
+ /**
+ * @brief Get MotionIndex from given index'th.
+ *
+ * @SINCE_2_2.34
+ * @param[in] index The index of motion list.
+ * @return Index of motion, or empty handle if invalid index inputed.
+ */
+ MotionIndex GetIndex(uint32_t index) const;
+
+ /**
+ * @brief Get MotionValue from given index'th.
+ *
+ * @SINCE_2_2.34
+ * @param[in] index The index of motion list.
+ * @return Value of motion, or empty handle if invalid index inputed.
+ */
+ MotionValue GetValue(uint32_t index) const;
+
+ /**
+ * @brief Append new motion.
+ * @note We don't check duplicated MotionIndex internally.
+ *
+ * @SINCE_2_2.34
+ * @param[in] index index of motion.
+ * @param[in] value value of motion.
+ */
+ void Add(MotionIndex index, MotionValue value);
+
+ /**
+ * @brief Clear all stored motion data.
+ *
+ * @SINCE_2_2.34
+ */
+ void Clear();
+
+ /**
+ * @brief Set the duration of this motion data if it be generated as Dali::Animation.
+ *
+ * @SINCE_2_2.34
+ * @param[in] durationSeconds Duration of animation as seconds.
+ */
+ void SetDuration(float durationSeconds);
+
+ /**
+ * @brief Get the duration of this motion data if it be generated as Dali::Animation.
+ *
+ * @SINCE_2_2.34
+ * @return The duration of this motion data seconds. Default is 0.0f
+ */
+ float GetDuration() const;
+
+ /**
+ * @brief Load MotionData from bvh file.
+ * It will use Dali::Scene3D::Loader::LoadBvh() internally.
+ * LoadCompleteSignal() will be emitted after load completed.
+ *
+ * @SINCE_2_2.34
+ * @param[in] path The file path.
+ * @param[in] scale The scale factor to set on the position property manually.
+ * @param[in] synchronousLoad True if we want to load result synchronously. Default is false.
+ */
+ void LoadBvh(const std::string& path, const Vector3& scale = Vector3::ONE, bool synchronousLoad = false);
+
+ /**
+ * @brief Load MotionData from bvh buffer.
+ * It will use Dali::Scene3D::Loader::LoadBvhFromBuffer() internally.
+ * LoadCompleteSignal() will be emitted after load completed.
+ *
+ * @SINCE_2_2.34
+ * @param[in] rawBuffer The bvh buffer containing the facial animation as bvh format string.
+ * @param[in] rawBufferLength The length of buffer.
+ * @param[in] scale The scale factor to set on the position property manually.
+ * @param[in] synchronousLoad True if we want to load result synchronously. Default is false.
+ */
+ void LoadBvhFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, const Vector3& scale = Vector3::ONE, bool synchronousLoad = false);
+
+ /**
+ * @brief Load MotionData from facial defined json file.
+ * It will use Dali::Scene3D::Loader::LoadFacialAnimation() internally.
+ * LoadCompleteSignal() will be emitted after load completed.
+ *
+ * @SINCE_2_2.34
+ * @param[in] url The file path.
+ * @param[in] synchronousLoad True if we want to load result synchronously. Default is false.
+ */
+ void LoadFacialAnimation(const std::string& url, bool synchronousLoad = false);
+
+ /**
+ * @brief Load MotionData from facial defined json file.
+ * It will use Dali::Scene3D::Loader::LoadFacialAnimationFromBuffer() internally.
+ * LoadCompleteSignal() will be emitted after load completed.
+ *
+ * @SINCE_2_2.34
+ * @param[in] rawBuffer The raw buffer containing the facial animation as json format string.
+ * @param[in] rawBufferLength The length of raw buffer.
+ * @param[in] synchronousLoad True if we want to load result synchronously. Default is false.
+ */
+ void LoadFacialAnimationFromBuffer(const uint8_t* rawBuffer, int rawBufferLength, bool synchronousLoad = false);
+
+public:
+ /**
+ * @brief This signal is emitted after motion data are loaded completed.
+ * @note Signal will be emitted even if we request load synchronously.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ * void YourCallbackName(MotionData motionData);
+ * @endcode
+ *
+ * @SINCE_2_2.34
+ * @return The signal to connect to.
+ */
+ LoadCompletedSignalType& LoadCompletedSignal();
+
+public: // Not intended for application developers
+ /// @cond internal
+ /**
+ * @brief Creates a handle using the Scene3D::Internal implementation.
+ *
+ * @param[in] implementation The MotionData implementation
+ */
+ DALI_INTERNAL MotionData(Dali::Scene3D::Internal::MotionData* implementation);
+ /// @endcond
+};
+
+/**
+ * @}
+ */
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_MODEL_MOTION_MOTION_DATA_H
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/public-api/model-motion/motion-index/blend-shape-index.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/model-motion/motion-index/blend-shape-index-impl.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+BlendShapeIndex BlendShapeIndex::New()
+{
+ Internal::BlendShapeIndexPtr internal = Internal::BlendShapeIndex::New();
+
+ return BlendShapeIndex(internal.Get());
+}
+
+BlendShapeIndex BlendShapeIndex::New(Property::Key blendShapeId)
+{
+ Internal::BlendShapeIndexPtr internal = Internal::BlendShapeIndex::New();
+
+ internal->SetBlendShapeId(blendShapeId);
+
+ return BlendShapeIndex(internal.Get());
+}
+
+BlendShapeIndex BlendShapeIndex::New(Property::Key modelNodeId, Property::Key blendShapeId)
+{
+ Internal::BlendShapeIndexPtr internal = Internal::BlendShapeIndex::New();
+
+ internal->SetModelNodeId(modelNodeId);
+ internal->SetBlendShapeId(blendShapeId);
+
+ return BlendShapeIndex(internal.Get());
+}
+
+BlendShapeIndex::BlendShapeIndex()
+{
+}
+
+BlendShapeIndex::BlendShapeIndex(const BlendShapeIndex& blendShapeIndex) = default;
+
+BlendShapeIndex::BlendShapeIndex(BlendShapeIndex&& rhs) noexcept = default;
+
+BlendShapeIndex::~BlendShapeIndex()
+{
+}
+
+BlendShapeIndex& BlendShapeIndex::operator=(const BlendShapeIndex& handle) = default;
+
+BlendShapeIndex& BlendShapeIndex::operator=(BlendShapeIndex&& rhs) noexcept = default;
+
+BlendShapeIndex BlendShapeIndex::DownCast(BaseHandle handle)
+{
+ return BlendShapeIndex(dynamic_cast<Dali::Scene3D::Internal::BlendShapeIndex*>(handle.GetObjectPtr()));
+}
+
+BlendShapeIndex::BlendShapeIndex(Dali::Scene3D::Internal::BlendShapeIndex* internal)
+: MotionIndex(internal)
+{
+}
+
+// Public Method
+
+void BlendShapeIndex::SetBlendShapeId(Property::Key blendShapeId)
+{
+ GetImplementation(*this).SetBlendShapeId(blendShapeId);
+}
+
+Property::Key BlendShapeIndex::GetBlendShapeId() const
+{
+ return GetImplementation(*this).GetBlendShapeId();
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_SCENE3D_MODEL_MOTION_BLEND_SHAPE_INDEX_H
+#define DALI_SCENE3D_MODEL_MOTION_BLEND_SHAPE_INDEX_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-index.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+//Forward declarations.
+namespace Internal
+{
+class BlendShapeIndex;
+} // namespace Internal
+
+/**
+ * @addtogroup dali_scene3d_model_motion_blend_shape_index
+ * @{
+ */
+
+/**
+ * @brief Specialized MotionIndex to control blend shape.
+ * We can control the blend shape by index (when we set BlendShapeId as IndexKey)
+ * or by name (when we set BlendShapeId as StringKey)
+ *
+ * @code
+ *
+ * BlendShapeIndex blendShapeIndex0 = BlendShapeIndex::New("nodeName", 0u);
+ * BlendShapeIndex blendShapeIndex1 = BlendShapeIndex::New("nodeName", "Target_1");
+ *
+ * // We can change the property later.
+ * BlendShapeIndex blendShapeIndex2 = BlendShapeIndex::New();
+ * blendShapeIndex2.SetModelNodeId("nodeName");
+ * blendShapeIndex2.SetBlendShapeId("Target_2");
+ *
+ * @endcode
+ *
+ * Specially, if ModelNodeId is Property::INVALID_KEY and BlendShapeId is StringKey,
+ * It will control all ModelNode that has the inputed BlendShape name.
+ *
+ * @code
+ *
+ * // If "node0" and "node1" has same BlendShape named "Smile",
+ * // blendShapeIndexAll will control both nodes.
+ * BlendShapeIndex blendShapeIndexAll = BlendShapeIndex::New("Smile");
+ *
+ * BlendShapeIndex blendShapeIndex0 = BlendShapeIndex::New("node0", "Smile");
+ * BlendShapeIndex blendShapeIndex1 = BlendShapeIndex::New("node1", "Smile");
+ *
+ * @endcode
+ *
+ * @SINCE_2_2.34
+ */
+class DALI_SCENE3D_API BlendShapeIndex : public MotionIndex
+{
+public: // Creation & Destruction
+ /**
+ * @brief Create an initialized BlendShapeIndex.
+ *
+ * @SINCE_2_2.34
+ * @return A handle to a newly allocated Dali resource
+ */
+ static BlendShapeIndex New();
+
+ /**
+ * @brief Create an initialized BlendShapeIndex with values. It will hold invalid ModelNodeId.
+ *
+ * @SINCE_2_2.34
+ * @param[in] blendShapeId The id of blend shape what this motion index looks.
+ * @return A handle to a newly allocated Dali resource
+ */
+ static BlendShapeIndex New(Property::Key blendShapeId);
+
+ /**
+ * @brief Create an initialized BlendShapeIndex with values.
+ *
+ * @SINCE_2_2.34
+ * @param[in] modelNodeId The id of model node what this motion index looks.
+ * @param[in] blendShapeId The id of blend shape what this motion index looks.
+ * @return A handle to a newly allocated Dali resource
+ */
+ static BlendShapeIndex New(Property::Key modelNodeId, Property::Key blendShapeId);
+
+ /**
+ * @brief Creates an uninitialized BlendShapeIndex.
+ *
+ * Only derived versions can be instantiated. Calling member
+ * functions with an uninitialized Dali::Object is not allowed.
+ *
+ * @SINCE_2_2.34
+ */
+ BlendShapeIndex();
+
+ /**
+ * @brief Destructor.
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ *
+ * @SINCE_2_2.34
+ */
+ ~BlendShapeIndex();
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @SINCE_2_2.34
+ * @param[in] blendShapeIndex Handle to an object
+ */
+ BlendShapeIndex(const BlendShapeIndex& blendShapeIndex);
+
+ /**
+ * @brief Move constructor
+ *
+ * @SINCE_2_2.34
+ * @param[in] rhs A reference to the moved handle
+ */
+ BlendShapeIndex(BlendShapeIndex&& rhs) noexcept;
+
+ /**
+ * @brief Assignment operator.
+ *
+ * @SINCE_2_2.34
+ * @param[in] blendShapeIndex Handle to an object
+ * @return reference to this
+ */
+ BlendShapeIndex& operator=(const BlendShapeIndex& blendShapeIndex);
+
+ /**
+ * @brief Move assignment
+ *
+ * @SINCE_2_2.34
+ * @param[in] rhs A reference to the moved handle
+ * @return A reference to this
+ */
+ BlendShapeIndex& operator=(BlendShapeIndex&& rhs) noexcept;
+
+ /**
+ * @brief Downcasts an Object handle to BlendShapeIndex.
+ *
+ * If handle points to a BlendShapeIndex, the downcast produces valid handle.
+ * If not, the returned handle is left uninitialized.
+ *
+ * @SINCE_2_2.34
+ * @param[in] handle Handle to an object
+ * @return Handle to a BlendShapeIndex or an uninitialized handle
+ */
+ static BlendShapeIndex DownCast(BaseHandle handle);
+
+public: // Public Method
+ /**
+ * @brief Set the id of BlendShape what this motion index looks.
+ *
+ * @SINCE_2_2.34
+ * @param[in] blendShapeId The blend shape id.
+ */
+ void SetBlendShapeId(Property::Key blendShapeId);
+
+ /**
+ * @brief Get the id of BlendShape what this motion index looks.
+ *
+ * @SINCE_2_2.34
+ * @return The blend shape id.
+ */
+ Property::Key GetBlendShapeId() const;
+
+public: // Not intended for application developers
+ /// @cond internal
+ /**
+ * @brief Creates a handle using the Scene3D::Internal implementation.
+ *
+ * @param[in] implementation The BlendShapeIndex implementation
+ */
+ DALI_INTERNAL BlendShapeIndex(Dali::Scene3D::Internal::BlendShapeIndex* implementation);
+ /// @endcond
+};
+
+/**
+ * @}
+ */
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_MODEL_MOTION_BLEND_SHAPE_INDEX_H
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-index.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/model-motion/motion-index/motion-index-impl.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+MotionIndex::MotionIndex()
+{
+}
+
+MotionIndex::MotionIndex(const MotionIndex& motionIndex) = default;
+
+MotionIndex::MotionIndex(MotionIndex&& rhs) noexcept = default;
+
+MotionIndex::~MotionIndex()
+{
+}
+
+MotionIndex& MotionIndex::operator=(const MotionIndex& handle) = default;
+
+MotionIndex& MotionIndex::operator=(MotionIndex&& rhs) noexcept = default;
+
+MotionIndex MotionIndex::DownCast(BaseHandle handle)
+{
+ return MotionIndex(dynamic_cast<Dali::Scene3D::Internal::MotionIndex*>(handle.GetObjectPtr()));
+}
+
+MotionIndex::MotionIndex(Dali::Scene3D::Internal::MotionIndex* internal)
+: BaseHandle(internal)
+{
+}
+
+// Public Method
+
+void MotionIndex::SetModelNodeId(Property::Key modelNodeId)
+{
+ GetImplementation(*this).SetModelNodeId(modelNodeId);
+}
+
+Property::Key MotionIndex::GetModelNodeId() const
+{
+ return GetImplementation(*this).GetModelNodeId();
+}
+
+std::string MotionIndex::GetPropertyName(ModelNode node)
+{
+ return GetImplementation(*this).GetPropertyName(node);
+}
+
+Property::Index MotionIndex::GetPropertyIndex(ModelNode node)
+{
+ return GetImplementation(*this).GetPropertyIndex(node);
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_SCENE3D_MODEL_MOTION_MOTION_INDEX_H
+#define DALI_SCENE3D_MODEL_MOTION_MOTION_INDEX_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/property-key.h>
+#include <dali/public-api/object/property.h>
+#include <string>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/model-components/model-node.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+//Forward declarations.
+namespace Internal
+{
+class MotionIndex;
+} // namespace Internal
+
+/**
+ * @addtogroup dali_scene3d_model_motion_motion_index
+ * @{
+ */
+
+/**
+ * @brief Key of motion data to specify what ModelNode's property will be moved.
+ * MotionIndex itself is abstract classes. We need to create New from one of below classes.
+ * - BlendShapeIndex : To control blendshape.
+ * - MotionPropertyIndex : To control the property by Dali::Property.
+ * - MotionTransfromIndex : To control the transform property. Usually be used on CSharp binded API who cannot use Dali::Property directly.
+ * @todo Need to implement ModelNodeId as IndexKey. Currently, StringKey only works well.
+ *
+ * @SINCE_2_2.34
+ */
+class DALI_SCENE3D_API MotionIndex : public Dali::BaseHandle
+{
+public: // Creation & Destruction
+ /**
+ * @brief Creates an uninitialized MotionIndex.
+ *
+ * Only derived versions can be instantiated. Calling member
+ * functions with an uninitialized Dali::Object is not allowed.
+ *
+ * @SINCE_2_2.34
+ */
+ MotionIndex();
+
+ /**
+ * @brief Destructor.
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ *
+ * @SINCE_2_2.34
+ */
+ ~MotionIndex();
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @SINCE_2_2.34
+ * @param[in] motionIndex Handle to an object
+ */
+ MotionIndex(const MotionIndex& motionIndex);
+
+ /**
+ * @brief Move constructor
+ *
+ * @SINCE_2_2.34
+ * @param[in] rhs A reference to the moved handle
+ */
+ MotionIndex(MotionIndex&& rhs) noexcept;
+
+ /**
+ * @brief Assignment operator.
+ *
+ * @SINCE_2_2.34
+ * @param[in] motionIndex Handle to an object
+ * @return reference to this
+ */
+ MotionIndex& operator=(const MotionIndex& motionIndex);
+
+ /**
+ * @brief Move assignment
+ *
+ * @SINCE_2_2.34
+ * @param[in] rhs A reference to the moved handle
+ * @return A reference to this
+ */
+ MotionIndex& operator=(MotionIndex&& rhs) noexcept;
+
+ /**
+ * @brief Downcasts an Object handle to MotionIndex.
+ *
+ * If handle points to a MotionIndex, the downcast produces valid handle.
+ * If not, the returned handle is left uninitialized.
+ *
+ * @SINCE_2_2.34
+ * @param[in] handle Handle to an object
+ * @return Handle to a MotionIndex or an uninitialized handle
+ */
+ static MotionIndex DownCast(BaseHandle handle);
+
+public: // Public Method
+ /**
+ * @brief Set the id of ModelNode what this motion index looks.
+ *
+ * @SINCE_2_2.34
+ * @param[in] modelNodeId The model node id.
+ */
+ void SetModelNodeId(Property::Key modelNodeId);
+
+ /**
+ * @brief Get the id of ModelNode what this motion index looks.
+ *
+ * @SINCE_2_2.34
+ * @return The model node id.
+ */
+ Property::Key GetModelNodeId() const;
+
+ /**
+ * @brief Get the property name of this MotionIndex from given ModelNode.
+ *
+ * @SINCE_2_2.34
+ * @param[in] node The model node to get the property name.
+ * @return The name of current property.
+ */
+ std::string GetPropertyName(ModelNode node = ModelNode());
+
+ /**
+ * @brief Get the property index of this MotionIndex from given ModelNode.
+ *
+ * @SINCE_2_2.34
+ * @param[in] node The model node to get the property index.
+ * @return The index of current property.
+ */
+ Property::Index GetPropertyIndex(ModelNode node = ModelNode());
+
+public: // Not intended for application developers
+ /// @cond internal
+ /**
+ * @brief Creates a handle using the Scene3D::Internal implementation.
+ *
+ * @param[in] implementation The MotionIndex implementation
+ */
+ DALI_INTERNAL MotionIndex(Dali::Scene3D::Internal::MotionIndex* implementation);
+ /// @endcond
+};
+
+/**
+ * @}
+ */
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_MODEL_MOTION_MOTION_INDEX_H
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-property-index.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/model-motion/motion-index/motion-property-index-impl.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+MotionPropertyIndex MotionPropertyIndex::New()
+{
+ Internal::MotionPropertyIndexPtr internal = Internal::MotionPropertyIndex::New();
+
+ return MotionPropertyIndex(internal.Get());
+}
+
+MotionPropertyIndex MotionPropertyIndex::New(Property::Key modelNodeId, Property::Key propertyId)
+{
+ Internal::MotionPropertyIndexPtr internal = Internal::MotionPropertyIndex::New();
+
+ internal->SetModelNodeId(modelNodeId);
+ internal->SetPropertyId(propertyId);
+
+ return MotionPropertyIndex(internal.Get());
+}
+
+MotionPropertyIndex::MotionPropertyIndex()
+{
+}
+
+MotionPropertyIndex::MotionPropertyIndex(const MotionPropertyIndex& motionPropertyIndex) = default;
+
+MotionPropertyIndex::MotionPropertyIndex(MotionPropertyIndex&& rhs) noexcept = default;
+
+MotionPropertyIndex::~MotionPropertyIndex()
+{
+}
+
+MotionPropertyIndex& MotionPropertyIndex::operator=(const MotionPropertyIndex& handle) = default;
+
+MotionPropertyIndex& MotionPropertyIndex::operator=(MotionPropertyIndex&& rhs) noexcept = default;
+
+MotionPropertyIndex MotionPropertyIndex::DownCast(BaseHandle handle)
+{
+ return MotionPropertyIndex(dynamic_cast<Dali::Scene3D::Internal::MotionPropertyIndex*>(handle.GetObjectPtr()));
+}
+
+MotionPropertyIndex::MotionPropertyIndex(Dali::Scene3D::Internal::MotionPropertyIndex* internal)
+: MotionIndex(internal)
+{
+}
+
+// Public Method
+
+void MotionPropertyIndex::SetPropertyId(Property::Key blendShapeId)
+{
+ GetImplementation(*this).SetPropertyId(blendShapeId);
+}
+
+Property::Key MotionPropertyIndex::GetPropertyId() const
+{
+ return GetImplementation(*this).GetPropertyId();
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_SCENE3D_MODEL_MOTION_MOTION_PROPERTY_INDEX_H
+#define DALI_SCENE3D_MODEL_MOTION_MOTION_PROPERTY_INDEX_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-index.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+//Forward declarations.
+namespace Internal
+{
+class MotionPropertyIndex;
+} // namespace Internal
+
+/**
+ * @addtogroup dali_scene3d_model_motion_motion_property_index
+ * @{
+ */
+
+/**
+ * @brief Basic MotionIndex to control Dali::Property.
+ * It can control more general case.
+ *
+ * @code
+ *
+ * MotionPropertyIndex color = MotionPropertyIndex::New("nodeName", Dali::Actor::Property::COLOR);
+ *
+ * // We can change the property later.
+ * MotionPropertyIndex custom = MotionPropertyIndex::New();
+ * orientation.SetModelNodeId("nodeName");
+ * orientation.SetPropertyId("some_custom_property");
+ *
+ * // Note that all cases of MotionTransformIndex can be controled by MotionPropertyIndex
+ * // Both position0 and position1 can control the node's Position.
+ * MotionTransformIndex position0 = MotionTransformIndex::New("nodeName", MotionTransformIndex::TransformType::POSITION);
+ * MotionPropertyIndex position1 = MotionPropertyIndex::New("nodeName", Dali::Actor::Property::POSITION);
+ *
+ * @endcode
+ *
+ * @SINCE_2_2.34
+ */
+class DALI_SCENE3D_API MotionPropertyIndex : public MotionIndex
+{
+public: // Creation & Destruction
+ /**
+ * @brief Create an initialized MotionPropertyIndex.
+ *
+ * @SINCE_2_2.34
+ * @return A handle to a newly allocated Dali resource
+ */
+ static MotionPropertyIndex New();
+
+ /**
+ * @brief Create an initialized MotionPropertyIndex with values.
+ *
+ * @SINCE_2_2.34
+ * @param[in] modelNodeId The id of model node what this motion index looks.
+ * @param[in] propertyId The id of property what this motion index looks.
+ * @return A handle to a newly allocated Dali resource
+ */
+ static MotionPropertyIndex New(Property::Key modelNodeId, Property::Key propertyId);
+
+ /**
+ * @brief Creates an uninitialized MotionPropertyIndex.
+ *
+ * Only derived versions can be instantiated. Calling member
+ * functions with an uninitialized Dali::Object is not allowed.
+ *
+ * @SINCE_2_2.34
+ */
+ MotionPropertyIndex();
+
+ /**
+ * @brief Destructor.
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ *
+ * @SINCE_2_2.34
+ */
+ ~MotionPropertyIndex();
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @SINCE_2_2.34
+ * @param[in] motionPropertyIndex Handle to an object
+ */
+ MotionPropertyIndex(const MotionPropertyIndex& motionPropertyIndex);
+
+ /**
+ * @brief Move constructor
+ *
+ * @SINCE_2_2.34
+ * @param[in] rhs A reference to the moved handle
+ */
+ MotionPropertyIndex(MotionPropertyIndex&& rhs) noexcept;
+
+ /**
+ * @brief Assignment operator.
+ *
+ * @SINCE_2_2.34
+ * @param[in] motionPropertyIndex Handle to an object
+ * @return reference to this
+ */
+ MotionPropertyIndex& operator=(const MotionPropertyIndex& motionPropertyIndex);
+
+ /**
+ * @brief Move assignment
+ *
+ * @SINCE_2_2.34
+ * @param[in] rhs A reference to the moved handle
+ * @return A reference to this
+ */
+ MotionPropertyIndex& operator=(MotionPropertyIndex&& rhs) noexcept;
+
+ /**
+ * @brief Downcasts an Object handle to MotionPropertyIndex.
+ *
+ * If handle points to a MotionPropertyIndex, the downcast produces valid handle.
+ * If not, the returned handle is left uninitialized.
+ *
+ * @SINCE_2_2.34
+ * @param[in] handle Handle to an object
+ * @return Handle to a MotionPropertyIndex or an uninitialized handle
+ */
+ static MotionPropertyIndex DownCast(BaseHandle handle);
+
+public: // Public Method
+ /**
+ * @brief Set the id of property what this motion index looks.
+ *
+ * @SINCE_2_2.34
+ * @param[in] propertyId The property id.
+ */
+ void SetPropertyId(Property::Key propertyId);
+
+ /**
+ * @brief Get the id of property what this motion index looks.
+ *
+ * @SINCE_2_2.34
+ * @return The blend shape id.
+ */
+ Property::Key GetPropertyId() const;
+
+public: // Not intended for application developers
+ /// @cond internal
+ /**
+ * @brief Creates a handle using the Scene3D::Internal implementation.
+ *
+ * @param[in] implementation The MotionPropertyIndex implementation
+ */
+ DALI_INTERNAL MotionPropertyIndex(Dali::Scene3D::Internal::MotionPropertyIndex* implementation);
+ /// @endcond
+};
+
+/**
+ * @}
+ */
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_MODEL_MOTION_MOTION_PROPERTY_INDEX_H
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-transform-index.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/model-motion/motion-index/motion-transform-index-impl.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+MotionTransformIndex MotionTransformIndex::New()
+{
+ Internal::MotionTransformIndexPtr internal = Internal::MotionTransformIndex::New();
+
+ return MotionTransformIndex(internal.Get());
+}
+
+MotionTransformIndex MotionTransformIndex::New(Property::Key modelNodeId, TransformType type)
+{
+ Internal::MotionTransformIndexPtr internal = Internal::MotionTransformIndex::New();
+
+ internal->SetModelNodeId(modelNodeId);
+ internal->SetTransformType(type);
+
+ return MotionTransformIndex(internal.Get());
+}
+
+MotionTransformIndex::MotionTransformIndex()
+{
+}
+
+MotionTransformIndex::MotionTransformIndex(const MotionTransformIndex& motionTransformIndex) = default;
+
+MotionTransformIndex::MotionTransformIndex(MotionTransformIndex&& rhs) noexcept = default;
+
+MotionTransformIndex::~MotionTransformIndex()
+{
+}
+
+MotionTransformIndex& MotionTransformIndex::operator=(const MotionTransformIndex& handle) = default;
+
+MotionTransformIndex& MotionTransformIndex::operator=(MotionTransformIndex&& rhs) noexcept = default;
+
+MotionTransformIndex MotionTransformIndex::DownCast(BaseHandle handle)
+{
+ return MotionTransformIndex(dynamic_cast<Dali::Scene3D::Internal::MotionTransformIndex*>(handle.GetObjectPtr()));
+}
+
+MotionTransformIndex::MotionTransformIndex(Dali::Scene3D::Internal::MotionTransformIndex* internal)
+: MotionIndex(internal)
+{
+}
+
+// Public Method
+
+void MotionTransformIndex::SetTransformType(MotionTransformIndex::TransformType type)
+{
+ GetImplementation(*this).SetTransformType(type);
+}
+
+MotionTransformIndex::TransformType MotionTransformIndex::GetTransformType() const
+{
+ return GetImplementation(*this).GetTransformType();
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_SCENE3D_MODEL_MOTION_MOTION_TRANSFORM_INDEX_H
+#define DALI_SCENE3D_MODEL_MOTION_MOTION_TRANSFORM_INDEX_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/model-motion/motion-index/motion-index.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+//Forward declarations.
+namespace Internal
+{
+class MotionTransformIndex;
+} // namespace Internal
+
+/**
+ * @addtogroup dali_scene3d_model_motion_motion_transform_index
+ * @{
+ */
+
+/**
+ * @brief Specialized MotionIndex to control transform.
+ * It will be used when app developer don't care about Dali::Actor::Property list,
+ * but want to change the transform properties anyway fast enough.
+ *
+ * @code
+ *
+ * MotionTransformIndex position = MotionTransformIndex::New("nodeName", MotionTransformIndex::TransformType::POSITION);
+ *
+ * // We can change the property later.
+ * MotionTransformIndex orientation = MotionTransformIndex::New();
+ * orientation.SetModelNodeId("nodeName");
+ * orientation.SetTransformType(MotionTransformIndex::TransformType::ORIENTATION);
+ *
+ * @endcode
+ *
+ * @SINCE_2_2.34
+ */
+class DALI_SCENE3D_API MotionTransformIndex : public MotionIndex
+{
+public:
+ /**
+ * @brief The type of Transform
+ * @SINCE_2_2.34
+ */
+ enum class TransformType
+ {
+ INVALID = -1,
+
+ POSITION = 0, ///< The position of ModelNode. MotionValue should be Vector3.
+ POSITION_X, ///< The x position of ModelNode. MotionValue should be float.
+ POSITION_Y, ///< The y position of ModelNode. MotionValue should be float.
+ POSITION_Z, ///< The z position of ModelNode. MotionValue should be float.
+
+ ORIENTATION, ///< The orientation of ModelNode. MotionValue should be Quaternion.
+
+ SCALE, ///< The scale of ModelNode. MotionValue should be Vector3.
+ SCALE_X, ///< The x scale of ModelNode. MotionValue should be float.
+ SCALE_Y, ///< The y scale of ModelNode. MotionValue should be float.
+ SCALE_Z, ///< The z scale of ModelNode. MotionValue should be float.
+ };
+
+public: // Creation & Destruction
+ /**
+ * @brief Create an initialized MotionTransformIndex.
+ *
+ * @SINCE_2_2.34
+ * @return A handle to a newly allocated Dali resource
+ */
+ static MotionTransformIndex New();
+
+ /**
+ * @brief Create an initialized MotionTransformIndex with values.
+ *
+ * @SINCE_2_2.34
+ * @param[in] modelNodeId The id of model node what this motion index looks.
+ * @param[in] type The type of transform what this motion index looks.
+ * @return A handle to a newly allocated Dali resource
+ */
+ static MotionTransformIndex New(Property::Key modelNodeId, TransformType type);
+
+ /**
+ * @brief Creates an uninitialized MotionTransformIndex.
+ *
+ * Only derived versions can be instantiated. Calling member
+ * functions with an uninitialized Dali::Object is not allowed.
+ *
+ * @SINCE_2_2.34
+ */
+ MotionTransformIndex();
+
+ /**
+ * @brief Destructor.
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ *
+ * @SINCE_2_2.34
+ */
+ ~MotionTransformIndex();
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @SINCE_2_2.34
+ * @param[in] motionTransformIndex Handle to an object
+ */
+ MotionTransformIndex(const MotionTransformIndex& motionTransformIndex);
+
+ /**
+ * @brief Move constructor
+ *
+ * @SINCE_2_2.34
+ * @param[in] rhs A reference to the moved handle
+ */
+ MotionTransformIndex(MotionTransformIndex&& rhs) noexcept;
+
+ /**
+ * @brief Assignment operator.
+ *
+ * @SINCE_2_2.34
+ * @param[in] motionTransformIndex Handle to an object
+ * @return reference to this
+ */
+ MotionTransformIndex& operator=(const MotionTransformIndex& motionTransformIndex);
+
+ /**
+ * @brief Move assignment
+ *
+ * @SINCE_2_2.34
+ * @param[in] rhs A reference to the moved handle
+ * @return A reference to this
+ */
+ MotionTransformIndex& operator=(MotionTransformIndex&& rhs) noexcept;
+
+ /**
+ * @brief Downcasts an Object handle to MotionTransformIndex.
+ *
+ * If handle points to a MotionTransformIndex, the downcast produces valid handle.
+ * If not, the returned handle is left uninitialized.
+ *
+ * @SINCE_2_2.34
+ * @param[in] handle Handle to an object
+ * @return Handle to a MotionTransformIndex or an uninitialized handle
+ */
+ static MotionTransformIndex DownCast(BaseHandle handle);
+
+public: // Public Method
+ /**
+ * @brief Set the type of transform what this motion index looks.
+ *
+ * @SINCE_2_2.34
+ * @param[in] type The type of transform.
+ */
+ void SetTransformType(TransformType type);
+
+ /**
+ * @brief Get the type of transform what this motion index looks.
+ *
+ * @SINCE_2_2.34
+ * @return The type of transform.
+ */
+ TransformType GetTransformType() const;
+
+public: // Not intended for application developers
+ /// @cond internal
+ /**
+ * @brief Creates a handle using the Scene3D::Internal implementation.
+ *
+ * @param[in] implementation The MotionTransformIndex implementation
+ */
+ DALI_INTERNAL MotionTransformIndex(Dali::Scene3D::Internal::MotionTransformIndex* implementation);
+ /// @endcond
+};
+
+/**
+ * @}
+ */
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_MODEL_MOTION_MOTION_TRANSFORM_INDEX_H
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/public-api/model-motion/motion-value.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/model-motion/motion-value-impl.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+MotionValue MotionValue::New()
+{
+ Internal::MotionValuePtr internal = Internal::MotionValue::New();
+
+ return MotionValue(internal.Get());
+}
+
+MotionValue MotionValue::New(Property::Value propertyValue)
+{
+ Internal::MotionValuePtr internal = Internal::MotionValue::New();
+
+ internal->SetValue(propertyValue);
+
+ return MotionValue(internal.Get());
+}
+
+MotionValue MotionValue::New(KeyFrames keyFrames)
+{
+ Internal::MotionValuePtr internal = Internal::MotionValue::New();
+
+ internal->SetValue(keyFrames);
+
+ return MotionValue(internal.Get());
+}
+
+MotionValue::MotionValue()
+{
+}
+
+MotionValue::MotionValue(const MotionValue& motionValue) = default;
+
+MotionValue::MotionValue(MotionValue&& rhs) noexcept = default;
+
+MotionValue::~MotionValue()
+{
+}
+
+MotionValue& MotionValue::operator=(const MotionValue& handle) = default;
+
+MotionValue& MotionValue::operator=(MotionValue&& rhs) noexcept = default;
+
+MotionValue MotionValue::DownCast(BaseHandle handle)
+{
+ return MotionValue(dynamic_cast<Dali::Scene3D::Internal::MotionValue*>(handle.GetObjectPtr()));
+}
+
+MotionValue::MotionValue(Dali::Scene3D::Internal::MotionValue* internal)
+: BaseHandle(internal)
+{
+}
+
+// Public Method
+
+MotionValue::ValueType MotionValue::GetValueType() const
+{
+ return GetImplementation(*this).GetValueType();
+}
+
+void MotionValue::SetValue(Property::Value propertyValue)
+{
+ GetImplementation(*this).SetValue(propertyValue);
+}
+
+void MotionValue::SetValue(KeyFrames keyFrames)
+{
+ GetImplementation(*this).SetValue(keyFrames);
+}
+
+void MotionValue::Invalidate()
+{
+ Clear();
+}
+
+void MotionValue::Clear()
+{
+ GetImplementation(*this).Clear();
+}
+
+Property::Value MotionValue::GetPropertyValue() const
+{
+ return GetImplementation(*this).GetPropertyValue();
+}
+
+KeyFrames MotionValue::GetKeyFrames() const
+{
+ return GetImplementation(*this).GetKeyFrames();
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_SCENE3D_MODEL_MOTION_MOTION_VALUE_H
+#define DALI_SCENE3D_MODEL_MOTION_MOTION_VALUE_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/animation/key-frames.h>
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/object/base-handle.h>
+#include <dali/public-api/object/property-value.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/api.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+//Forward declarations.
+namespace Internal
+{
+class MotionValue;
+} // namespace Internal
+
+/**
+ * @addtogroup dali_scene3d_model_motion_motion_value
+ * @{
+ */
+
+/**
+ * @brief This MotionValue be used for target value of each MotionIndex.
+ * We can get and set MotionValue as 2 types : Property::Value and KeyFrames.
+ *
+ * Each types will be cross-converted internally.
+ * For example, when we set Property::Value, we can get KeyFrames with 2 frames, and target value is setted.
+ *
+ * @note The type of property should be matched with MotionIndex required.
+ * @SINCE_2_2.34
+ */
+class DALI_SCENE3D_API MotionValue : public Dali::BaseHandle
+{
+public:
+ /**
+ * @brief Determine whether current stored value is PropertyValue, or KeyFrames.
+ * @SINCE_2_2.34
+ */
+ enum class ValueType
+ {
+ INVALID = -1, ///< Value is null, or invalid.
+
+ PROPERTY_VALUE = 0, ///< Value is PropertyValue.
+ KEY_FRAMES, ///< Value is KeyFrames.
+ };
+
+public: // Creation & Destruction
+ /**
+ * @brief Create an initialized MotionValue.
+ *
+ * @SINCE_2_2.34
+ * @return A handle to a newly allocated Dali resource
+ */
+ static MotionValue New();
+
+ /**
+ * @brief Create an initialized MotionValue with Property::Value.
+ *
+ * @SINCE_2_2.34
+ * @param[in] propertyValue The static value.
+ * @return A handle to a newly allocated Dali resource
+ */
+ static MotionValue New(Property::Value propertyValue);
+
+ /**
+ * @brief Create an initialized MotionValue with KeyFrames.
+ *
+ * @SINCE_2_2.34
+ * @param[in] keyFrames The keyframes value.
+ * @return A handle to a newly allocated Dali resource
+ */
+ static MotionValue New(KeyFrames keyFrames);
+
+ /**
+ * @brief Creates an uninitialized MotionValue.
+ *
+ * Only derived versions can be instantiated. Calling member
+ * functions with an uninitialized Dali::Object is not allowed.
+ *
+ * @SINCE_2_2.34
+ */
+ MotionValue();
+
+ /**
+ * @brief Destructor.
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ *
+ * @SINCE_2_2.34
+ */
+ ~MotionValue();
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @SINCE_2_2.34
+ * @param[in] motionValue Handle to an object
+ */
+ MotionValue(const MotionValue& motionValue);
+
+ /**
+ * @brief Move constructor
+ *
+ * @SINCE_2_2.34
+ * @param[in] rhs A reference to the moved handle
+ */
+ MotionValue(MotionValue&& rhs) noexcept;
+
+ /**
+ * @brief Assignment operator.
+ *
+ * @SINCE_2_2.34
+ * @param[in] motionValue Handle to an object
+ * @return reference to this
+ */
+ MotionValue& operator=(const MotionValue& motionValue);
+
+ /**
+ * @brief Move assignment
+ *
+ * @SINCE_2_2.34
+ * @param[in] rhs A reference to the moved handle
+ * @return A reference to this
+ */
+ MotionValue& operator=(MotionValue&& rhs) noexcept;
+
+ /**
+ * @brief Downcasts an Object handle to MotionValue.
+ *
+ * If handle points to a MotionValue, the downcast produces valid handle.
+ * If not, the returned handle is left uninitialized.
+ *
+ * @SINCE_2_2.34
+ * @param[in] handle Handle to an object
+ * @return Handle to a MotionValue or an uninitialized handle
+ */
+ static MotionValue DownCast(BaseHandle handle);
+
+public: // Public Method
+ /**
+ * @brief Get the type of value this MotionValue hold.
+ * The type of value will be changed what we set.
+ *
+ * @SINCE_2_2.34
+ * @return Type of value.
+ */
+ ValueType GetValueType() const;
+
+ /**
+ * @brief Set the value as Property::Value type.
+ *
+ * @SINCE_2_2.34
+ * @param[in] propertyValue The static value.
+ */
+ void SetValue(Property::Value propertyValue);
+
+ /**
+ * @brief Set the value as KeyFrames type.
+ *
+ * @SINCE_2_2.34
+ * @param[in] keyFrames The keyframes value.
+ */
+ void SetValue(KeyFrames keyFrames);
+
+ /**
+ * @brief Make value as Invalid type.
+ *
+ * @SINCE_2_2.34
+ */
+ void Invalidate();
+
+ /**
+ * @brief Make value as Invalid type.
+ * @see Dali::Scene3D::MotionValue::Invalidate()
+ *
+ * @SINCE_2_2.34
+ */
+ void Clear();
+
+ /**
+ * @brief Get the value as Property::Value.
+ * If ValueType is KEY_FRAMES, it will return last value of stored KeyFrames.
+ *
+ * @SINCE_2_2.34
+ * @return Property value, or empty if it is invalid.
+ */
+ Property::Value GetPropertyValue() const;
+
+ /**
+ * @brief Get the value as KeyFrames
+ * If ValueType is PROPERTY_VALUE, it will create new KeyFrames by stored Property::Value.
+ *
+ * @SINCE_2_2.34
+ * @return Keyframes handle, or empty if it is invalid.
+ */
+ KeyFrames GetKeyFrames() const;
+
+public: // Not intended for application developers
+ /// @cond internal
+ /**
+ * @brief Creates a handle using the Scene3D::Internal implementation.
+ *
+ * @param[in] implementation The MotionValue implementation
+ */
+ DALI_INTERNAL MotionValue(Dali::Scene3D::Internal::MotionValue* implementation);
+ /// @endcond
+};
+
+/**
+ * @}
+ */
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_MODEL_MOTION_MOTION_VALUE_H
\ No newline at end of file