From: Adeel Kazmi Date: Fri, 10 Mar 2023 10:30:38 +0000 (+0000) Subject: [dali_2.2.17] Merge branch 'devel/master' X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dca138975014fcdee6e45f541551d99aa406cbf0;hp=c48a946574693335f60a357219b483af864d8091;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git [dali_2.2.17] Merge branch 'devel/master' Change-Id: I5c75b28be1202aa04454b11c09ef37632e4ee94e --- diff --git a/automated-tests/resources/BoxAnimated.glb b/automated-tests/resources/BoxAnimated.glb new file mode 100644 index 0000000..69481ec Binary files /dev/null and b/automated-tests/resources/BoxAnimated.glb differ diff --git a/automated-tests/src/dali-scene3d-internal/CMakeLists.txt b/automated-tests/src/dali-scene3d-internal/CMakeLists.txt index 5af964f..a7a419e 100755 --- a/automated-tests/src/dali-scene3d-internal/CMakeLists.txt +++ b/automated-tests/src/dali-scene3d-internal/CMakeLists.txt @@ -7,7 +7,10 @@ SET(CAPI_LIB "dali-scene3d") # List of test case sources (Only these get parsed for test cases) SET(TC_SOURCES + utc-Dali-DliLoaderImpl.cpp + utc-Dali-GlbLoaderImpl.cpp utc-Dali-Gltf2Asset.cpp + utc-Dali-Gltf2LoaderImpl.cpp utc-Dali-Hash.cpp utc-Dali-JsonReader.cpp utc-Dali-JsonUtil.cpp diff --git a/automated-tests/src/dali-scene3d/utc-Dali-DliLoader.cpp b/automated-tests/src/dali-scene3d-internal/utc-Dali-DliLoaderImpl.cpp similarity index 92% rename from automated-tests/src/dali-scene3d/utc-Dali-DliLoader.cpp rename to automated-tests/src/dali-scene3d-internal/utc-Dali-DliLoaderImpl.cpp index 9d67ab4..0610deb 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-DliLoader.cpp +++ b/automated-tests/src/dali-scene3d-internal/utc-Dali-DliLoaderImpl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,8 +18,8 @@ // Enable debug log for test coverage #define DEBUG_ENABLED 1 +#include #include -#include #include #include #include @@ -34,7 +34,8 @@ namespace void ConfigureBlendShapeShaders(ResourceBundle& resources, const SceneDefinition& scene, Actor root, std::vector&& requests) { std::vector errors; - auto onError = [&errors](const std::string& msg) { + auto onError = [&errors](const std::string& msg) + { errors.push_back(msg); }; @@ -50,7 +51,8 @@ void ConfigureBlendShapeShaders(ResourceBundle& resources, const SceneDefinition struct Context { - ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) { + ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) + { return TEST_RESOURCE_DIR "/"; }; @@ -72,26 +74,21 @@ struct Context cameraParameters, lights}; - DliLoader::InputParams input{ - pathProvider(ResourceType::Mesh), - nullptr, - {}, - {}, - nullptr, - }; - DliLoader::LoadParams loadParams{input, output}; - - std::vector errors; - DliLoader loader; + Dali::Scene3D::Loader::DliInputParameter input; + std::vector errors; + Dali::Scene3D::Loader::Internal::DliLoaderImpl loader; - StringCallback onError = [this](const std::string& error) { + StringCallback onError = [this](const std::string& error) + { errors.push_back(error); printf("%s\n", error.c_str()); }; Context() { + input.mAnimationsPath = pathProvider(ResourceType::Mesh); loader.SetErrorCallback(onError); + loader.SetInputParameter(input); } }; @@ -115,7 +112,7 @@ int UtcDaliDliLoaderLoadSceneNotFound(void) { Context ctx; - DALI_TEST_EQUAL(ctx.loader.LoadScene("does_not_exist.dli", ctx.loadParams), false); + DALI_TEST_EQUAL(ctx.loader.LoadModel("does_not_exist.dli", ctx.output), false); auto error = ctx.loader.GetParseError(); DALI_TEST_CHECK(StringHasTokens(error.c_str(), {"Empty source buffer to parse."})); @@ -128,7 +125,7 @@ int UtcDaliDliLoaderLoadSceneFailParse(void) Context ctx; auto path = ctx.pathProvider(ResourceType::Mesh) + "invalid.gltf"; - DALI_TEST_EQUAL(ctx.loader.LoadScene(path, ctx.loadParams), false); + DALI_TEST_EQUAL(ctx.loader.LoadModel(path, ctx.output), false); auto error = ctx.loader.GetParseError(); DALI_TEST_CHECK(StringHasTokens(error.c_str(), {"Unexpected character."})); @@ -177,7 +174,7 @@ int UtcDaliDliLoaderLoadSceneAssertions(void) auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/" + i.first + ".dli"; printf("\n\n%s: %s\n", path.c_str(), i.second.c_str()); - DALI_TEST_ASSERTION(ctx.loader.LoadScene(path, ctx.loadParams), i.second.c_str()); + DALI_TEST_ASSERTION(ctx.loader.LoadModel(path, ctx.output), i.second.c_str()); } END_TEST; @@ -188,7 +185,7 @@ int UtcDaliDliLoaderLoadSceneExercise(void) Context ctx; auto path = ctx.pathProvider(ResourceType::Mesh) + "exercise.dli"; - DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams)); + DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output)); DALI_TEST_CHECK(ctx.errors.empty()); auto& scene = ctx.scene; @@ -230,8 +227,9 @@ int UtcDaliDliLoaderLoadSceneExercise(void) { auto resourceRefs = resources.CreateRefCounter(); scene.CountResourceRefs(iRoot, choices, resourceRefs); - resources.CountEnvironmentReferences(resourceRefs); - resources.LoadResources(resourceRefs, ctx.pathProvider); + resources.mReferenceCounts = std::move(resourceRefs); + resources.CountEnvironmentReferences(); + resources.LoadResources(ctx.pathProvider); if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams)) { scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor); @@ -256,7 +254,8 @@ int UtcDaliDliLoaderLoadSceneMorph(void) std::vector metadata; uint32_t metadataCount = 0; ctx.input.mPreNodeCategoryProcessors.push_back({"metadata", - [&](const Property::Array& array, StringCallback) { + [&](const Property::Array& array, StringCallback) + { std::string key, value; for(uint32_t i0 = 0, i1 = array.Count(); i0 < i1; ++i0) { @@ -277,7 +276,8 @@ int UtcDaliDliLoaderLoadSceneMorph(void) std::vector behaviors; uint32_t behaviorCount = 0; ctx.input.mPostNodeCategoryProcessors.push_back({"behaviors", - [&](const Property::Array& array, StringCallback) { + [&](const Property::Array& array, StringCallback) + { for(uint32_t i0 = 0, i1 = array.Count(); i0 < i1; ++i0) { auto& data = array.GetElementAt(i0); @@ -295,12 +295,13 @@ int UtcDaliDliLoaderLoadSceneMorph(void) }}); size_t numNodes = 0; - ctx.input.mNodePropertyProcessor = [&](const NodeDefinition&, const Property::Map&, StringCallback) { + ctx.input.mNodePropertyProcessor = [&](const NodeDefinition&, const Property::Map&, StringCallback) + { ++numNodes; }; auto path = ctx.pathProvider(ResourceType::Mesh) + "morph.dli"; - DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams)); + DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output)); DALI_TEST_CHECK(ctx.errors.empty()); auto& scene = ctx.scene; @@ -345,8 +346,9 @@ int UtcDaliDliLoaderLoadSceneMorph(void) { auto resourceRefs = resources.CreateRefCounter(); scene.CountResourceRefs(iRoot, choices, resourceRefs); - resources.CountEnvironmentReferences(resourceRefs); - resources.LoadResources(resourceRefs, ctx.pathProvider); + resources.mReferenceCounts = std::move(resourceRefs); + resources.CountEnvironmentReferences(); + resources.LoadResources(ctx.pathProvider); if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams)) { scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor); @@ -368,7 +370,7 @@ int UtcDaliDliLoaderLoadSceneArc(void) Context ctx; auto path = ctx.pathProvider(ResourceType::Mesh) + "arc.dli"; - DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams)); + DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output)); DALI_TEST_CHECK(ctx.errors.empty()); auto& scene = ctx.scene; @@ -409,8 +411,9 @@ int UtcDaliDliLoaderLoadSceneArc(void) { auto resourceRefs = resources.CreateRefCounter(); scene.CountResourceRefs(iRoot, choices, resourceRefs); - resources.CountEnvironmentReferences(resourceRefs); - resources.LoadResources(resourceRefs, ctx.pathProvider); + resources.mReferenceCounts = std::move(resourceRefs); + resources.CountEnvironmentReferences(); + resources.LoadResources(ctx.pathProvider); if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams)) { scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor); @@ -432,7 +435,7 @@ int UtcDaliDliLoaderLoadSceneShaderUniforms(void) Context ctx; auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/shader-uniforms.dli"; - DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams)); + DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output)); DALI_TEST_EQUAL(ctx.errors.size(), 1u); DALI_TEST_CHECK(ctx.errors[0].find("failed to infer type") != std::string::npos); @@ -475,7 +478,7 @@ int UtcDaliDliLoaderLoadSceneExtras(void) Context ctx; auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/extras.dli"; - DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams)); + DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output)); DALI_TEST_EQUAL(ctx.errors.size(), 3u); DALI_TEST_CHECK(ctx.errors[0].find("already defined; overriding") != std::string::npos); DALI_TEST_CHECK(ctx.errors[1].find("empty string is invalid for name") != std::string::npos); @@ -518,7 +521,7 @@ int UtcDaliDliLoaderLoadSceneConstraints(void) Context ctx; auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/constraints.dli"; - DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams)); + DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output)); DALI_TEST_EQUAL(ctx.errors.size(), 1u); DALI_TEST_CHECK(ctx.errors[0].find("invalid", ctx.errors[0].find("node ID")) != std::string::npos); @@ -576,12 +579,13 @@ int UtcDaliDliLoaderNodeProcessor(void) Context ctx; std::vector nodeMaps; - ctx.input.mNodePropertyProcessor = [&](const NodeDefinition&, Property::Map&& map, StringCallback) { + ctx.input.mNodePropertyProcessor = [&](const NodeDefinition&, Property::Map&& map, StringCallback) + { nodeMaps.push_back(map); }; auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/node-processor.dli"; - DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams)); + DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output)); DALI_TEST_EQUAL(nodeMaps.size(), 2u); DALI_TEST_EQUAL(nodeMaps[0].Count(), 5u); @@ -636,7 +640,7 @@ int UtcDaliDliLoaderLoadCoverageTest(void) Context ctx; auto path = ctx.pathProvider(ResourceType::Mesh) + "coverageTest.dli"; - DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams)); + DALI_TEST_CHECK(ctx.loader.LoadModel(path, ctx.output)); DALI_TEST_CHECK(ctx.errors.empty()); auto& scene = ctx.scene; @@ -688,8 +692,9 @@ int UtcDaliDliLoaderLoadCoverageTest(void) { auto resourceRefs = resources.CreateRefCounter(); scene.CountResourceRefs(iRoot, choices, resourceRefs); - resources.CountEnvironmentReferences(resourceRefs); - resources.LoadResources(resourceRefs, ctx.pathProvider); + resources.mReferenceCounts = std::move(resourceRefs); + resources.CountEnvironmentReferences(); + resources.LoadResources(ctx.pathProvider); if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams)) { scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor); diff --git a/automated-tests/src/dali-scene3d-internal/utc-Dali-GlbLoaderImpl.cpp b/automated-tests/src/dali-scene3d-internal/utc-Dali-GlbLoaderImpl.cpp new file mode 100644 index 0000000..f3d8a93 --- /dev/null +++ b/automated-tests/src/dali-scene3d-internal/utc-Dali-GlbLoaderImpl.cpp @@ -0,0 +1,175 @@ +/* + * 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. + * + */ + +// Enable debug log for test coverage +#define DEBUG_ENABLED 1 + +#include +#include +#include +#include +#include +#include +#include + +using namespace Dali; +using namespace Dali::Scene3D::Loader; + +#define DALI_TEST_THROW(expression, exception, predicate) \ + { \ + bool daliTestThrowSuccess__ = false; \ + try \ + { \ + do \ + { \ + expression; \ + } while(0); \ + printf("No exception was thrown.\n"); \ + } \ + catch(std::decay::type & ex) \ + { \ + daliTestThrowSuccess__ = predicate(ex); \ + } \ + catch(...) \ + { \ + printf("Wrong type of exception thrown.\n"); \ + } \ + DALI_TEST_CHECK(daliTestThrowSuccess__); \ + } + +namespace +{ +struct Context +{ + ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) { + return TEST_RESOURCE_DIR "/"; + }; + + ResourceBundle resources; + SceneDefinition scene; + SceneMetadata metaData; + + std::vector animations; + std::vector animationGroups; + std::vector cameras; + std::vector lights; + + LoadResult loadResult{ + resources, + scene, + metaData, + animations, + animationGroups, + cameras, + lights}; + + Dali::Scene3D::Loader::Internal::GlbLoaderImpl loader; +}; + +struct ExceptionMessageStartsWith +{ + const std::string_view expected; + + bool operator()(const std::runtime_error& e) + { + const bool success = (0 == strncmp(e.what(), expected.data(), expected.size())); + if(!success) + { + printf("Expected: %s, got: %s.\n", expected.data(), e.what()); + } + return success; + } +}; + +} // namespace + +int UtcDaliGlbLoaderFailedToLoad(void) +{ + Context ctx; + + DALI_TEST_EQUAL(ctx.loader.LoadModel("non-existent.glb", ctx.loadResult), false); + + DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size()); + DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount()); + + DALI_TEST_EQUAL(0, ctx.resources.mEnvironmentMaps.size()); + DALI_TEST_EQUAL(0, ctx.resources.mMaterials.size()); + DALI_TEST_EQUAL(0, ctx.resources.mMeshes.size()); + DALI_TEST_EQUAL(0, ctx.resources.mShaders.size()); + DALI_TEST_EQUAL(0, ctx.resources.mSkeletons.size()); + + DALI_TEST_EQUAL(0, ctx.cameras.size()); + DALI_TEST_EQUAL(0, ctx.lights.size()); + DALI_TEST_EQUAL(0, ctx.animations.size()); + DALI_TEST_EQUAL(0, ctx.animationGroups.size()); + + END_TEST; +} + +int UtcDaliGlbLoaderFailedToParse(void) +{ + Context ctx; + + ShaderDefinitionFactory sdf; + sdf.SetResources(ctx.resources); + + DALI_TEST_EQUAL(ctx.loader.LoadModel(TEST_RESOURCE_DIR "/invalid.glb", ctx.loadResult), false); + + DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size()); + DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount()); + + DALI_TEST_EQUAL(0, ctx.resources.mEnvironmentMaps.size()); + DALI_TEST_EQUAL(0, ctx.resources.mMaterials.size()); + DALI_TEST_EQUAL(0, ctx.resources.mMeshes.size()); + DALI_TEST_EQUAL(0, ctx.resources.mShaders.size()); + DALI_TEST_EQUAL(0, ctx.resources.mSkeletons.size()); + + DALI_TEST_EQUAL(0, ctx.cameras.size()); + DALI_TEST_EQUAL(0, ctx.lights.size()); + DALI_TEST_EQUAL(0, ctx.animations.size()); + DALI_TEST_EQUAL(0, ctx.animationGroups.size()); + + END_TEST; +} + +int UtcDaliGlbLoaderSuccess1(void) +{ + Context ctx; + ShaderDefinitionFactory sdf; + sdf.SetResources(ctx.resources); + + ctx.loader.LoadModel(TEST_RESOURCE_DIR "/BoxAnimated.glb", ctx.loadResult); + + DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size()); + DALI_TEST_EQUAL(5u, ctx.scene.GetNodeCount()); + + TestApplication app; + + Customization::Choices choices; + for(auto iRoot : ctx.scene.GetRoots()) + { + auto resourceRefs = ctx.resources.CreateRefCounter(); + ctx.scene.CountResourceRefs(iRoot, choices, resourceRefs); + ctx.resources.mReferenceCounts = std::move(resourceRefs); + ctx.resources.LoadResources(ctx.pathProvider); + } + + DALI_TEST_EQUAL(true, ctx.resources.mMeshes[0u].first.mPositions.IsDefined()); + DALI_TEST_EQUAL(1152, ctx.resources.mMeshes[0u].first.mPositions.mBlob.mLength); + + END_TEST; +} diff --git a/automated-tests/src/dali-scene3d/utc-Dali-Gltf2Loader.cpp b/automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp similarity index 91% rename from automated-tests/src/dali-scene3d/utc-Dali-Gltf2Loader.cpp rename to automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp index bcb61b5..b305a41 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-Gltf2Loader.cpp +++ b/automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp @@ -18,7 +18,7 @@ // Enable debug log for test coverage #define DEBUG_ENABLED 1 -#include +#include #include #include #include @@ -55,7 +55,8 @@ namespace { struct Context { - ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) { + ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) + { return TEST_RESOURCE_DIR "/"; }; @@ -76,6 +77,8 @@ struct Context animationGroups, cameras, lights}; + + Dali::Scene3D::Loader::Internal::Gltf2LoaderImpl loader; }; struct ExceptionMessageStartsWith @@ -99,13 +102,7 @@ int UtcDaliGltfLoaderFailedToLoad(void) { Context ctx; - ShaderDefinitionFactory sdf; - sdf.SetResources(ctx.resources); - - InitializeGltfLoader(); - DALI_TEST_THROW(LoadGltfScene("non-existent.gltf", sdf, ctx.loadResult), - std::runtime_error, - ExceptionMessageStartsWith{"Failed to load"}); + DALI_TEST_EQUAL(ctx.loader.LoadModel("non-existent.gltf", ctx.loadResult), false); DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size()); DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount()); @@ -131,10 +128,7 @@ int UtcDaliGltfLoaderFailedToParse(void) ShaderDefinitionFactory sdf; sdf.SetResources(ctx.resources); - InitializeGltfLoader(); - DALI_TEST_THROW(LoadGltfScene(TEST_RESOURCE_DIR "/invalid.gltf", sdf, ctx.loadResult), - std::runtime_error, - ExceptionMessageStartsWith{"Failed to parse"}); + DALI_TEST_EQUAL(ctx.loader.LoadModel(TEST_RESOURCE_DIR "/invalid.gltf", ctx.loadResult), false); DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size()); DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount()); @@ -172,11 +166,7 @@ int UtcDaliGltfLoaderSuccess1(void) ++metaData; } - ShaderDefinitionFactory sdf; - sdf.SetResources(ctx.resources); - - InitializeGltfLoader(); - LoadGltfScene(TEST_RESOURCE_DIR "/AnimatedCube.gltf", sdf, ctx.loadResult); + ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AnimatedCube.gltf", ctx.loadResult); DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size()); DALI_TEST_EQUAL(9u, ctx.scene.GetNodeCount()); @@ -191,8 +181,9 @@ int UtcDaliGltfLoaderSuccess1(void) { auto resourceRefs = ctx.resources.CreateRefCounter(); ctx.scene.CountResourceRefs(iRoot, choices, resourceRefs); - ctx.resources.CountEnvironmentReferences(resourceRefs); - ctx.resources.LoadResources(resourceRefs, ctx.pathProvider); + ctx.resources.mReferenceCounts = std::move(resourceRefs); + ctx.resources.CountEnvironmentReferences(); + ctx.resources.LoadResources(ctx.pathProvider); } auto& materials = ctx.resources.mMaterials; @@ -466,8 +457,7 @@ int UtcDaliGltfLoaderSuccess2(void) ShaderDefinitionFactory sdf; sdf.SetResources(ctx.resources); - InitializeGltfLoader(); - LoadGltfScene(TEST_RESOURCE_DIR "/AnimatedCubeStride.gltf", sdf, ctx.loadResult); + ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AnimatedCubeStride.gltf", ctx.loadResult); DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size()); DALI_TEST_EQUAL(1u, ctx.scene.GetNodeCount()); @@ -479,7 +469,8 @@ int UtcDaliGltfLoaderSuccess2(void) { auto resourceRefs = ctx.resources.CreateRefCounter(); ctx.scene.CountResourceRefs(iRoot, choices, resourceRefs); - ctx.resources.LoadResources(resourceRefs, ctx.pathProvider); + ctx.resources.mReferenceCounts = std::move(resourceRefs); + ctx.resources.LoadResources(ctx.pathProvider); } DALI_TEST_EQUAL(true, ctx.resources.mMeshes[0u].first.mPositions.IsDefined()); @@ -493,7 +484,8 @@ int UtcDaliGltfLoaderSuccessShort(void) TestApplication app; const std::string resourcePath = TEST_RESOURCE_DIR "/"; - auto pathProvider = [resourcePath](ResourceType::Value) { + auto pathProvider = [resourcePath](ResourceType::Value) + { return resourcePath; }; @@ -517,16 +509,11 @@ int UtcDaliGltfLoaderSuccessShort(void) { Context ctx; - ShaderDefinitionFactory sdf; - auto& resources = ctx.resources; resources.mEnvironmentMaps.push_back({}); - sdf.SetResources(resources); - printf("%s\n", modelName); - InitializeGltfLoader(); - LoadGltfScene(resourcePath + modelName + ".gltf", sdf, ctx.loadResult); + ctx.loader.LoadModel(resourcePath + modelName + ".gltf", ctx.loadResult); DALI_TEST_CHECK(ctx.scene.GetNodeCount() > 0); auto& scene = ctx.scene; @@ -587,8 +574,7 @@ int UtcDaliGltfLoaderMRendererTest(void) sdf.SetResources(ctx.resources); auto& resources = ctx.resources; - InitializeGltfLoader(); - LoadGltfScene(TEST_RESOURCE_DIR "/MRendererTest.gltf", sdf, ctx.loadResult); + ctx.loader.LoadModel(TEST_RESOURCE_DIR "/MRendererTest.gltf", ctx.loadResult); auto& scene = ctx.scene; auto& roots = scene.GetRoots(); @@ -617,8 +603,9 @@ int UtcDaliGltfLoaderMRendererTest(void) { auto resourceRefs = resources.CreateRefCounter(); scene.CountResourceRefs(iRoot, choices, resourceRefs); - resources.CountEnvironmentReferences(resourceRefs); - resources.LoadResources(resourceRefs, ctx.pathProvider); + ctx.resources.mReferenceCounts = std::move(resourceRefs); + ctx.resources.CountEnvironmentReferences(); + ctx.resources.LoadResources(ctx.pathProvider); if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams)) { scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor); @@ -646,12 +633,9 @@ int UtcDaliGltfLoaderAnimationLoadingTest(void) { Context ctx; - ShaderDefinitionFactory sdf; - sdf.SetResources(ctx.resources); auto& resources = ctx.resources; - InitializeGltfLoader(); - LoadGltfScene(TEST_RESOURCE_DIR "/CesiumMan_e.gltf", sdf, ctx.loadResult); + ctx.loader.LoadModel(TEST_RESOURCE_DIR "/CesiumMan_e.gltf", ctx.loadResult); auto& scene = ctx.scene; auto& roots = scene.GetRoots(); @@ -676,8 +660,9 @@ int UtcDaliGltfLoaderAnimationLoadingTest(void) { auto resourceRefs = resources.CreateRefCounter(); scene.CountResourceRefs(iRoot, choices, resourceRefs); - resources.CountEnvironmentReferences(resourceRefs); - resources.LoadResources(resourceRefs, ctx.pathProvider); + resources.mReferenceCounts = std::move(resourceRefs); + resources.CountEnvironmentReferences(); + resources.LoadResources(ctx.pathProvider); if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams)) { scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor); @@ -704,8 +689,7 @@ int UtcDaliGltfLoaderImageFromBufferView(void) sdf.SetResources(ctx.resources); auto& resources = ctx.resources; - InitializeGltfLoader(); - LoadGltfScene(TEST_RESOURCE_DIR "/EnvironmentTest_b.gltf", sdf, ctx.loadResult); + ctx.loader.LoadModel(TEST_RESOURCE_DIR "/EnvironmentTest_b.gltf", ctx.loadResult); auto& scene = ctx.scene; auto& roots = scene.GetRoots(); @@ -730,8 +714,9 @@ int UtcDaliGltfLoaderImageFromBufferView(void) { auto resourceRefs = resources.CreateRefCounter(); scene.CountResourceRefs(iRoot, choices, resourceRefs); - resources.CountEnvironmentReferences(resourceRefs); - resources.LoadResources(resourceRefs, ctx.pathProvider); + resources.mReferenceCounts = std::move(resourceRefs); + resources.CountEnvironmentReferences(); + resources.LoadResources(ctx.pathProvider); if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams)) { scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor); @@ -752,12 +737,9 @@ int UtcDaliGltfLoaderUint8Indices(void) { Context ctx; - ShaderDefinitionFactory sdf; - sdf.SetResources(ctx.resources); auto& resources = ctx.resources; - InitializeGltfLoader(); - LoadGltfScene(TEST_RESOURCE_DIR "/AlphaBlendModeTest.gltf", sdf, ctx.loadResult); + ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AlphaBlendModeTest.gltf", ctx.loadResult); auto& scene = ctx.scene; auto& roots = scene.GetRoots(); @@ -782,8 +764,9 @@ int UtcDaliGltfLoaderUint8Indices(void) { auto resourceRefs = resources.CreateRefCounter(); scene.CountResourceRefs(iRoot, choices, resourceRefs); - resources.CountEnvironmentReferences(resourceRefs); - resources.LoadResources(resourceRefs, ctx.pathProvider); + resources.mReferenceCounts = std::move(resourceRefs); + resources.CountEnvironmentReferences(); + resources.LoadResources(ctx.pathProvider); if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams)) { scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor); diff --git a/automated-tests/src/dali-scene3d/CMakeLists.txt b/automated-tests/src/dali-scene3d/CMakeLists.txt index 707bdd5..66a766a 100755 --- a/automated-tests/src/dali-scene3d/CMakeLists.txt +++ b/automated-tests/src/dali-scene3d/CMakeLists.txt @@ -13,10 +13,8 @@ SET(TC_SOURCES utc-Dali-BvhLoader.cpp utc-Dali-CameraParameters.cpp utc-Dali-EnvironmentMapLoader.cpp - utc-Dali-DliLoader.cpp utc-Dali-EnvironmentDefinition.cpp utc-Dali-FacialAnimation.cpp - utc-Dali-Gltf2Loader.cpp utc-Dali-KtxLoader.cpp utc-Dali-Model.cpp utc-Dali-SceneView.cpp diff --git a/automated-tests/src/dali-scene3d/utc-Dali-Model.cpp b/automated-tests/src/dali-scene3d/utc-Dali-Model.cpp index 7840c74..28b929e 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-Model.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-Model.cpp @@ -54,12 +54,8 @@ const char* TEST_GLTF_FILE_NAME = TEST_RESOURCE_DIR "/Animate const char* TEST_GLTF_ANIMATION_TEST_FILE_NAME = TEST_RESOURCE_DIR "/animationTest.gltf"; const char* TEST_GLTF_MULTIPLE_PRIMITIVE_FILE_NAME = TEST_RESOURCE_DIR "/simpleMultiplePrimitiveTest.gltf"; const char* TEST_DLI_FILE_NAME = TEST_RESOURCE_DIR "/arc.dli"; -// @TODO: The test cases for loading the DLI model below is temporarily disabled. -// Need to fix how resources are loaded when a model contains multiple scenes and -// each scene has its own root node. -#ifdef MULTIPLE_SCENES_MODEL_SUPPORT const char* TEST_DLI_EXERCISE_FILE_NAME = TEST_RESOURCE_DIR "/exercise.dli"; -#endif + /** * For the diffuse and specular cube map texture. * These textures are based off version of Wave engine sample @@ -1011,7 +1007,6 @@ int UtcDaliModelAnimation02(void) int UtcDaliModelAnimation03(void) { -#ifdef MULTIPLE_SCENES_MODEL_SUPPORT ToolkitTestApplication application; Scene3D::Model model = Scene3D::Model::New(TEST_DLI_EXERCISE_FILE_NAME); @@ -1040,16 +1035,12 @@ int UtcDaliModelAnimation03(void) Animation animationByName = model.GetAnimation("idleClip"); DALI_TEST_CHECK(animationByName); DALI_TEST_EQUALS(animationByIndex, animationByName, TEST_LOCATION); -#else - tet_result(TET_PASS); -#endif END_TEST; } int UtcDaliModelCameraGenerate01(void) { -#ifdef MULTIPLE_SCENES_MODEL_SUPPORT ToolkitTestApplication application; Scene3D::Model model = Scene3D::Model::New(TEST_DLI_EXERCISE_FILE_NAME); @@ -1077,9 +1068,6 @@ int UtcDaliModelCameraGenerate01(void) generatedCamera = model.GenerateCamera(1u); // Fail to generate camera DALI_TEST_CHECK(!generatedCamera); -#else - tet_result(TET_PASS); -#endif END_TEST; } diff --git a/automated-tests/src/dali-scene3d/utc-Dali-ResourceBundle.cpp b/automated-tests/src/dali-scene3d/utc-Dali-ResourceBundle.cpp index 20c1bcb..162e48e 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-ResourceBundle.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-ResourceBundle.cpp @@ -18,10 +18,10 @@ // Enable debug log for test coverage #define DEBUG_ENABLED 1 -#include "dali-scene3d/public-api/loader/resource-bundle.h" -#include "dali-scene3d/public-api/loader/utils.h" #include #include +#include "dali-scene3d/public-api/loader/resource-bundle.h" +#include "dali-scene3d/public-api/loader/utils.h" using namespace Dali; using namespace Dali::Scene3D::Loader; @@ -34,9 +34,9 @@ int UtcDaliResourceRefCounts(void) resourceBundle.mMeshes.resize(17); resourceBundle.mMaterials.resize(19); - int i = 0; + int i = 0; std::vector testEnvironmentReferences(resourceBundle.mEnvironmentMaps.size()); - for (auto& m : resourceBundle.mMaterials) + for(auto& m : resourceBundle.mMaterials) { Index iEnv = 0; iEnv += (i % 3) == 0; @@ -56,9 +56,12 @@ int UtcDaliResourceRefCounts(void) DALI_TEST_EQUAL(counter[ResourceType::Material].Size(), resourceBundle.mMaterials.size()); std::fill(counter[ResourceType::Material].begin(), counter[ResourceType::Material].end(), 1u); - resourceBundle.CountEnvironmentReferences(counter); - i = 0; - for (auto& er: counter[ResourceType::Environment]) + resourceBundle.mReferenceCounts = std::move(counter); + resourceBundle.CountEnvironmentReferences(); + + const ResourceRefCounts& referenceCounts = resourceBundle.mReferenceCounts; + i = 0; + for(auto& er : referenceCounts[ResourceType::Environment]) { DALI_TEST_EQUAL(er, testEnvironmentReferences[i]); ++i; diff --git a/automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionFactory.cpp b/automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionFactory.cpp index 12f9605..0a269a5 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionFactory.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionFactory.cpp @@ -24,7 +24,6 @@ #include #include #include -#include "dali-scene3d/public-api/loader/gltf2-loader.h" #include "dali-scene3d/public-api/loader/node-definition.h" #include "dali-scene3d/public-api/loader/resource-bundle.h" #include "dali-scene3d/public-api/loader/shader-definition-factory.h" diff --git a/dali-scene3d/internal/algorithm/navigation-mesh-impl.cpp b/dali-scene3d/internal/algorithm/navigation-mesh-impl.cpp index 7e78094..e3b72d2 100644 --- a/dali-scene3d/internal/algorithm/navigation-mesh-impl.cpp +++ b/dali-scene3d/internal/algorithm/navigation-mesh-impl.cpp @@ -14,31 +14,30 @@ * limitations under the License. */ -// INTERNAL INCLUDES +// CLASS HEADER #include // EXTERNAL INCLUDES #include -#include #include #include #include #include +#include using Dali::Vector3; namespace Dali::Scene3D::Internal::Algorithm { - -using Poly = Dali::Scene3D::Algorithm::NavigationMesh::Face; -using Edge = Dali::Scene3D::Algorithm::NavigationMesh::Edge; +using Poly = Dali::Scene3D::Algorithm::NavigationMesh::Face; +using Edge = Dali::Scene3D::Algorithm::NavigationMesh::Edge; using Vertex = Dali::Scene3D::Algorithm::NavigationMesh::Vertex; // Internal Navigation ray structure struct NavigationRay { - Dali::Vector3 origin; // Origin of ray + Dali::Vector3 origin; // Origin of ray Dali::Vector3 direction; // Direction of ray }; @@ -96,7 +95,7 @@ NavigationMesh::NavigationMesh(const std::vector& buffer) std::copy(buffer.begin(), buffer.end(), mBuffer.begin()); // Setup header from the buffer - mHeader = *reinterpret_cast(mBuffer.data()); + mHeader = *reinterpret_cast(mBuffer.data()); mCurrentFace = Scene3D::Algorithm::NavigationMesh::NULL_FACE; } @@ -225,8 +224,7 @@ bool NavigationMesh::FindFloor(const Dali::Vector3& position, Dali::Vector3& out return false; } - std::sort(results.begin(), results.end(), [](const IntersectResult& lhs, const IntersectResult& rhs) - { return lhs.distance < rhs.distance; }); + std::sort(results.begin(), results.end(), [](const IntersectResult& lhs, const IntersectResult& rhs) { return lhs.distance < rhs.distance; }); outPosition = PointLocalToScene(results.front().point); faceIndex = results.front().faceIndex; @@ -291,7 +289,7 @@ Dali::Vector3 NavigationMesh::PointLocalToScene(const Dali::Vector3& point) Dali::Vector3 NavigationMesh::GetGravityVector() const { - return Dali::Vector3( mHeader.gravityVector ); + return Dali::Vector3(mHeader.gravityVector); } -} \ No newline at end of file +} // namespace Dali::Scene3D::Internal::Algorithm \ No newline at end of file diff --git a/dali-scene3d/internal/algorithm/navigation-mesh-impl.h b/dali-scene3d/internal/algorithm/navigation-mesh-impl.h index 2ba1b6d..f61a922 100644 --- a/dali-scene3d/internal/algorithm/navigation-mesh-impl.h +++ b/dali-scene3d/internal/algorithm/navigation-mesh-impl.h @@ -17,12 +17,9 @@ * limitations under the License. */ -// INTERNAL INCLUDES -#include -#include - -// INTERNAL EXTERNAL +// EXTERNAL EXTERNAL #include +#include #include #include #include @@ -30,8 +27,11 @@ #include #include #include -#include -#include "navigation-mesh-header.h" + +// INTERNAL INCLUDES +#include +#include +#include namespace Dali::Scene3D::Loader { @@ -40,7 +40,6 @@ class NavigationMeshFactory; namespace Dali::Scene3D::Internal::Algorithm { - class NavigationRay; /** @@ -54,7 +53,6 @@ public: using Vertex = Dali::Scene3D::Algorithm::NavigationMesh::Vertex; private: - friend class Scene3D::Loader::NavigationMeshFactory; /** @@ -63,7 +61,6 @@ private: NavigationMesh(const std::vector& buffer); public: - /** * Destructor */ @@ -157,11 +154,11 @@ public: [[nodiscard]] Dali::Vector3 GetGravityVector() const; private: - std::vector mBuffer; //< Data buffer - NavigationMeshHeader_V10 mHeader; //< Navigation mesh header - uint16_t mCurrentFace; //< Current face (last floor position) - Dali::Matrix mTransform; //< Transform matrix - Dali::Matrix mTransformInverse; //< Inverse of the transform matrix + std::vector mBuffer; //< Data buffer + NavigationMeshHeader_V10 mHeader; //< Navigation mesh header + uint16_t mCurrentFace; //< Current face (last floor position) + Dali::Matrix mTransform; //< Transform matrix + Dali::Matrix mTransformInverse; //< Inverse of the transform matrix }; inline Internal::Algorithm::NavigationMesh& GetImplementation(Dali::Scene3D::Algorithm::NavigationMesh& navigationMesh) diff --git a/dali-scene3d/internal/algorithm/path-finder-djikstra.cpp b/dali-scene3d/internal/algorithm/path-finder-djikstra.cpp index 0da6568..7c751ad 100644 --- a/dali-scene3d/internal/algorithm/path-finder-djikstra.cpp +++ b/dali-scene3d/internal/algorithm/path-finder-djikstra.cpp @@ -14,20 +14,21 @@ * limitations under the License. */ -// INTERNAL INCLUDES -#include +// CLASS HEADER #include -#include // EXTERNAL INCLUDES +#include #include -#include + +// INTERNAL INCLUDES +#include +#include using WayPointList = Dali::Scene3D::Algorithm::WayPointList; namespace Dali::Scene3D::Internal::Algorithm { - PathFinderAlgorithmDjikstra::PathFinderAlgorithmDjikstra(Dali::Scene3D::Algorithm::NavigationMesh& navMesh) : mNavigationMesh(&GetImplementation(navMesh)) { @@ -40,7 +41,7 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::FindPath(const Dal { Dali::Vector3 outPosFrom; uint32_t polyIndexFrom; - auto result = mNavigationMesh->FindFloor(positionFrom, outPosFrom, polyIndexFrom); + auto result = mNavigationMesh->FindFloor(positionFrom, outPosFrom, polyIndexFrom); Scene3D::Algorithm::WayPointList waypoints; @@ -57,7 +58,7 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::FindPath(const Dal // replace first and last waypoint auto& wpFrom = static_cast(waypoints[0]); - auto& wpTo = static_cast(waypoints.back()); + auto& wpTo = static_cast(waypoints.back()); Vector2 fromCenter(wpFrom.point3d.x, wpFrom.point3d.y); wpFrom.point3d = outPosFrom; @@ -100,8 +101,7 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::FindPath(uint32_t dist[sourcePolyIndex] = 0.0f; // TO OPTIMIZE WITH PRIORITY QUEUE - auto FindMinDistance = [&nodeQueue](decltype(dist)& dist) - { + auto FindMinDistance = [&nodeQueue](decltype(dist)& dist) { float w = std::numeric_limits::max(); int index = -1; for(auto i = 0u; i < dist.size(); ++i) @@ -215,7 +215,7 @@ void PathFinderAlgorithmDjikstra::PrepareData() auto p2 = edge->face[1]; // One of faces is current face so ignore it - auto p = ((p1 != i) ? p1 : p2); + auto p = ((p1 != i) ? p1 : p2); node.faces[edgeIndex] = p; if(p != ::Dali::Scene3D::Algorithm::NavigationMesh::NULL_FACE) { @@ -248,7 +248,7 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::OptimizeWaypoints( bool finished = false; for(auto j = 0; !finished; ++j) { - auto& startWaypoint = optimizedWaypoints.back(); + auto& startWaypoint = optimizedWaypoints.back(); const auto& startWaypointData = static_cast(startWaypoint); // add new-last waypoint which will be overriden as long as intersection takes place @@ -277,8 +277,8 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::OptimizeWaypoints( { continue; } - auto Pb0 = mNavigationMesh->GetVertex(wp.edge->vertex[0]); - auto Pb1 = mNavigationMesh->GetVertex(wp.edge->vertex[1]); + auto Pb0 = mNavigationMesh->GetVertex(wp.edge->vertex[0]); + auto Pb1 = mNavigationMesh->GetVertex(wp.edge->vertex[1]); auto vPb0 = Dali::Vector2(Pb0->x, Pb0->y); auto vPb1 = Dali::Vector2(Pb1->x, Pb1->y); @@ -292,7 +292,7 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::OptimizeWaypoints( if(!doesIntersect) { optimizedWaypoints.back() = waypoints[wpIndex - 1]; - startIndex = wpIndex - 1; + startIndex = wpIndex - 1; break; } } @@ -300,11 +300,11 @@ Scene3D::Algorithm::WayPointList PathFinderAlgorithmDjikstra::OptimizeWaypoints( for(auto& wp : optimizedWaypoints) { - auto& wpData = static_cast(wp); + auto& wpData = static_cast(wp); wpData.point3d = mNavigationMesh->PointLocalToScene(Dali::Vector3(wpData.face->center)); wpData.point2d = Vector2::ZERO; } return optimizedWaypoints; } -} +} // namespace Dali::Scene3D::Internal::Algorithm diff --git a/dali-scene3d/internal/algorithm/path-finder-spfa-double-way.cpp b/dali-scene3d/internal/algorithm/path-finder-spfa-double-way.cpp index d29a6f2..3b5f844 100644 --- a/dali-scene3d/internal/algorithm/path-finder-spfa-double-way.cpp +++ b/dali-scene3d/internal/algorithm/path-finder-spfa-double-way.cpp @@ -14,15 +14,17 @@ * limitations under the License. */ -// INTERNAL INCLUDES +// CLASS HEADER #include -#include -#include // EXTERNAL INCLUDES +#include #include #include -#include + +// INTERNAL INCLUDES +#include +#include using WayPointList = Dali::Scene3D::Algorithm::WayPointList; diff --git a/dali-scene3d/internal/algorithm/path-finder-spfa.cpp b/dali-scene3d/internal/algorithm/path-finder-spfa.cpp index 977eb90..aa8b3bd 100644 --- a/dali-scene3d/internal/algorithm/path-finder-spfa.cpp +++ b/dali-scene3d/internal/algorithm/path-finder-spfa.cpp @@ -14,14 +14,16 @@ * limitations under the License. */ -// INTERNAL INCLUDES +// CLASS HEADER #include -#include -#include // EXTERNAL INCLUDES +#include #include -#include + +// INTERNAL INCLUDES +#include +#include using WayPointList = Dali::Scene3D::Algorithm::WayPointList; diff --git a/dali-scene3d/internal/algorithm/path-finder-waypoint-data.h b/dali-scene3d/internal/algorithm/path-finder-waypoint-data.h index 53df123..ab5c3b0 100644 --- a/dali-scene3d/internal/algorithm/path-finder-waypoint-data.h +++ b/dali-scene3d/internal/algorithm/path-finder-waypoint-data.h @@ -17,11 +17,9 @@ * limitations under the License. */ -// CLASS HEADER -#include - // INTERNAL INCLUDES #include +#include // EXTERNAL INCLUDES #include @@ -51,6 +49,6 @@ struct WayPointData // internal data needed for processing const NavigationMesh::Edge* edge; ///< Edge between this face and next face }; -} +} // namespace Dali::Scene3D::Internal::Algorithm #endif // DALI_SCENE3D_INTERNAL_PATH_FINDER_WAYPOINT_DATA_H diff --git a/dali-scene3d/internal/common/environment-map-load-task.cpp b/dali-scene3d/internal/common/environment-map-load-task.cpp index d847f46..5ff0d51 100644 --- a/dali-scene3d/internal/common/environment-map-load-task.cpp +++ b/dali-scene3d/internal/common/environment-map-load-task.cpp @@ -21,14 +21,12 @@ // INTERNAL INCLUDES #include - namespace Dali { namespace Scene3D { namespace Internal { - EnvironmentMapLoadTask::EnvironmentMapLoadTask(const std::string& environmentMapUrl, Dali::Scene3D::EnvironmentMapType environmentMapType, CallbackBase* callback) : AsyncTask(callback), mEnvironmentMapUrl(environmentMapUrl), @@ -60,7 +58,7 @@ bool EnvironmentMapLoadTask::HasSucceeded() const Dali::Texture EnvironmentMapLoadTask::GetLoadedTexture() { - return (HasSucceeded()) ? mEnvironmentMapData.GetTexture() : Texture();; + return (HasSucceeded()) ? mEnvironmentMapData.GetTexture() : Texture(); } } // namespace Internal diff --git a/dali-scene3d/internal/common/model-cache-manager.cpp b/dali-scene3d/internal/common/model-cache-manager.cpp index 01d2eba..0a26bcc 100644 --- a/dali-scene3d/internal/common/model-cache-manager.cpp +++ b/dali-scene3d/internal/common/model-cache-manager.cpp @@ -57,12 +57,6 @@ public: return cache.loadSceneConditionalWait; } - Dali::ConditionalWait& GetLoadRawResourceConditionalWaitInstance(std::string modelUri) - { - ModelCache& cache = mModelCache[modelUri]; - return cache.loadRawResourceConditionalWait; - } - void ReferenceModelCache(std::string modelUri) { ModelCache& cache = mModelCache[modelUri]; @@ -129,7 +123,6 @@ private: uint32_t refCount{0}; ///< The reference count of this model cache. Dali::ConditionalWait loadSceneConditionalWait{}; ///< The conditionalWait instance used to synchronise the loading of the scene for the same model in different threads. - Dali::ConditionalWait loadRawResourceConditionalWait{}; ///< The conditionalWait instance used to synchronise the loading of the shared raw resources for the same model in different threads. bool isSceneLoaded{false}; ///< Whether the scene of the model has been loaded. bool isSceneLoading{false}; ///< Whether the scene loading of the model is in progress. @@ -192,12 +185,6 @@ Dali::ConditionalWait& ModelCacheManager::GetLoadSceneConditionalWaitInstance(st return impl.GetLoadSceneConditionalWaitInstance(modelUri); } -Dali::ConditionalWait& ModelCacheManager::GetLoadRawResourceConditionalWaitInstance(std::string modelUri) -{ - ModelCacheManager::Impl& impl = static_cast(GetBaseObject()); - return impl.GetLoadRawResourceConditionalWaitInstance(modelUri); -} - void ModelCacheManager::ReferenceModelCache(std::string modelUri) { ModelCacheManager::Impl& impl = static_cast(GetBaseObject()); diff --git a/dali-scene3d/internal/common/model-cache-manager.h b/dali-scene3d/internal/common/model-cache-manager.h index a427945..0d30b26 100644 --- a/dali-scene3d/internal/common/model-cache-manager.h +++ b/dali-scene3d/internal/common/model-cache-manager.h @@ -86,14 +86,6 @@ public: Dali::ConditionalWait& GetLoadSceneConditionalWaitInstance(std::string modelUri); /** - * @brief Retrieves the ConditionalWait object to synchronize the raw resources loading of the - * model with the given URI between multiple threads. - * @param[in] modelUri The unique model URI with its absolute path. - * @return The ConditionalWait object. - */ - Dali::ConditionalWait& GetLoadRawResourceConditionalWaitInstance(std::string modelUri); - - /** * @brief Reference the cache of the model with the given URI. * This will increment the reference count of the load result by 1. * @param[in] modelUri The model URI. diff --git a/dali-scene3d/internal/common/model-load-task.cpp b/dali-scene3d/internal/common/model-load-task.cpp index aaec429..6456b6d 100644 --- a/dali-scene3d/internal/common/model-load-task.cpp +++ b/dali-scene3d/internal/common/model-load-task.cpp @@ -22,16 +22,6 @@ #include #include -// INTERNAL INCLUDES -#include -#include -#include -#include -#include -#include -#include -#include - namespace Dali { namespace Scene3D @@ -41,20 +31,15 @@ namespace Internal namespace { static constexpr Vector3 Y_DIRECTION(1.0f, -1.0f, 1.0f); - -static constexpr std::string_view OBJ_EXTENSION = ".obj"; -static constexpr std::string_view GLTF_EXTENSION = ".gltf"; -static constexpr std::string_view DLI_EXTENSION = ".dli"; -static constexpr std::string_view METADATA_EXTENSION = "metadata"; } // namespace ModelLoadTask::ModelLoadTask(const std::string& modelUrl, const std::string& resourceDirectoryUrl, CallbackBase* callback) : AsyncTask(callback), mModelUrl(modelUrl), mResourceDirectoryUrl(resourceDirectoryUrl), - mHasSucceeded(false), - mModelCacheManager(ModelCacheManager::Get()), - mLoadResult(mModelCacheManager.GetModelLoadResult(modelUrl)) + mModelCacheManager(Scene3D::Internal::ModelCacheManager::Get()), + mLoadResult(mModelCacheManager.GetModelLoadResult(mModelUrl)), + mHasSucceeded(false) { } @@ -64,124 +49,50 @@ ModelLoadTask::~ModelLoadTask() void ModelLoadTask::Process() { - uint32_t cacheRefCount = mModelCacheManager.GetModelCacheRefCount(mModelUrl); - Dali::ConditionalWait& loadSceneConditionalWait = mModelCacheManager.GetLoadSceneConditionalWaitInstance(mModelUrl); - Dali::ConditionalWait& loadRawResourceConditionalWait = mModelCacheManager.GetLoadRawResourceConditionalWaitInstance(mModelUrl); - - std::filesystem::path modelUrl(mModelUrl); if(mResourceDirectoryUrl.empty()) { + std::filesystem::path modelUrl(mModelUrl); mResourceDirectoryUrl = std::string(modelUrl.parent_path()) + "/"; } - std::string extension = modelUrl.extension(); - std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); Dali::Scene3D::Loader::ResourceBundle::PathProvider pathProvider = [&](Dali::Scene3D::Loader::ResourceType::Value type) { return mResourceDirectoryUrl; }; + mModelLoader = std::make_shared(mModelUrl, mResourceDirectoryUrl, mLoadResult); + + bool loadSucceeded = false; + Dali::ConditionalWait& loadSceneConditionalWait = mModelCacheManager.GetLoadSceneConditionalWaitInstance(mModelUrl); { ConditionalWait::ScopedLock lock(loadSceneConditionalWait); - - while(cacheRefCount > 1 && mModelCacheManager.IsSceneLoading(mModelUrl)) + if(mModelCacheManager.IsSceneLoaded(mModelUrl)) { - loadSceneConditionalWait.Wait(); + loadSucceeded = true; } - } - - { - ConditionalWait::ScopedLock lock(loadSceneConditionalWait); - - if(!mModelCacheManager.IsSceneLoaded(mModelUrl)) + else { mModelCacheManager.SetSceneLoading(mModelUrl, true); - std::filesystem::path metaDataUrl = modelUrl; - metaDataUrl.replace_extension(METADATA_EXTENSION.data()); + loadSucceeded = mModelLoader->LoadModel(pathProvider, true); - Dali::Scene3D::Loader::LoadSceneMetadata(metaDataUrl.c_str(), mLoadResult.mSceneMetadata); - - mLoadResult.mAnimationDefinitions.clear(); - - if(extension == DLI_EXTENSION) + // Mesh of glTF and dli is defined in right hand coordinate system, with positive Y for Up direction. + // Because DALi uses left hand system, Y direciton will be flipped for environment map sampling. + for(auto&& env : GetResources().mEnvironmentMaps) { - Dali::Scene3D::Loader::DliLoader loader; - Dali::Scene3D::Loader::DliLoader::InputParams input{ - pathProvider(Dali::Scene3D::Loader::ResourceType::Mesh), - nullptr, - {}, - {}, - nullptr, - {}}; - Dali::Scene3D::Loader::DliLoader::LoadParams loadParams{input, mLoadResult}; - if(!loader.LoadScene(mModelUrl, loadParams)) - { - DALI_LOG_ERROR("Failed to load scene from '%s': %s\n", mModelUrl.c_str(), loader.GetParseError().c_str()); - - mModelCacheManager.SetSceneLoaded(mModelUrl, false); - mModelCacheManager.SetSceneLoading(mModelUrl, false); - mModelCacheManager.UnreferenceModelCache(mModelUrl); - - return; - } + env.first.mYDirection = Y_DIRECTION; } - else if(extension == GLTF_EXTENSION) - { - Dali::Scene3D::Loader::ShaderDefinitionFactory sdf; - sdf.SetResources(mLoadResult.mResources); - Dali::Scene3D::Loader::LoadGltfScene(mModelUrl, sdf, mLoadResult); - } - else - { - DALI_LOG_ERROR("Unsupported model type.\n"); - - mModelCacheManager.SetSceneLoaded(mModelUrl, false); - mModelCacheManager.SetSceneLoading(mModelUrl, false); - mModelCacheManager.UnreferenceModelCache(mModelUrl); - return; - } - - mModelCacheManager.SetSceneLoaded(mModelUrl, true); mModelCacheManager.SetSceneLoading(mModelUrl, false); + mModelCacheManager.SetSceneLoaded(mModelUrl, loadSucceeded); } } - loadSceneConditionalWait.Notify(); - - { - ConditionalWait::ScopedLock lock(loadRawResourceConditionalWait); - - while(cacheRefCount > 1 && mLoadResult.mResources.mRawResourcesLoading) - { - loadRawResourceConditionalWait.Wait(); - } - } - + if(!loadSucceeded) { - ConditionalWait::ScopedLock lock(loadRawResourceConditionalWait); - - mResourceRefCount = std::move(mLoadResult.mResources.CreateRefCounter()); - - for(auto iRoot : mLoadResult.mScene.GetRoots()) - { - mLoadResult.mScene.CountResourceRefs(iRoot, mResourceChoices, mResourceRefCount); - } - - mLoadResult.mResources.CountEnvironmentReferences(mResourceRefCount); - - mLoadResult.mResources.LoadRawResources(mResourceRefCount, pathProvider); - - // glTF Mesh is defined in right hand coordinate system, with positive Y for Up direction. - // Because DALi uses left hand system, Y direciton will be flipped for environment map sampling. - for(auto&& env : mLoadResult.mResources.mEnvironmentMaps) - { - env.first.mYDirection = Y_DIRECTION; - } + DALI_LOG_ERROR("Failed to load scene from '%s'\n", mModelUrl.c_str()); + return; } - loadRawResourceConditionalWait.Notify(); - mHasSucceeded = true; } @@ -195,6 +106,31 @@ bool ModelLoadTask::HasSucceeded() const return mHasSucceeded; } +Dali::Scene3D::Loader::SceneDefinition& ModelLoadTask::GetScene() const +{ + return mModelLoader->GetScene(); +} + +Dali::Scene3D::Loader::ResourceBundle& ModelLoadTask::GetResources() const +{ + return mModelLoader->GetResources(); +} + +std::vector& ModelLoadTask::GetAnimations() const +{ + return mModelLoader->GetAnimations(); +} + +std::vector& ModelLoadTask::GetCameras() const +{ + return mModelLoader->GetCameras(); +} + +Dali::Scene3D::Loader::Customization::Choices& ModelLoadTask::GetResourceChoices() +{ + return mModelLoader->GetResourceChoices(); +} + } // namespace Internal } // namespace Scene3D diff --git a/dali-scene3d/internal/common/model-load-task.h b/dali-scene3d/internal/common/model-load-task.h index bfafeb0..a880748 100644 --- a/dali-scene3d/internal/common/model-load-task.h +++ b/dali-scene3d/internal/common/model-load-task.h @@ -18,6 +18,7 @@ */ // EXTERNAL INCLUDES +#include #include #include #include @@ -26,9 +27,9 @@ // INTERNAL INCLUDES #include #include +#include #include #include -#include namespace Dali { @@ -72,6 +73,36 @@ public: */ bool HasSucceeded() const; + /** + * @brief Retrieves loaded scene + * @return SceneDefinition that is loaded from file + */ + Dali::Scene3D::Loader::SceneDefinition& GetScene() const; + + /** + * @brief Retrieves resource bunder that includes resource information + * @return ResourceBundle for model resources + */ + Dali::Scene3D::Loader::ResourceBundle& GetResources() const; + + /** + * @brief Retrieves loaded AnimationDefinition + * @return AnimationDefinition that is loaded from file + */ + std::vector& GetAnimations() const; + + /** + * @brief Retrieves loaded CameraParameters + * @return CameraParameters list that is loaded from file + */ + std::vector& GetCameras() const; + + /** + * @brief Retrieves ResourceChoices + * @return Choices for loaded Resources + */ + Dali::Scene3D::Loader::Customization::Choices& GetResourceChoices(); + private: // Undefined ModelLoadTask(const ModelLoadTask& task) = delete; @@ -79,16 +110,12 @@ private: // Undefined ModelLoadTask& operator=(const ModelLoadTask& task) = delete; -public: - std::string mModelUrl; - std::string mResourceDirectoryUrl; - - Dali::Scene3D::Loader::Customization::Choices mResourceChoices; - Dali::Scene3D::Loader::ResourceRefCounts mResourceRefCount; - bool mHasSucceeded; - - ModelCacheManager mModelCacheManager; - Dali::Scene3D::Loader::LoadResult mLoadResult; + std::string mModelUrl; + std::string mResourceDirectoryUrl; + std::shared_ptr mModelLoader; + ModelCacheManager mModelCacheManager; + Dali::Scene3D::Loader::LoadResult mLoadResult; + bool mHasSucceeded; }; } // namespace Internal diff --git a/dali-scene3d/internal/controls/model/model-impl.cpp b/dali-scene3d/internal/controls/model/model-impl.cpp index b7cb6ef..5aa4a5f 100644 --- a/dali-scene3d/internal/controls/model/model-impl.cpp +++ b/dali-scene3d/internal/controls/model/model-impl.cpp @@ -36,8 +36,6 @@ #include #include #include -#include -#include #include #include #include @@ -117,7 +115,8 @@ void ConfigureBlendShapeShaders( Dali::Scene3D::Loader::ResourceBundle& resources, const Dali::Scene3D::Loader::SceneDefinition& scene, Actor root, std::vector&& requests) { std::vector errors; - auto onError = [&errors](const std::string& msg) { errors.push_back(msg); }; + auto onError = [&errors](const std::string& msg) + { errors.push_back(msg); }; if(!scene.ConfigureBlendshapeShaders(resources, root, std::move(requests), onError)) { Dali::Scene3D::Loader::ExceptionFlinger flinger(ASSERT_LOCATION); @@ -447,8 +446,6 @@ void Model::OnSceneConnection(int depth) { ModelCacheManager::Get().ReferenceModelCache(mModelUrl); } - - Scene3D::Loader::InitializeGltfLoader(); mModelLoadTask = new ModelLoadTask(mModelUrl, mResourceDirectoryUrl, MakeCallback(this, &Model::OnModelLoadComplete)); Dali::AsyncTaskManager::Get().AddTask(mModelLoadTask); } @@ -732,13 +729,14 @@ void Model::OnModelLoadComplete() mRenderableActors.clear(); CollectRenderableActor(mModelRoot); - CreateAnimations(mModelLoadTask->mLoadResult.mScene); + auto& resources = mModelLoadTask->GetResources(); + auto& scene = mModelLoadTask->GetScene(); + CreateAnimations(scene); ResetCameraParameters(); - - if(!mModelLoadTask->mLoadResult.mResources.mEnvironmentMaps.empty()) + if(!resources.mEnvironmentMaps.empty()) { - mDefaultDiffuseTexture = mModelLoadTask->mLoadResult.mResources.mEnvironmentMaps.front().second.mDiffuse; - mDefaultSpecularTexture = mModelLoadTask->mLoadResult.mResources.mEnvironmentMaps.front().second.mSpecular; + mDefaultDiffuseTexture = resources.mEnvironmentMaps.front().second.mDiffuse; + mDefaultSpecularTexture = resources.mEnvironmentMaps.front().second.mSpecular; } UpdateImageBasedLightTexture(); @@ -820,26 +818,28 @@ void Model::CreateModel() mModelRoot.SetProperty(Actor::Property::COLOR_MODE, ColorMode::USE_OWN_MULTIPLY_PARENT_COLOR); BoundingVolume AABB; + auto& resources = mModelLoadTask->GetResources(); + auto& scene = mModelLoadTask->GetScene(); + auto& resourceChoices = mModelLoadTask->GetResourceChoices(); Dali::Scene3D::Loader::Transforms xforms{Dali::Scene3D::Loader::MatrixStack{}, Dali::Scene3D::Loader::ViewProjection{}}; - Dali::Scene3D::Loader::NodeDefinition::CreateParams nodeParams{mModelLoadTask->mLoadResult.mResources, xforms, {}, {}, {}}; + Dali::Scene3D::Loader::NodeDefinition::CreateParams nodeParams{resources, xforms, {}, {}, {}}; // Generate Dali handles from resource bundle. Note that we generate all scene's resouce immediatly. - mModelLoadTask->mLoadResult.mResources.GenerateResources(mModelLoadTask->mResourceRefCount); - - for(auto iRoot : mModelLoadTask->mLoadResult.mScene.GetRoots()) + resources.GenerateResources(); + for(auto iRoot : scene.GetRoots()) { - if(auto actor = mModelLoadTask->mLoadResult.mScene.CreateNodes(iRoot, mModelLoadTask->mResourceChoices, nodeParams)) + if(auto actor = scene.CreateNodes(iRoot, resourceChoices, nodeParams)) { - mModelLoadTask->mLoadResult.mScene.ConfigureSkeletonJoints(iRoot, mModelLoadTask->mLoadResult.mResources.mSkeletons, actor); - mModelLoadTask->mLoadResult.mScene.ConfigureSkinningShaders(mModelLoadTask->mLoadResult.mResources, actor, std::move(nodeParams.mSkinnables)); - ConfigureBlendShapeShaders(mModelLoadTask->mLoadResult.mResources, mModelLoadTask->mLoadResult.mScene, actor, std::move(nodeParams.mBlendshapeRequests)); + scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor); + scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables)); + ConfigureBlendShapeShaders(resources, scene, actor, std::move(nodeParams.mBlendshapeRequests)); - mModelLoadTask->mLoadResult.mScene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables)); + scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables)); mModelRoot.Add(actor); } - AddModelTreeToAABB(AABB, mModelLoadTask->mLoadResult.mScene, mModelLoadTask->mResourceChoices, iRoot, nodeParams, Matrix::IDENTITY); + AddModelTreeToAABB(AABB, scene, resourceChoices, iRoot, nodeParams, Matrix::IDENTITY); } mNaturalSize = AABB.CalculateSize(); @@ -857,9 +857,10 @@ void Model::CreateModel() void Model::CreateAnimations(Dali::Scene3D::Loader::SceneDefinition& scene) { mAnimations.clear(); - if(!mModelLoadTask->mLoadResult.mAnimationDefinitions.empty()) + if(!mModelLoadTask->GetAnimations().empty()) { - auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property) { + auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property) + { if(property.mNodeIndex == Scene3D::Loader::INVALID_INDEX) { return mModelRoot.FindChildByName(property.mNodeName); @@ -872,7 +873,7 @@ void Model::CreateAnimations(Dali::Scene3D::Loader::SceneDefinition& scene) return mModelRoot.FindChildById(node->mNodeId); }; - for(auto&& animation : mModelLoadTask->mLoadResult.mAnimationDefinitions) + for(auto&& animation : mModelLoadTask->GetAnimations()) { Dali::Animation anim = animation.ReAnimate(getActor); mAnimations.push_back({animation.mName, anim}); @@ -883,10 +884,10 @@ void Model::CreateAnimations(Dali::Scene3D::Loader::SceneDefinition& scene) void Model::ResetCameraParameters() { mCameraParameters.clear(); - if(!mModelLoadTask->mLoadResult.mCameraParameters.empty()) + if(!mModelLoadTask->GetCameras().empty()) { // Copy camera parameters. - std::copy(mModelLoadTask->mLoadResult.mCameraParameters.begin(), mModelLoadTask->mLoadResult.mCameraParameters.end(), std::back_inserter(mCameraParameters)); + std::copy(mModelLoadTask->GetCameras().begin(), mModelLoadTask->GetCameras().end(), std::back_inserter(mCameraParameters)); } } diff --git a/dali-scene3d/internal/controls/model/model-impl.h b/dali-scene3d/internal/controls/model/model-impl.h index cd1daf5..939de84 100644 --- a/dali-scene3d/internal/controls/model/model-impl.h +++ b/dali-scene3d/internal/controls/model/model-impl.h @@ -263,11 +263,6 @@ private: void ResetResourceTask(IntrusivePtr asyncTask); /** - * @brief Request to load a Ibl texture asynchronously - */ - void RequestLoadIblTexture(EnvironmentMapLoadTaskPtr asyncLoadTask, const std::string& url); - - /** * @brief Notify Resource Ready signal. */ void NotifyResourceReady(); diff --git a/dali-scene3d/internal/file.list b/dali-scene3d/internal/file.list index 85b5cbc..7a6c868 100644 --- a/dali-scene3d/internal/file.list +++ b/dali-scene3d/internal/file.list @@ -10,7 +10,11 @@ set(scene3d_src_files ${scene3d_src_files} ${scene3d_internal_dir}/common/model-load-task.cpp ${scene3d_internal_dir}/controls/model/model-impl.cpp ${scene3d_internal_dir}/controls/scene-view/scene-view-impl.cpp + ${scene3d_internal_dir}/loader/dli-loader-impl.cpp ${scene3d_internal_dir}/loader/gltf2-asset.cpp + ${scene3d_internal_dir}/loader/gltf2-util.cpp + ${scene3d_internal_dir}/loader/gltf2-loader-impl.cpp + ${scene3d_internal_dir}/loader/glb-loader-impl.cpp ${scene3d_internal_dir}/loader/hash.cpp ${scene3d_internal_dir}/loader/json-reader.cpp ${scene3d_internal_dir}/loader/json-util.cpp diff --git a/dali-scene3d/public-api/loader/dli-loader.cpp b/dali-scene3d/internal/loader/dli-loader-impl.cpp similarity index 90% rename from dali-scene3d/public-api/loader/dli-loader.cpp rename to dali-scene3d/internal/loader/dli-loader-impl.cpp index 1a087c9..2285940 100644 --- a/dali-scene3d/public-api/loader/dli-loader.cpp +++ b/dali-scene3d/internal/loader/dli-loader-impl.cpp @@ -16,32 +16,34 @@ */ // CLASS HEADER -#include "dali-scene3d/public-api/loader/dli-loader.h" +#include // EXTERNAL INCLUDES +#include +#include +#include +#include + #include #include +#include #include #include #include -#include "dali-toolkit/devel-api/builder/json-parser.h" -#include "dali/devel-api/common/map-wrapper.h" -#include "dali/integration-api/debug.h" -#include "dali/public-api/object/property-array.h" // INTERNAL INCLUDES -#include "dali-scene3d/internal/loader/json-util.h" -#include "dali-scene3d/public-api/loader/alpha-function-helper.h" -#include "dali-scene3d/public-api/loader/animation-definition.h" -#include "dali-scene3d/public-api/loader/blend-shape-details.h" -#include "dali-scene3d/public-api/loader/camera-parameters.h" -#include "dali-scene3d/public-api/loader/ktx-loader.h" -#include "dali-scene3d/public-api/loader/light-parameters.h" -#include "dali-scene3d/public-api/loader/load-result.h" -#include "dali-scene3d/public-api/loader/parse-renderer-state.h" -#include "dali-scene3d/public-api/loader/scene-definition.h" -#include "dali-scene3d/public-api/loader/skinning-details.h" -#include "dali-scene3d/public-api/loader/utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #define DLI_0_1_COMPATIBILITY @@ -53,6 +55,8 @@ namespace Scene3D { namespace Loader { +namespace Internal +{ namespace rs = RendererState; namespace @@ -109,7 +113,7 @@ bool ReadAttribAccessor(const TreeNode* node, MeshDefinition::Accessor& accessor return ReadBlob(node, accessor.mBlob.mOffset, accessor.mBlob.mLength); } -bool ReadColorCode(const TreeNode* node, Vector4& color, DliLoader::ConvertColorCode convertColorCode) +bool ReadColorCode(const TreeNode* node, Vector4& color, DliInputParameter::ConvertColorCode convertColorCode) { if(!node || !convertColorCode) { @@ -121,7 +125,7 @@ bool ReadColorCode(const TreeNode* node, Vector4& color, DliLoader::ConvertColor return true; } -bool ReadColorCodeOrColor(const TreeNode* node, Vector4& color, DliLoader::ConvertColorCode convertColorCode) +bool ReadColorCodeOrColor(const TreeNode* node, Vector4& color, DliInputParameter::ConvertColorCode convertColorCode) { return ReadColorCode(node->GetChild("colorCode"), color, convertColorCode) || ReadColor(node->GetChild("color"), color); @@ -302,7 +306,7 @@ void ParseProperties(const Toolkit::TreeNode& node, Property::Array& array) } // namespace -struct DliLoader::Impl +struct DliLoaderImpl::Impl { StringCallback mOnError = DefaultErrorCallback; Toolkit::JsonParser mParser; @@ -342,9 +346,9 @@ private: */ void ParseSceneInternal(Index iScene, const Toolkit::TreeNode* tnScenes, const Toolkit::TreeNode* tnNodes, LoadParams& params); - void ParseSkeletons(const Toolkit::TreeNode* skeletons, SceneDefinition& scene, ResourceBundle& resources); - void ParseEnvironments(const Toolkit::TreeNode* environments, ResourceBundle& resources); - void ParseMaterials(const Toolkit::TreeNode* materials, ConvertColorCode convertColorCode, ResourceBundle& resources); + void ParseSkeletons(const Toolkit::TreeNode* skeletons, Dali::Scene3D::Loader::SceneDefinition& scene, Dali::Scene3D::Loader::ResourceBundle& resources); + void ParseEnvironments(const Toolkit::TreeNode* environments, Dali::Scene3D::Loader::ResourceBundle& resources); + void ParseMaterials(const Toolkit::TreeNode* materials, DliInputParameter::ConvertColorCode convertColorCode, Dali::Scene3D::Loader::ResourceBundle& resources); void ParseNodes(const Toolkit::TreeNode* nodes, Index index, LoadParams& params); void ParseNodesInternal(const Toolkit::TreeNode* nodes, Index index, std::vector& inOutParentStack, LoadParams& params, IIndexMapper& indexMapper); @@ -352,26 +356,26 @@ private: void ParseAnimations(const Toolkit::TreeNode* animations, LoadParams& params); void ParseAnimationGroups(const Toolkit::TreeNode* animationGroups, LoadParams& params); - void ParseShaders(const Toolkit::TreeNode* shaders, ResourceBundle& resources); - void ParseMeshes(const Toolkit::TreeNode* meshes, ResourceBundle& resources); + void ParseShaders(const Toolkit::TreeNode* shaders, Dali::Scene3D::Loader::ResourceBundle& resources); + void ParseMeshes(const Toolkit::TreeNode* meshes, Dali::Scene3D::Loader::ResourceBundle& resources); - void GetCameraParameters(std::vector& cameras) const; - void GetLightParameters(std::vector& lights) const; + void GetCameraParameters(std::vector& cameras) const; + void GetLightParameters(std::vector& lights) const; }; -DliLoader::DliLoader() +DliLoaderImpl::DliLoaderImpl() : mImpl{new Impl} { } -DliLoader::~DliLoader() = default; +DliLoaderImpl::~DliLoaderImpl() = default; -void DliLoader::SetErrorCallback(StringCallback onError) +void DliLoaderImpl::SetErrorCallback(StringCallback onError) { mImpl->mOnError = onError; } -bool DliLoader::LoadScene(const std::string& uri, LoadParams& params) +bool DliLoaderImpl::LoadModel(const std::string& uri, Dali::Scene3D::Loader::LoadResult& result) { std::string daliBuffer = LoadTextFile(uri.c_str()); @@ -382,11 +386,25 @@ bool DliLoader::LoadScene(const std::string& uri, LoadParams& params) return false; } - mImpl->ParseScene(params); + std::filesystem::path modelPath(uri); + Dali::Scene3D::Loader::DliInputParameter input; + LoadParams loadParams; + if(mInputParameter) + { + loadParams.input = static_cast(mInputParameter); + } + else + { + input.mAnimationsPath = std::string(modelPath.parent_path()) + "/"; + loadParams.input = &input; + } + loadParams.output = &result; + + mImpl->ParseScene(loadParams); return true; } -std::string DliLoader::GetParseError() const +std::string DliLoaderImpl::GetParseError() const { std::stringstream stream; @@ -399,10 +417,10 @@ std::string DliLoader::GetParseError() const return stream.str(); } -void DliLoader::Impl::ParseScene(LoadParams& params) +void DliLoaderImpl::Impl::ParseScene(LoadParams& params) { - auto& input = params.input; - auto& output = params.output; + auto& input = *params.input; + auto& output = *params.output; // get index of root node. auto docRoot = mParser.GetRoot(); @@ -482,7 +500,7 @@ void DliLoader::Impl::ParseScene(LoadParams& params) } } -void DliLoader::Impl::ParseSceneInternal(Index iScene, const Toolkit::TreeNode* tnScenes, const Toolkit::TreeNode* tnNodes, LoadParams& params) +void DliLoaderImpl::Impl::ParseSceneInternal(Index iScene, const Toolkit::TreeNode* tnScenes, const Toolkit::TreeNode* tnNodes, LoadParams& params) { auto getSceneRootIdx = [tnScenes, tnNodes](Index iScene) { auto tn = GetNthChild(tnScenes, iScene); // now a "scene" object @@ -526,7 +544,7 @@ void DliLoader::Impl::ParseSceneInternal(Index iScene, const Toolkit::TreeNode* Index iRootNode = getSceneRootIdx(iScene); ParseNodes(tnNodes, iRootNode, params); - auto& scene = params.output.mScene; + auto& scene = params.output->mScene; scene.AddRootNode(0); for(Index i = 0; i < iScene; ++i) @@ -547,7 +565,7 @@ void DliLoader::Impl::ParseSceneInternal(Index iScene, const Toolkit::TreeNode* } } -void DliLoader::Impl::ParseSkeletons(const TreeNode* skeletons, SceneDefinition& scene, ResourceBundle& resources) +void DliLoaderImpl::Impl::ParseSkeletons(const TreeNode* skeletons, Dali::Scene3D::Loader::SceneDefinition& scene, Dali::Scene3D::Loader::ResourceBundle& resources) { if(skeletons) { @@ -611,7 +629,7 @@ void DliLoader::Impl::ParseSkeletons(const TreeNode* skeletons, SceneDefinition& } } -void DliLoader::Impl::ParseEnvironments(const TreeNode* environments, ResourceBundle& resources) +void DliLoaderImpl::Impl::ParseEnvironments(const TreeNode* environments, Dali::Scene3D::Loader::ResourceBundle& resources) { Matrix cubeOrientation(Matrix::IDENTITY); @@ -641,7 +659,7 @@ void DliLoader::Impl::ParseEnvironments(const TreeNode* environments, ResourceBu } } -void DliLoader::Impl::ParseShaders(const TreeNode* shaders, ResourceBundle& resources) +void DliLoaderImpl::Impl::ParseShaders(const TreeNode* shaders, Dali::Scene3D::Loader::ResourceBundle& resources) { uint32_t iShader = 0; for(auto i0 = shaders->CBegin(), i1 = shaders->CEnd(); i0 != i1; ++i0, ++iShader) @@ -760,7 +778,7 @@ void DliLoader::Impl::ParseShaders(const TreeNode* shaders, ResourceBundle& reso } } -void DliLoader::Impl::ParseMeshes(const TreeNode* meshes, ResourceBundle& resources) +void DliLoaderImpl::Impl::ParseMeshes(const TreeNode* meshes, Dali::Scene3D::Loader::ResourceBundle& resources) { for(auto i0 = meshes->CBegin(), i1 = meshes->CEnd(); i0 != i1; ++i0) { @@ -918,7 +936,7 @@ void DliLoader::Impl::ParseMeshes(const TreeNode* meshes, ResourceBundle& resour } } -void DliLoader::Impl::ParseMaterials(const TreeNode* materials, ConvertColorCode convertColorCode, ResourceBundle& resources) +void DliLoaderImpl::Impl::ParseMaterials(const TreeNode* materials, DliInputParameter::ConvertColorCode convertColorCode, Dali::Scene3D::Loader::ResourceBundle& resources) { for(auto i0 = materials->CBegin(), i1 = materials->CEnd(); i0 != i1; ++i0) { @@ -1048,7 +1066,7 @@ void DliLoader::Impl::ParseMaterials(const TreeNode* materials, ConvertColorCode } } -void DliLoader::Impl::ParseNodes(const TreeNode* const nodes, Index index, LoadParams& params) +void DliLoaderImpl::Impl::ParseNodes(const TreeNode* const nodes, Index index, LoadParams& params) { std::vector parents; parents.reserve(8); @@ -1097,7 +1115,7 @@ void DliLoader::Impl::ParseNodes(const TreeNode* const nodes, Index index, LoadP } mapper(nodes->Size()); ParseNodesInternal(nodes, index, parents, params, mapper); - auto& scene = params.output.mScene; + auto& scene = params.output->mScene; for(size_t i0 = 0, i1 = scene.GetNodeCount(); i0 < i1; ++i0) { for(auto& c : scene.GetNode(i0)->mConstraints) @@ -1107,7 +1125,7 @@ void DliLoader::Impl::ParseNodes(const TreeNode* const nodes, Index index, LoadP } } -void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index index, std::vector& inOutParentStack, LoadParams& params, IIndexMapper& mapper) +void DliLoaderImpl::Impl::ParseNodesInternal(const TreeNode* const nodes, Index index, std::vector& inOutParentStack, LoadParams& params, IIndexMapper& mapper) { // Properties that may be resolved from a JSON value with ReadInt() -- or default to 0. struct IndexProperty @@ -1121,7 +1139,7 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde if(auto node = GetNthChild(nodes, index)) { - NodeDefinition nodeDef; + Dali::Scene3D::Loader::NodeDefinition nodeDef; nodeDef.mParentIdx = inOutParentStack.empty() ? INVALID_INDEX : inOutParentStack.back(); // name @@ -1151,13 +1169,13 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde std::string tag; if(ReadString(eCustomization->GetChild("tag"), tag)) { - nodeDef.mCustomization.reset(new NodeDefinition::CustomizationDefinition{tag}); + nodeDef.mCustomization.reset(new Dali::Scene3D::Loader::NodeDefinition::CustomizationDefinition{tag}); } } else // something renderable maybe { - std::unique_ptr renderable; - ModelRenderable* modelRenderable = nullptr; // no ownership, aliasing renderable for the right type. + std::unique_ptr renderable; + ModelRenderable* modelRenderable = nullptr; // no ownership, aliasing renderable for the right type. const TreeNode* eRenderable = nullptr; if((eRenderable = node->GetChild("model"))) @@ -1212,9 +1230,9 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde resourceIds.push_back({ResourceType::Material, eMaterial, modelRenderable->mMaterialIdx}); } - if(!ReadColorCodeOrColor(eRenderable, modelRenderable->mColor, params.input.mConvertColorCode)) + if(!ReadColorCodeOrColor(eRenderable, modelRenderable->mColor, params.input->mConvertColorCode)) { - ReadColorCodeOrColor(node, modelRenderable->mColor, params.input.mConvertColorCode); + ReadColorCodeOrColor(node, modelRenderable->mColor, params.input->mConvertColorCode); } } @@ -1230,15 +1248,15 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde switch(idRes.type) { case ResourceType::Shader: - iCheck = output.mResources.mShaders.size(); + iCheck = output->mResources.mShaders.size(); break; case ResourceType::Mesh: - iCheck = output.mResources.mMeshes.size(); + iCheck = output->mResources.mMeshes.size(); break; case ResourceType::Material: - iCheck = output.mResources.mMaterials.size(); + iCheck = output->mResources.mMaterials.size(); break; default: @@ -1273,7 +1291,7 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde for(auto i0 = eExtras->CBegin(), i1 = eExtras->CEnd(); i0 != i1; ++i0) { - NodeDefinition::Extra e; + Dali::Scene3D::Loader::NodeDefinition::Extra e; auto eExtra = *i0; e.mKey = eExtra.first; @@ -1350,7 +1368,7 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde } // Determine index for mapping - const unsigned int myIndex = output.mScene.GetNodeCount(); + const unsigned int myIndex = output->mScene.GetNodeCount(); if(!mapper.Map(index, myIndex)) { mOnError(FormatString("node %d: error mapping dli index %d: node has multiple parents. Ignoring subtree.", index, myIndex)); @@ -1365,7 +1383,7 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde } // Register nodeDef - auto rawDef = output.mScene.AddNode(std::make_unique(std::move(nodeDef))); + auto rawDef = output->mScene.AddNode(std::make_unique(std::move(nodeDef))); if(rawDef) // NOTE: no ownership. Guaranteed to stay in scope. { // ...And only then parse children. @@ -1396,7 +1414,7 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde mOnError(FormatString("node %d: not an actual customization without children.", index)); } - if(auto proc = params.input.mNodePropertyProcessor) // optional processing + if(auto proc = params.input->mNodePropertyProcessor) // optional processing { // WARNING: constraint IDs are not resolved at this point. Property::Map nodeData; @@ -1411,9 +1429,9 @@ void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index inde } } -void DliLoader::Impl::ParseAnimations(const TreeNode* tnAnimations, LoadParams& params) +void DliLoaderImpl::Impl::ParseAnimations(const TreeNode* tnAnimations, LoadParams& params) { - auto& definitions = params.output.mAnimationDefinitions; + auto& definitions = params.output->mAnimationDefinitions; definitions.reserve(definitions.size() + tnAnimations->Size()); for(TreeNode::ConstIterator iAnim = tnAnimations->CBegin(), iAnimEnd = tnAnimations->CEnd(); @@ -1532,7 +1550,7 @@ void DliLoader::Impl::ParseAnimations(const TreeNode* tnAnimations, LoadParams& std::string animationFilename; if(ReadString(tnKeyFramesBin->GetChild(URL), animationFilename)) { - std::string animationFullPath = params.input.mAnimationsPath + animationFilename; + std::string animationFullPath = params.input->mAnimationsPath + animationFilename; binAniFile.open(animationFullPath, std::ios::binary); if(binAniFile.fail()) { @@ -1663,7 +1681,7 @@ void DliLoader::Impl::ParseAnimations(const TreeNode* tnAnimations, LoadParams& iFind = definitions.insert(iFind, std::move(animDef)); } - if(auto proc = params.input.mAnimationPropertyProcessor) // optional processing + if(auto proc = params.input->mAnimationPropertyProcessor) // optional processing { Property::Map map; ParseProperties(tnAnim, map); @@ -1672,9 +1690,9 @@ void DliLoader::Impl::ParseAnimations(const TreeNode* tnAnimations, LoadParams& } } -void DliLoader::Impl::ParseAnimationGroups(const Toolkit::TreeNode* tnAnimationGroups, LoadParams& params) +void DliLoaderImpl::Impl::ParseAnimationGroups(const Toolkit::TreeNode* tnAnimationGroups, LoadParams& params) { - auto& animGroups = params.output.mAnimationGroupDefinitions; + auto& animGroups = params.output->mAnimationGroupDefinitions; int numGroups = 0; for(auto iGroups = tnAnimationGroups->CBegin(), iGroupsEnd = tnAnimationGroups->CEnd(); @@ -1715,7 +1733,7 @@ void DliLoader::Impl::ParseAnimationGroups(const Toolkit::TreeNode* tnAnimationG } } -void DliLoader::Impl::GetCameraParameters(std::vector& cameras) const +void DliLoaderImpl::Impl::GetCameraParameters(std::vector& cameras) const { if(mParser.GetRoot()) { @@ -1751,7 +1769,7 @@ void DliLoader::Impl::GetCameraParameters(std::vector& cameras } } -void DliLoader::Impl::GetLightParameters(std::vector& lights) const +void DliLoaderImpl::Impl::GetLightParameters(std::vector& lights) const { if(mParser.GetRoot()) { @@ -1821,6 +1839,7 @@ void DliLoader::Impl::GetLightParameters(std::vector& lights) c } } +} // namespace Internal } // namespace Loader } // namespace Scene3D } // namespace Dali diff --git a/dali-scene3d/internal/loader/dli-loader-impl.h b/dali-scene3d/internal/loader/dli-loader-impl.h new file mode 100644 index 0000000..ba6b117 --- /dev/null +++ b/dali-scene3d/internal/loader/dli-loader-impl.h @@ -0,0 +1,75 @@ +#ifndef DALI_SCENE3D_LOADER_DLI_LOADER_IMPL_H +#define DALI_SCENE3D_LOADER_DLI_LOADER_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 + +// INTERNAL INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Dali::Scene3D::Loader::Internal +{ +typedef std::pair Metadata; + +// Forward declarations +struct LoadResult; + +class DliLoaderImpl : public ModelLoaderImpl +{ +public: + struct LoadParams + { + Dali::Scene3D::Loader::DliInputParameter* input; + Dali::Scene3D::Loader::LoadResult* output; + }; + + DliLoaderImpl(); + ~DliLoaderImpl(); + + /** + * @brief Sets the callback that messages from non-fatal errors get posted to. + * Uses DefaultErrorCallback by default. + */ + void SetErrorCallback(StringCallback onError); + + /** + * @copydoc Dali::Scene3D::Loader::Internal::ModelLoaderImpl::LoadMode() + */ + bool LoadModel(const std::string& uri, Dali::Scene3D::Loader::LoadResult& result) override; + + /** + * @return The error string describing how the parse has failed, if any. + */ + std::string GetParseError() const; + +private: + struct Impl; + const std::unique_ptr mImpl; +}; + +} // namespace Dali::Scene3D::Loader::Internal + +#endif // DALI_SCENE3D_LOADER_DLI_LOADER_IMPL_H diff --git a/dali-scene3d/internal/loader/glb-loader-impl.cpp b/dali-scene3d/internal/loader/glb-loader-impl.cpp new file mode 100644 index 0000000..deaa91e --- /dev/null +++ b/dali-scene3d/internal/loader/glb-loader-impl.cpp @@ -0,0 +1,140 @@ +/* + * 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. + * + */ + +// FILE HEADER +#include + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include + +namespace gt = gltf2; +namespace js = json; + +namespace Dali::Scene3D::Loader::Internal +{ +namespace +{ +static constexpr uint32_t GLB_MAGIC = 0x46546C67; +static constexpr uint32_t JSON_CHUNK_TYPE = 0x4E4F534A; +static constexpr uint32_t DATA_CHUNK_TYPE = 0x004E4942; + +struct GlbHeader +{ + uint32_t magic; + uint32_t version; + uint32_t length; +}; + +struct ChunkHeader +{ + uint32_t chunkLength; + uint32_t chunkType; +}; + +} // namespace + +bool GlbLoaderImpl::LoadModel(const std::string& url, Dali::Scene3D::Loader::LoadResult& result) +{ + Dali::FileStream fileStream(url, FileStream::READ | FileStream::BINARY); + auto& stream = fileStream.GetStream(); + if(!stream.rdbuf()->in_avail()) + { + DALI_LOG_ERROR("Load Model file is failed, url : %s\n", url.c_str()); + return false; + } + + GlbHeader glbHeader; + stream.clear(); + stream.seekg(0u, stream.beg); + stream.read(reinterpret_cast(&glbHeader), sizeof(GlbHeader)); + + if(glbHeader.magic != GLB_MAGIC) + { + DALI_LOG_ERROR("Wrong file format, url : %s\n", url.c_str()); + return false; + } + + ChunkHeader jsonChunkHeader; + stream.read(reinterpret_cast(&jsonChunkHeader), sizeof(ChunkHeader)); + + if(jsonChunkHeader.chunkType != JSON_CHUNK_TYPE) + { + DALI_LOG_ERROR("Glb files first chunk is not a json chunk.\n"); + return false; + } + + std::vector jsonChunkData; + jsonChunkData.resize(jsonChunkHeader.chunkLength); + stream.read(reinterpret_cast(&jsonChunkData[0]), static_cast(static_cast(jsonChunkHeader.chunkLength))); + std::string gltfText(jsonChunkData.begin(), jsonChunkData.end()); + + uint32_t binaryChunkOffset = sizeof(GlbHeader) + sizeof(ChunkHeader) + jsonChunkHeader.chunkLength; + std::vector binaryChunkData; + if(glbHeader.length > binaryChunkOffset) + { + ChunkHeader binaryChunkHeader; + stream.read(reinterpret_cast(&binaryChunkHeader), sizeof(ChunkHeader)); + + if(binaryChunkHeader.chunkType != DATA_CHUNK_TYPE) + { + DALI_LOG_ERROR("Glb files has wrong binary chunk data.\n"); + return false; + } + + binaryChunkData.resize(binaryChunkHeader.chunkLength); + stream.read(reinterpret_cast(&binaryChunkData[0]), static_cast(static_cast(binaryChunkHeader.chunkLength))); + } + + json::unique_ptr root(json_parse(gltfText.c_str(), gltfText.size())); + if(!root) + { + DALI_LOG_ERROR("Failed to parse %s\n", url.c_str()); + return false; + } + + gt::Document document; + + bool isMRendererModel(false); + if(!Gltf2Util::GenerateDocument(root, document, isMRendererModel)) + { + DALI_LOG_ERROR("Failed to parse %s\n", url.c_str()); + return false; + } + + auto path = url.substr(0, url.rfind('/') + 1); + Gltf2Util::ConversionContext context{result, path, INVALID_INDEX}; + + auto& outBuffers = context.mOutput.mResources.mBuffers; + outBuffers.reserve(document.mBuffers.size()); + if(!binaryChunkData.empty()) + { + BufferDefinition dataBuffer(binaryChunkData); + outBuffers.emplace_back(std::move(dataBuffer)); + } + + Gltf2Util::ConvertGltfToContext(document, context, isMRendererModel); + + return true; +} + +} // namespace Dali::Scene3D::Loader::Internal diff --git a/dali-scene3d/internal/loader/glb-loader-impl.h b/dali-scene3d/internal/loader/glb-loader-impl.h new file mode 100644 index 0000000..05c9d9c --- /dev/null +++ b/dali-scene3d/internal/loader/glb-loader-impl.h @@ -0,0 +1,41 @@ +#ifndef DALI_SCENE3D_LOADER_GLB_LOADER_IMPL_H +#define DALI_SCENE3D_LOADER_GLB_LOADER_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 +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali::Scene3D::Loader::Internal +{ +class GlbLoaderImpl : public ModelLoaderImpl +{ +public: + /** + * @copydoc Dali::Scene3D::Loader::Internal::ModelLoaderImpl::LoadMode() + */ + bool LoadModel(const std::string& url, Dali::Scene3D::Loader::LoadResult& result) override; +}; + +} // namespace Dali::Scene3D::Loader::Internal + +#endif // DALI_SCENE3D_LOADER_GLB_LOADER_IMPL_H diff --git a/dali-scene3d/internal/loader/gltf2-asset.h b/dali-scene3d/internal/loader/gltf2-asset.h index 6576803..7a8af2b 100644 --- a/dali-scene3d/internal/loader/gltf2-asset.h +++ b/dali-scene3d/internal/loader/gltf2-asset.h @@ -17,10 +17,6 @@ * */ -// INTERNAL INCLUDES -#include -#include - // EXTERNAL INCLUDES #include #include @@ -29,6 +25,10 @@ #include #include +// INTERNAL INCLUDES +#include +#include + #define ENUM_STRING_MAPPING(t, x) \ { \ #x, t::x \ diff --git a/dali-scene3d/internal/loader/gltf2-loader-impl.cpp b/dali-scene3d/internal/loader/gltf2-loader-impl.cpp new file mode 100644 index 0000000..d4e0614 --- /dev/null +++ b/dali-scene3d/internal/loader/gltf2-loader-impl.cpp @@ -0,0 +1,67 @@ +/* + * 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. + * + */ + +// FILE HEADER +#include + +// EXTERNAL INCLUDES +#include + +// INTERNAL INCLUDES +#include +#include +#include + +namespace gt = gltf2; +namespace js = json; + +namespace Dali::Scene3D::Loader::Internal +{ +bool Gltf2LoaderImpl::LoadModel(const std::string& url, Dali::Scene3D::Loader::LoadResult& result) +{ + bool failed = false; + auto gltfText = LoadTextFile(url.c_str(), &failed); + if(failed) + { + DALI_LOG_ERROR("Failed to load %s\n", url.c_str()); + return false; + } + + json::unique_ptr root(json_parse(gltfText.c_str(), gltfText.size())); + if(!root) + { + DALI_LOG_ERROR("Failed to parse %s\n", url.c_str()); + return false; + } + + gt::Document document; + + bool isMRendererModel(false); + if(!Gltf2Util::GenerateDocument(root, document, isMRendererModel)) + { + return false; + } + + auto path = url.substr(0, url.rfind('/') + 1); + Gltf2Util::ConversionContext context{result, path, INVALID_INDEX}; + + Gltf2Util::ConvertGltfToContext(document, context, isMRendererModel); + + return true; +} + +} // namespace Dali::Scene3D::Loader::Internal diff --git a/dali-scene3d/internal/loader/gltf2-loader-impl.h b/dali-scene3d/internal/loader/gltf2-loader-impl.h new file mode 100644 index 0000000..a4dfc6e --- /dev/null +++ b/dali-scene3d/internal/loader/gltf2-loader-impl.h @@ -0,0 +1,41 @@ +#ifndef DALI_SCENE3D_LOADER_GLTF2_LOADER_IMPL_H +#define DALI_SCENE3D_LOADER_GLTF2_LOADER_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 +#include + +// INTERNAL INCLUDES +#include +#include + +namespace Dali::Scene3D::Loader::Internal +{ +class Gltf2LoaderImpl : public ModelLoaderImpl +{ +public: + /** + * @copydoc Dali::Scene3D::Loader::Internal::ModelLoaderImpl::LoadMode() + */ + bool LoadModel(const std::string& url, Dali::Scene3D::Loader::LoadResult& result) override; +}; + +} // namespace Dali::Scene3D::Loader::Internal + +#endif // DALI_SCENE3D_LOADER_GLTF2_LOADER_IMPL_H diff --git a/dali-scene3d/internal/loader/gltf2-util.cpp b/dali-scene3d/internal/loader/gltf2-util.cpp new file mode 100644 index 0000000..96925cc --- /dev/null +++ b/dali-scene3d/internal/loader/gltf2-util.cpp @@ -0,0 +1,1321 @@ +/* + * 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 + +// EXTERNAL INCLUDES +#include + +using namespace Dali::Scene3D::Loader; + +namespace Dali::Scene3D::Loader::Internal +{ +namespace Gltf2Util +{ +static constexpr std::string_view MRENDERER_MODEL_IDENTIFICATION = "M-Renderer"; +static constexpr std::string_view POSITION_PROPERTY = "position"; +static constexpr std::string_view ORIENTATION_PROPERTY = "orientation"; +static constexpr std::string_view SCALE_PROPERTY = "scale"; +static constexpr std::string_view BLEND_SHAPE_WEIGHTS_UNIFORM = "uBlendShapeWeight"; +static constexpr std::string_view ROOT_NODE_NAME = "RootNode"; +static const Vector3 SCALE_TO_ADJUST(100.0f, 100.0f, 100.0f); + +static const Geometry::Type GLTF2_TO_DALI_PRIMITIVES[]{ + Geometry::POINTS, + Geometry::LINES, + Geometry::LINE_LOOP, + Geometry::LINE_STRIP, + Geometry::TRIANGLES, + Geometry::TRIANGLE_STRIP, + Geometry::TRIANGLE_FAN}; //...because Dali swaps the last two. + +static struct AttributeMapping +{ + gltf2::Attribute::Type mType; + MeshDefinition::Accessor MeshDefinition::*mAccessor; + uint16_t mElementSizeRequired; +} ATTRIBUTE_MAPPINGS[]{ + {gltf2::Attribute::NORMAL, &MeshDefinition::mNormals, sizeof(Vector3)}, + {gltf2::Attribute::TANGENT, &MeshDefinition::mTangents, sizeof(Vector3)}, + {gltf2::Attribute::TEXCOORD_0, &MeshDefinition::mTexCoords, sizeof(Vector2)}, + {gltf2::Attribute::COLOR_0, &MeshDefinition::mColors, sizeof(Vector4)}, + {gltf2::Attribute::JOINTS_0, &MeshDefinition::mJoints0, sizeof(Vector4)}, + {gltf2::Attribute::WEIGHTS_0, &MeshDefinition::mWeights0, sizeof(Vector4)}, +}; + +std::vector ReadAnimationArray(const json_value_s& j) +{ + auto results = json::Read::Array::Read>(j); + + for(auto& animation : results) + { + for(auto& channel : animation.mChannels) + { + channel.mSampler.UpdateVector(animation.mSamplers); + } + } + + return results; +} + +void ApplyAccessorMinMax(const gltf2::Accessor& acc, float* values) +{ + DALI_ASSERT_ALWAYS(acc.mMax.empty() || gltf2::AccessorType::ElementCount(acc.mType) == acc.mMax.size()); + DALI_ASSERT_ALWAYS(acc.mMin.empty() || gltf2::AccessorType::ElementCount(acc.mType) == acc.mMin.size()); + MeshDefinition::Blob::ApplyMinMax(acc.mMin, acc.mMax, acc.mCount, values); +} + +const auto BUFFER_READER = std::move(json::Reader() + .Register(*json::MakeProperty("byteLength", json::Read::Number, &gltf2::Buffer::mByteLength)) + .Register(*json::MakeProperty("uri", json::Read::StringView, &gltf2::Buffer::mUri))); + +const auto BUFFER_VIEW_READER = std::move(json::Reader() + .Register(*json::MakeProperty("buffer", gltf2::RefReader::Read, &gltf2::BufferView::mBuffer)) + .Register(*json::MakeProperty("byteOffset", json::Read::Number, &gltf2::BufferView::mByteOffset)) + .Register(*json::MakeProperty("byteLength", json::Read::Number, &gltf2::BufferView::mByteLength)) + .Register(*json::MakeProperty("byteStride", json::Read::Number, &gltf2::BufferView::mByteStride)) + .Register(*json::MakeProperty("target", json::Read::Number, &gltf2::BufferView::mTarget))); + +const auto BUFFER_VIEW_CLIENT_READER = std::move(json::Reader() + .Register(*json::MakeProperty("bufferView", gltf2::RefReader::Read, &gltf2::BufferViewClient::mBufferView)) + .Register(*json::MakeProperty("byteOffset", json::Read::Number, &gltf2::BufferViewClient::mByteOffset))); + +const auto COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER = std::move(json::Reader() + .Register(*new json::Property>("bufferView", gltf2::RefReader::Read, &gltf2::ComponentTypedBufferViewClient::mBufferView)) + .Register(*new json::Property("byteOffset", json::Read::Number, &gltf2::ComponentTypedBufferViewClient::mByteOffset)) + .Register(*json::MakeProperty("componentType", json::Read::Enum, &gltf2::ComponentTypedBufferViewClient::mComponentType))); + +const auto ACCESSOR_SPARSE_READER = std::move(json::Reader() + .Register(*json::MakeProperty("count", json::Read::Number, &gltf2::Accessor::Sparse::mCount)) + .Register(*json::MakeProperty("indices", json::ObjectReader::Read, &gltf2::Accessor::Sparse::mIndices)) + .Register(*json::MakeProperty("values", json::ObjectReader::Read, &gltf2::Accessor::Sparse::mValues))); + +const auto ACCESSOR_READER = std::move(json::Reader() + .Register(*new json::Property>("bufferView", + gltf2::RefReader::Read, + &gltf2::Accessor::mBufferView)) + .Register(*new json::Property("byteOffset", + json::Read::Number, + &gltf2::Accessor::mByteOffset)) + .Register(*new json::Property("componentType", + json::Read::Enum, + &gltf2::Accessor::mComponentType)) + .Register(*new json::Property("name", json::Read::StringView, &gltf2::Accessor::mName)) + .Register(*json::MakeProperty("count", json::Read::Number, &gltf2::Accessor::mCount)) + .Register(*json::MakeProperty("normalized", json::Read::Boolean, &gltf2::Accessor::mNormalized)) + .Register(*json::MakeProperty("type", gltf2::ReadStringEnum, &gltf2::Accessor::mType)) + .Register(*json::MakeProperty("min", json::Read::Array, &gltf2::Accessor::mMin)) + .Register(*json::MakeProperty("max", json::Read::Array, &gltf2::Accessor::mMax)) + .Register(*new json::Property("sparse", json::ObjectReader::Read, &gltf2::Accessor::SetSparse))); + +const auto IMAGE_READER = std::move(json::Reader() + .Register(*new json::Property("name", json::Read::StringView, &gltf2::Material::mName)) + .Register(*json::MakeProperty("uri", json::Read::StringView, &gltf2::Image::mUri)) + .Register(*json::MakeProperty("mimeType", json::Read::StringView, &gltf2::Image::mMimeType)) + .Register(*json::MakeProperty("bufferView", gltf2::RefReader::Read, &gltf2::Image::mBufferView))); + +const auto SAMPLER_READER = std::move(json::Reader() + .Register(*json::MakeProperty("minFilter", json::Read::Enum, &gltf2::Sampler::mMinFilter)) + .Register(*json::MakeProperty("magFilter", json::Read::Enum, &gltf2::Sampler::mMagFilter)) + .Register(*json::MakeProperty("wrapS", json::Read::Enum, &gltf2::Sampler::mWrapS)) + .Register(*json::MakeProperty("wrapT", json::Read::Enum, &gltf2::Sampler::mWrapT))); + +const auto TEXURE_READER = std::move(json::Reader() + .Register(*json::MakeProperty("source", gltf2::RefReader::Read, &gltf2::Texture::mSource)) + .Register(*json::MakeProperty("sampler", gltf2::RefReader::Read, &gltf2::Texture::mSampler))); + +const auto TEXURE_INFO_READER = std::move(json::Reader() + .Register(*json::MakeProperty("index", gltf2::RefReader::Read, &gltf2::TextureInfo::mTexture)) + .Register(*json::MakeProperty("texCoord", json::Read::Number, &gltf2::TextureInfo::mTexCoord)) + .Register(*json::MakeProperty("scale", json::Read::Number, &gltf2::TextureInfo::mScale)) + .Register(*json::MakeProperty("strength", json::Read::Number, &gltf2::TextureInfo::mStrength))); + +const auto MATERIAL_PBR_READER = std::move(json::Reader() + .Register(*json::MakeProperty("baseColorFactor", gltf2::ReadDaliVector, &gltf2::Material::Pbr::mBaseColorFactor)) + .Register(*json::MakeProperty("baseColorTexture", json::ObjectReader::Read, &gltf2::Material::Pbr::mBaseColorTexture)) + .Register(*json::MakeProperty("metallicFactor", json::Read::Number, &gltf2::Material::Pbr::mMetallicFactor)) + .Register(*json::MakeProperty("roughnessFactor", json::Read::Number, &gltf2::Material::Pbr::mRoughnessFactor)) + .Register(*json::MakeProperty("metallicRoughnessTexture", json::ObjectReader::Read, &gltf2::Material::Pbr::mMetallicRoughnessTexture))); + +const auto MATERIAL_SPECULAR_READER = std::move(json::Reader() + .Register(*json::MakeProperty("specularFactor", json::Read::Number, &gltf2::MaterialSpecular::mSpecularFactor)) + .Register(*json::MakeProperty("specularTexture", json::ObjectReader::Read, &gltf2::MaterialSpecular::mSpecularTexture)) + .Register(*json::MakeProperty("specularColorFactor", gltf2::ReadDaliVector, &gltf2::MaterialSpecular::mSpecularColorFactor)) + .Register(*json::MakeProperty("specularColorTexture", json::ObjectReader::Read, &gltf2::MaterialSpecular::mSpecularColorTexture))); + +const auto MATERIAL_IOR_READER = std::move(json::Reader() + .Register(*json::MakeProperty("ior", json::Read::Number, &gltf2::MaterialIor::mIor))); + +const auto MATERIAL_EXTENSION_READER = std::move(json::Reader() + .Register(*json::MakeProperty("KHR_materials_ior", json::ObjectReader::Read, &gltf2::MaterialExtensions::mMaterialIor)) + .Register(*json::MakeProperty("KHR_materials_specular", json::ObjectReader::Read, &gltf2::MaterialExtensions::mMaterialSpecular))); + +const auto MATERIAL_READER = std::move(json::Reader() + .Register(*new json::Property("name", json::Read::StringView, &gltf2::Material::mName)) + .Register(*json::MakeProperty("pbrMetallicRoughness", json::ObjectReader::Read, &gltf2::Material::mPbrMetallicRoughness)) + .Register(*json::MakeProperty("normalTexture", json::ObjectReader::Read, &gltf2::Material::mNormalTexture)) + .Register(*json::MakeProperty("occlusionTexture", json::ObjectReader::Read, &gltf2::Material::mOcclusionTexture)) + .Register(*json::MakeProperty("emissiveTexture", json::ObjectReader::Read, &gltf2::Material::mEmissiveTexture)) + .Register(*json::MakeProperty("emissiveFactor", gltf2::ReadDaliVector, &gltf2::Material::mEmissiveFactor)) + .Register(*json::MakeProperty("alphaMode", gltf2::ReadStringEnum, &gltf2::Material::mAlphaMode)) + .Register(*json::MakeProperty("alphaCutoff", json::Read::Number, &gltf2::Material::mAlphaCutoff)) + .Register(*json::MakeProperty("doubleSided", json::Read::Boolean, &gltf2::Material::mDoubleSided)) + .Register(*json::MakeProperty("extensions", json::ObjectReader::Read, &gltf2::Material::mMaterialExtensions))); + +std::map> ReadMeshPrimitiveAttributes(const json_value_s& j) +{ + auto& jo = json::Cast(j); + std::map> result; + + auto i = jo.start; + while(i) + { + auto jstr = *i->name; + result[gltf2::Attribute::FromString(jstr.string, jstr.string_size)] = gltf2::RefReader::Read(*i->value); + i = i->next; + } + return result; +} + +std::vector>> ReadMeshPrimitiveTargets(const json_value_s& j) +{ + auto& jo = json::Cast(j); + std::vector>> result; + + result.reserve(jo.length); + + auto i = jo.start; + while(i) + { + result.push_back(std::move(ReadMeshPrimitiveAttributes(*i->value))); + i = i->next; + } + + return result; +} + +const auto MESH_PRIMITIVE_READER = std::move(json::Reader() + .Register(*json::MakeProperty("attributes", ReadMeshPrimitiveAttributes, &gltf2::Mesh::Primitive::mAttributes)) + .Register(*json::MakeProperty("indices", gltf2::RefReader::Read, &gltf2::Mesh::Primitive::mIndices)) + .Register(*json::MakeProperty("material", gltf2::RefReader::Read, &gltf2::Mesh::Primitive::mMaterial)) + .Register(*json::MakeProperty("mode", json::Read::Enum, &gltf2::Mesh::Primitive::mMode)) + .Register(*json::MakeProperty("targets", ReadMeshPrimitiveTargets, &gltf2::Mesh::Primitive::mTargets))); + +const auto MESH_READER = std::move(json::Reader() + .Register(*new json::Property("name", json::Read::StringView, &gltf2::Mesh::mName)) + .Register(*json::MakeProperty("primitives", + json::Read::Array::Read>, + &gltf2::Mesh::mPrimitives)) + .Register(*json::MakeProperty("weights", json::Read::Array, &gltf2::Mesh::mWeights))); + +const auto SKIN_READER = std::move(json::Reader() + .Register(*new json::Property("name", json::Read::StringView, &gltf2::Skin::mName)) + .Register(*json::MakeProperty("inverseBindMatrices", + gltf2::RefReader::Read, + &gltf2::Skin::mInverseBindMatrices)) + .Register(*json::MakeProperty("skeleton", + gltf2::RefReader::Read, + &gltf2::Skin::mSkeleton)) + .Register(*json::MakeProperty("joints", + json::Read::Array, gltf2::RefReader::Read>, + &gltf2::Skin::mJoints))); + +const auto CAMERA_PERSPECTIVE_READER = std::move(json::Reader() + .Register(*json::MakeProperty("aspectRatio", json::Read::Number, &gltf2::Camera::Perspective::mAspectRatio)) + .Register(*json::MakeProperty("yfov", json::Read::Number, &gltf2::Camera::Perspective::mYFov)) + .Register(*json::MakeProperty("zfar", json::Read::Number, &gltf2::Camera::Perspective::mZFar)) + .Register(*json::MakeProperty("znear", json::Read::Number, &gltf2::Camera::Perspective::mZNear))); // TODO: infinite perspective projection, where znear is omitted + +const auto CAMERA_ORTHOGRAPHIC_READER = std::move(json::Reader() + .Register(*json::MakeProperty("xmag", json::Read::Number, &gltf2::Camera::Orthographic::mXMag)) + .Register(*json::MakeProperty("ymag", json::Read::Number, &gltf2::Camera::Orthographic::mYMag)) + .Register(*json::MakeProperty("zfar", json::Read::Number, &gltf2::Camera::Orthographic::mZFar)) + .Register(*json::MakeProperty("znear", json::Read::Number, &gltf2::Camera::Orthographic::mZNear))); + +const auto CAMERA_READER = std::move(json::Reader() + .Register(*new json::Property("name", json::Read::StringView, &gltf2::Camera::mName)) + .Register(*json::MakeProperty("type", json::Read::StringView, &gltf2::Camera::mType)) + .Register(*json::MakeProperty("perspective", json::ObjectReader::Read, &gltf2::Camera::mPerspective)) + .Register(*json::MakeProperty("orthographic", json::ObjectReader::Read, &gltf2::Camera::mOrthographic))); + +const auto NODE_READER = std::move(json::Reader() + .Register(*new json::Property("name", json::Read::StringView, &gltf2::Node::mName)) + .Register(*json::MakeProperty("translation", gltf2::ReadDaliVector, &gltf2::Node::mTranslation)) + .Register(*json::MakeProperty("rotation", gltf2::ReadQuaternion, &gltf2::Node::mRotation)) + .Register(*json::MakeProperty("scale", gltf2::ReadDaliVector, &gltf2::Node::mScale)) + .Register(*new json::Property("matrix", gltf2::ReadDaliVector, &gltf2::Node::SetMatrix)) + .Register(*json::MakeProperty("camera", gltf2::RefReader::Read, &gltf2::Node::mCamera)) + .Register(*json::MakeProperty("children", json::Read::Array, gltf2::RefReader::Read>, &gltf2::Node::mChildren)) + .Register(*json::MakeProperty("mesh", gltf2::RefReader::Read, &gltf2::Node::mMesh)) + .Register(*json::MakeProperty("skin", gltf2::RefReader::Read, &gltf2::Node::mSkin))); + +const auto ANIMATION_SAMPLER_READER = std::move(json::Reader() + .Register(*json::MakeProperty("input", gltf2::RefReader::Read, &gltf2::Animation::Sampler::mInput)) + .Register(*json::MakeProperty("output", gltf2::RefReader::Read, &gltf2::Animation::Sampler::mOutput)) + .Register(*json::MakeProperty("interpolation", gltf2::ReadStringEnum, &gltf2::Animation::Sampler::mInterpolation))); + +const auto ANIMATION_TARGET_READER = std::move(json::Reader() + .Register(*json::MakeProperty("node", gltf2::RefReader::Read, &gltf2::Animation::Channel::Target::mNode)) + .Register(*json::MakeProperty("path", gltf2::ReadStringEnum, &gltf2::Animation::Channel::Target::mPath))); + +const auto ANIMATION_CHANNEL_READER = std::move(json::Reader() + .Register(*json::MakeProperty("target", json::ObjectReader::Read, &gltf2::Animation::Channel::mTarget)) + .Register(*json::MakeProperty("sampler", gltf2::RefReader::Read, &gltf2::Animation::Channel::mSampler))); + +const auto ANIMATION_READER = std::move(json::Reader() + .Register(*new json::Property("name", json::Read::StringView, &gltf2::Animation::mName)) + .Register(*json::MakeProperty("samplers", + json::Read::Array::Read>, + &gltf2::Animation::mSamplers)) + .Register(*json::MakeProperty("channels", + json::Read::Array::Read>, + &gltf2::Animation::mChannels))); + +const auto SCENE_READER = std::move(json::Reader() + .Register(*new json::Property("name", json::Read::StringView, &gltf2::Scene::mName)) + .Register(*json::MakeProperty("nodes", + json::Read::Array, gltf2::RefReader::Read>, + &gltf2::Scene::mNodes))); + +const auto DOCUMENT_READER = std::move(json::Reader() + .Register(*json::MakeProperty("buffers", + json::Read::Array::Read>, + &gltf2::Document::mBuffers)) + .Register(*json::MakeProperty("bufferViews", + json::Read::Array::Read>, + &gltf2::Document::mBufferViews)) + .Register(*json::MakeProperty("accessors", + json::Read::Array::Read>, + &gltf2::Document::mAccessors)) + .Register(*json::MakeProperty("images", + json::Read::Array::Read>, + &gltf2::Document::mImages)) + .Register(*json::MakeProperty("samplers", + json::Read::Array::Read>, + &gltf2::Document::mSamplers)) + .Register(*json::MakeProperty("textures", + json::Read::Array::Read>, + &gltf2::Document::mTextures)) + .Register(*json::MakeProperty("materials", + json::Read::Array::Read>, + &gltf2::Document::mMaterials)) + .Register(*json::MakeProperty("meshes", + json::Read::Array::Read>, + &gltf2::Document::mMeshes)) + .Register(*json::MakeProperty("skins", + json::Read::Array::Read>, + &gltf2::Document::mSkins)) + .Register(*json::MakeProperty("cameras", + json::Read::Array::Read>, + &gltf2::Document::mCameras)) + .Register(*json::MakeProperty("nodes", + json::Read::Array::Read>, + &gltf2::Document::mNodes)) + .Register(*json::MakeProperty("animations", + ReadAnimationArray, + &gltf2::Document::mAnimations)) + .Register(*json::MakeProperty("scenes", + json::Read::Array::Read>, + &gltf2::Document::mScenes)) + .Register(*json::MakeProperty("scene", gltf2::RefReader::Read, &gltf2::Document::mScene))); + +void ConvertBuffer(const gltf2::Buffer& buffer, decltype(ResourceBundle::mBuffers)& outBuffers, const std::string& resourcePath) +{ + BufferDefinition bufferDefinition; + + bufferDefinition.mResourcePath = resourcePath; + bufferDefinition.mUri = buffer.mUri; + bufferDefinition.mByteLength = buffer.mByteLength; + + outBuffers.emplace_back(std::move(bufferDefinition)); +} + +void ConvertBuffers(const gltf2::Document& doc, ConversionContext& context) +{ + auto& outBuffers = context.mOutput.mResources.mBuffers; + outBuffers.reserve(doc.mBuffers.size()); + + for(auto& buffer : doc.mBuffers) + { + if(buffer.mUri.empty()) + { + continue; + } + ConvertBuffer(buffer, outBuffers, context.mPath); + } +} + +SamplerFlags::Type ConvertWrapMode(gltf2::Wrap::Type wrapMode) +{ + switch(wrapMode) + { + case gltf2::Wrap::REPEAT: + return SamplerFlags::WRAP_REPEAT; + case gltf2::Wrap::CLAMP_TO_EDGE: + return SamplerFlags::WRAP_CLAMP; + case gltf2::Wrap::MIRRORED_REPEAT: + return SamplerFlags::WRAP_MIRROR; + default: + throw std::runtime_error("Invalid wrap type."); + } +} + +SamplerFlags::Type ConvertSampler(const gltf2::Ref& sampler) +{ + if(sampler) + { + return ((sampler->mMinFilter < gltf2::Filter::NEAREST_MIPMAP_NEAREST) ? (sampler->mMinFilter - gltf2::Filter::NEAREST) : ((sampler->mMinFilter - gltf2::Filter::NEAREST_MIPMAP_NEAREST) + 2)) | + ((sampler->mMagFilter - gltf2::Filter::NEAREST) << SamplerFlags::FILTER_MAG_SHIFT) | + (ConvertWrapMode(sampler->mWrapS) << SamplerFlags::WRAP_S_SHIFT) | + (ConvertWrapMode(sampler->mWrapT) << SamplerFlags::WRAP_T_SHIFT); + } + else + { + // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#texturesampler + // "The index of the sampler used by this texture. When undefined, a sampler with repeat wrapping and auto filtering should be used." + // "What is an auto filtering", I hear you ask. Since there's nothing else to determine mipmapping from - including glTF image + // properties, if not in some extension -, we will simply assume linear filtering. + return SamplerFlags::FILTER_LINEAR | (SamplerFlags::FILTER_LINEAR << SamplerFlags::FILTER_MAG_SHIFT) | + (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_S_SHIFT) | (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_T_SHIFT); + } +} + +TextureDefinition ConvertTextureInfo(const gltf2::TextureInfo& mm, ConversionContext& context, const ImageMetadata& metaData = ImageMetadata()) +{ + TextureDefinition textureDefinition; + std::string uri = std::string(mm.mTexture->mSource->mUri); + if(uri.empty()) + { + uint32_t bufferIndex = mm.mTexture->mSource->mBufferView->mBuffer.GetIndex(); + if(bufferIndex != INVALID_INDEX && context.mOutput.mResources.mBuffers[bufferIndex].IsAvailable()) + { + auto& stream = context.mOutput.mResources.mBuffers[bufferIndex].GetBufferStream(); + stream.clear(); + stream.seekg(mm.mTexture->mSource->mBufferView->mByteOffset, stream.beg); + std::vector dataBuffer; + dataBuffer.resize(mm.mTexture->mSource->mBufferView->mByteLength); + stream.read(reinterpret_cast(dataBuffer.data()), static_cast(static_cast(mm.mTexture->mSource->mBufferView->mByteLength))); + return TextureDefinition{std::move(dataBuffer), ConvertSampler(mm.mTexture->mSampler), metaData.mMinSize, metaData.mSamplingMode}; + } + return TextureDefinition(); + } + else + { + return TextureDefinition{uri, ConvertSampler(mm.mTexture->mSampler), metaData.mMinSize, metaData.mSamplingMode}; + } +} + +void ConvertMaterial(const gltf2::Material& material, const std::unordered_map& imageMetaData, decltype(ResourceBundle::mMaterials)& outMaterials, ConversionContext& context) +{ + auto getTextureMetaData = [](const std::unordered_map& metaData, const gltf2::TextureInfo& info) { + if(!info.mTexture->mSource->mUri.empty()) + { + if(auto search = metaData.find(info.mTexture->mSource->mUri.data()); search != metaData.end()) + { + return search->second; + } + } + return ImageMetadata(); + }; + + MaterialDefinition matDef; + + auto& pbr = material.mPbrMetallicRoughness; + if(material.mAlphaMode == gltf2::AlphaMode::BLEND) + { + matDef.mIsOpaque = false; + matDef.mFlags |= MaterialDefinition::TRANSPARENCY; + } + else if(material.mAlphaMode == gltf2::AlphaMode::MASK) + { + matDef.mIsMask = true; + matDef.SetAlphaCutoff(std::min(1.f, std::max(0.f, material.mAlphaCutoff))); + } + + matDef.mBaseColorFactor = pbr.mBaseColorFactor; + + matDef.mTextureStages.reserve(!!pbr.mBaseColorTexture + !!pbr.mMetallicRoughnessTexture + !!material.mNormalTexture + !!material.mOcclusionTexture + !!material.mEmissiveTexture); + if(pbr.mBaseColorTexture) + { + const auto semantic = MaterialDefinition::ALBEDO; + matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(pbr.mBaseColorTexture, context, getTextureMetaData(imageMetaData, pbr.mBaseColorTexture))}); + // TODO: and there had better be one + matDef.mFlags |= semantic; + } + else + { + matDef.mNeedAlbedoTexture = false; + } + + matDef.mMetallic = pbr.mMetallicFactor; + matDef.mRoughness = pbr.mRoughnessFactor; + + if(pbr.mMetallicRoughnessTexture) + { + const auto semantic = MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | + MaterialDefinition::GLTF_CHANNELS; + matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(pbr.mMetallicRoughnessTexture, context, getTextureMetaData(imageMetaData, pbr.mMetallicRoughnessTexture))}); + // TODO: and there had better be one + matDef.mFlags |= semantic; + } + else + { + matDef.mNeedMetallicRoughnessTexture = false; + } + + matDef.mNormalScale = material.mNormalTexture.mScale; + if(material.mNormalTexture) + { + const auto semantic = MaterialDefinition::NORMAL; + matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mNormalTexture, context, getTextureMetaData(imageMetaData, material.mNormalTexture))}); + // TODO: and there had better be one + matDef.mFlags |= semantic; + } + else + { + matDef.mNeedNormalTexture = false; + } + + if(material.mOcclusionTexture) + { + const auto semantic = MaterialDefinition::OCCLUSION; + matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mOcclusionTexture, context, getTextureMetaData(imageMetaData, material.mOcclusionTexture))}); + // TODO: and there had better be one + matDef.mFlags |= semantic; + matDef.mOcclusionStrength = material.mOcclusionTexture.mStrength; + } + + if(material.mEmissiveTexture) + { + const auto semantic = MaterialDefinition::EMISSIVE; + matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mEmissiveTexture, context, getTextureMetaData(imageMetaData, material.mEmissiveTexture))}); + // TODO: and there had better be one + matDef.mFlags |= semantic; + matDef.mEmissiveFactor = material.mEmissiveFactor; + } + + if(!Dali::Equals(material.mMaterialExtensions.mMaterialIor.mIor, gltf2::UNDEFINED_FLOAT_VALUE)) + { + float ior = material.mMaterialExtensions.mMaterialIor.mIor; + matDef.mDielectricSpecular = powf((ior - 1.0f) / (ior + 1.0f), 2.0f); + } + matDef.mSpecularFactor = material.mMaterialExtensions.mMaterialSpecular.mSpecularFactor; + matDef.mSpecularColorFactor = material.mMaterialExtensions.mMaterialSpecular.mSpecularColorFactor; + + if(material.mMaterialExtensions.mMaterialSpecular.mSpecularTexture) + { + const auto semantic = MaterialDefinition::SPECULAR; + matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mMaterialExtensions.mMaterialSpecular.mSpecularTexture, context, getTextureMetaData(imageMetaData, material.mMaterialExtensions.mMaterialSpecular.mSpecularTexture))}); + matDef.mFlags |= semantic; + } + + if(material.mMaterialExtensions.mMaterialSpecular.mSpecularColorTexture) + { + const auto semantic = MaterialDefinition::SPECULAR_COLOR; + matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mMaterialExtensions.mMaterialSpecular.mSpecularColorTexture, context, getTextureMetaData(imageMetaData, material.mMaterialExtensions.mMaterialSpecular.mSpecularColorTexture))}); + matDef.mFlags |= semantic; + } + + matDef.mDoubleSided = material.mDoubleSided; + + outMaterials.emplace_back(std::move(matDef), TextureSet()); +} + +void ConvertMaterials(const gltf2::Document& doc, ConversionContext& context) +{ + auto& imageMetaData = context.mOutput.mSceneMetadata.mImageMetadata; + + auto& outMaterials = context.mOutput.mResources.mMaterials; + outMaterials.reserve(doc.mMaterials.size()); + + for(auto& m : doc.mMaterials) + { + ConvertMaterial(m, imageMetaData, outMaterials, context); + } +} + +MeshDefinition::Accessor ConvertMeshPrimitiveAccessor(const gltf2::Accessor& acc) +{ + DALI_ASSERT_ALWAYS((acc.mBufferView && + (acc.mBufferView->mByteStride < std::numeric_limits::max())) || + (acc.mSparse && !acc.mBufferView)); + + DALI_ASSERT_ALWAYS(!acc.mSparse || + ((acc.mSparse->mIndices.mBufferView && (acc.mSparse->mIndices.mBufferView->mByteStride < std::numeric_limits::max())) && + (acc.mSparse->mValues.mBufferView && (acc.mSparse->mValues.mBufferView->mByteStride < std::numeric_limits::max())))); + + MeshDefinition::SparseBlob sparseBlob; + if(acc.mSparse) + { + const gltf2::Accessor::Sparse& sparse = *acc.mSparse; + const gltf2::ComponentTypedBufferViewClient& indices = sparse.mIndices; + const gltf2::BufferViewClient& values = sparse.mValues; + + MeshDefinition::Blob indicesBlob( + indices.mBufferView->mByteOffset + indices.mByteOffset, + sparse.mCount * indices.GetBytesPerComponent(), + static_cast(indices.mBufferView->mByteStride), + static_cast(indices.GetBytesPerComponent()), + {}, + {}); + MeshDefinition::Blob valuesBlob( + values.mBufferView->mByteOffset + values.mByteOffset, + sparse.mCount * acc.GetElementSizeBytes(), + static_cast(values.mBufferView->mByteStride), + static_cast(acc.GetElementSizeBytes()), + {}, + {}); + + sparseBlob = std::move(MeshDefinition::SparseBlob(std::move(indicesBlob), std::move(valuesBlob), acc.mSparse->mCount)); + } + + uint32_t bufferViewOffset = 0u; + uint32_t bufferViewStride = 0u; + if(acc.mBufferView) + { + bufferViewOffset = acc.mBufferView->mByteOffset; + bufferViewStride = acc.mBufferView->mByteStride; + } + + return MeshDefinition::Accessor{ + std::move(MeshDefinition::Blob{bufferViewOffset + acc.mByteOffset, + acc.GetBytesLength(), + static_cast(bufferViewStride), + static_cast(acc.GetElementSizeBytes()), + acc.mMin, + acc.mMax}), + std::move(sparseBlob), + acc.mBufferView ? acc.mBufferView->mBuffer.GetIndex() : 0}; +} + +void ConvertMeshes(const gltf2::Document& doc, ConversionContext& context) +{ + uint32_t meshCount = 0; + context.mMeshIds.reserve(doc.mMeshes.size()); + for(auto& mesh : doc.mMeshes) + { + context.mMeshIds.push_back(meshCount); + meshCount += mesh.mPrimitives.size(); + } + + auto& outMeshes = context.mOutput.mResources.mMeshes; + outMeshes.reserve(meshCount); + for(auto& mesh : doc.mMeshes) + { + for(auto& primitive : mesh.mPrimitives) + { + MeshDefinition meshDefinition; + + auto& attribs = primitive.mAttributes; + meshDefinition.mPrimitiveType = GLTF2_TO_DALI_PRIMITIVES[primitive.mMode]; + + auto& accPositions = *attribs.find(gltf2::Attribute::POSITION)->second; + meshDefinition.mPositions = ConvertMeshPrimitiveAccessor(accPositions); + // glTF2 support vector4 tangent for mesh. + // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#meshes-overview + meshDefinition.mTangentType = Property::VECTOR4; + + const bool needNormalsTangents = accPositions.mType == gltf2::AccessorType::VEC3; + for(auto& am : ATTRIBUTE_MAPPINGS) + { + auto iFind = attribs.find(am.mType); + if(iFind != attribs.end()) + { + auto& accessor = meshDefinition.*(am.mAccessor); + accessor = ConvertMeshPrimitiveAccessor(*iFind->second); + + if(iFind->first == gltf2::Attribute::JOINTS_0) + { + meshDefinition.mFlags |= (iFind->second->mComponentType == gltf2::Component::UNSIGNED_SHORT) * MeshDefinition::U16_JOINT_IDS; + meshDefinition.mFlags |= (iFind->second->mComponentType == gltf2::Component::UNSIGNED_BYTE) * MeshDefinition::U8_JOINT_IDS; + DALI_ASSERT_DEBUG(MaskMatch(meshDefinition.mFlags, MeshDefinition::U16_JOINT_IDS) || MaskMatch(meshDefinition.mFlags, MeshDefinition::U8_JOINT_IDS) || iFind->second->mComponentType == gltf2::Component::FLOAT); + } + } + else if(needNormalsTangents) + { + switch(am.mType) + { + case gltf2::Attribute::NORMAL: + meshDefinition.RequestNormals(); + break; + + case gltf2::Attribute::TANGENT: + meshDefinition.RequestTangents(); + break; + + default: + break; + } + } + } + + if(primitive.mIndices) + { + meshDefinition.mIndices = ConvertMeshPrimitiveAccessor(*primitive.mIndices); + meshDefinition.mFlags |= (primitive.mIndices->mComponentType == gltf2::Component::UNSIGNED_INT) * MeshDefinition::U32_INDICES; + meshDefinition.mFlags |= (primitive.mIndices->mComponentType == gltf2::Component::UNSIGNED_BYTE) * MeshDefinition::U8_INDICES; + DALI_ASSERT_DEBUG(MaskMatch(meshDefinition.mFlags, MeshDefinition::U32_INDICES) || MaskMatch(meshDefinition.mFlags, MeshDefinition::U8_INDICES) || primitive.mIndices->mComponentType == gltf2::Component::UNSIGNED_SHORT); + } + + if(!primitive.mTargets.empty()) + { + meshDefinition.mBlendShapes.reserve(primitive.mTargets.size()); + meshDefinition.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0; + for(const auto& target : primitive.mTargets) + { + MeshDefinition::BlendShape blendShape; + + auto endIt = target.end(); + auto it = target.find(gltf2::Attribute::POSITION); + if(it != endIt) + { + blendShape.deltas = ConvertMeshPrimitiveAccessor(*it->second); + } + it = target.find(gltf2::Attribute::NORMAL); + if(it != endIt) + { + blendShape.normals = ConvertMeshPrimitiveAccessor(*it->second); + } + it = target.find(gltf2::Attribute::TANGENT); + if(it != endIt) + { + blendShape.tangents = ConvertMeshPrimitiveAccessor(*it->second); + } + + if(!mesh.mWeights.empty()) + { + blendShape.weight = mesh.mWeights[meshDefinition.mBlendShapes.size()]; + } + + meshDefinition.mBlendShapes.push_back(std::move(blendShape)); + } + } + + outMeshes.push_back({std::move(meshDefinition), MeshGeometry{}}); + } + } +} + +ModelRenderable* MakeModelRenderable(const gltf2::Mesh::Primitive& prim, ConversionContext& context) +{ + auto modelRenderable = new ModelRenderable(); + + modelRenderable->mShaderIdx = 0; // TODO: further thought + + auto materialIdx = prim.mMaterial.GetIndex(); + if(INVALID_INDEX == materialIdx) + { + // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#default-material + if(INVALID_INDEX == context.mDefaultMaterial) + { + auto& outMaterials = context.mOutput.mResources.mMaterials; + context.mDefaultMaterial = outMaterials.size(); + + ConvertMaterial(gltf2::Material{}, context.mOutput.mSceneMetadata.mImageMetadata, outMaterials, context); + } + + materialIdx = context.mDefaultMaterial; + } + + modelRenderable->mMaterialIdx = materialIdx; + + return modelRenderable; +} + +void ConvertCamera(const gltf2::Camera& camera, CameraParameters& camParams) +{ + camParams.isPerspective = camera.mType.compare("perspective") == 0; + if(camParams.isPerspective) + { + auto& perspective = camera.mPerspective; + if(!Dali::Equals(perspective.mYFov, gltf2::UNDEFINED_FLOAT_VALUE)) + { + camParams.yFovDegree = Degree(Radian(perspective.mYFov)); + } + else + { + camParams.yFovDegree = Degree(gltf2::UNDEFINED_FLOAT_VALUE); + } + camParams.zNear = perspective.mZNear; + camParams.zFar = perspective.mZFar; + // TODO: yes, we seem to ignore aspectRatio in CameraParameters. + } + else + { + auto& ortho = camera.mOrthographic; + if(!Dali::Equals(ortho.mYMag, gltf2::UNDEFINED_FLOAT_VALUE) && !Dali::Equals(ortho.mXMag, gltf2::UNDEFINED_FLOAT_VALUE)) + { + camParams.orthographicSize = ortho.mYMag * .5f; + camParams.aspectRatio = ortho.mXMag / ortho.mYMag; + } + else + { + camParams.orthographicSize = gltf2::UNDEFINED_FLOAT_VALUE; + camParams.aspectRatio = gltf2::UNDEFINED_FLOAT_VALUE; + } + camParams.zNear = ortho.mZNear; + camParams.zFar = ortho.mZFar; + } +} + +void ConvertNode(gltf2::Node const& node, const Index gltfIdx, Index parentIdx, ConversionContext& context, bool isMRendererModel) +{ + auto& output = context.mOutput; + auto& scene = output.mScene; + auto& resources = output.mResources; + + const auto idx = scene.GetNodeCount(); + auto weakNode = scene.AddNode([&]() { + std::unique_ptr nodeDef{new NodeDefinition()}; + + nodeDef->mParentIdx = parentIdx; + nodeDef->mName = node.mName; + if(nodeDef->mName.empty()) + { + // TODO: Production quality generation of unique names. + nodeDef->mName = std::to_string(reinterpret_cast(nodeDef.get())); + } + + if(!node.mSkin) // Nodes with skinned meshes are not supposed to have local transforms. + { + nodeDef->mPosition = node.mTranslation; + nodeDef->mOrientation = node.mRotation; + nodeDef->mScale = node.mScale; + + if(isMRendererModel && node.mName == ROOT_NODE_NAME && node.mScale == SCALE_TO_ADJUST) + { + nodeDef->mScale *= 0.01f; + } + } + + return nodeDef; }()); + if(!weakNode) + { + ExceptionFlinger(ASSERT_LOCATION) << "Node name '" << node.mName << "' is not unique; scene is invalid."; + } + + context.mNodeIndices.RegisterMapping(gltfIdx, idx); + + Index skeletonIdx = node.mSkin ? node.mSkin.GetIndex() : INVALID_INDEX; + if(node.mMesh) + { + auto& mesh = *node.mMesh; + uint32_t primitiveCount = mesh.mPrimitives.size(); + auto meshIdx = context.mMeshIds[node.mMesh.GetIndex()]; + weakNode->mRenderables.reserve(primitiveCount); + for(uint32_t i = 0; i < primitiveCount; ++i) + { + std::unique_ptr renderable; + auto modelRenderable = MakeModelRenderable(mesh.mPrimitives[i], context); + modelRenderable->mMeshIdx = meshIdx + i; + + DALI_ASSERT_DEBUG(resources.mMeshes[modelRenderable->mMeshIdx].first.mSkeletonIdx == INVALID_INDEX || + resources.mMeshes[modelRenderable->mMeshIdx].first.mSkeletonIdx == skeletonIdx); + resources.mMeshes[modelRenderable->mMeshIdx].first.mSkeletonIdx = skeletonIdx; + + renderable.reset(modelRenderable); + weakNode->mRenderables.push_back(std::move(renderable)); + } + } + + if(node.mCamera) + { + CameraParameters camParams; + ConvertCamera(*node.mCamera, camParams); + + camParams.matrix.SetTransformComponents(node.mScale, node.mRotation, node.mTranslation); + output.mCameraParameters.push_back(camParams); + } + + for(auto& n : node.mChildren) + { + ConvertNode(*n, n.GetIndex(), idx, context, isMRendererModel); + } +} + +void ConvertSceneNodes(const gltf2::Scene& scene, ConversionContext& context, bool isMRendererModel) +{ + auto& outScene = context.mOutput.mScene; + Index rootIdx = outScene.GetNodeCount(); + switch(scene.mNodes.size()) + { + case 0: + break; + + case 1: + ConvertNode(*scene.mNodes[0], scene.mNodes[0].GetIndex(), INVALID_INDEX, context, isMRendererModel); + outScene.AddRootNode(rootIdx); + break; + + default: + { + std::unique_ptr sceneRoot{new NodeDefinition()}; + sceneRoot->mName = "GLTF_LOADER_SCENE_ROOT_" + std::to_string(outScene.GetRoots().size()); + + outScene.AddNode(std::move(sceneRoot)); + outScene.AddRootNode(rootIdx); + + for(auto& n : scene.mNodes) + { + ConvertNode(*n, n.GetIndex(), rootIdx, context, isMRendererModel); + } + break; + } + } +} + +void ConvertNodes(const gltf2::Document& doc, ConversionContext& context, bool isMRendererModel) +{ + if(!doc.mScenes.empty()) + { + uint32_t rootSceneIndex = 0u; + if(doc.mScene) + { + rootSceneIndex = doc.mScene.GetIndex(); + } + ConvertSceneNodes(doc.mScenes[rootSceneIndex], context, isMRendererModel); + + for(uint32_t i = 0, i1 = rootSceneIndex; i < i1; ++i) + { + ConvertSceneNodes(doc.mScenes[i], context, isMRendererModel); + } + + for(uint32_t i = rootSceneIndex + 1; i < doc.mScenes.size(); ++i) + { + ConvertSceneNodes(doc.mScenes[i], context, isMRendererModel); + } + } +} + +template +void LoadDataFromAccessor(ConversionContext& context, uint32_t bufferIndex, Vector& dataBuffer, uint32_t offset, uint32_t size) +{ + if(bufferIndex >= context.mOutput.mResources.mBuffers.size()) + { + DALI_LOG_ERROR("Invailid buffer index\n"); + return; + } + + auto& buffer = context.mOutput.mResources.mBuffers[bufferIndex]; + if(!buffer.IsAvailable()) + { + DALI_LOG_ERROR("Failed to load from buffer stream.\n"); + } + auto& stream = buffer.GetBufferStream(); + stream.clear(); + stream.seekg(offset, stream.beg); + stream.read(reinterpret_cast(dataBuffer.Begin()), static_cast(static_cast(size))); +} + +template +float LoadDataFromAccessors(ConversionContext& context, const gltf2::Accessor& input, const gltf2::Accessor& output, Vector& inputDataBuffer, Vector& outputDataBuffer) +{ + inputDataBuffer.Resize(input.mCount); + outputDataBuffer.Resize(output.mCount); + + const uint32_t inputDataBufferSize = input.GetBytesLength(); + const uint32_t outputDataBufferSize = output.GetBytesLength(); + + LoadDataFromAccessor(context, output.mBufferView->mBuffer.GetIndex(), inputDataBuffer, input.mBufferView->mByteOffset + input.mByteOffset, inputDataBufferSize); + LoadDataFromAccessor(context, output.mBufferView->mBuffer.GetIndex(), outputDataBuffer, output.mBufferView->mByteOffset + output.mByteOffset, outputDataBufferSize); + ApplyAccessorMinMax(input, reinterpret_cast(inputDataBuffer.begin())); + ApplyAccessorMinMax(output, reinterpret_cast(outputDataBuffer.begin())); + + return inputDataBuffer[input.mCount - 1u]; +} + +template +float LoadKeyFrames(ConversionContext& context, const gltf2::Animation::Channel& channel, KeyFrames& keyFrames, gltf2::Animation::Channel::Target::Type type) +{ + const gltf2::Accessor& input = *channel.mSampler->mInput; + const gltf2::Accessor& output = *channel.mSampler->mOutput; + + Vector inputDataBuffer; + Vector outputDataBuffer; + + const float duration = std::max(LoadDataFromAccessors(context, input, output, inputDataBuffer, outputDataBuffer), AnimationDefinition::MIN_DURATION_SECONDS); + + // Set first frame value as first keyframe (gltf animation spec) + if(input.mCount > 0 && !Dali::EqualsZero(inputDataBuffer[0])) + { + keyFrames.Add(0.0f, outputDataBuffer[0]); + } + + for(uint32_t i = 0; i < input.mCount; ++i) + { + keyFrames.Add(inputDataBuffer[i] / duration, outputDataBuffer[i]); + } + + return duration; +} + +float LoadBlendShapeKeyFrames(ConversionContext& context, const gltf2::Animation::Channel& channel, Index nodeIndex, uint32_t& propertyIndex, std::vector& properties) +{ + const gltf2::Accessor& input = *channel.mSampler->mInput; + const gltf2::Accessor& output = *channel.mSampler->mOutput; + + Vector inputDataBuffer; + Vector outputDataBuffer; + + const float duration = std::max(LoadDataFromAccessors(context, input, output, inputDataBuffer, outputDataBuffer), AnimationDefinition::MIN_DURATION_SECONDS); + + char weightNameBuffer[32]; + auto prefixSize = snprintf(weightNameBuffer, sizeof(weightNameBuffer), "%s[", BLEND_SHAPE_WEIGHTS_UNIFORM.data()); + char* const pWeightName = weightNameBuffer + prefixSize; + const auto remainingSize = sizeof(weightNameBuffer) - prefixSize; + for(uint32_t weightIndex = 0u, endWeightIndex = channel.mSampler->mOutput->mCount / channel.mSampler->mInput->mCount; weightIndex < endWeightIndex; ++weightIndex) + { + AnimatedProperty& animatedProperty = properties[propertyIndex++]; + + animatedProperty.mNodeIndex = nodeIndex; + snprintf(pWeightName, remainingSize, "%d]", weightIndex); + animatedProperty.mPropertyName = std::string(weightNameBuffer); + + animatedProperty.mKeyFrames = KeyFrames::New(); + + // Set first frame value as first keyframe (gltf animation spec) + if(input.mCount > 0 && !Dali::EqualsZero(inputDataBuffer[0])) + { + animatedProperty.mKeyFrames.Add(0.0f, outputDataBuffer[weightIndex]); + } + + for(uint32_t i = 0; i < input.mCount; ++i) + { + animatedProperty.mKeyFrames.Add(inputDataBuffer[i] / duration, outputDataBuffer[i * endWeightIndex + weightIndex]); + } + + animatedProperty.mTimePeriod = {0.f, duration}; + } + + return duration; +} + +void ConvertAnimations(const gltf2::Document& doc, ConversionContext& context) +{ + auto& output = context.mOutput; + + output.mAnimationDefinitions.reserve(output.mAnimationDefinitions.size() + doc.mAnimations.size()); + + for(const auto& animation : doc.mAnimations) + { + AnimationDefinition animationDef; + + if(!animation.mName.empty()) + { + animationDef.mName = animation.mName; + } + + uint32_t numberOfProperties = 0u; + for(const auto& channel : animation.mChannels) + { + if(channel.mTarget.mPath == gltf2::Animation::Channel::Target::WEIGHTS) + { + numberOfProperties += channel.mSampler->mOutput->mCount / channel.mSampler->mInput->mCount; + } + else + { + numberOfProperties++; + } + } + animationDef.mProperties.resize(numberOfProperties); + + Index propertyIndex = 0u; + for(const auto& channel : animation.mChannels) + { + Index nodeIndex = context.mNodeIndices.GetRuntimeId(channel.mTarget.mNode.GetIndex()); + float duration = 0.f; + + switch(channel.mTarget.mPath) + { + case gltf2::Animation::Channel::Target::TRANSLATION: + { + AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex]; + + animatedProperty.mNodeIndex = nodeIndex; + animatedProperty.mPropertyName = POSITION_PROPERTY; + + animatedProperty.mKeyFrames = KeyFrames::New(); + duration = LoadKeyFrames(context, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath); + + animatedProperty.mTimePeriod = {0.f, duration}; + break; + } + case gltf2::Animation::Channel::Target::ROTATION: + { + AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex]; + + animatedProperty.mNodeIndex = nodeIndex; + animatedProperty.mPropertyName = ORIENTATION_PROPERTY; + + animatedProperty.mKeyFrames = KeyFrames::New(); + duration = LoadKeyFrames(context, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath); + + animatedProperty.mTimePeriod = {0.f, duration}; + break; + } + case gltf2::Animation::Channel::Target::SCALE: + { + AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex]; + + animatedProperty.mNodeIndex = nodeIndex; + animatedProperty.mPropertyName = SCALE_PROPERTY; + + animatedProperty.mKeyFrames = KeyFrames::New(); + duration = LoadKeyFrames(context, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath); + + animatedProperty.mTimePeriod = {0.f, duration}; + break; + } + case gltf2::Animation::Channel::Target::WEIGHTS: + { + duration = LoadBlendShapeKeyFrames(context, channel, nodeIndex, propertyIndex, animationDef.mProperties); + + break; + } + default: + { + // nothing to animate. + break; + } + } + + animationDef.mDuration = std::max(duration, animationDef.mDuration); + + ++propertyIndex; + } + + output.mAnimationDefinitions.push_back(std::move(animationDef)); + } +} + +void ProcessSkins(const gltf2::Document& doc, ConversionContext& context) +{ + // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skininversebindmatrices + // If an inverseBindMatrices accessor was provided, we'll load the joint data from the buffer, + // otherwise we'll set identity matrices for inverse bind pose. + struct IInverseBindMatrixProvider + { + virtual ~IInverseBindMatrixProvider() + { + } + virtual void Provide(Matrix& ibm) = 0; + }; + + struct InverseBindMatrixAccessor : public IInverseBindMatrixProvider + { + std::istream& mStream; + const uint32_t mElementSizeBytes; + + InverseBindMatrixAccessor(const gltf2::Accessor& accessor, ConversionContext& context) + : mStream(context.mOutput.mResources.mBuffers[accessor.mBufferView->mBuffer.GetIndex()].GetBufferStream()), + mElementSizeBytes(accessor.GetElementSizeBytes()) + { + DALI_ASSERT_DEBUG(accessor.mType == gltf2::AccessorType::MAT4 && accessor.mComponentType == gltf2::Component::FLOAT); + + if(!mStream.rdbuf()->in_avail()) + { + DALI_LOG_ERROR("Failed to load from stream\n"); + } + mStream.clear(); + mStream.seekg(accessor.mBufferView->mByteOffset + accessor.mByteOffset, mStream.beg); + } + + virtual void Provide(Matrix& ibm) override + { + DALI_ASSERT_ALWAYS(mStream.read(reinterpret_cast(ibm.AsFloat()), static_cast(static_cast(mElementSizeBytes)))); + } + }; + + struct DefaultInverseBindMatrixProvider : public IInverseBindMatrixProvider + { + virtual void Provide(Matrix& ibm) override + { + ibm = Matrix::IDENTITY; + } + }; + + auto& resources = context.mOutput.mResources; + resources.mSkeletons.reserve(doc.mSkins.size()); + + for(auto& skin : doc.mSkins) + { + std::unique_ptr ibmProvider; + if(skin.mInverseBindMatrices) + { + ibmProvider.reset(new InverseBindMatrixAccessor(*skin.mInverseBindMatrices, context)); + } + else + { + ibmProvider.reset(new DefaultInverseBindMatrixProvider()); + } + + SkeletonDefinition skeleton; + if(skin.mSkeleton.GetIndex() != INVALID_INDEX) + { + skeleton.mRootNodeIdx = context.mNodeIndices.GetRuntimeId(skin.mSkeleton.GetIndex()); + } + + skeleton.mJoints.resize(skin.mJoints.size()); + auto iJoint = skeleton.mJoints.begin(); + for(auto& joint : skin.mJoints) + { + iJoint->mNodeIdx = context.mNodeIndices.GetRuntimeId(joint.GetIndex()); + + ibmProvider->Provide(iJoint->mInverseBindMatrix); + + ++iJoint; + } + + resources.mSkeletons.push_back(std::move(skeleton)); + } +} + +void ProduceShaders(ShaderDefinitionFactory& shaderFactory, Dali::Scene3D::Loader::SceneDefinition& scene) +{ + uint32_t nodeCount = scene.GetNodeCount(); + for(uint32_t i = 0; i < nodeCount; ++i) + { + auto nodeDef = scene.GetNode(i); + for(auto& renderable : nodeDef->mRenderables) + { + if(shaderFactory.ProduceShader(*renderable) == INVALID_INDEX) + { + DALI_LOG_ERROR("Fail to produce shader\n"); + } + } + } +} + +void SetObjectReaders() +{ + json::SetObjectReader(BUFFER_READER); + json::SetObjectReader(BUFFER_VIEW_READER); + json::SetObjectReader(BUFFER_VIEW_CLIENT_READER); + json::SetObjectReader(COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER); + json::SetObjectReader(ACCESSOR_SPARSE_READER); + json::SetObjectReader(ACCESSOR_READER); + json::SetObjectReader(IMAGE_READER); + json::SetObjectReader(SAMPLER_READER); + json::SetObjectReader(TEXURE_READER); + json::SetObjectReader(TEXURE_INFO_READER); + json::SetObjectReader(MATERIAL_PBR_READER); + json::SetObjectReader(MATERIAL_SPECULAR_READER); + json::SetObjectReader(MATERIAL_IOR_READER); + json::SetObjectReader(MATERIAL_EXTENSION_READER); + json::SetObjectReader(MATERIAL_READER); + json::SetObjectReader(MESH_PRIMITIVE_READER); + json::SetObjectReader(MESH_READER); + json::SetObjectReader(SKIN_READER); + json::SetObjectReader(CAMERA_PERSPECTIVE_READER); + json::SetObjectReader(CAMERA_ORTHOGRAPHIC_READER); + json::SetObjectReader(CAMERA_READER); + json::SetObjectReader(NODE_READER); + json::SetObjectReader(ANIMATION_SAMPLER_READER); + json::SetObjectReader(ANIMATION_TARGET_READER); + json::SetObjectReader(ANIMATION_CHANNEL_READER); + json::SetObjectReader(ANIMATION_READER); + json::SetObjectReader(SCENE_READER); +} + +void SetDefaultEnvironmentMap(const gltf2::Document& doc, ConversionContext& context) +{ + EnvironmentDefinition envDef; + envDef.mUseBrdfTexture = true; + envDef.mIblIntensity = Scene3D::Loader::EnvironmentDefinition::GetDefaultIntensity(); + context.mOutput.mResources.mEnvironmentMaps.push_back({std::move(envDef), EnvironmentDefinition::Textures()}); +} + +void InitializeGltfLoader() +{ + static Dali::Mutex gInitializeMutex; + // Set ObjectReader only once (for all gltf loading). + static bool setObjectReadersRequired = true; + { + Mutex::ScopedLock lock(gInitializeMutex); + if(setObjectReadersRequired) + { + // NOTE: only referencing own, anonymous namespace, const objects; the pointers will never need to change. + SetObjectReaders(); + setObjectReadersRequired = false; + } + } +} + +const std::string_view GetRendererModelIdentification() +{ + return MRENDERER_MODEL_IDENTIFICATION; +} + +void ReadDocument(const json_object_s& jsonObject, gltf2::Document& document) +{ + DOCUMENT_READER.Read(jsonObject, document); +} + +void ReadDocumentFromParsedData(const json_object_s& jsonObject, gltf2::Document& document) +{ + static Dali::Mutex gReadMutex; + Mutex::ScopedLock lock(gReadMutex); + gt::SetRefReaderObject(document); + Gltf2Util::ReadDocument(jsonObject, document); +} + +bool GenerateDocument(json::unique_ptr& root, gt::Document& document, bool& isMRendererModel) +{ + auto& rootObj = js::Cast(*root); + auto jsAsset = js::FindObjectChild("asset", rootObj); + + auto jsAssetVersion = js::FindObjectChild("version", js::Cast(*jsAsset)); + if(jsAssetVersion) + { + document.mAsset.mVersion = js::Read::StringView(*jsAssetVersion); + } + + auto jsAssetGenerator = js::FindObjectChild("generator", js::Cast(*jsAsset)); + if(jsAssetGenerator) + { + document.mAsset.mGenerator = js::Read::StringView(*jsAssetGenerator); + isMRendererModel = (document.mAsset.mGenerator.find(Gltf2Util::GetRendererModelIdentification().data()) != std::string_view::npos); + } + + Gltf2Util::InitializeGltfLoader(); + Gltf2Util::ReadDocumentFromParsedData(rootObj, document); + + return true; +} + +void ConvertGltfToContext(gt::Document& document, Gltf2Util::ConversionContext& context, bool isMRendererModel) +{ + Dali::Scene3D::Loader::ShaderDefinitionFactory shaderFactory; + shaderFactory.SetResources(context.mOutput.mResources); + + Gltf2Util::ConvertBuffers(document, context); + Gltf2Util::ConvertMaterials(document, context); + Gltf2Util::ConvertMeshes(document, context); + Gltf2Util::ConvertNodes(document, context, isMRendererModel); + Gltf2Util::ConvertAnimations(document, context); + Gltf2Util::ProcessSkins(document, context); + Gltf2Util::ProduceShaders(shaderFactory, context.mOutput.mScene); + context.mOutput.mScene.EnsureUniqueSkinningShaderInstances(context.mOutput.mResources); + + // Set Default Environment map + Gltf2Util::SetDefaultEnvironmentMap(document, context); +} + +} // namespace Gltf2Util + +} // namespace Dali::Scene3D::Loader::Internal \ No newline at end of file diff --git a/dali-scene3d/internal/loader/gltf2-util.h b/dali-scene3d/internal/loader/gltf2-util.h new file mode 100644 index 0000000..909ae59 --- /dev/null +++ b/dali-scene3d/internal/loader/gltf2-util.h @@ -0,0 +1,125 @@ +#ifndef DALI_SCENE3D_LOADER_GLTF2_UTIL_H +#define DALI_SCENE3D_LOADER_GLTF2_UTIL_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 +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include +#include + +namespace gt = gltf2; +namespace js = json; + +namespace Dali::Scene3D::Loader::Internal +{ +namespace Gltf2Util +{ +struct NodeMapping +{ + Index gltfIdx; + Index runtimeIdx; + + bool operator<(Index gltfIdx) const + { + return this->gltfIdx < gltfIdx; + } +}; + +class NodeIndexMapper +{ +public: + NodeIndexMapper() = default; + NodeIndexMapper(const NodeIndexMapper&) = delete; + NodeIndexMapper& operator=(const NodeIndexMapper&) = delete; + + ///@brief Registers a mapping of the @a gltfIdx of a node to its @a runtimeIdx . + ///@note If the indices are the same, the registration is omitted, in order to + /// save growing a vector. + void RegisterMapping(Index gltfIdx, Index runtimeIdx) + { + if(gltfIdx != runtimeIdx) + { + auto iInsert = std::lower_bound(mNodes.begin(), mNodes.end(), gltfIdx); + DALI_ASSERT_DEBUG(iInsert == mNodes.end() || iInsert->gltfIdx != gltfIdx); + mNodes.insert(iInsert, NodeMapping{gltfIdx, runtimeIdx}); + } + } + + ///@brief Retrieves the runtime index of a Node, mapped to the given @a gltfIdx. + Index GetRuntimeId(Index gltfIdx) const + { + auto iFind = std::lower_bound(mNodes.begin(), mNodes.end(), gltfIdx); // using custom operator< + return (iFind != mNodes.end() && iFind->gltfIdx == gltfIdx) ? iFind->runtimeIdx : gltfIdx; + } + +private: + std::vector mNodes; +}; + +struct ConversionContext +{ + LoadResult& mOutput; + + std::string mPath; + Index mDefaultMaterial; + + std::vector mMeshIds; + NodeIndexMapper mNodeIndices; +}; + +void ConvertBuffers(const gt::Document& doc, ConversionContext& context); + +void ConvertMaterials(const gt::Document& doc, ConversionContext& context); + +void ConvertMeshes(const gt::Document& doc, ConversionContext& context); + +void ConvertCamera(const gt::Camera& camera, CameraParameters& camParams); + +void ConvertNodes(const gt::Document& doc, ConversionContext& context, bool isMRendererModel); + +void ConvertAnimations(const gt::Document& doc, ConversionContext& context); + +void ProcessSkins(const gt::Document& doc, ConversionContext& context); + +void ProduceShaders(ShaderDefinitionFactory& shaderFactory, SceneDefinition& scene); + +void SetDefaultEnvironmentMap(const gt::Document& doc, ConversionContext& context); + +const std::string_view GetRendererModelIdentification(); + +void ReadDocument(const json_object_s& jsonObject, gt::Document& document); + +void InitializeGltfLoader(); + +void ReadDocumentFromParsedData(const json_object_s& jsonObject, gltf2::Document& document); + +bool GenerateDocument(json::unique_ptr& root, gt::Document& document, bool& isMRendererModel); + +void ConvertGltfToContext(gt::Document& document, Gltf2Util::ConversionContext& context, bool isMRendererModel); + +} // namespace Gltf2Util + +} // namespace Dali::Scene3D::Loader::Internal + +#endif // DALI_SCENE3D_LOADER_GLTF2_UTIL_H diff --git a/dali-scene3d/internal/loader/hash.cpp b/dali-scene3d/internal/loader/hash.cpp index d1ea70f..7abb277 100644 --- a/dali-scene3d/internal/loader/hash.cpp +++ b/dali-scene3d/internal/loader/hash.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,13 +14,11 @@ * limitations under the License. * */ -#include "dali-scene3d/internal/loader/hash.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// CLASS HEADER +#include + +namespace Dali::Scene3D::Loader { Hash::Hash(uint64_t initial) : mValue(initial) @@ -93,6 +91,4 @@ uint64_t Hash::Concatenate(uint64_t value) return mValue * 31 + value; } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/internal/loader/hash.h b/dali-scene3d/internal/loader/hash.h index a5bba8e..0f63c94 100644 --- a/dali-scene3d/internal/loader/hash.h +++ b/dali-scene3d/internal/loader/hash.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_HASH_H_ #define DALI_SCENE3D_LOADER_HASH_H_ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,15 +17,12 @@ * */ +// EXTERNAL INCLUDES #include #include #include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { /** * @brief Rudimentary hash generator that follows a builder pattern. @@ -119,8 +116,6 @@ Hash& Hash::AddObjectBytes(const T& value) return *this; } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif // DALI_SCENE3D_LOADER_HASH_H_ diff --git a/dali-scene3d/internal/loader/json-reader.cpp b/dali-scene3d/internal/loader/json-reader.cpp index ead6269..2ea2925 100644 --- a/dali-scene3d/internal/loader/json-reader.cpp +++ b/dali-scene3d/internal/loader/json-reader.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022 Samsung Electronics Co., Ltd. +* Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,11 @@ * limitations under the License. * */ -#include "dali-scene3d/internal/loader/json-reader.h" + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES #include #include diff --git a/dali-scene3d/internal/loader/json-reader.h b/dali-scene3d/internal/loader/json-reader.h index c0a8abd..100472a 100644 --- a/dali-scene3d/internal/loader/json-reader.h +++ b/dali-scene3d/internal/loader/json-reader.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_JSON_READER_H_ #define DALI_SCENE3D_LOADER_JSON_READER_H_ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,17 +17,17 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/third-party/json.h" - // EXTERNAL INCLUDES +#include #include #include #include #include #include #include -#include "dali/public-api/common/vector-wrapper.h" + +// INTERNAL INCLUDES +#include // TODO : Since license issue, We shoud replace this thing as namespace json { diff --git a/dali-scene3d/internal/loader/json-util.cpp b/dali-scene3d/internal/loader/json-util.cpp index fcb91ad..ec6e95f 100644 --- a/dali-scene3d/internal/loader/json-util.cpp +++ b/dali-scene3d/internal/loader/json-util.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,19 +14,21 @@ * limitations under the License. * */ -#include "dali-scene3d/internal/loader/json-util.h" + +// CLASS HEADER +#include // EXTERNAL INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include "dali/devel-api/common/map-wrapper.h" -#include "dali/public-api/common/extents.h" -#include "dali/public-api/math/matrix.h" -#include "dali/public-api/math/matrix3.h" -#include "dali/public-api/math/quaternion.h" -#include "dali/public-api/math/radian.h" -#include "dali/public-api/math/vector2.h" -#include "dali/public-api/math/vector3.h" -#include "dali/public-api/object/property-value.h" namespace Dali { diff --git a/dali-scene3d/internal/loader/json-util.h b/dali-scene3d/internal/loader/json-util.h index 1d2b983..e7c222d 100644 --- a/dali-scene3d/internal/loader/json-util.h +++ b/dali-scene3d/internal/loader/json-util.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_JSON_UTIL_H_ #define DALI_SCENE3D_LOADER_JSON_UTIL_H_ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,21 +17,17 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/loader/index.h" - // EXTERNAL INCLUDES -#include "dali-toolkit/devel-api/builder/tree-node.h" -#include "dali/public-api/animation/time-period.h" -#include "dali/public-api/common/vector-wrapper.h" -#include "dali/public-api/math/vector4.h" -#include "dali/public-api/object/property.h" +#include +#include +#include +#include +#include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { bool ReadBool(const Toolkit::TreeNode* node, bool& num); @@ -90,8 +86,6 @@ Property::Value ReadPropertyValue(const Property::Type& propType, const Toolkit: */ Property::Value ReadPropertyValue(const Toolkit::TreeNode& tn); -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADER_JSON_UTIL_H_ diff --git a/dali-scene3d/internal/loader/model-loader-impl.h b/dali-scene3d/internal/loader/model-loader-impl.h new file mode 100644 index 0000000..619cacb --- /dev/null +++ b/dali-scene3d/internal/loader/model-loader-impl.h @@ -0,0 +1,69 @@ +#ifndef DALI_SCENE3D_LOADER_MODEL_LOADER_IMPL_H +#define DALI_SCENE3D_LOADER_MODEL_LOADER_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. + * + */ + +// INTERNAL INCLUDES +#include +#include +#include +#include + +// EXTERNAL INCLUDES +#include + +namespace Dali +{ +namespace Scene3D +{ +namespace Loader +{ +namespace Internal +{ +class ModelLoaderImpl +{ +public: + ModelLoaderImpl() = default; + + /** + * @brief Set InputParameter. + * Thie method store only a pointer of InputParameter. + * The object of InputParameter should not be deleted until it is no longer used. + * @param[in] inputParameter Input parameters those can be used for model loading. + */ + void SetInputParameter(Dali::Scene3D::Loader::ModelLoader::InputParameter& inputParameter) + { + mInputParameter = &inputParameter; + } + + /** + * @brief Request to load model from url. + * @param[in] url model file url. + * @param[out] result loaded model data. + * @return True if model loading is successfully finished. + */ + virtual bool LoadModel(const std::string& url, Dali::Scene3D::Loader::LoadResult& result) = 0; + +protected: + Dali::Scene3D::Loader::ModelLoader::InputParameter* mInputParameter{nullptr}; +}; +} // namespace Internal +} // namespace Loader +} // namespace Scene3D +} // namespace Dali + +#endif // DALI_SCENE3D_LOADER_MODEL_LOADER_IMPL_H diff --git a/dali-scene3d/public-api/algorithm/navigation-mesh.h b/dali-scene3d/public-api/algorithm/navigation-mesh.h index 12f3387..b2a0fd9 100644 --- a/dali-scene3d/public-api/algorithm/navigation-mesh.h +++ b/dali-scene3d/public-api/algorithm/navigation-mesh.h @@ -17,19 +17,19 @@ * limitations under the License. */ -// INTERNAL INCLUDES -#include - // EXTERNAL INCLUDES +#include #include #include #include #include #include -#include #include +// INTERNAL INCLUDES +#include + namespace Dali::Scene3D::Internal::Algorithm { class NavigationMesh; @@ -41,9 +41,9 @@ class NavigationMeshFactory; } constexpr auto NAVIGATION_MESH_MAX_VERTICES_PER_FACE = 3u; -constexpr auto NAVIGATION_MESH_MAX_EDGES_PER_FACE = 3u; -constexpr auto NAVIGATION_MESH_MAX_COMPONENTS_3D = 3u; -constexpr auto NAVIGATION_MESH_MAX_COMPONENTS_2D = 2u; +constexpr auto NAVIGATION_MESH_MAX_EDGES_PER_FACE = 3u; +constexpr auto NAVIGATION_MESH_MAX_COMPONENTS_3D = 3u; +constexpr auto NAVIGATION_MESH_MAX_COMPONENTS_2D = 2u; namespace Dali::Scene3D::Algorithm { @@ -72,7 +72,6 @@ using NavigationMeshImpl = Dali::Scene3D::Internal::Algorithm::NavigationMesh; class DALI_SCENE3D_API NavigationMesh { public: - /** * @struct Face * @@ -81,9 +80,9 @@ public: struct Face { uint16_t vertex[NAVIGATION_MESH_MAX_VERTICES_PER_FACE]; ///< Vertices per face - uint16_t edge[NAVIGATION_MESH_MAX_EDGES_PER_FACE]; ///< Edges per face - float normal[NAVIGATION_MESH_MAX_COMPONENTS_3D]; ///< Normal vector - float center[NAVIGATION_MESH_MAX_COMPONENTS_3D]; ///< Barycentric coordinates + uint16_t edge[NAVIGATION_MESH_MAX_EDGES_PER_FACE]; ///< Edges per face + float normal[NAVIGATION_MESH_MAX_COMPONENTS_3D]; ///< Normal vector + float center[NAVIGATION_MESH_MAX_COMPONENTS_3D]; ///< Barycentric coordinates }; /** @@ -118,7 +117,6 @@ public: NavigationMesh() = delete; public: - /** * @brief Destructor */ @@ -171,7 +169,6 @@ public: */ bool FindFloorForFace(const Dali::Vector3& position, uint32_t faceIndex, bool dontCheckNeighbours, Dali::Vector3& outPosition); - /** * @brief Returns pointer to Face structure * @param[in] index Index of face to retrieve @@ -253,8 +250,7 @@ public: static constexpr uint16_t NULL_EDGE{0xffff}; ///< represents null edge public: - - DALI_INTERNAL explicit NavigationMesh( NavigationMeshImpl* impl ); + DALI_INTERNAL explicit NavigationMesh(NavigationMeshImpl* impl); std::unique_ptr mImpl; }; diff --git a/dali-scene3d/public-api/algorithm/path-finder-waypoint.cpp b/dali-scene3d/public-api/algorithm/path-finder-waypoint.cpp index 9254e04..edaf1e1 100644 --- a/dali-scene3d/public-api/algorithm/path-finder-waypoint.cpp +++ b/dali-scene3d/public-api/algorithm/path-finder-waypoint.cpp @@ -17,16 +17,15 @@ // CLASS HEADER #include +// EXTERNAL INCLUDES +#include + // INTERNAL INCLUDES #include #include -// EXTERNAL INCLUDES -#include - namespace Dali::Scene3D::Algorithm { - WayPoint::WayPoint() { mImpl = std::make_unique(); @@ -51,13 +50,13 @@ Dali::Vector3 WayPoint::GetScenePosition() const WayPoint::WayPoint(const WayPoint& wp) { - mImpl = std::make_unique(); + mImpl = std::make_unique(); *mImpl = *wp.mImpl; } WayPoint& WayPoint::operator=(const WayPoint& wp) { - mImpl = std::make_unique(); + mImpl = std::make_unique(); *mImpl = *wp.mImpl; return *this; } @@ -67,4 +66,4 @@ WayPoint::operator Internal::Algorithm::WayPointData&() return *mImpl; } -} +} // namespace Dali::Scene3D::Algorithm diff --git a/dali-scene3d/public-api/algorithm/path-finder-waypoint.h b/dali-scene3d/public-api/algorithm/path-finder-waypoint.h index 201783c..ec07a5e 100644 --- a/dali-scene3d/public-api/algorithm/path-finder-waypoint.h +++ b/dali-scene3d/public-api/algorithm/path-finder-waypoint.h @@ -17,9 +17,6 @@ * limitations under the License. */ -// INTERNAL INCLUDES -#include - // EXTERNAL INCLUDES #include #include @@ -27,6 +24,9 @@ #include #include +// INTERNAL INCLUDES +#include + namespace Dali::Scene3D::Internal::Algorithm { class WayPointData; @@ -42,7 +42,6 @@ namespace Dali::Scene3D::Algorithm class DALI_SCENE3D_API WayPoint { public: - /** * @brief Constructor */ @@ -101,14 +100,11 @@ public: WayPoint& operator=(const WayPoint&); private: - std::unique_ptr mImpl; public: - DALI_INTERNAL operator Internal::Algorithm::WayPointData&(); - }; -} +} // namespace Dali::Scene3D::Algorithm #endif // DALI_SCENE3D_PATH_FINDER_WAYPOINT_H diff --git a/dali-scene3d/public-api/algorithm/path-finder.cpp b/dali-scene3d/public-api/algorithm/path-finder.cpp index f48ffb3..6f29448 100644 --- a/dali-scene3d/public-api/algorithm/path-finder.cpp +++ b/dali-scene3d/public-api/algorithm/path-finder.cpp @@ -17,6 +17,7 @@ // CLASS HEADER #include +// INTERNAL INCLUDES // default algorithm #include #include diff --git a/dali-scene3d/public-api/controls/model/model.h b/dali-scene3d/public-api/controls/model/model.h index ce723ea..da3f7a6 100644 --- a/dali-scene3d/public-api/controls/model/model.h +++ b/dali-scene3d/public-api/controls/model/model.h @@ -18,15 +18,15 @@ * */ -// INTERNAL INCLUDES -#include - // EXTERNAL INCLUDES #include #include #include #include +// INTERNAL INCLUDES +#include + namespace Dali { namespace Scene3D diff --git a/dali-scene3d/public-api/controls/scene-view/scene-view.h b/dali-scene3d/public-api/controls/scene-view/scene-view.h index 1a3407f..f64715d 100644 --- a/dali-scene3d/public-api/controls/scene-view/scene-view.h +++ b/dali-scene3d/public-api/controls/scene-view/scene-view.h @@ -18,15 +18,15 @@ * */ -// INTERNAL INCLUDES -#include -#include - // EXTERNAL INCLUDES #include #include #include +// INTERNAL INCLUDES +#include +#include + namespace Dali { namespace Scene3D diff --git a/dali-scene3d/public-api/file.list b/dali-scene3d/public-api/file.list index 95363dc..e812ae7 100644 --- a/dali-scene3d/public-api/file.list +++ b/dali-scene3d/public-api/file.list @@ -16,15 +16,14 @@ set(scene3d_src_files ${scene3d_src_files} ${scene3d_public_api_dir}/loader/environment-map-data.cpp ${scene3d_public_api_dir}/loader/environment-map-loader.cpp ${scene3d_public_api_dir}/loader/customization.cpp - ${scene3d_public_api_dir}/loader/dli-loader.cpp ${scene3d_public_api_dir}/loader/environment-definition.cpp ${scene3d_public_api_dir}/loader/facial-animation-loader.cpp - ${scene3d_public_api_dir}/loader/gltf2-loader.cpp ${scene3d_public_api_dir}/loader/ktx-loader.cpp ${scene3d_public_api_dir}/loader/load-scene-metadata.cpp ${scene3d_public_api_dir}/loader/material-definition.cpp ${scene3d_public_api_dir}/loader/matrix-stack.cpp ${scene3d_public_api_dir}/loader/mesh-definition.cpp + ${scene3d_public_api_dir}/loader/model-loader.cpp ${scene3d_public_api_dir}/loader/navigation-mesh-factory.cpp ${scene3d_public_api_dir}/loader/node-definition.cpp ${scene3d_public_api_dir}/loader/parse-renderer-state.cpp diff --git a/dali-scene3d/public-api/loader/alpha-function-helper.cpp b/dali-scene3d/public-api/loader/alpha-function-helper.cpp index 1ac61ee..2aecc50 100644 --- a/dali-scene3d/public-api/loader/alpha-function-helper.cpp +++ b/dali-scene3d/public-api/loader/alpha-function-helper.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,14 @@ * limitations under the License. * */ -#include "dali-scene3d/public-api/loader/alpha-function-helper.h" + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES #include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { namespace { @@ -67,6 +67,4 @@ void RegisterAlphaFunction(const std::string& name, AlphaFunction alphaFn) "Function with given key already exists."); } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/alpha-function-helper.h b/dali-scene3d/public-api/loader/alpha-function-helper.h index d421a3e..3fdb4ed 100644 --- a/dali-scene3d/public-api/loader/alpha-function-helper.h +++ b/dali-scene3d/public-api/loader/alpha-function-helper.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_ALPHA_FUNCTION_HELPER_H_ #define DALI_SCENE3D_LOADER_ALPHA_FUNCTION_HELPER_H_ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,14 @@ * */ -#include "dali-scene3d/public-api/api.h" - +// EXTERNAL INCLUDES +#include #include -#include "dali/public-api/animation/alpha-function.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { /** * @return Given a name, provide a AlphaFunction; if the name was not @@ -40,8 +38,6 @@ AlphaFunction DALI_SCENE3D_API GetAlphaFunction(const std::string& name, bool* f */ void DALI_SCENE3D_API RegisterAlphaFunction(const std::string& name, AlphaFunction alphaFn) noexcept(false); -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADER_ALPHA_FUNCTION_HELPER_H_ diff --git a/dali-scene3d/public-api/loader/animated-property.cpp b/dali-scene3d/public-api/loader/animated-property.cpp index 83ae2df..a3969ff 100644 --- a/dali-scene3d/public-api/loader/animated-property.cpp +++ b/dali-scene3d/public-api/loader/animated-property.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,13 +14,11 @@ * limitations under the License. * */ -#include "dali-scene3d/public-api/loader/animated-property.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// CLASS HEADER +#include + +namespace Dali::Scene3D::Loader { void AnimatedProperty::Animate(Animation& anim, GetActor getActor) { @@ -45,6 +43,4 @@ void AnimatedProperty::Animate(Animation& anim, GetActor getActor) } } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader \ No newline at end of file diff --git a/dali-scene3d/public-api/loader/animated-property.h b/dali-scene3d/public-api/loader/animated-property.h index 87fe87a..07b251f 100644 --- a/dali-scene3d/public-api/loader/animated-property.h +++ b/dali-scene3d/public-api/loader/animated-property.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_ANIMATED_PROPERTY_H #define DALI_SCENE3D_LOADER_ANIMATED_PROPERTY_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,23 +17,18 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" -#include "dali-scene3d/public-api/loader/index.h" - - // EXTERNAL INCLUDES +#include +#include +#include #include #include -#include "dali/public-api/actors/actor.h" -#include "dali/public-api/animation/animation.h" -#include "dali/public-api/object/property.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include +#include + +namespace Dali::Scene3D::Loader { /** * @brief Intermediate representation for a property that's given to @@ -95,8 +90,6 @@ public: // DATA TimePeriod mTimePeriod = TimePeriod(0.f); }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADER_ANIMATED_PROPERTY_H diff --git a/dali-scene3d/public-api/loader/animation-definition.cpp b/dali-scene3d/public-api/loader/animation-definition.cpp index c201314..31c5ed1 100644 --- a/dali-scene3d/public-api/loader/animation-definition.cpp +++ b/dali-scene3d/public-api/loader/animation-definition.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,13 +14,11 @@ * limitations under the License. * */ -#include "dali-scene3d/public-api/loader/animation-definition.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// CLASS HEADER +#include + +namespace Dali::Scene3D::Loader { const float AnimationDefinition::DEFAULT_DURATION_SECONDS = 1.f; const float AnimationDefinition::MIN_DURATION_SECONDS = 1e-2f; @@ -85,6 +83,4 @@ AnimationDefinition& AnimationDefinition::operator=(AnimationDefinition&& other) return *this; } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/animation-definition.h b/dali-scene3d/public-api/loader/animation-definition.h index cb8e5db..27fe2ac 100644 --- a/dali-scene3d/public-api/loader/animation-definition.h +++ b/dali-scene3d/public-api/loader/animation-definition.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_ANIMATION_DEFINITION_H #define DALI_SCENE3D_LOADER_ANIMATION_DEFINITION_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,15 +17,14 @@ * */ -#include "dali-scene3d/public-api/api.h" -#include "dali-scene3d/public-api/loader/animated-property.h" -#include "dali/public-api/common/vector-wrapper.h" +// EXTERNAL INCLUDES +#include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include +#include + +namespace Dali::Scene3D::Loader { /** * @brief Animation handle + name + definition of properties. @@ -83,8 +82,6 @@ struct AnimationGroupDefinition std::vector mAnimations; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADER_ANIMATION_DEFINITION_H diff --git a/dali-scene3d/public-api/loader/blend-shape-details.cpp b/dali-scene3d/public-api/loader/blend-shape-details.cpp index 8e0353c..3ef97b2 100644 --- a/dali-scene3d/public-api/loader/blend-shape-details.cpp +++ b/dali-scene3d/public-api/loader/blend-shape-details.cpp @@ -1,6 +1,6 @@ /* -* Copyright (c) 2022 Samsung Electronics Co., Ltd. +* Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,11 +26,7 @@ // INTERNAL INCLUDES #include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { const char* BlendShapes::NUMBER_OF_BLEND_SHAPES("uNumberOfBlendShapes"); const char* BlendShapes::UNNORMALIZE_FACTOR("uBlendShapeUnnormalizeFactor"); @@ -85,6 +81,4 @@ void BlendShapes::ConfigureProperties(const std::pair +#include #include -#include "dali/public-api/actors/actor.h" -#include "dali/public-api/rendering/shader.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { struct MeshDefinition; struct MeshGeometry; @@ -73,8 +69,6 @@ struct DALI_SCENE3D_API BlendShapes BlendShapes() = delete; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif // DALI_SCENE3D_LOADER_BLEND_SHAPE_DETAILS_H diff --git a/dali-scene3d/public-api/loader/buffer-definition.cpp b/dali-scene3d/public-api/loader/buffer-definition.cpp index 1704927..8f2bc57 100644 --- a/dali-scene3d/public-api/loader/buffer-definition.cpp +++ b/dali-scene3d/public-api/loader/buffer-definition.cpp @@ -15,7 +15,7 @@ * */ -// INTERNAL INCLUDES +// CLASS HEADER #include // EXTERNAL INCLUDES @@ -23,11 +23,7 @@ #include #include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { namespace { @@ -42,6 +38,14 @@ struct BufferDefinition::Impl std::shared_ptr stream; }; +BufferDefinition::BufferDefinition(std::vector& buffer) +: mImpl{new BufferDefinition::Impl} +{ + mImpl.get()->buffer = std::move(buffer); + mImpl.get()->stream = std::make_shared(reinterpret_cast(mImpl.get()->buffer.data()), mImpl.get()->buffer.size(), FileStream::READ | FileStream::BINARY); + mIsEmbedded = true; +} + BufferDefinition::BufferDefinition() : mImpl{new BufferDefinition::Impl} { @@ -103,6 +107,4 @@ void BufferDefinition::LoadBuffer() } } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/buffer-definition.h b/dali-scene3d/public-api/loader/buffer-definition.h index 8f6952a..533aa04 100644 --- a/dali-scene3d/public-api/loader/buffer-definition.h +++ b/dali-scene3d/public-api/loader/buffer-definition.h @@ -17,19 +17,16 @@ * */ -// INTERNAL INCLUDES -#include - // EXTERNAL INCLUDES +#include +#include #include #include -#include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { /** * @brief Defines a buffer that is loaded from input uri. @@ -40,9 +37,11 @@ struct DALI_SCENE3D_API BufferDefinition using Vector = std::vector; BufferDefinition(); + BufferDefinition(std::vector& buffer); + ~BufferDefinition(); - BufferDefinition(const BufferDefinition& other) = default; + BufferDefinition(const BufferDefinition& other) = default; BufferDefinition& operator=(const BufferDefinition& other) = default; BufferDefinition(BufferDefinition&& other); @@ -86,8 +85,6 @@ private: bool mIsEmbedded{false}; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif // DALI_SCENE3D_LOADER_BUFFER_DEFINITION_H diff --git a/dali-scene3d/public-api/loader/bvh-loader.cpp b/dali-scene3d/public-api/loader/bvh-loader.cpp index 7d3b775..93a826d 100644 --- a/dali-scene3d/public-api/loader/bvh-loader.cpp +++ b/dali-scene3d/public-api/loader/bvh-loader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,11 +25,7 @@ #include #include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { namespace { @@ -340,6 +336,4 @@ AnimationDefinition LoadBvh(const std::string& path, const std::string& animatio return GenerateAnimation(animationName, rootJoint, frameCount, frameTime, scale); } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali \ No newline at end of file +} // namespace Dali::Scene3D::Loader \ No newline at end of file diff --git a/dali-scene3d/public-api/loader/bvh-loader.h b/dali-scene3d/public-api/loader/bvh-loader.h index 2c3dbc7..9830031 100644 --- a/dali-scene3d/public-api/loader/bvh-loader.h +++ b/dali-scene3d/public-api/loader/bvh-loader.h @@ -2,7 +2,7 @@ #define DALI_SCENE3D_LOADER_BVH_LOADER_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,13 +21,8 @@ // INTERNAL INCLUDES #include -namespace Dali +namespace Dali::Scene3D::Loader { -namespace Scene3D -{ -namespace Loader -{ - /** * @brief Loads motion capture data from bvh file format. * @@ -38,8 +33,6 @@ namespace Loader */ DALI_SCENE3D_API AnimationDefinition LoadBvh(const std::string& path, const std::string& animationName, const Vector3& scale = Vector3::ONE); -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif // DALI_SCENE3D_LOADER_BVH_LOADER_H \ No newline at end of file diff --git a/dali-scene3d/public-api/loader/camera-parameters.cpp b/dali-scene3d/public-api/loader/camera-parameters.cpp index cc9a351..05bcef1 100644 --- a/dali-scene3d/public-api/loader/camera-parameters.cpp +++ b/dali-scene3d/public-api/loader/camera-parameters.cpp @@ -28,11 +28,7 @@ #include // for gltf2::UNDEFINED_FLOAT_VALUE #include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { namespace { @@ -270,6 +266,4 @@ bool CameraParameters::ConfigureCamera(CameraActor& camera, bool invertY) const return true; } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader \ No newline at end of file diff --git a/dali-scene3d/public-api/loader/customization.cpp b/dali-scene3d/public-api/loader/customization.cpp index f48c191..7922400 100644 --- a/dali-scene3d/public-api/loader/customization.cpp +++ b/dali-scene3d/public-api/loader/customization.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,14 @@ * limitations under the License. * */ -#include "dali-scene3d/public-api/loader/customization.h" -#include "dali/devel-api/common/map-wrapper.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { struct Customization::Map::Impl { @@ -111,6 +111,4 @@ void Customization::Choices::Clear() mImpl->mOptions.clear(); } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader \ No newline at end of file diff --git a/dali-scene3d/public-api/loader/customization.h b/dali-scene3d/public-api/loader/customization.h index 667cada..90a42bf 100644 --- a/dali-scene3d/public-api/loader/customization.h +++ b/dali-scene3d/public-api/loader/customization.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_CUSTOMIZATION_STATE_H_ #define DALI_SCENE3D_LOADER_CUSTOMIZATION_STATE_H_ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,19 +17,15 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" - // EXTERNAL INCLUDES +#include #include #include -#include "dali/public-api/common/vector-wrapper.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { /** * @brief Offers a description of an aspect of the scene that can be customized: @@ -119,8 +115,6 @@ struct DALI_SCENE3D_API Customization std::vector nodes; // to apply option to. }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADER_CUSTOMIZATION_STATE_H_ diff --git a/dali-scene3d/public-api/loader/dli-input-parameter.h b/dali-scene3d/public-api/loader/dli-input-parameter.h new file mode 100644 index 0000000..1db4844 --- /dev/null +++ b/dali-scene3d/public-api/loader/dli-input-parameter.h @@ -0,0 +1,88 @@ +#ifndef DALI_SCENE3D_LOADER_DLI_INPUT_PARAMETER_H +#define DALI_SCENE3D_LOADER_DLI_INPUT_PARAMETER_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 + +// INTERNAL INCLUDES +#include +#include + +namespace Dali::Scene3D::Loader +{ +class DliInputParameter : public ModelLoader::InputParameter +{ +public: + using ConvertFontCode = void (*)(const std::string& code, std::string& fontFamily, std::string& slant, std::string& weight, float& size); + using ConvertColorCode = Vector4 (*)(const std::string& code); + using CategoryProcessor = std::function; + using CategoryProcessorVector = std::vector>; + using NodeProcessor = std::function; + using AnimationProcessor = std::function; + +public: + /** + * @brief The absolute path of animation binaries referenced in the .dli. + */ + std::string mAnimationsPath; + + /** + * @brief Provides a facility to determine a color from a code instead of RGB(A) values. + */ + ConvertColorCode mConvertColorCode{nullptr}; + + /** + * @brief A collection of handlers, mapped to the names of the top level (i.e. below + * root) element, whom they will attempt to process. This will take place before + * the parsing of scene Nodes and Animations, but after skeletons, environment, mesh, + * shader and material resources. + */ + CategoryProcessorVector mPreNodeCategoryProcessors; + + /** + * @brief A collection of handlers, mapped to the names of the top level (i.e. below + * root) element, whom they will attempt to process. This will take place after + * the parsing of the scene Nodes and Animations. + */ + CategoryProcessorVector mPostNodeCategoryProcessors; + + /** + * @brief Provides an extension point to nodes. If provided, this function will be + * called with each JSON element and definition, of a scene node. + * @note Constraints rely on ID resolution (from .dli to scene definition), which + * takes place after the parsing of the nodes; therefore AT THIS POINT the node + * IDs seen in constraints will still be the .dli IDs - NOT to be relied on for + * indexing into mScene. + */ + NodeProcessor mNodePropertyProcessor{nullptr}; + + /** + * @brief Provides an extension point to animations. If provided, this function will be + * called with each JSON element and fully processed definition, of an animation. + */ + AnimationProcessor mAnimationPropertyProcessor; +}; + +} // namespace Dali::Scene3D::Loader + +#endif // DALI_SCENE3D_LOADER_DLI_INPUT_PARAMETER_H diff --git a/dali-scene3d/public-api/loader/dli-loader.h b/dali-scene3d/public-api/loader/dli-loader.h deleted file mode 100644 index c516f9a..0000000 --- a/dali-scene3d/public-api/loader/dli-loader.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef DALI_SCENE3D_LOADER_DLI_LOADER_H -#define DALI_SCENE3D_LOADER_DLI_LOADER_H -/* - * Copyright (c) 2022 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. - * - */ - -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" -#include "dali-scene3d/public-api/loader/animation-definition.h" -#include "dali-scene3d/public-api/loader/customization.h" -#include "dali-scene3d/public-api/loader/index.h" -#include "dali-scene3d/public-api/loader/string-callback.h" - -// EXTERNAL INCLUDES -#include "dali/public-api/common/vector-wrapper.h" - -namespace Dali -{ -namespace Scene3D -{ -namespace Loader -{ -typedef std::pair Metadata; - -// Forward declarations -struct LoadResult; -struct CameraParameters; -struct LightParameters; -struct TextParameters; - -class ResourceBundle; -struct NodeDefinition; -class SceneDefinition; - -class DALI_SCENE3D_API DliLoader -{ -public: - using ConvertFontCode = void (*)(const std::string& code, std::string& fontFamily, std::string& slant, std::string& weight, float& size); - using ConvertColorCode = Vector4 (*)(const std::string& code); - - using CategoryProcessor = std::function; - using CategoryProcessorVector = std::vector>; - - using NodeProcessor = std::function; - - using AnimationProcessor = std::function; - - struct InputParams - { - /** - * @brief The absolute path of animation binaries referenced in the .dli. - */ - std::string mAnimationsPath; - - /** - * @brief Provides a facility to determine a color from a code instead of RGB(A) values. - */ - ConvertColorCode mConvertColorCode; - - /** - * @brief A collection of handlers, mapped to the names of the top level (i.e. below - * root) element, whom they will attempt to process. This will take place before - * the parsing of scene Nodes and Animations, but after skeletons, environment, mesh, - * shader and material resources. - */ - CategoryProcessorVector mPreNodeCategoryProcessors; - - /** - * @brief A collection of handlers, mapped to the names of the top level (i.e. below - * root) element, whom they will attempt to process. This will take place after - * the parsing of the scene Nodes and Animations. - */ - CategoryProcessorVector mPostNodeCategoryProcessors; - - /** - * @brief Provides an extension point to nodes. If provided, this function will be - * called with each JSON element and definition, of a scene node. - * @note Constraints rely on ID resolution (from .dli to scene definition), which - * takes place after the parsing of the nodes; therefore AT THIS POINT the node - * IDs seen in constraints will still be the .dli IDs - NOT to be relied on for - * indexing into mScene. - */ - NodeProcessor mNodePropertyProcessor; - - /** - * @brief Provides an extension point to animations. If provided, this function will be - * called with each JSON element and fully processed definition, of an animation. - */ - AnimationProcessor mAnimationPropertyProcessor; - }; - - struct LoadParams - { - InputParams const& input; - LoadResult& output; - }; - - DliLoader(); - ~DliLoader(); - - /** - * @brief Sets the callback that messages from non-fatal errors get posted to. - * Uses DefaultErrorCallback by default. - */ - void SetErrorCallback(StringCallback onError); - - /** - * @brief Attempts to load and parse a .dli document into a DOM tree. - * @return Whether the operation was successful. - */ - bool LoadScene(const std::string& uri, LoadParams& params); - - /** - * @return The error string describing how the parse has failed, if any. - */ - std::string GetParseError() const; - -private: - struct Impl; - const std::unique_ptr mImpl; -}; - -} // namespace Loader -} // namespace Scene3D -} // namespace Dali - -#endif // DALI_SCENE3D_LOADER_DLI_LOADER_H diff --git a/dali-scene3d/public-api/loader/environment-definition.cpp b/dali-scene3d/public-api/loader/environment-definition.cpp index 3dea7c9..16ec2df 100644 --- a/dali-scene3d/public-api/loader/environment-definition.cpp +++ b/dali-scene3d/public-api/loader/environment-definition.cpp @@ -15,14 +15,16 @@ * */ +// CLASS HEADER +#include + // EXTERNAL INCLUDES #include #include // INTERNAL INCLUDES -#include "dali-scene3d/public-api/loader/environment-map-loader.h" -#include "dali-scene3d/public-api/loader/environment-definition.h" -#include "dali-scene3d/public-api/loader/utils.h" +#include +#include namespace { @@ -35,11 +37,7 @@ std::string GetDaliImagePath() static constexpr float DEFAULT_INTENSITY = 1.0f; } // unnamed namespace -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { namespace { @@ -109,6 +107,4 @@ float EnvironmentDefinition::GetDefaultIntensity() return DEFAULT_INTENSITY; } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader \ No newline at end of file diff --git a/dali-scene3d/public-api/loader/environment-definition.h b/dali-scene3d/public-api/loader/environment-definition.h index 8f1525d..3c4ceee 100644 --- a/dali-scene3d/public-api/loader/environment-definition.h +++ b/dali-scene3d/public-api/loader/environment-definition.h @@ -17,20 +17,16 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" -#include "dali-scene3d/public-api/loader/environment-map-data.h" - // EXTERNAL INCLUDES +#include +#include #include -#include "dali/public-api/math/quaternion.h" -#include "dali/public-api/rendering/texture.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include +#include + +namespace Dali::Scene3D::Loader { /** * @brief Defines an environment map with either or both of radiance @@ -62,10 +58,10 @@ struct DALI_SCENE3D_API EnvironmentDefinition EnvironmentDefinition() = default; - EnvironmentDefinition(const EnvironmentDefinition&) = delete; + EnvironmentDefinition(const EnvironmentDefinition&) = delete; EnvironmentDefinition& operator=(const EnvironmentDefinition&) = delete; - EnvironmentDefinition(EnvironmentDefinition&&) = default; + EnvironmentDefinition(EnvironmentDefinition&&) = default; EnvironmentDefinition& operator=(EnvironmentDefinition&&) = default; /** @@ -97,8 +93,6 @@ public: // DATA bool mUseBrdfTexture = false; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif // DALI_SCENE3D_LOADER_ENVIRONMENT_DEFINITION_H diff --git a/dali-scene3d/public-api/loader/environment-map-data.cpp b/dali-scene3d/public-api/loader/environment-map-data.cpp index fdbd159..cca2952 100644 --- a/dali-scene3d/public-api/loader/environment-map-data.cpp +++ b/dali-scene3d/public-api/loader/environment-map-data.cpp @@ -24,11 +24,7 @@ // INTERNAL INCLUDES #include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { Texture EnvironmentMapData::GetTexture() { @@ -67,6 +63,4 @@ Texture EnvironmentMapData::GetTexture() return mEnvironmentMapTexture; } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/environment-map-data.h b/dali-scene3d/public-api/loader/environment-map-data.h index 7f3ee8c..2feac5b 100644 --- a/dali-scene3d/public-api/loader/environment-map-data.h +++ b/dali-scene3d/public-api/loader/environment-map-data.h @@ -17,21 +17,17 @@ * */ -// INTERNAL INCLUDES -#include -#include - // EXTERNAL INCLUDES #include #include -#include #include +#include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include +#include + +namespace Dali::Scene3D::Loader { /** * @brief Stores the pixel data objects for environment map texture. @@ -78,8 +74,6 @@ private: Dali::Scene3D::EnvironmentMapType mEnvironmentMapType{Dali::Scene3D::EnvironmentMapType::AUTO}; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif // DALI_SCENE3D_LOADER_ENVIRONMENT_MAP_DATA_H diff --git a/dali-scene3d/public-api/loader/environment-map-loader.cpp b/dali-scene3d/public-api/loader/environment-map-loader.cpp index 175c19a..7abff75 100644 --- a/dali-scene3d/public-api/loader/environment-map-loader.cpp +++ b/dali-scene3d/public-api/loader/environment-map-loader.cpp @@ -18,14 +18,14 @@ // FILE HEADER #include -// INTERNAL INCLUDES -#include - // EXTERNAL INCLUDES #include #include #include +// INTERNAL INCLUDES +#include + namespace Dali { namespace @@ -45,21 +45,19 @@ static constexpr uint32_t CUBEMAP_INDEX_X[NUMBER_OF_CUBE_MAP_TYPE][6] = {{2, 0, static constexpr uint32_t CUBEMAP_INDEX_Y[NUMBER_OF_CUBE_MAP_TYPE][6] = {{1, 1, 0, 2, 1, 1}, {0, 0, 0, 0, 0, 0}, {1, 3, 0, 2, 1, 1}, {0, 1, 2, 3, 4, 5}}; static constexpr Vector2 NUMBER_OF_CUBE_FACE[NUMBER_OF_CUBE_MAP_TYPE] = -{ - Vector2(4, 3), - Vector2(6, 1), - Vector2(3, 4), - Vector2(1, 6) -}; + { + Vector2(4, 3), + Vector2(6, 1), + Vector2(3, 4), + Vector2(1, 6)}; static constexpr float expectedAspectRatios[NUMBER_OF_ENVIRONMENT_MAP_TYPE] = -{ - 4.0f / 3.0f, - 6.0f / 1.0f, - 3.0f / 4.0f, - 1.0f / 6.0f, - 2.0f / 1.0f -}; + { + 4.0f / 3.0f, + 6.0f / 1.0f, + 3.0f / 4.0f, + 1.0f / 6.0f, + 2.0f / 1.0f}; enum CubeType { @@ -189,7 +187,6 @@ namespace Scene3D { namespace Loader { - bool LoadEnvironmentMap(const std::string& environmentMapUrl, EnvironmentMapData& environmentMapData) { std::filesystem::path modelPath(environmentMapUrl); diff --git a/dali-scene3d/public-api/loader/environment-map-loader.h b/dali-scene3d/public-api/loader/environment-map-loader.h index 57047ea..f07f28c 100644 --- a/dali-scene3d/public-api/loader/environment-map-loader.h +++ b/dali-scene3d/public-api/loader/environment-map-loader.h @@ -19,16 +19,11 @@ // INTERNAL INCLUDES #include -#include #include +#include -namespace Dali -{ -namespace Scene3D +namespace Dali::Scene3D::Loader { -namespace Loader -{ - /** * @brief Loads environment map data from a environment map file. * @@ -38,8 +33,6 @@ namespace Loader */ bool DALI_SCENE3D_API LoadEnvironmentMap(const std::string& environmentMapUrl, EnvironmentMapData& environmentMapData); -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif // DALI_SCENE3D_LOADER_ENVIRONMENT_MAP_LOADER_H diff --git a/dali-scene3d/public-api/loader/gltf2-loader.cpp b/dali-scene3d/public-api/loader/gltf2-loader.cpp deleted file mode 100644 index c0ca6cd..0000000 --- a/dali-scene3d/public-api/loader/gltf2-loader.cpp +++ /dev/null @@ -1,1500 +0,0 @@ -/* - * 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. - * - */ - -// FILE HEADER -#include - -// EXTERNAL INCLUDES -#include -#include -#include -#include -#include - -// INTERNAL INCLUDES -#include -#include -#include -#include -#include -#include - -namespace gt = gltf2; -namespace js = json; - -namespace Dali -{ -namespace Scene3D -{ -namespace Loader -{ -namespace -{ -Dali::Mutex gInitializeMutex; -Dali::Mutex gReadMutex; - -const char* POSITION_PROPERTY("position"); -const char* ORIENTATION_PROPERTY("orientation"); -const char* SCALE_PROPERTY("scale"); -const char* BLEND_SHAPE_WEIGHTS_UNIFORM("uBlendShapeWeight"); -const char* MRENDERER_MODEL_IDENTIFICATION("M-Renderer"); -const char* ROOT_NODE_NAME("RootNode"); -const Vector3 SCALE_TO_ADJUST(100.0f, 100.0f, 100.0f); - -const Geometry::Type GLTF2_TO_DALI_PRIMITIVES[]{ - Geometry::POINTS, - Geometry::LINES, - Geometry::LINE_LOOP, - Geometry::LINE_STRIP, - Geometry::TRIANGLES, - Geometry::TRIANGLE_STRIP, - Geometry::TRIANGLE_FAN}; //...because Dali swaps the last two. - -struct AttributeMapping -{ - gt::Attribute::Type mType; - MeshDefinition::Accessor MeshDefinition::*mAccessor; - uint16_t mElementSizeRequired; -} ATTRIBUTE_MAPPINGS[]{ - {gt::Attribute::NORMAL, &MeshDefinition::mNormals, sizeof(Vector3)}, - {gt::Attribute::TANGENT, &MeshDefinition::mTangents, sizeof(Vector3)}, - {gt::Attribute::TEXCOORD_0, &MeshDefinition::mTexCoords, sizeof(Vector2)}, - {gt::Attribute::COLOR_0, &MeshDefinition::mColors, sizeof(Vector4)}, - {gt::Attribute::JOINTS_0, &MeshDefinition::mJoints0, sizeof(Vector4)}, - {gt::Attribute::WEIGHTS_0, &MeshDefinition::mWeights0, sizeof(Vector4)}, -}; - -std::vector ReadAnimationArray(const json_value_s& j) -{ - auto results = js::Read::Array::Read>(j); - - for(auto& animation : results) - { - for(auto& channel : animation.mChannels) - { - channel.mSampler.UpdateVector(animation.mSamplers); - } - } - - return results; -} - -void ApplyAccessorMinMax(const gt::Accessor& acc, float* values) -{ - DALI_ASSERT_ALWAYS(acc.mMax.empty() || gt::AccessorType::ElementCount(acc.mType) == acc.mMax.size()); - DALI_ASSERT_ALWAYS(acc.mMin.empty() || gt::AccessorType::ElementCount(acc.mType) == acc.mMin.size()); - MeshDefinition::Blob::ApplyMinMax(acc.mMin, acc.mMax, acc.mCount, values); -} - -const js::Reader& GetBufferReader() -{ - static const auto BUFFER_READER = std::move(js::Reader() - .Register(*js::MakeProperty("byteLength", js::Read::Number, >::Buffer::mByteLength)) - .Register(*js::MakeProperty("uri", js::Read::StringView, >::Buffer::mUri))); - return BUFFER_READER; -} - -const js::Reader& GetBufferViewReader() -{ - static const auto BUFFER_VIEW_READER = std::move(js::Reader() - .Register(*js::MakeProperty("buffer", gt::RefReader::Read, >::BufferView::mBuffer)) - .Register(*js::MakeProperty("byteOffset", js::Read::Number, >::BufferView::mByteOffset)) - .Register(*js::MakeProperty("byteLength", js::Read::Number, >::BufferView::mByteLength)) - .Register(*js::MakeProperty("byteStride", js::Read::Number, >::BufferView::mByteStride)) - .Register(*js::MakeProperty("target", js::Read::Number, >::BufferView::mTarget))); - return BUFFER_VIEW_READER; -} - -const js::Reader& GetBufferViewClientReader() -{ - static const auto BUFFER_VIEW_CLIENT_READER = std::move(js::Reader() - .Register(*js::MakeProperty("bufferView", gt::RefReader::Read, >::BufferViewClient::mBufferView)) - .Register(*js::MakeProperty("byteOffset", js::Read::Number, >::BufferViewClient::mByteOffset))); - return BUFFER_VIEW_CLIENT_READER; -} - -const js::Reader& GetComponentTypedBufferViewClientReader() -{ - static const auto COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER = std::move(js::Reader() - .Register(*new js::Property>("bufferView", gt::RefReader::Read, >::ComponentTypedBufferViewClient::mBufferView)) - .Register(*new js::Property("byteOffset", js::Read::Number, >::ComponentTypedBufferViewClient::mByteOffset)) - .Register(*js::MakeProperty("componentType", js::Read::Enum, >::ComponentTypedBufferViewClient::mComponentType))); - return COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER; -} - -const js::Reader& GetAccessorSparseReader() -{ - static const auto ACCESSOR_SPARSE_READER = std::move(js::Reader() - .Register(*js::MakeProperty("count", js::Read::Number, >::Accessor::Sparse::mCount)) - .Register(*js::MakeProperty("indices", js::ObjectReader::Read, >::Accessor::Sparse::mIndices)) - .Register(*js::MakeProperty("values", js::ObjectReader::Read, >::Accessor::Sparse::mValues))); - return ACCESSOR_SPARSE_READER; -} - -const js::Reader& GetAccessorReader() -{ - static const auto ACCESSOR_READER = std::move(js::Reader() - .Register(*new js::Property>("bufferView", - gt::RefReader::Read, - >::Accessor::mBufferView)) - .Register(*new js::Property("byteOffset", - js::Read::Number, - >::Accessor::mByteOffset)) - .Register(*new js::Property("componentType", - js::Read::Enum, - >::Accessor::mComponentType)) - .Register(*new js::Property("name", js::Read::StringView, >::Accessor::mName)) - .Register(*js::MakeProperty("count", js::Read::Number, >::Accessor::mCount)) - .Register(*js::MakeProperty("normalized", js::Read::Boolean, >::Accessor::mNormalized)) - .Register(*js::MakeProperty("type", gt::ReadStringEnum, >::Accessor::mType)) - .Register(*js::MakeProperty("min", js::Read::Array, >::Accessor::mMin)) - .Register(*js::MakeProperty("max", js::Read::Array, >::Accessor::mMax)) - .Register(*new js::Property("sparse", js::ObjectReader::Read, >::Accessor::SetSparse))); - return ACCESSOR_READER; -} - -const js::Reader& GetImageReader() -{ - static const auto IMAGE_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Material::mName)) - .Register(*js::MakeProperty("uri", js::Read::StringView, >::Image::mUri)) - .Register(*js::MakeProperty("mimeType", js::Read::StringView, >::Image::mMimeType)) - .Register(*js::MakeProperty("bufferView", gt::RefReader::Read, >::Image::mBufferView))); - return IMAGE_READER; -} - -const js::Reader& GetSamplerReader() -{ - static const auto SAMPLER_READER = std::move(js::Reader() - .Register(*js::MakeProperty("minFilter", js::Read::Enum, >::Sampler::mMinFilter)) - .Register(*js::MakeProperty("magFilter", js::Read::Enum, >::Sampler::mMagFilter)) - .Register(*js::MakeProperty("wrapS", js::Read::Enum, >::Sampler::mWrapS)) - .Register(*js::MakeProperty("wrapT", js::Read::Enum, >::Sampler::mWrapT))); - return SAMPLER_READER; -} - -const js::Reader& GetTextureReader() -{ - static const auto TEXURE_READER = std::move(js::Reader() - .Register(*js::MakeProperty("source", gt::RefReader::Read, >::Texture::mSource)) - .Register(*js::MakeProperty("sampler", gt::RefReader::Read, >::Texture::mSampler))); - return TEXURE_READER; -} - -const js::Reader& GetTextureInfoReader() -{ - static const auto TEXURE_INFO_READER = std::move(js::Reader() - .Register(*js::MakeProperty("index", gt::RefReader::Read, >::TextureInfo::mTexture)) - .Register(*js::MakeProperty("texCoord", js::Read::Number, >::TextureInfo::mTexCoord)) - .Register(*js::MakeProperty("scale", js::Read::Number, >::TextureInfo::mScale)) - .Register(*js::MakeProperty("strength", js::Read::Number, >::TextureInfo::mStrength))); - return TEXURE_INFO_READER; -} - -const js::Reader& GetMaterialPbrReader() -{ - static const auto MATERIAL_PBR_READER = std::move(js::Reader() - .Register(*js::MakeProperty("baseColorFactor", gt::ReadDaliVector, >::Material::Pbr::mBaseColorFactor)) - .Register(*js::MakeProperty("baseColorTexture", js::ObjectReader::Read, >::Material::Pbr::mBaseColorTexture)) - .Register(*js::MakeProperty("metallicFactor", js::Read::Number, >::Material::Pbr::mMetallicFactor)) - .Register(*js::MakeProperty("roughnessFactor", js::Read::Number, >::Material::Pbr::mRoughnessFactor)) - .Register(*js::MakeProperty("metallicRoughnessTexture", js::ObjectReader::Read, >::Material::Pbr::mMetallicRoughnessTexture))); - return MATERIAL_PBR_READER; -} - -const js::Reader& GetMaterialSpecularReader() -{ - static const auto MATERIAL_SPECULAR_READER = std::move(js::Reader() - .Register(*js::MakeProperty("specularFactor", js::Read::Number, >::MaterialSpecular::mSpecularFactor)) - .Register(*js::MakeProperty("specularTexture", js::ObjectReader::Read, >::MaterialSpecular::mSpecularTexture)) - .Register(*js::MakeProperty("specularColorFactor", gt::ReadDaliVector, >::MaterialSpecular::mSpecularColorFactor)) - .Register(*js::MakeProperty("specularColorTexture", js::ObjectReader::Read, >::MaterialSpecular::mSpecularColorTexture))); - return MATERIAL_SPECULAR_READER; -} - -const js::Reader& GetMaterialIorReader() -{ - static const auto MATERIAL_IOR_READER = std::move(js::Reader() - .Register(*js::MakeProperty("ior", js::Read::Number, >::MaterialIor::mIor))); - return MATERIAL_IOR_READER; -} - -const js::Reader& GetMaterialExtensionsReader() -{ - static const auto MATERIAL_EXTENSION_READER = std::move(js::Reader() - .Register(*js::MakeProperty("KHR_materials_ior", js::ObjectReader::Read, >::MaterialExtensions::mMaterialIor)) - .Register(*js::MakeProperty("KHR_materials_specular", js::ObjectReader::Read, >::MaterialExtensions::mMaterialSpecular))); - return MATERIAL_EXTENSION_READER; -} - -const js::Reader& GetMaterialReader() -{ - static const auto MATERIAL_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Material::mName)) - .Register(*js::MakeProperty("pbrMetallicRoughness", js::ObjectReader::Read, >::Material::mPbrMetallicRoughness)) - .Register(*js::MakeProperty("normalTexture", js::ObjectReader::Read, >::Material::mNormalTexture)) - .Register(*js::MakeProperty("occlusionTexture", js::ObjectReader::Read, >::Material::mOcclusionTexture)) - .Register(*js::MakeProperty("emissiveTexture", js::ObjectReader::Read, >::Material::mEmissiveTexture)) - .Register(*js::MakeProperty("emissiveFactor", gt::ReadDaliVector, >::Material::mEmissiveFactor)) - .Register(*js::MakeProperty("alphaMode", gt::ReadStringEnum, >::Material::mAlphaMode)) - .Register(*js::MakeProperty("alphaCutoff", js::Read::Number, >::Material::mAlphaCutoff)) - .Register(*js::MakeProperty("doubleSided", js::Read::Boolean, >::Material::mDoubleSided)) - .Register(*js::MakeProperty("extensions", js::ObjectReader::Read, >::Material::mMaterialExtensions))); - return MATERIAL_READER; -} - -std::map> ReadMeshPrimitiveAttributes(const json_value_s& j) -{ - auto& jo = js::Cast(j); - std::map> result; - - auto i = jo.start; - while(i) - { - auto jstr = *i->name; - result[gt::Attribute::FromString(jstr.string, jstr.string_size)] = gt::RefReader::Read(*i->value); - i = i->next; - } - return result; -} - -std::vector>> ReadMeshPrimitiveTargets(const json_value_s& j) -{ - auto& jo = js::Cast(j); - std::vector>> result; - - result.reserve(jo.length); - - auto i = jo.start; - while(i) - { - result.push_back(std::move(ReadMeshPrimitiveAttributes(*i->value))); - i = i->next; - } - - return result; -} - -const js::Reader& GetMeshPrimitiveReader() -{ - static const auto MESH_PRIMITIVE_READER = std::move(js::Reader() - .Register(*js::MakeProperty("attributes", ReadMeshPrimitiveAttributes, >::Mesh::Primitive::mAttributes)) - .Register(*js::MakeProperty("indices", gt::RefReader::Read, >::Mesh::Primitive::mIndices)) - .Register(*js::MakeProperty("material", gt::RefReader::Read, >::Mesh::Primitive::mMaterial)) - .Register(*js::MakeProperty("mode", js::Read::Enum, >::Mesh::Primitive::mMode)) - .Register(*js::MakeProperty("targets", ReadMeshPrimitiveTargets, >::Mesh::Primitive::mTargets))); - return MESH_PRIMITIVE_READER; -} - -const js::Reader& GetMeshReader() -{ - static const auto MESH_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Mesh::mName)) - .Register(*js::MakeProperty("primitives", - js::Read::Array::Read>, - >::Mesh::mPrimitives)) - .Register(*js::MakeProperty("weights", js::Read::Array, >::Mesh::mWeights))); - return MESH_READER; -} - -const js::Reader& GetSkinReader() -{ - static const auto SKIN_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Skin::mName)) - .Register(*js::MakeProperty("inverseBindMatrices", - gt::RefReader::Read, - >::Skin::mInverseBindMatrices)) - .Register(*js::MakeProperty("skeleton", - gt::RefReader::Read, - >::Skin::mSkeleton)) - .Register(*js::MakeProperty("joints", - js::Read::Array, gt::RefReader::Read>, - >::Skin::mJoints))); - return SKIN_READER; -} - -const js::Reader& GetCameraPerspectiveReader() -{ - static const auto CAMERA_PERSPECTIVE_READER = std::move(js::Reader() - .Register(*js::MakeProperty("aspectRatio", js::Read::Number, >::Camera::Perspective::mAspectRatio)) - .Register(*js::MakeProperty("yfov", js::Read::Number, >::Camera::Perspective::mYFov)) - .Register(*js::MakeProperty("zfar", js::Read::Number, >::Camera::Perspective::mZFar)) - .Register(*js::MakeProperty("znear", js::Read::Number, >::Camera::Perspective::mZNear))); // TODO: infinite perspective projection, where znear is omitted - return CAMERA_PERSPECTIVE_READER; -} - -const js::Reader& GetCameraOrthographicReader() -{ - static const auto CAMERA_ORTHOGRAPHIC_READER = std::move(js::Reader() - .Register(*js::MakeProperty("xmag", js::Read::Number, >::Camera::Orthographic::mXMag)) - .Register(*js::MakeProperty("ymag", js::Read::Number, >::Camera::Orthographic::mYMag)) - .Register(*js::MakeProperty("zfar", js::Read::Number, >::Camera::Orthographic::mZFar)) - .Register(*js::MakeProperty("znear", js::Read::Number, >::Camera::Orthographic::mZNear))); - return CAMERA_ORTHOGRAPHIC_READER; -} - -const js::Reader& GetCameraReader() -{ - static const auto CAMERA_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Camera::mName)) - .Register(*js::MakeProperty("type", js::Read::StringView, >::Camera::mType)) - .Register(*js::MakeProperty("perspective", js::ObjectReader::Read, >::Camera::mPerspective)) - .Register(*js::MakeProperty("orthographic", js::ObjectReader::Read, >::Camera::mOrthographic))); - return CAMERA_READER; -} - -const js::Reader& GetNodeReader() -{ - static const auto NODE_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Node::mName)) - .Register(*js::MakeProperty("translation", gt::ReadDaliVector, >::Node::mTranslation)) - .Register(*js::MakeProperty("rotation", gt::ReadQuaternion, >::Node::mRotation)) - .Register(*js::MakeProperty("scale", gt::ReadDaliVector, >::Node::mScale)) - .Register(*new js::Property("matrix", gt::ReadDaliVector, >::Node::SetMatrix)) - .Register(*js::MakeProperty("camera", gt::RefReader::Read, >::Node::mCamera)) - .Register(*js::MakeProperty("children", js::Read::Array, gt::RefReader::Read>, >::Node::mChildren)) - .Register(*js::MakeProperty("mesh", gt::RefReader::Read, >::Node::mMesh)) - .Register(*js::MakeProperty("skin", gt::RefReader::Read, >::Node::mSkin))); - return NODE_READER; -} - -const js::Reader& GetAnimationSamplerReader() -{ - static const auto ANIMATION_SAMPLER_READER = std::move(js::Reader() - .Register(*js::MakeProperty("input", gt::RefReader::Read, >::Animation::Sampler::mInput)) - .Register(*js::MakeProperty("output", gt::RefReader::Read, >::Animation::Sampler::mOutput)) - .Register(*js::MakeProperty("interpolation", gt::ReadStringEnum, >::Animation::Sampler::mInterpolation))); - return ANIMATION_SAMPLER_READER; -} - -const js::Reader& GetAnimationChannelTargetReader() -{ - static const auto ANIMATION_TARGET_READER = std::move(js::Reader() - .Register(*js::MakeProperty("node", gt::RefReader::Read, >::Animation::Channel::Target::mNode)) - .Register(*js::MakeProperty("path", gt::ReadStringEnum, >::Animation::Channel::Target::mPath))); - return ANIMATION_TARGET_READER; -} - -const js::Reader& GetAnimationChannelReader() -{ - static const auto ANIMATION_CHANNEL_READER = std::move(js::Reader() - .Register(*js::MakeProperty("target", js::ObjectReader::Read, >::Animation::Channel::mTarget)) - .Register(*js::MakeProperty("sampler", gt::RefReader::Read, >::Animation::Channel::mSampler))); - return ANIMATION_CHANNEL_READER; -} - -const js::Reader& GetAnimationReader() -{ - static const auto ANIMATION_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Animation::mName)) - .Register(*js::MakeProperty("samplers", - js::Read::Array::Read>, - >::Animation::mSamplers)) - .Register(*js::MakeProperty("channels", - js::Read::Array::Read>, - >::Animation::mChannels))); - return ANIMATION_READER; -} - -const js::Reader& GetSceneReader() -{ - static const auto SCENE_READER = std::move(js::Reader() - .Register(*new js::Property("name", js::Read::StringView, >::Scene::mName)) - .Register(*js::MakeProperty("nodes", - js::Read::Array, gt::RefReader::Read>, - >::Scene::mNodes))); - return SCENE_READER; -} - -const js::Reader& GetDocumentReader() -{ - static const auto DOCUMENT_READER = std::move(js::Reader() - .Register(*js::MakeProperty("buffers", - js::Read::Array::Read>, - >::Document::mBuffers)) - .Register(*js::MakeProperty("bufferViews", - js::Read::Array::Read>, - >::Document::mBufferViews)) - .Register(*js::MakeProperty("accessors", - js::Read::Array::Read>, - >::Document::mAccessors)) - .Register(*js::MakeProperty("images", - js::Read::Array::Read>, - >::Document::mImages)) - .Register(*js::MakeProperty("samplers", - js::Read::Array::Read>, - >::Document::mSamplers)) - .Register(*js::MakeProperty("textures", - js::Read::Array::Read>, - >::Document::mTextures)) - .Register(*js::MakeProperty("materials", - js::Read::Array::Read>, - >::Document::mMaterials)) - .Register(*js::MakeProperty("meshes", - js::Read::Array::Read>, - >::Document::mMeshes)) - .Register(*js::MakeProperty("skins", - js::Read::Array::Read>, - >::Document::mSkins)) - .Register(*js::MakeProperty("cameras", - js::Read::Array::Read>, - >::Document::mCameras)) - .Register(*js::MakeProperty("nodes", - js::Read::Array::Read>, - >::Document::mNodes)) - .Register(*js::MakeProperty("animations", - ReadAnimationArray, - >::Document::mAnimations)) - .Register(*js::MakeProperty("scenes", - js::Read::Array::Read>, - >::Document::mScenes)) - .Register(*js::MakeProperty("scene", gt::RefReader::Read, >::Document::mScene))); - return DOCUMENT_READER; -} - -struct NodeMapping -{ - Index gltfIdx; - Index runtimeIdx; -}; - -bool operator<(const NodeMapping& mapping, Index gltfIdx) -{ - return mapping.gltfIdx < gltfIdx; -} - -class NodeIndexMapper -{ -public: - NodeIndexMapper() = default; - NodeIndexMapper(const NodeIndexMapper&) = delete; - NodeIndexMapper& operator=(const NodeIndexMapper&) = delete; - - ///@brief Registers a mapping of the @a gltfIdx of a node to its @a runtimeIdx . - ///@note If the indices are the same, the registration is omitted, in order to - /// save growing a vector. - void RegisterMapping(Index gltfIdx, Index runtimeIdx) - { - if(gltfIdx != runtimeIdx) - { - auto iInsert = std::lower_bound(mNodes.begin(), mNodes.end(), gltfIdx); - DALI_ASSERT_DEBUG(iInsert == mNodes.end() || iInsert->gltfIdx != gltfIdx); - mNodes.insert(iInsert, NodeMapping{gltfIdx, runtimeIdx}); - } - } - - ///@brief Retrieves the runtime index of a Node, mapped to the given @a gltfIdx. - Index GetRuntimeId(Index gltfIdx) const - { - auto iFind = std::lower_bound(mNodes.begin(), mNodes.end(), gltfIdx); // using custom operator< - return (iFind != mNodes.end() && iFind->gltfIdx == gltfIdx) ? iFind->runtimeIdx : gltfIdx; - } - -private: - std::vector mNodes; -}; - -struct ConversionContext -{ - LoadResult& mOutput; - - std::string mPath; - Index mDefaultMaterial; - - std::vector mMeshIds; - NodeIndexMapper mNodeIndices; -}; - -void ConvertBuffer(const gt::Buffer& buffer, decltype(ResourceBundle::mBuffers)& outBuffers, const std::string& resourcePath) -{ - BufferDefinition bufferDefinition; - - bufferDefinition.mResourcePath = resourcePath; - bufferDefinition.mUri = buffer.mUri; - bufferDefinition.mByteLength = buffer.mByteLength; - - outBuffers.emplace_back(std::move(bufferDefinition)); -} - -void ConvertBuffers(const gt::Document& doc, ConversionContext& context) -{ - auto& outBuffers = context.mOutput.mResources.mBuffers; - outBuffers.reserve(doc.mBuffers.size()); - - for(auto& buffer : doc.mBuffers) - { - ConvertBuffer(buffer, outBuffers, context.mPath); - } -} - -SamplerFlags::Type ConvertWrapMode(gt::Wrap::Type wrapMode) -{ - switch(wrapMode) - { - case gt::Wrap::REPEAT: - return SamplerFlags::WRAP_REPEAT; - case gt::Wrap::CLAMP_TO_EDGE: - return SamplerFlags::WRAP_CLAMP; - case gt::Wrap::MIRRORED_REPEAT: - return SamplerFlags::WRAP_MIRROR; - default: - throw std::runtime_error("Invalid wrap type."); - } -} - -SamplerFlags::Type ConvertSampler(const gt::Ref& sampler) -{ - if(sampler) - { - return ((sampler->mMinFilter < gt::Filter::NEAREST_MIPMAP_NEAREST) ? (sampler->mMinFilter - gt::Filter::NEAREST) : ((sampler->mMinFilter - gt::Filter::NEAREST_MIPMAP_NEAREST) + 2)) | - ((sampler->mMagFilter - gt::Filter::NEAREST) << SamplerFlags::FILTER_MAG_SHIFT) | - (ConvertWrapMode(sampler->mWrapS) << SamplerFlags::WRAP_S_SHIFT) | - (ConvertWrapMode(sampler->mWrapT) << SamplerFlags::WRAP_T_SHIFT); - } - else - { - // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#texturesampler - // "The index of the sampler used by this texture. When undefined, a sampler with repeat wrapping and auto filtering should be used." - // "What is an auto filtering", I hear you ask. Since there's nothing else to determine mipmapping from - including glTF image - // properties, if not in some extension -, we will simply assume linear filtering. - return SamplerFlags::FILTER_LINEAR | (SamplerFlags::FILTER_LINEAR << SamplerFlags::FILTER_MAG_SHIFT) | - (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_S_SHIFT) | (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_T_SHIFT); - } -} - -TextureDefinition ConvertTextureInfo(const gt::TextureInfo& mm, ConversionContext& context, const ImageMetadata& metaData = ImageMetadata()) -{ - TextureDefinition textureDefinition; - std::string uri = std::string(mm.mTexture->mSource->mUri); - if(uri.empty()) - { - uint32_t bufferIndex = mm.mTexture->mSource->mBufferView->mBuffer.GetIndex(); - if(bufferIndex != INVALID_INDEX && context.mOutput.mResources.mBuffers[bufferIndex].IsAvailable()) - { - auto& stream = context.mOutput.mResources.mBuffers[bufferIndex].GetBufferStream(); - stream.clear(); - stream.seekg(mm.mTexture->mSource->mBufferView->mByteOffset, stream.beg); - std::vector dataBuffer; - dataBuffer.resize(mm.mTexture->mSource->mBufferView->mByteLength); - stream.read(reinterpret_cast(dataBuffer.data()), static_cast(static_cast(mm.mTexture->mSource->mBufferView->mByteLength))); - return TextureDefinition{std::move(dataBuffer), ConvertSampler(mm.mTexture->mSampler), metaData.mMinSize, metaData.mSamplingMode}; - } - return TextureDefinition(); - } - else - { - return TextureDefinition{uri, ConvertSampler(mm.mTexture->mSampler), metaData.mMinSize, metaData.mSamplingMode}; - } -} - -void ConvertMaterial(const gt::Material& material, const std::unordered_map& imageMetaData, decltype(ResourceBundle::mMaterials)& outMaterials, ConversionContext& context) -{ - auto getTextureMetaData = [](const std::unordered_map& metaData, const gt::TextureInfo& info) { - if(!info.mTexture->mSource->mUri.empty()) - { - if(auto search = metaData.find(info.mTexture->mSource->mUri.data()); search != metaData.end()) - { - return search->second; - } - } - return ImageMetadata(); - }; - - MaterialDefinition matDef; - - auto& pbr = material.mPbrMetallicRoughness; - if(material.mAlphaMode == gt::AlphaMode::BLEND) - { - matDef.mIsOpaque = false; - matDef.mFlags |= MaterialDefinition::TRANSPARENCY; - } - else if(material.mAlphaMode == gt::AlphaMode::MASK) - { - matDef.mIsMask = true; - matDef.SetAlphaCutoff(std::min(1.f, std::max(0.f, material.mAlphaCutoff))); - } - - matDef.mBaseColorFactor = pbr.mBaseColorFactor; - - matDef.mTextureStages.reserve(!!pbr.mBaseColorTexture + !!pbr.mMetallicRoughnessTexture + !!material.mNormalTexture + !!material.mOcclusionTexture + !!material.mEmissiveTexture); - if(pbr.mBaseColorTexture) - { - const auto semantic = MaterialDefinition::ALBEDO; - matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(pbr.mBaseColorTexture, context, getTextureMetaData(imageMetaData, pbr.mBaseColorTexture))}); - // TODO: and there had better be one - matDef.mFlags |= semantic; - } - else - { - matDef.mNeedAlbedoTexture = false; - } - - matDef.mMetallic = pbr.mMetallicFactor; - matDef.mRoughness = pbr.mRoughnessFactor; - - if(pbr.mMetallicRoughnessTexture) - { - const auto semantic = MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | - MaterialDefinition::GLTF_CHANNELS; - matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(pbr.mMetallicRoughnessTexture, context, getTextureMetaData(imageMetaData, pbr.mMetallicRoughnessTexture))}); - // TODO: and there had better be one - matDef.mFlags |= semantic; - } - else - { - matDef.mNeedMetallicRoughnessTexture = false; - } - - matDef.mNormalScale = material.mNormalTexture.mScale; - if(material.mNormalTexture) - { - const auto semantic = MaterialDefinition::NORMAL; - matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mNormalTexture, context, getTextureMetaData(imageMetaData, material.mNormalTexture))}); - // TODO: and there had better be one - matDef.mFlags |= semantic; - } - else - { - matDef.mNeedNormalTexture = false; - } - - if(material.mOcclusionTexture) - { - const auto semantic = MaterialDefinition::OCCLUSION; - matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mOcclusionTexture, context, getTextureMetaData(imageMetaData, material.mOcclusionTexture))}); - // TODO: and there had better be one - matDef.mFlags |= semantic; - matDef.mOcclusionStrength = material.mOcclusionTexture.mStrength; - } - - if(material.mEmissiveTexture) - { - const auto semantic = MaterialDefinition::EMISSIVE; - matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mEmissiveTexture, context, getTextureMetaData(imageMetaData, material.mEmissiveTexture))}); - // TODO: and there had better be one - matDef.mFlags |= semantic; - matDef.mEmissiveFactor = material.mEmissiveFactor; - } - - if(!Dali::Equals(material.mMaterialExtensions.mMaterialIor.mIor, gltf2::UNDEFINED_FLOAT_VALUE)) - { - float ior = material.mMaterialExtensions.mMaterialIor.mIor; - matDef.mDielectricSpecular = powf((ior - 1.0f) / (ior + 1.0f), 2.0f); - } - matDef.mSpecularFactor = material.mMaterialExtensions.mMaterialSpecular.mSpecularFactor; - matDef.mSpecularColorFactor = material.mMaterialExtensions.mMaterialSpecular.mSpecularColorFactor; - - if(material.mMaterialExtensions.mMaterialSpecular.mSpecularTexture) - { - const auto semantic = MaterialDefinition::SPECULAR; - matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mMaterialExtensions.mMaterialSpecular.mSpecularTexture, context, getTextureMetaData(imageMetaData, material.mMaterialExtensions.mMaterialSpecular.mSpecularTexture))}); - matDef.mFlags |= semantic; - } - - if(material.mMaterialExtensions.mMaterialSpecular.mSpecularColorTexture) - { - const auto semantic = MaterialDefinition::SPECULAR_COLOR; - matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(material.mMaterialExtensions.mMaterialSpecular.mSpecularColorTexture, context, getTextureMetaData(imageMetaData, material.mMaterialExtensions.mMaterialSpecular.mSpecularColorTexture))}); - matDef.mFlags |= semantic; - } - - matDef.mDoubleSided = material.mDoubleSided; - - outMaterials.emplace_back(std::move(matDef), TextureSet()); -} - -void ConvertMaterials(const gt::Document& doc, ConversionContext& context) -{ - auto& imageMetaData = context.mOutput.mSceneMetadata.mImageMetadata; - - auto& outMaterials = context.mOutput.mResources.mMaterials; - outMaterials.reserve(doc.mMaterials.size()); - - for(auto& m : doc.mMaterials) - { - ConvertMaterial(m, imageMetaData, outMaterials, context); - } -} - -MeshDefinition::Accessor ConvertMeshPrimitiveAccessor(const gt::Accessor& acc) -{ - DALI_ASSERT_ALWAYS((acc.mBufferView && - (acc.mBufferView->mByteStride < std::numeric_limits::max())) || - (acc.mSparse && !acc.mBufferView)); - - DALI_ASSERT_ALWAYS(!acc.mSparse || - ((acc.mSparse->mIndices.mBufferView && (acc.mSparse->mIndices.mBufferView->mByteStride < std::numeric_limits::max())) && - (acc.mSparse->mValues.mBufferView && (acc.mSparse->mValues.mBufferView->mByteStride < std::numeric_limits::max())))); - - MeshDefinition::SparseBlob sparseBlob; - if(acc.mSparse) - { - const gt::Accessor::Sparse& sparse = *acc.mSparse; - const gt::ComponentTypedBufferViewClient& indices = sparse.mIndices; - const gt::BufferViewClient& values = sparse.mValues; - - MeshDefinition::Blob indicesBlob( - indices.mBufferView->mByteOffset + indices.mByteOffset, - sparse.mCount * indices.GetBytesPerComponent(), - static_cast(indices.mBufferView->mByteStride), - static_cast(indices.GetBytesPerComponent()), - {}, - {}); - MeshDefinition::Blob valuesBlob( - values.mBufferView->mByteOffset + values.mByteOffset, - sparse.mCount * acc.GetElementSizeBytes(), - static_cast(values.mBufferView->mByteStride), - static_cast(acc.GetElementSizeBytes()), - {}, - {}); - - sparseBlob = std::move(MeshDefinition::SparseBlob(std::move(indicesBlob), std::move(valuesBlob), acc.mSparse->mCount)); - } - - uint32_t bufferViewOffset = 0u; - uint32_t bufferViewStride = 0u; - if(acc.mBufferView) - { - bufferViewOffset = acc.mBufferView->mByteOffset; - bufferViewStride = acc.mBufferView->mByteStride; - } - - return MeshDefinition::Accessor{ - std::move(MeshDefinition::Blob{bufferViewOffset + acc.mByteOffset, - acc.GetBytesLength(), - static_cast(bufferViewStride), - static_cast(acc.GetElementSizeBytes()), - acc.mMin, - acc.mMax}), - std::move(sparseBlob), - acc.mBufferView ? acc.mBufferView->mBuffer.GetIndex() : 0}; -} - -void ConvertMeshes(const gt::Document& doc, ConversionContext& context) -{ - uint32_t meshCount = 0; - context.mMeshIds.reserve(doc.mMeshes.size()); - for(auto& mesh : doc.mMeshes) - { - context.mMeshIds.push_back(meshCount); - meshCount += mesh.mPrimitives.size(); - } - - auto& outMeshes = context.mOutput.mResources.mMeshes; - outMeshes.reserve(meshCount); - for(auto& mesh : doc.mMeshes) - { - for(auto& primitive : mesh.mPrimitives) - { - MeshDefinition meshDefinition; - - auto& attribs = primitive.mAttributes; - meshDefinition.mPrimitiveType = GLTF2_TO_DALI_PRIMITIVES[primitive.mMode]; - - auto& accPositions = *attribs.find(gt::Attribute::POSITION)->second; - meshDefinition.mPositions = ConvertMeshPrimitiveAccessor(accPositions); - // glTF2 support vector4 tangent for mesh. - // https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html#meshes-overview - meshDefinition.mTangentType = Property::VECTOR4; - - const bool needNormalsTangents = accPositions.mType == gt::AccessorType::VEC3; - for(auto& am : ATTRIBUTE_MAPPINGS) - { - auto iFind = attribs.find(am.mType); - if(iFind != attribs.end()) - { - auto& accessor = meshDefinition.*(am.mAccessor); - accessor = ConvertMeshPrimitiveAccessor(*iFind->second); - - if(iFind->first == gt::Attribute::JOINTS_0) - { - meshDefinition.mFlags |= (iFind->second->mComponentType == gt::Component::UNSIGNED_SHORT) * MeshDefinition::U16_JOINT_IDS; - meshDefinition.mFlags |= (iFind->second->mComponentType == gt::Component::UNSIGNED_BYTE) * MeshDefinition::U8_JOINT_IDS; - DALI_ASSERT_DEBUG(MaskMatch(meshDefinition.mFlags, MeshDefinition::U16_JOINT_IDS) || MaskMatch(meshDefinition.mFlags, MeshDefinition::U8_JOINT_IDS) || iFind->second->mComponentType == gt::Component::FLOAT); - } - } - else if(needNormalsTangents) - { - switch(am.mType) - { - case gt::Attribute::NORMAL: - meshDefinition.RequestNormals(); - break; - - case gt::Attribute::TANGENT: - meshDefinition.RequestTangents(); - break; - - default: - break; - } - } - } - - if(primitive.mIndices) - { - meshDefinition.mIndices = ConvertMeshPrimitiveAccessor(*primitive.mIndices); - meshDefinition.mFlags |= (primitive.mIndices->mComponentType == gt::Component::UNSIGNED_INT) * MeshDefinition::U32_INDICES; - meshDefinition.mFlags |= (primitive.mIndices->mComponentType == gt::Component::UNSIGNED_BYTE) * MeshDefinition::U8_INDICES; - DALI_ASSERT_DEBUG(MaskMatch(meshDefinition.mFlags, MeshDefinition::U32_INDICES) || MaskMatch(meshDefinition.mFlags, MeshDefinition::U8_INDICES) || primitive.mIndices->mComponentType == gt::Component::UNSIGNED_SHORT); - } - - if(!primitive.mTargets.empty()) - { - meshDefinition.mBlendShapes.reserve(primitive.mTargets.size()); - meshDefinition.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0; - for(const auto& target : primitive.mTargets) - { - MeshDefinition::BlendShape blendShape; - - auto endIt = target.end(); - auto it = target.find(gt::Attribute::POSITION); - if(it != endIt) - { - blendShape.deltas = ConvertMeshPrimitiveAccessor(*it->second); - } - it = target.find(gt::Attribute::NORMAL); - if(it != endIt) - { - blendShape.normals = ConvertMeshPrimitiveAccessor(*it->second); - } - it = target.find(gt::Attribute::TANGENT); - if(it != endIt) - { - blendShape.tangents = ConvertMeshPrimitiveAccessor(*it->second); - } - - if(!mesh.mWeights.empty()) - { - blendShape.weight = mesh.mWeights[meshDefinition.mBlendShapes.size()]; - } - - meshDefinition.mBlendShapes.push_back(std::move(blendShape)); - } - } - - outMeshes.push_back({std::move(meshDefinition), MeshGeometry{}}); - } - } -} - -ModelRenderable* MakeModelRenderable(const gt::Mesh::Primitive& prim, ConversionContext& context) -{ - auto modelRenderable = new ModelRenderable(); - - modelRenderable->mShaderIdx = 0; // TODO: further thought - - auto materialIdx = prim.mMaterial.GetIndex(); - if(INVALID_INDEX == materialIdx) - { - // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#default-material - if(INVALID_INDEX == context.mDefaultMaterial) - { - auto& outMaterials = context.mOutput.mResources.mMaterials; - context.mDefaultMaterial = outMaterials.size(); - - ConvertMaterial(gt::Material{}, context.mOutput.mSceneMetadata.mImageMetadata, outMaterials, context); - } - - materialIdx = context.mDefaultMaterial; - } - - modelRenderable->mMaterialIdx = materialIdx; - - return modelRenderable; -} - -void ConvertCamera(const gt::Camera& camera, CameraParameters& camParams) -{ - camParams.isPerspective = camera.mType.compare("perspective") == 0; - if(camParams.isPerspective) - { - auto& perspective = camera.mPerspective; - if(!Dali::Equals(perspective.mYFov, gltf2::UNDEFINED_FLOAT_VALUE)) - { - camParams.yFovDegree = Degree(Radian(perspective.mYFov)); - } - else - { - camParams.yFovDegree = Degree(gltf2::UNDEFINED_FLOAT_VALUE); - } - camParams.zNear = perspective.mZNear; - camParams.zFar = perspective.mZFar; - // TODO: yes, we seem to ignore aspectRatio in CameraParameters. - } - else - { - auto& ortho = camera.mOrthographic; - if(!Dali::Equals(ortho.mYMag, gltf2::UNDEFINED_FLOAT_VALUE) && !Dali::Equals(ortho.mXMag, gltf2::UNDEFINED_FLOAT_VALUE)) - { - camParams.orthographicSize = ortho.mYMag * .5f; - camParams.aspectRatio = ortho.mXMag / ortho.mYMag; - } - else - { - camParams.orthographicSize = gltf2::UNDEFINED_FLOAT_VALUE; - camParams.aspectRatio = gltf2::UNDEFINED_FLOAT_VALUE; - } - camParams.zNear = ortho.mZNear; - camParams.zFar = ortho.mZFar; - } -} - -void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, ConversionContext& context, bool isMRendererModel) -{ - auto& output = context.mOutput; - auto& scene = output.mScene; - auto& resources = output.mResources; - - const auto idx = scene.GetNodeCount(); - auto weakNode = scene.AddNode([&]() { - std::unique_ptr nodeDef{new NodeDefinition()}; - - nodeDef->mParentIdx = parentIdx; - nodeDef->mName = node.mName; - if(nodeDef->mName.empty()) - { - // TODO: Production quality generation of unique names. - nodeDef->mName = std::to_string(reinterpret_cast(nodeDef.get())); - } - - if(!node.mSkin) // Nodes with skinned meshes are not supposed to have local transforms. - { - nodeDef->mPosition = node.mTranslation; - nodeDef->mOrientation = node.mRotation; - nodeDef->mScale = node.mScale; - - if(isMRendererModel && node.mName == ROOT_NODE_NAME && node.mScale == SCALE_TO_ADJUST) - { - nodeDef->mScale *= 0.01f; - } - } - - return nodeDef; - }()); - if(!weakNode) - { - ExceptionFlinger(ASSERT_LOCATION) << "Node name '" << node.mName << "' is not unique; scene is invalid."; - } - - context.mNodeIndices.RegisterMapping(gltfIdx, idx); - - Index skeletonIdx = node.mSkin ? node.mSkin.GetIndex() : INVALID_INDEX; - if(node.mMesh) - { - auto& mesh = *node.mMesh; - uint32_t primitiveCount = mesh.mPrimitives.size(); - auto meshIdx = context.mMeshIds[node.mMesh.GetIndex()]; - weakNode->mRenderables.reserve(primitiveCount); - for(uint32_t i = 0; i < primitiveCount; ++i) - { - std::unique_ptr renderable; - auto modelRenderable = MakeModelRenderable(mesh.mPrimitives[i], context); - modelRenderable->mMeshIdx = meshIdx + i; - - DALI_ASSERT_DEBUG(resources.mMeshes[modelRenderable->mMeshIdx].first.mSkeletonIdx == INVALID_INDEX || - resources.mMeshes[modelRenderable->mMeshIdx].first.mSkeletonIdx == skeletonIdx); - resources.mMeshes[modelRenderable->mMeshIdx].first.mSkeletonIdx = skeletonIdx; - - renderable.reset(modelRenderable); - weakNode->mRenderables.push_back(std::move(renderable)); - } - } - - if(node.mCamera) - { - CameraParameters camParams; - ConvertCamera(*node.mCamera, camParams); - - camParams.matrix.SetTransformComponents(node.mScale, node.mRotation, node.mTranslation); - output.mCameraParameters.push_back(camParams); - } - - for(auto& n : node.mChildren) - { - ConvertNode(*n, n.GetIndex(), idx, context, isMRendererModel); - } -} - -void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& context, bool isMRendererModel) -{ - auto& outScene = context.mOutput.mScene; - Index rootIdx = outScene.GetNodeCount(); - switch(scene.mNodes.size()) - { - case 0: - break; - - case 1: - ConvertNode(*scene.mNodes[0], scene.mNodes[0].GetIndex(), INVALID_INDEX, context, isMRendererModel); - outScene.AddRootNode(rootIdx); - break; - - default: - { - std::unique_ptr sceneRoot{new NodeDefinition()}; - sceneRoot->mName = "GLTF_LOADER_SCENE_ROOT_" + std::to_string(outScene.GetRoots().size()); - - outScene.AddNode(std::move(sceneRoot)); - outScene.AddRootNode(rootIdx); - - for(auto& n : scene.mNodes) - { - ConvertNode(*n, n.GetIndex(), rootIdx, context, isMRendererModel); - } - break; - } - } -} - -void ConvertNodes(const gt::Document& doc, ConversionContext& context, bool isMRendererModel) -{ - if(!doc.mScenes.empty()) - { - uint32_t rootSceneIndex = 0u; - if(doc.mScene) - { - rootSceneIndex = doc.mScene.GetIndex(); - } - ConvertSceneNodes(doc.mScenes[rootSceneIndex], context, isMRendererModel); - - for(uint32_t i = 0, i1 = rootSceneIndex; i < i1; ++i) - { - ConvertSceneNodes(doc.mScenes[i], context, isMRendererModel); - } - - for(uint32_t i = rootSceneIndex + 1; i < doc.mScenes.size(); ++i) - { - ConvertSceneNodes(doc.mScenes[i], context, isMRendererModel); - } - } -} - -template -void LoadDataFromAccessor(ConversionContext& context, uint32_t bufferIndex, Vector& dataBuffer, uint32_t offset, uint32_t size) -{ - if(bufferIndex >= context.mOutput.mResources.mBuffers.size()) - { - DALI_LOG_ERROR("Invailid buffer index\n"); - return; - } - - auto& buffer = context.mOutput.mResources.mBuffers[bufferIndex]; - if(!buffer.IsAvailable()) - { - DALI_LOG_ERROR("Failed to load from buffer stream.\n"); - } - auto& stream = buffer.GetBufferStream(); - stream.clear(); - stream.seekg(offset, stream.beg); - stream.read(reinterpret_cast(dataBuffer.Begin()), static_cast(static_cast(size))); -} - -template -float LoadDataFromAccessors(ConversionContext& context, const gltf2::Accessor& input, const gltf2::Accessor& output, Vector& inputDataBuffer, Vector& outputDataBuffer) -{ - inputDataBuffer.Resize(input.mCount); - outputDataBuffer.Resize(output.mCount); - - const uint32_t inputDataBufferSize = input.GetBytesLength(); - const uint32_t outputDataBufferSize = output.GetBytesLength(); - - LoadDataFromAccessor(context, output.mBufferView->mBuffer.GetIndex(), inputDataBuffer, input.mBufferView->mByteOffset + input.mByteOffset, inputDataBufferSize); - LoadDataFromAccessor(context, output.mBufferView->mBuffer.GetIndex(), outputDataBuffer, output.mBufferView->mByteOffset + output.mByteOffset, outputDataBufferSize); - ApplyAccessorMinMax(input, reinterpret_cast(inputDataBuffer.begin())); - ApplyAccessorMinMax(output, reinterpret_cast(outputDataBuffer.begin())); - - return inputDataBuffer[input.mCount - 1u]; -} - -template -float LoadKeyFrames(ConversionContext& context, const gt::Animation::Channel& channel, KeyFrames& keyFrames, gt::Animation::Channel::Target::Type type) -{ - const gltf2::Accessor& input = *channel.mSampler->mInput; - const gltf2::Accessor& output = *channel.mSampler->mOutput; - - Vector inputDataBuffer; - Vector outputDataBuffer; - - const float duration = std::max(LoadDataFromAccessors(context, input, output, inputDataBuffer, outputDataBuffer), AnimationDefinition::MIN_DURATION_SECONDS); - - // Set first frame value as first keyframe (gltf animation spec) - if(input.mCount > 0 && !Dali::EqualsZero(inputDataBuffer[0])) - { - keyFrames.Add(0.0f, outputDataBuffer[0]); - } - - for(uint32_t i = 0; i < input.mCount; ++i) - { - keyFrames.Add(inputDataBuffer[i] / duration, outputDataBuffer[i]); - } - - return duration; -} - -float LoadBlendShapeKeyFrames(ConversionContext& context, const gt::Animation::Channel& channel, Index nodeIndex, uint32_t& propertyIndex, std::vector& properties) -{ - const gltf2::Accessor& input = *channel.mSampler->mInput; - const gltf2::Accessor& output = *channel.mSampler->mOutput; - - Vector inputDataBuffer; - Vector outputDataBuffer; - - const float duration = std::max(LoadDataFromAccessors(context, input, output, inputDataBuffer, outputDataBuffer), AnimationDefinition::MIN_DURATION_SECONDS); - - char weightNameBuffer[32]; - auto prefixSize = snprintf(weightNameBuffer, sizeof(weightNameBuffer), "%s[", BLEND_SHAPE_WEIGHTS_UNIFORM); - char* const pWeightName = weightNameBuffer + prefixSize; - const auto remainingSize = sizeof(weightNameBuffer) - prefixSize; - for(uint32_t weightIndex = 0u, endWeightIndex = channel.mSampler->mOutput->mCount / channel.mSampler->mInput->mCount; weightIndex < endWeightIndex; ++weightIndex) - { - AnimatedProperty& animatedProperty = properties[propertyIndex++]; - - animatedProperty.mNodeIndex = nodeIndex; - snprintf(pWeightName, remainingSize, "%d]", weightIndex); - animatedProperty.mPropertyName = std::string(weightNameBuffer); - - animatedProperty.mKeyFrames = KeyFrames::New(); - - // Set first frame value as first keyframe (gltf animation spec) - if(input.mCount > 0 && !Dali::EqualsZero(inputDataBuffer[0])) - { - animatedProperty.mKeyFrames.Add(0.0f, outputDataBuffer[weightIndex]); - } - - for(uint32_t i = 0; i < input.mCount; ++i) - { - animatedProperty.mKeyFrames.Add(inputDataBuffer[i] / duration, outputDataBuffer[i * endWeightIndex + weightIndex]); - } - - animatedProperty.mTimePeriod = {0.f, duration}; - } - - return duration; -} - -void ConvertAnimations(const gt::Document& doc, ConversionContext& context) -{ - auto& output = context.mOutput; - - output.mAnimationDefinitions.reserve(output.mAnimationDefinitions.size() + doc.mAnimations.size()); - - for(const auto& animation : doc.mAnimations) - { - AnimationDefinition animationDef; - - if(!animation.mName.empty()) - { - animationDef.mName = animation.mName; - } - - uint32_t numberOfProperties = 0u; - for(const auto& channel : animation.mChannels) - { - if(channel.mTarget.mPath == gt::Animation::Channel::Target::WEIGHTS) - { - numberOfProperties += channel.mSampler->mOutput->mCount / channel.mSampler->mInput->mCount; - } - else - { - numberOfProperties++; - } - } - animationDef.mProperties.resize(numberOfProperties); - - Index propertyIndex = 0u; - for(const auto& channel : animation.mChannels) - { - Index nodeIndex = context.mNodeIndices.GetRuntimeId(channel.mTarget.mNode.GetIndex()); - float duration = 0.f; - - switch(channel.mTarget.mPath) - { - case gt::Animation::Channel::Target::TRANSLATION: - { - AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex]; - - animatedProperty.mNodeIndex = nodeIndex; - animatedProperty.mPropertyName = POSITION_PROPERTY; - - animatedProperty.mKeyFrames = KeyFrames::New(); - duration = LoadKeyFrames(context, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath); - - animatedProperty.mTimePeriod = {0.f, duration}; - break; - } - case gt::Animation::Channel::Target::ROTATION: - { - AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex]; - - animatedProperty.mNodeIndex = nodeIndex; - animatedProperty.mPropertyName = ORIENTATION_PROPERTY; - - animatedProperty.mKeyFrames = KeyFrames::New(); - duration = LoadKeyFrames(context, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath); - - animatedProperty.mTimePeriod = {0.f, duration}; - break; - } - case gt::Animation::Channel::Target::SCALE: - { - AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex]; - - animatedProperty.mNodeIndex = nodeIndex; - animatedProperty.mPropertyName = SCALE_PROPERTY; - - animatedProperty.mKeyFrames = KeyFrames::New(); - duration = LoadKeyFrames(context, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath); - - animatedProperty.mTimePeriod = {0.f, duration}; - break; - } - case gt::Animation::Channel::Target::WEIGHTS: - { - duration = LoadBlendShapeKeyFrames(context, channel, nodeIndex, propertyIndex, animationDef.mProperties); - - break; - } - default: - { - // nothing to animate. - break; - } - } - - animationDef.mDuration = std::max(duration, animationDef.mDuration); - - ++propertyIndex; - } - - output.mAnimationDefinitions.push_back(std::move(animationDef)); - } -} - -void ProcessSkins(const gt::Document& doc, ConversionContext& context) -{ - // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skininversebindmatrices - // If an inverseBindMatrices accessor was provided, we'll load the joint data from the buffer, - // otherwise we'll set identity matrices for inverse bind pose. - struct IInverseBindMatrixProvider - { - virtual ~IInverseBindMatrixProvider() - { - } - virtual void Provide(Matrix& ibm) = 0; - }; - - struct InverseBindMatrixAccessor : public IInverseBindMatrixProvider - { - std::istream& mStream; - const uint32_t mElementSizeBytes; - - InverseBindMatrixAccessor(const gt::Accessor& accessor, ConversionContext& context) - : mStream(context.mOutput.mResources.mBuffers[accessor.mBufferView->mBuffer.GetIndex()].GetBufferStream()), - mElementSizeBytes(accessor.GetElementSizeBytes()) - { - DALI_ASSERT_DEBUG(accessor.mType == gt::AccessorType::MAT4 && accessor.mComponentType == gt::Component::FLOAT); - - if(!mStream.rdbuf()->in_avail()) - { - DALI_LOG_ERROR("Failed to load from stream\n"); - } - mStream.clear(); - mStream.seekg(accessor.mBufferView->mByteOffset + accessor.mByteOffset, mStream.beg); - } - - virtual void Provide(Matrix& ibm) override - { - DALI_ASSERT_ALWAYS(mStream.read(reinterpret_cast(ibm.AsFloat()), static_cast(static_cast(mElementSizeBytes)))); - } - }; - - struct DefaultInverseBindMatrixProvider : public IInverseBindMatrixProvider - { - virtual void Provide(Matrix& ibm) override - { - ibm = Matrix::IDENTITY; - } - }; - - auto& resources = context.mOutput.mResources; - resources.mSkeletons.reserve(doc.mSkins.size()); - - for(auto& skin : doc.mSkins) - { - std::unique_ptr ibmProvider; - if(skin.mInverseBindMatrices) - { - ibmProvider.reset(new InverseBindMatrixAccessor(*skin.mInverseBindMatrices, context)); - } - else - { - ibmProvider.reset(new DefaultInverseBindMatrixProvider()); - } - - SkeletonDefinition skeleton; - if(skin.mSkeleton.GetIndex() != INVALID_INDEX) - { - skeleton.mRootNodeIdx = context.mNodeIndices.GetRuntimeId(skin.mSkeleton.GetIndex()); - } - - skeleton.mJoints.resize(skin.mJoints.size()); - auto iJoint = skeleton.mJoints.begin(); - for(auto& joint : skin.mJoints) - { - iJoint->mNodeIdx = context.mNodeIndices.GetRuntimeId(joint.GetIndex()); - - ibmProvider->Provide(iJoint->mInverseBindMatrix); - - ++iJoint; - } - - resources.mSkeletons.push_back(std::move(skeleton)); - } -} - -void ProduceShaders(ShaderDefinitionFactory& shaderFactory, SceneDefinition& scene) -{ - uint32_t nodeCount = scene.GetNodeCount(); - for(uint32_t i = 0; i < nodeCount; ++i) - { - auto nodeDef = scene.GetNode(i); - for(auto& renderable : nodeDef->mRenderables) - { - if(shaderFactory.ProduceShader(*renderable) == INVALID_INDEX) - { - DALI_LOG_ERROR("Fail to produce shader\n"); - } - } - } -} - -void SetObjectReaders() -{ - js::SetObjectReader(GetBufferReader()); - js::SetObjectReader(GetBufferViewReader()); - js::SetObjectReader(GetBufferViewClientReader()); - js::SetObjectReader(GetComponentTypedBufferViewClientReader()); - js::SetObjectReader(GetAccessorSparseReader()); - js::SetObjectReader(GetAccessorReader()); - js::SetObjectReader(GetImageReader()); - js::SetObjectReader(GetSamplerReader()); - js::SetObjectReader(GetTextureReader()); - js::SetObjectReader(GetTextureInfoReader()); - js::SetObjectReader(GetMaterialPbrReader()); - js::SetObjectReader(GetMaterialSpecularReader()); - js::SetObjectReader(GetMaterialIorReader()); - js::SetObjectReader(GetMaterialExtensionsReader()); - js::SetObjectReader(GetMaterialReader()); - js::SetObjectReader(GetMeshPrimitiveReader()); - js::SetObjectReader(GetMeshReader()); - js::SetObjectReader(GetSkinReader()); - js::SetObjectReader(GetCameraPerspectiveReader()); - js::SetObjectReader(GetCameraOrthographicReader()); - js::SetObjectReader(GetCameraReader()); - js::SetObjectReader(GetNodeReader()); - js::SetObjectReader(GetAnimationSamplerReader()); - js::SetObjectReader(GetAnimationChannelTargetReader()); - js::SetObjectReader(GetAnimationChannelReader()); - js::SetObjectReader(GetAnimationReader()); - js::SetObjectReader(GetSceneReader()); -} - -void SetDefaultEnvironmentMap(const gt::Document& doc, ConversionContext& context) -{ - EnvironmentDefinition envDef; - envDef.mUseBrdfTexture = true; - envDef.mIblIntensity = Scene3D::Loader::EnvironmentDefinition::GetDefaultIntensity(); - context.mOutput.mResources.mEnvironmentMaps.push_back({std::move(envDef), EnvironmentDefinition::Textures()}); -} - -} // namespace - -void InitializeGltfLoader() -{ - // Set ObjectReader only once (for all gltf loading). - static bool setObjectReadersRequired = true; - { - Mutex::ScopedLock lock(gInitializeMutex); - if(setObjectReadersRequired) - { - // NOTE: only referencing own, anonymous namespace, const objects; the pointers will never need to change. - SetObjectReaders(); - setObjectReadersRequired = false; - } - } -} - -void LoadGltfScene(const std::string& url, ShaderDefinitionFactory& shaderFactory, LoadResult& params) -{ - bool failed = false; - auto js = LoadTextFile(url.c_str(), &failed); - if(failed) - { - throw std::runtime_error("Failed to load " + url); - } - - json::unique_ptr root(json_parse(js.c_str(), js.size())); - if(!root) - { - throw std::runtime_error("Failed to parse " + url); - } - - gt::Document doc; - - auto& rootObj = js::Cast(*root); - auto jsAsset = js::FindObjectChild("asset", rootObj); - - auto jsAssetVersion = js::FindObjectChild("version", js::Cast(*jsAsset)); - if(jsAssetVersion) - { - doc.mAsset.mVersion = js::Read::StringView(*jsAssetVersion); - } - - bool isMRendererModel(false); - auto jsAssetGenerator = js::FindObjectChild("generator", js::Cast(*jsAsset)); - if(jsAssetGenerator) - { - doc.mAsset.mGenerator = js::Read::StringView(*jsAssetGenerator); - isMRendererModel = (doc.mAsset.mGenerator.find(MRENDERER_MODEL_IDENTIFICATION) != std::string_view::npos); - } - - { - Mutex::ScopedLock lock(gReadMutex); - gt::SetRefReaderObject(doc); - GetDocumentReader().Read(rootObj, doc); - } - - auto path = url.substr(0, url.rfind('/') + 1); - ConversionContext context{params, path, INVALID_INDEX}; - - ConvertBuffers(doc, context); - ConvertMaterials(doc, context); - ConvertMeshes(doc, context); - ConvertNodes(doc, context, isMRendererModel); - ConvertAnimations(doc, context); - ProcessSkins(doc, context); - ProduceShaders(shaderFactory, params.mScene); - params.mScene.EnsureUniqueSkinningShaderInstances(params.mResources); - - // Set Default Environment map - SetDefaultEnvironmentMap(doc, context); -} - -} // namespace Loader -} // namespace Scene3D -} // namespace Dali diff --git a/dali-scene3d/public-api/loader/gltf2-loader.h b/dali-scene3d/public-api/loader/gltf2-loader.h deleted file mode 100644 index dc7becf..0000000 --- a/dali-scene3d/public-api/loader/gltf2-loader.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef DALI_SCENE3D_LOADER_GLTF2_LOADER_H -#define DALI_SCENE3D_LOADER_GLTF2_LOADER_H -/* - * Copyright (c) 2022 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. - * - */ - -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" - -// EXTERNAL INCLUDES -#include - -namespace Dali -{ -namespace Scene3D -{ -namespace Loader -{ -struct CameraParameters; -struct LoadResult; -class ShaderDefinitionFactory; - -/** - * @brief Initialize glTF Loader. - * @note This method should be called once before LoadGltfScene() is called. - */ -DALI_SCENE3D_API void InitializeGltfLoader(); - -/** - * @brief Loads the scene from the glTF file located at @a url, storing the results in @a params. - * @note Will throw std::runtime_error for JSON entities with types mismatching expectations, carrying - * invalid values, or I/O errors. - * @note InitializeGltfLoader() should be called once before this function is called. - */ -DALI_SCENE3D_API void LoadGltfScene(const std::string& url, ShaderDefinitionFactory& shaderFactory, LoadResult& params); - -} // namespace Loader -} // namespace Scene3D -} // namespace Dali - -#endif //DALI_SCENE3D_LOADER_GLTF2_LOADER_H diff --git a/dali-scene3d/public-api/loader/index.h b/dali-scene3d/public-api/loader/index.h index 3048def..cbf09a2 100644 --- a/dali-scene3d/public-api/loader/index.h +++ b/dali-scene3d/public-api/loader/index.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_INDEX_H_ #define DALI_SCENE3D_LOADER_INDEX_H_ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,24 +17,18 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" - // EXTERNAL INCLUDES #include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { using Index = uint32_t; constexpr Index INVALID_INDEX = static_cast(-1); -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADER_INDEX_H_ diff --git a/dali-scene3d/public-api/loader/ktx-loader.h b/dali-scene3d/public-api/loader/ktx-loader.h index fcb3b7d..d495ee0 100644 --- a/dali-scene3d/public-api/loader/ktx-loader.h +++ b/dali-scene3d/public-api/loader/ktx-loader.h @@ -21,11 +21,7 @@ #include #include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { /** * @brief Loads cube map data texture from a ktx file. @@ -36,8 +32,6 @@ namespace Loader */ bool LoadKtxData(const std::string& path, EnvironmentMapData& environmentMapData); -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif // DALI_SCENE3D_LOADER_KTX_LOADER_H diff --git a/dali-scene3d/public-api/loader/light-parameters.h b/dali-scene3d/public-api/loader/light-parameters.h index 2fde52e..e148413 100644 --- a/dali-scene3d/public-api/loader/light-parameters.h +++ b/dali-scene3d/public-api/loader/light-parameters.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_LIGHT_PARAMETERS_H #define DALI_SCENE3D_LOADER_LIGHT_PARAMETERS_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,19 +17,15 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" - // EXTERNAL INCLUDES +#include +#include #include -#include "dali/public-api/math/matrix.h" -#include "dali/public-api/math/vector3.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { struct DALI_SCENE3D_API LightParameters { @@ -42,8 +38,6 @@ struct DALI_SCENE3D_API LightParameters float orthographicSize; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif // DALI_SCENE3D_LOADER_LIGHT_PARAMETERS_H diff --git a/dali-scene3d/public-api/loader/load-result.h b/dali-scene3d/public-api/loader/load-result.h index bd7e486..da05a36 100644 --- a/dali-scene3d/public-api/loader/load-result.h +++ b/dali-scene3d/public-api/loader/load-result.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_OUTPUT_H #define DALI_SCENE3D_LOADER_OUTPUT_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,11 +24,7 @@ #include #include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { class ResourceBundle; class SceneDefinition; @@ -74,8 +70,6 @@ struct DALI_SCENE3D_API LoadResult std::vector& mLightParameters; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADER_OUTPUT_H diff --git a/dali-scene3d/public-api/loader/material-definition.cpp b/dali-scene3d/public-api/loader/material-definition.cpp index 58ab65d..ac6b73a 100644 --- a/dali-scene3d/public-api/loader/material-definition.cpp +++ b/dali-scene3d/public-api/loader/material-definition.cpp @@ -15,7 +15,7 @@ * */ -// INTERNAL INCLUDES +// CLASS HEADER #include // EXTERNAL INCLUDES diff --git a/dali-scene3d/public-api/loader/material-definition.h b/dali-scene3d/public-api/loader/material-definition.h index ca63129..b40a746 100644 --- a/dali-scene3d/public-api/loader/material-definition.h +++ b/dali-scene3d/public-api/loader/material-definition.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H #define DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,23 +17,19 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" -#include "dali-scene3d/public-api/loader/environment-definition.h" -#include "dali-scene3d/public-api/loader/index.h" -#include "dali-scene3d/public-api/loader/utils.h" - // EXTERNAL INCLUDES +#include #include +#include #include -#include "dali/public-api/common/vector-wrapper.h" -#include "dali/public-api/math/vector4.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include +#include +#include +#include + +namespace Dali::Scene3D::Loader { /** * @brief Helper enum for encoding and decoding sampler states. @@ -254,8 +250,6 @@ public: // DATA std::vector mTextureStages; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H diff --git a/dali-scene3d/public-api/loader/matrix-stack.cpp b/dali-scene3d/public-api/loader/matrix-stack.cpp index a7b8870..146e4ed 100644 --- a/dali-scene3d/public-api/loader/matrix-stack.cpp +++ b/dali-scene3d/public-api/loader/matrix-stack.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2022 Samsung Electronics Co., Ltd. +* Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,14 @@ * limitations under the License. * */ -#include "dali-scene3d/public-api/loader/matrix-stack.h" -#include "dali-scene3d/public-api/loader/utils.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// CLASS HEADER +#include + +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { MatrixStack::MatrixStack() { @@ -63,6 +63,4 @@ void MatrixStack::PopAll() mStack.clear(); } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/matrix-stack.h b/dali-scene3d/public-api/loader/matrix-stack.h index 63bbc90..f34614b 100644 --- a/dali-scene3d/public-api/loader/matrix-stack.h +++ b/dali-scene3d/public-api/loader/matrix-stack.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADERER_MATRIX_STACK_H_ #define DALI_SCENE3D_LOADERER_MATRIX_STACK_H_ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,18 +17,14 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" - // EXTERNAL INCLUDES -#include "dali/public-api/common/vector-wrapper.h" -#include "dali/public-api/math/matrix.h" +#include +#include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { /** * @brief A stack of matrices whereby each newly pushed matrix is stored @@ -50,8 +46,6 @@ private: std::vector mStack; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADERER_MATRIX_STACK_H_ diff --git a/dali-scene3d/public-api/loader/mesh-definition.cpp b/dali-scene3d/public-api/loader/mesh-definition.cpp index 18093a5..3d5f6eb 100644 --- a/dali-scene3d/public-api/loader/mesh-definition.cpp +++ b/dali-scene3d/public-api/loader/mesh-definition.cpp @@ -15,8 +15,8 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/loader/mesh-definition.h" +// CLASS HEADER +#include // EXTERNAL INCLUDES #include @@ -27,11 +27,7 @@ #include #include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { namespace { @@ -1075,6 +1071,4 @@ MeshGeometry MeshDefinition::Load(RawData&& raw) const return meshGeometry; } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/mesh-definition.h b/dali-scene3d/public-api/loader/mesh-definition.h index bb4d716..7289b40 100644 --- a/dali-scene3d/public-api/loader/mesh-definition.h +++ b/dali-scene3d/public-api/loader/mesh-definition.h @@ -17,23 +17,19 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" -#include "dali-scene3d/public-api/loader/blend-shape-details.h" -#include "dali-scene3d/public-api/loader/index.h" -#include "dali-scene3d/public-api/loader/mesh-geometry.h" -#include "dali-scene3d/public-api/loader/utils.h" -#include - // EXTERNAL INCLUDES +#include #include -#include "dali/public-api/common/vector-wrapper.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include +#include +#include +#include +#include +#include + +namespace Dali::Scene3D::Loader { /** * @brief Defines a mesh with its attributes, the primitive type to render it as, @@ -177,10 +173,10 @@ struct DALI_SCENE3D_API MeshDefinition Accessor(const MeshDefinition::Blob& blob, const MeshDefinition::SparseBlob& sparse, - Index bufferIndex = INVALID_INDEX); + Index bufferIndex = INVALID_INDEX); Accessor(MeshDefinition::Blob&& blob, MeshDefinition::SparseBlob&& sparse, - Index bufferIndex = INVALID_INDEX); + Index bufferIndex = INVALID_INDEX); bool IsDefined() const { @@ -295,8 +291,6 @@ public: // DATA Index mSkeletonIdx = INVALID_INDEX; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADER_MESH_DEFINITION_H diff --git a/dali-scene3d/public-api/loader/mesh-geometry.h b/dali-scene3d/public-api/loader/mesh-geometry.h index 331acf7..1ce30a7 100644 --- a/dali-scene3d/public-api/loader/mesh-geometry.h +++ b/dali-scene3d/public-api/loader/mesh-geometry.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADERER_MESH_GEOMETRY_H #define DALI_SCENE3D_LOADERER_MESH_GEOMETRY_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,18 +17,14 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" - // EXTERNAL INCLUDES -#include "dali/public-api/rendering/geometry.h" -#include "dali/public-api/rendering/texture.h" +#include +#include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { struct DALI_SCENE3D_API MeshGeometry { @@ -38,8 +34,6 @@ struct DALI_SCENE3D_API MeshGeometry unsigned int blendShapeBufferOffset{0}; ///< Offset used to calculate the start of each blend shape. }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif // DALI_SCENE3D_LOADERER_MESH_GEOMETRY_H diff --git a/dali-scene3d/public-api/loader/model-loader.cpp b/dali-scene3d/public-api/loader/model-loader.cpp new file mode 100644 index 0000000..2f5c34e --- /dev/null +++ b/dali-scene3d/public-api/loader/model-loader.cpp @@ -0,0 +1,155 @@ +/* + * 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. + * + */ + +// FILE HEADER +#include + +// EXTERNAL INCLUDES +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include + +namespace Dali::Scene3D::Loader +{ +namespace +{ +static constexpr std::string_view OBJ_EXTENSION = ".obj"; +static constexpr std::string_view GLTF_EXTENSION = ".gltf"; +static constexpr std::string_view GLB_EXTENSION = ".glb"; +static constexpr std::string_view DLI_EXTENSION = ".dli"; +static constexpr std::string_view METADATA_EXTENSION = "metadata"; +} // namespace + +ModelLoader::ModelLoader(const std::string& modelUrl, const std::string& resourceDirectoryUrl, Dali::Scene3D::Loader::LoadResult& loadResult) +: mModelUrl(modelUrl), + mResourceDirectoryUrl(resourceDirectoryUrl), + mLoadResult(loadResult) +{ + CreateModelLoader(); +} + +bool ModelLoader::LoadModel(Dali::Scene3D::Loader::ResourceBundle::PathProvider& pathProvider, bool loadOnlyRawResource) +{ + if(!mImpl) + { + return false; + } + + bool loadSucceeded = false; + + mLoadResult.mAnimationDefinitions.clear(); + std::filesystem::path metaDataUrl(mModelUrl); + metaDataUrl.replace_extension(METADATA_EXTENSION.data()); + + Dali::Scene3D::Loader::LoadSceneMetadata(metaDataUrl.c_str(), mLoadResult.mSceneMetadata); + loadSucceeded = mImpl->LoadModel(mModelUrl, mLoadResult); + LoadResource(pathProvider, loadOnlyRawResource); + + return loadSucceeded; +} + +void ModelLoader::SetInputParameter(InputParameter& inputParameter) +{ + mImpl->SetInputParameter(inputParameter); +} + +Dali::Scene3D::Loader::SceneDefinition& ModelLoader::GetScene() +{ + return mLoadResult.mScene; +} + +Dali::Scene3D::Loader::ResourceBundle& ModelLoader::GetResources() +{ + return mLoadResult.mResources; +} + +std::vector& ModelLoader::GetAnimations() +{ + return mLoadResult.mAnimationDefinitions; +} + +std::vector& ModelLoader::GetCameras() +{ + return mLoadResult.mCameraParameters; +} + +Dali::Scene3D::Loader::Customization::Choices& ModelLoader::GetResourceChoices() +{ + return mResourceChoices; +} + +void ModelLoader::CreateModelLoader() +{ + std::filesystem::path modelPath(mModelUrl); + if(mResourceDirectoryUrl.empty()) + { + mResourceDirectoryUrl = std::string(modelPath.parent_path()) + "/"; + } + std::string extension = modelPath.extension(); + std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); + + if(extension == DLI_EXTENSION) + { + mImpl = std::make_shared(); + } + else if(extension == GLTF_EXTENSION) + { + mImpl = std::make_shared(); + } + else if(extension == GLB_EXTENSION) + { + mImpl = std::make_shared(); + } + else + { + DALI_LOG_ERROR("Not supported model format : %s\n", extension.c_str()); + } +} + +void ModelLoader::LoadResource(Dali::Scene3D::Loader::ResourceBundle::PathProvider& pathProvider, bool loadOnlyRawResource) +{ + if(GetResources().mRawResourcesLoaded && loadOnlyRawResource) + { + return; + } + + Dali::Scene3D::Loader::ResourceRefCounts resourceRefCount = std::move(mLoadResult.mResources.CreateRefCounter()); + for(auto iRoot : GetScene().GetRoots()) + { + GetScene().CountResourceRefs(iRoot, mResourceChoices, resourceRefCount); + } + + GetResources().mReferenceCounts = std::move(resourceRefCount); + GetResources().CountEnvironmentReferences(); + + if(loadOnlyRawResource) + { + GetResources().LoadRawResources(pathProvider); + } + else + { + GetResources().LoadResources(pathProvider); + } +} + +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/model-loader.h b/dali-scene3d/public-api/loader/model-loader.h new file mode 100644 index 0000000..702b308 --- /dev/null +++ b/dali-scene3d/public-api/loader/model-loader.h @@ -0,0 +1,120 @@ +#ifndef DALI_SCENE3D_LOADER_MODEL_LOADER_H +#define DALI_SCENE3D_LOADER_MODEL_LOADER_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. + * + */ + +// INTERNAL INCLUDES +#include +#include +#include + +// EXTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader +{ +namespace Internal +{ +class ModelLoaderImpl; +} + +class DALI_SCENE3D_API ModelLoader +{ +public: + class InputParameter + { + }; + + /** + * @brief ModelLoader Constructor. + * @param[in] modelUrl Url of the model file to be loaded + * @param[in] resourceDirectoryUrl Url of directory that contains resources. + * @param[out] loadResult Loaded result that includes scene tree and resources. + */ + ModelLoader(const std::string& modelUrl, const std::string& resourceDirectoryUrl, Dali::Scene3D::Loader::LoadResult& loadResult); + + /** + * @brief Request to load model from model url. + * @param[in] pathProvider Path provider that defines resource paths. + * @param[in] loadOnlyRawResource If true, load Raw resource only, and do not create Dali::Handle + * If false, this loader load Raw resource and create Dali::Handle too. + * Default value is false; + * @return True if model loading is successfully finished. + */ + bool LoadModel(Dali::Scene3D::Loader::ResourceBundle::PathProvider& pathProvider, bool loadOnlyRawResource = false); + + /** + * @brief Set InputParameter. + * Thie method store only a pointer of InputParameter. + * The object of InputParameter should not be deleted until it is no longer used. + * @param[in] inputParameter Input parameters that can be used in loading time. + */ + void SetInputParameter(InputParameter& inputParameter); + + /** + * @brief Retrieves loaded scene + * @return SceneDefinition that is loaded from file + */ + Dali::Scene3D::Loader::SceneDefinition& GetScene(); + + /** + * @brief Retrieves resource bundle that includes resource information + * @return ResourceBundle for model resources + */ + Dali::Scene3D::Loader::ResourceBundle& GetResources(); + + /** + * @brief Retrieves loaded AnimationDefinition + * @return AnimationDefinition that is loaded from file + */ + std::vector& GetAnimations(); + + /** + * @brief Retrieves loaded CameraParameters + * @return CameraParameters list that is loaded from file + */ + std::vector& GetCameras(); + + /** + * @brief Retrieves ResourceChoices + * @return Choices for loaded Resources + */ + Dali::Scene3D::Loader::Customization::Choices& GetResourceChoices(); + +private: + /** + * @brief Create model loader for each file format. + */ + void CreateModelLoader(); + + /** + * @brief Load resource of the model. + */ + void LoadResource(Dali::Scene3D::Loader::ResourceBundle::PathProvider& pathProvider, bool loadOnlyRawResource); + +private: + std::string mModelUrl; + std::string mResourceDirectoryUrl; + + Dali::Scene3D::Loader::LoadResult mLoadResult; + Dali::Scene3D::Loader::Customization::Choices mResourceChoices; + + std::shared_ptr mImpl; +}; +} // namespace Dali::Scene3D::Loader + +#endif // DALI_SCENE3D_LOADER_MODEL_LOADER_H diff --git a/dali-scene3d/public-api/loader/navigation-mesh-factory.cpp b/dali-scene3d/public-api/loader/navigation-mesh-factory.cpp index 9d03f0d..5f66539 100644 --- a/dali-scene3d/public-api/loader/navigation-mesh-factory.cpp +++ b/dali-scene3d/public-api/loader/navigation-mesh-factory.cpp @@ -17,19 +17,18 @@ // CLASS HEADER #include -// INTERNAL INCLUDES -#include - // EXTERNAL INCLUDES #include +// INTERNAL INCLUDES +#include + namespace Dali::Scene3D::Loader { - std::unique_ptr NavigationMeshFactory::CreateFromFile(std::string filename) { std::vector buffer; - auto fin = fopen(filename.c_str(), "rb"); + auto fin = fopen(filename.c_str(), "rb"); if(!fin) { DALI_LOG_ERROR("NavigationMesh: Can't open %s for reading: %s", filename.c_str(), strerror(errno)); @@ -50,14 +49,14 @@ std::unique_ptr NavigationMeshFactory::CreateFromFile } fclose(fin); - return CreateFromBuffer( buffer ); + return CreateFromBuffer(buffer); } } std::unique_ptr NavigationMeshFactory::CreateFromBuffer(const std::vector& buffer) { auto impl = new Scene3D::Internal::Algorithm::NavigationMesh(buffer); - return std::unique_ptr( new Algorithm::NavigationMesh(impl)); + return std::unique_ptr(new Algorithm::NavigationMesh(impl)); } -} \ No newline at end of file +} // namespace Dali::Scene3D::Loader \ No newline at end of file diff --git a/dali-scene3d/public-api/loader/navigation-mesh-factory.h b/dali-scene3d/public-api/loader/navigation-mesh-factory.h index 0bbe8a9..bbe5f00 100644 --- a/dali-scene3d/public-api/loader/navigation-mesh-factory.h +++ b/dali-scene3d/public-api/loader/navigation-mesh-factory.h @@ -17,19 +17,15 @@ * limitations under the License. */ +// EXTERNAL INCLUDES +#include +#include + // INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" #include +#include -// EXTERNAL INCLUDES -#include "dali/public-api/rendering/geometry.h" -#include "dali/public-api/rendering/texture.h" - -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { struct DALI_SCENE3D_API NavigationMeshFactory { @@ -49,10 +45,7 @@ public: * @return Valid NavigationMesh or nullptr */ static std::unique_ptr CreateFromBuffer(const std::vector& buffer); - }; -} -} -} +} // namespace Dali::Scene3D::Loader #endif // DALI_SCENE3D_INTERNAL_LOADER_NAVIGATION_MESH_FACTORY_H diff --git a/dali-scene3d/public-api/loader/node-definition.cpp b/dali-scene3d/public-api/loader/node-definition.cpp index 98405d7..f110150 100644 --- a/dali-scene3d/public-api/loader/node-definition.cpp +++ b/dali-scene3d/public-api/loader/node-definition.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,12 @@ * */ -// INTERNAL -#include "dali-scene3d/public-api/loader/node-definition.h" -#include "dali-scene3d/public-api/loader/renderer-state.h" -#include "dali-scene3d/public-api/loader/utils.h" +// CLASS HEADER +#include + +// INTERNAL INCLUDES +#include +#include namespace Dali { diff --git a/dali-scene3d/public-api/loader/node-definition.h b/dali-scene3d/public-api/loader/node-definition.h index 0e9a5d7..7474a5f 100644 --- a/dali-scene3d/public-api/loader/node-definition.h +++ b/dali-scene3d/public-api/loader/node-definition.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_NODE_DEFINITION_H_ #define DALI_SCENE3D_LOADER_NODE_DEFINITION_H_ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,19 +17,19 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/loader/customization.h" -#include "dali-scene3d/public-api/loader/matrix-stack.h" -#include "dali-scene3d/public-api/loader/resource-bundle.h" - // EXTERNAL INCLUDES +#include +#include +#include +#include #include #include #include -#include "dali/public-api/actors/actor.h" -#include "dali/public-api/math/matrix.h" -#include "dali/public-api/math/quaternion.h" -#include "dali/public-api/math/vector4.h" + +// INTERNAL INCLUDES +#include +#include +#include namespace Dali { diff --git a/dali-scene3d/public-api/loader/parse-renderer-state.cpp b/dali-scene3d/public-api/loader/parse-renderer-state.cpp index 3c01701..30b4d44 100644 --- a/dali-scene3d/public-api/loader/parse-renderer-state.cpp +++ b/dali-scene3d/public-api/loader/parse-renderer-state.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,15 +15,14 @@ * */ -#include "dali-scene3d/public-api/loader/parse-renderer-state.h" +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include #include -#include "dali/devel-api/common/map-wrapper.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { namespace RendererState { @@ -168,6 +167,4 @@ Type Parse(const char* string, size_t length, StringCallback onError) } } // namespace RendererState -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/parse-renderer-state.h b/dali-scene3d/public-api/loader/parse-renderer-state.h index 43ca5b3..65a6269 100644 --- a/dali-scene3d/public-api/loader/parse-renderer-state.h +++ b/dali-scene3d/public-api/loader/parse-renderer-state.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADERERER_INTERPRET_RENDERER_STATE_H #define DALI_SCENE3D_LOADERERER_INTERPRET_RENDERER_STATE_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,14 +17,11 @@ * */ -#include "dali-scene3d/public-api/loader/renderer-state.h" -#include "dali-scene3d/public-api/loader/string-callback.h" +// INTERNAL INCLUDES +#include +#include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { namespace RendererState { @@ -44,8 +41,6 @@ namespace RendererState DALI_SCENE3D_API Type Parse(const char* string, size_t length = 0, StringCallback onError = DefaultErrorCallback); } // namespace RendererState -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADERERER_INTERPRET_RENDERER_STATE_H diff --git a/dali-scene3d/public-api/loader/renderer-state.cpp b/dali-scene3d/public-api/loader/renderer-state.cpp index cc2837b..c14d8a6 100644 --- a/dali-scene3d/public-api/loader/renderer-state.cpp +++ b/dali-scene3d/public-api/loader/renderer-state.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,14 @@ * limitations under the License. * */ -#include "dali-scene3d/public-api/loader/renderer-state.h" -#include "dali-scene3d/public-api/loader/utils.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// CLASS HEADER +#include + +// INTENRAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { namespace { @@ -97,6 +97,4 @@ void Apply(Type rendererState, Renderer& renderer) } // namespace RendererState -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/renderer-state.h b/dali-scene3d/public-api/loader/renderer-state.h index 0dc3c52..240a343 100644 --- a/dali-scene3d/public-api/loader/renderer-state.h +++ b/dali-scene3d/public-api/loader/renderer-state.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_RENDERER_STATE_H #define DALI_SCENE3D_LOADER_RENDERER_STATE_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,17 +17,13 @@ * */ -// INTERAL INCLUDES -#include "dali-scene3d/public-api/api.h" - // EXTERNAL INCLUDES -#include "dali/public-api/rendering/renderer.h" +#include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { /* * @brief Contains values for comparison functions used in depth and stencil testing. @@ -158,8 +154,6 @@ DALI_SCENE3D_API void Apply(Type rendererState, Renderer& renderer); } // namespace RendererState -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADER_RENDERER_STATE_H diff --git a/dali-scene3d/public-api/loader/resource-bundle.cpp b/dali-scene3d/public-api/loader/resource-bundle.cpp index 98c8de6..6b4dde6 100644 --- a/dali-scene3d/public-api/loader/resource-bundle.cpp +++ b/dali-scene3d/public-api/loader/resource-bundle.cpp @@ -18,7 +18,7 @@ // FILE HEADER #include -// EXTERNAL +// EXTERNAL INCLUDES #include #include #include @@ -53,9 +53,7 @@ ResourceBundle::ResourceBundle() : mRawResourcesLoading(false), mResourcesGenerating(false), mRawResourcesLoaded(false), - mResourcesGenerated(false) -{ -}; + mResourcesGenerated(false){}; ResourceRefCounts ResourceBundle::CreateRefCounter() const { @@ -67,11 +65,11 @@ ResourceRefCounts ResourceBundle::CreateRefCounter() const return refCounts; } -void ResourceBundle::CountEnvironmentReferences(ResourceRefCounts& refCounts) const +void ResourceBundle::CountEnvironmentReferences() { - auto& environmentRefCounts = refCounts[ResourceType::Environment]; + auto& environmentRefCounts = mReferenceCounts[ResourceType::Environment]; - const auto& materialRefs = refCounts[ResourceType::Material]; + const auto& materialRefs = mReferenceCounts[ResourceType::Material]; for(uint32_t i = 0, iEnd = materialRefs.Size(); i != iEnd; ++i) { if(materialRefs[i] > 0) @@ -81,7 +79,7 @@ void ResourceBundle::CountEnvironmentReferences(ResourceRefCounts& refCounts) co } } -void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvider pathProvider, Options::Type options) +void ResourceBundle::LoadResources(PathProvider pathProvider, Options::Type options) { mRawResourcesLoading = true; mResourcesGenerating = true; @@ -89,7 +87,7 @@ void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvi const auto kForceLoad = MaskMatch(options, Options::ForceReload); const auto kKeepUnused = MaskMatch(options, Options::KeepUnused); - const auto& refCountEnvMaps = refCounts[ResourceType::Environment]; + const auto& refCountEnvMaps = mReferenceCounts[ResourceType::Environment]; auto environmentsPath = pathProvider(ResourceType::Environment); for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i) { @@ -107,7 +105,7 @@ void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvi } } - const auto& refCountShaders = refCounts[ResourceType::Shader]; + const auto& refCountShaders = mReferenceCounts[ResourceType::Shader]; auto shadersPath = pathProvider(ResourceType::Shader); for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i) { @@ -124,7 +122,7 @@ void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvi } } - const auto& refCountMeshes = refCounts[ResourceType::Mesh]; + const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh]; auto modelsPath = pathProvider(ResourceType::Mesh); for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i) { @@ -141,7 +139,7 @@ void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvi } } - const auto& refCountMaterials = refCounts[ResourceType::Material]; + const auto& refCountMaterials = mReferenceCounts[ResourceType::Material]; auto imagesPath = pathProvider(ResourceType::Material); for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i) { @@ -165,7 +163,7 @@ void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvi mResourcesGenerated = true; } -void ResourceBundle::LoadRawResources(const ResourceRefCounts& refCounts, PathProvider pathProvider, Options::Type options) +void ResourceBundle::LoadRawResources(PathProvider pathProvider, Options::Type options) { const auto kForceLoad = MaskMatch(options, Options::ForceReload); @@ -173,7 +171,7 @@ void ResourceBundle::LoadRawResources(const ResourceRefCounts& refCounts, PathPr { mRawResourcesLoading = true; - const auto& refCountEnvMaps = refCounts[ResourceType::Environment]; + const auto& refCountEnvMaps = mReferenceCounts[ResourceType::Environment]; auto environmentsPath = pathProvider(ResourceType::Environment); for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i) { @@ -185,7 +183,7 @@ void ResourceBundle::LoadRawResources(const ResourceRefCounts& refCounts, PathPr } } - const auto& refCountShaders = refCounts[ResourceType::Shader]; + const auto& refCountShaders = mReferenceCounts[ResourceType::Shader]; auto shadersPath = pathProvider(ResourceType::Shader); for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i) { @@ -197,7 +195,7 @@ void ResourceBundle::LoadRawResources(const ResourceRefCounts& refCounts, PathPr } } - const auto& refCountMeshes = refCounts[ResourceType::Mesh]; + const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh]; auto modelsPath = pathProvider(ResourceType::Mesh); for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i) { @@ -209,7 +207,7 @@ void ResourceBundle::LoadRawResources(const ResourceRefCounts& refCounts, PathPr } } - const auto& refCountMaterials = refCounts[ResourceType::Material]; + const auto& refCountMaterials = mReferenceCounts[ResourceType::Material]; auto imagesPath = pathProvider(ResourceType::Material); for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i) { @@ -226,7 +224,7 @@ void ResourceBundle::LoadRawResources(const ResourceRefCounts& refCounts, PathPr } } -void ResourceBundle::GenerateResources(const ResourceRefCounts& refCounts, Options::Type options) +void ResourceBundle::GenerateResources(Options::Type options) { const auto kForceLoad = MaskMatch(options, Options::ForceReload); @@ -236,7 +234,7 @@ void ResourceBundle::GenerateResources(const ResourceRefCounts& refCounts, Optio { mResourcesGenerating = true; - const auto& refCountEnvMaps = refCounts[ResourceType::Environment]; + const auto& refCountEnvMaps = mReferenceCounts[ResourceType::Environment]; for(uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i) { auto refCount = refCountEnvMaps[i]; @@ -255,7 +253,7 @@ void ResourceBundle::GenerateResources(const ResourceRefCounts& refCounts, Optio } } - const auto& refCountShaders = refCounts[ResourceType::Shader]; + const auto& refCountShaders = mReferenceCounts[ResourceType::Shader]; for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i) { auto refCount = refCountShaders[i]; @@ -273,7 +271,7 @@ void ResourceBundle::GenerateResources(const ResourceRefCounts& refCounts, Optio } } - const auto& refCountMeshes = refCounts[ResourceType::Mesh]; + const auto& refCountMeshes = mReferenceCounts[ResourceType::Mesh]; for(uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i) { auto refCount = refCountMeshes[i]; @@ -291,7 +289,7 @@ void ResourceBundle::GenerateResources(const ResourceRefCounts& refCounts, Optio } } - const auto& refCountMaterials = refCounts[ResourceType::Material]; + const auto& refCountMaterials = mReferenceCounts[ResourceType::Material]; for(uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i) { auto refCount = refCountMaterials[i]; @@ -316,7 +314,7 @@ void ResourceBundle::GenerateResources(const ResourceRefCounts& refCounts, Optio { mResourcesGenerating = true; - const auto& refCountShaders = refCounts[ResourceType::Shader]; + const auto& refCountShaders = mReferenceCounts[ResourceType::Shader]; for(uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i) { auto refCount = refCountShaders[i]; diff --git a/dali-scene3d/public-api/loader/resource-bundle.h b/dali-scene3d/public-api/loader/resource-bundle.h index 95c8609..fe386ca 100644 --- a/dali-scene3d/public-api/loader/resource-bundle.h +++ b/dali-scene3d/public-api/loader/resource-bundle.h @@ -17,7 +17,14 @@ * */ -// INTERNAL +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES #include #include #include @@ -25,18 +32,7 @@ #include #include -// EXTERNAL -#include -#include -#include -#include -#include - -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { /* * @brief The types of resources that .dli may define. @@ -103,7 +99,7 @@ public: * count of materials therein, it will calculate the reference count of * environment maps. */ - void CountEnvironmentReferences(ResourceRefCounts& refCounts) const; + void CountEnvironmentReferences(); /** * @brief Performs the loading of all resources based on their respective @@ -111,14 +107,12 @@ public: * loaded unless we already have a handle to them (OR the ForceReload option was specified). * Any handles we have to resources that come in with a zero ref count will be reset, * UNLESS the KeepUnused option was specified. - * @param[in] refCounts Reference Count that denote how many the resource is used. * @param[in] pathProvider path provider for resource data. * @param[in] options Option to load resource * @note This method creates DALi objects like Dali::Texture, Dali::Geometry, etc. */ - void LoadResources(const ResourceRefCounts& refCounts, - PathProvider pathProvider, - Options::Type options = Options::None); + void LoadResources(PathProvider pathProvider, + Options::Type options = Options::None); /** * @brief Loads of all resources based on their respective @@ -127,29 +121,26 @@ public: * Any handles we have to resources that come in with a zero ref count will be reset, * UNLESS the KeepUnused option was specified. * @note This method don't create any of DALi objects. - * @param[in] refCounts Reference Count that denote how many the resource is used. * @param[in] pathProvider path provider for resource data. * @param[in] options Option to load resource * @note This method only loads raw data from resource file, and * doesn't create any of DALi objects. GenerateResources() method is required to be called * after this method to create DALi objects. */ - void LoadRawResources(const ResourceRefCounts& refCounts, - PathProvider pathProvider, - Options::Type options = Options::None); + void LoadRawResources(PathProvider pathProvider, + Options::Type options = Options::None); /** * @brief Generates DALi objects from already loaded Raw Resources. - * @param[in] refCounts Reference Count that denote how many the resource is used. * @param[in] options Option to load resource * @note This method generates DALi objects from raw data that is already * loaded by LoadRawResources method. Therefore, LoadRawResources should be called first * before this method is called. */ - void GenerateResources(const ResourceRefCounts& refCounts, - Options::Type options = Options::None); + void GenerateResources(Options::Type options = Options::None); public: // DATA + ResourceRefCounts mReferenceCounts; EnvironmentDefinition::Vector mEnvironmentMaps; ShaderDefinition::Vector mShaders; MeshDefinition::Vector mMeshes; @@ -165,8 +156,6 @@ public: // DATA bool mResourcesGenerated; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADERERERERER_RESOURCE_BUNDLE_H_ diff --git a/dali-scene3d/public-api/loader/scene-definition.cpp b/dali-scene3d/public-api/loader/scene-definition.cpp index f41422e..f8377c3 100644 --- a/dali-scene3d/public-api/loader/scene-definition.cpp +++ b/dali-scene3d/public-api/loader/scene-definition.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,16 +15,18 @@ * */ -// EXTERNAL -#include "dali/devel-api/common/map-wrapper.h" -#include "dali/public-api/animation/constraints.h" +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include // INTERNAL -#include "dali-scene3d/internal/graphics/builtin-shader-extern-gen.h" -#include "dali-scene3d/public-api/loader/blend-shape-details.h" -#include "dali-scene3d/public-api/loader/scene-definition.h" -#include "dali-scene3d/public-api/loader/skinning-details.h" -#include "dali-scene3d/public-api/loader/utils.h" +#include +#include +#include +#include //#define DEBUG_SCENE_DEFINITION //#define DEBUG_JOINTS @@ -37,11 +39,7 @@ #define LOGD(x) DEBUG_ONLY(printf x; printf("\n"); fflush(stdout)) -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { namespace { @@ -1195,6 +1193,4 @@ bool SceneDefinition::FindNode(const std::string& name, std::unique_ptr +#include +#include +#include #include #include -#include "dali/public-api/actors/actor.h" -#include "dali/public-api/math/matrix.h" -#include "dali/public-api/math/quaternion.h" -#include "dali/public-api/math/vector4.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include +#include +#include +#include + +namespace Dali::Scene3D::Loader { class MatrixStack; @@ -274,8 +270,6 @@ private: // DATA std::vector mRootNodeIds; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADERER_SCENE_DEFINITION_H_ diff --git a/dali-scene3d/public-api/loader/shader-definition-factory.cpp b/dali-scene3d/public-api/loader/shader-definition-factory.cpp index b5566e0..5db7ab0 100644 --- a/dali-scene3d/public-api/loader/shader-definition-factory.cpp +++ b/dali-scene3d/public-api/loader/shader-definition-factory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,18 +14,20 @@ * limitations under the License. * */ -#include "dali-scene3d/public-api/loader/shader-definition-factory.h" + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include #include -#include "dali-scene3d/internal/loader/hash.h" -#include "dali-scene3d/public-api/loader/blend-shape-details.h" -#include "dali-scene3d/public-api/loader/node-definition.h" -#include "dali/devel-api/common/map-wrapper.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include +#include +#include + +namespace Dali::Scene3D::Loader { namespace { @@ -375,6 +377,4 @@ Index ShaderDefinitionFactory::ProduceShader(NodeDefinition::Renderable& rendera return renderable.mShaderIdx; } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/shader-definition-factory.h b/dali-scene3d/public-api/loader/shader-definition-factory.h index b7e9195..273ac8f 100644 --- a/dali-scene3d/public-api/loader/shader-definition-factory.h +++ b/dali-scene3d/public-api/loader/shader-definition-factory.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_SHADER_DEFINITION_FACTORY_H_ #define DALI_SCENE3D_LOADER_SHADER_DEFINITION_FACTORY_H_ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,19 +17,15 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" -#include "dali-scene3d/public-api/loader/index.h" -#include - // EXTERNAL INCLUDER #include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include +#include +#include + +namespace Dali::Scene3D::Loader { struct NodeDefinition; class ResourceBundle; @@ -59,8 +55,6 @@ private: const std::unique_ptr mImpl; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADER_SHADER_DEFINITION_FACTORY_H_ diff --git a/dali-scene3d/public-api/loader/shader-definition.cpp b/dali-scene3d/public-api/loader/shader-definition.cpp index a753155..2796340 100644 --- a/dali-scene3d/public-api/loader/shader-definition.cpp +++ b/dali-scene3d/public-api/loader/shader-definition.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,16 +15,14 @@ * */ +// CLASS HEADER +#include + // INTERNAL INCLUDES -#include "dali-scene3d/public-api/loader/shader-definition.h" #include -#include "dali-scene3d/public-api/loader/utils.h" +#include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { namespace { @@ -144,6 +142,4 @@ Shader ShaderDefinition::Load(RawData&& raw) const return shader; } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/shader-definition.h b/dali-scene3d/public-api/loader/shader-definition.h index 3d3236b..27bb051 100644 --- a/dali-scene3d/public-api/loader/shader-definition.h +++ b/dali-scene3d/public-api/loader/shader-definition.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_SHADER_DEFINITION_H #define DALI_SCENE3D_LOADER_SHADER_DEFINITION_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,19 +17,15 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/loader/renderer-state.h" - // EXTERNAL INCLUDES +#include +#include #include -#include "dali/public-api/common/vector-wrapper.h" -#include "dali/public-api/rendering/shader.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { /* * @brief Defines a shader with paths to the files which define its @@ -56,7 +52,7 @@ struct DALI_SCENE3D_API ShaderDefinition ShaderDefinition(const ShaderDefinition& other); ShaderDefinition& operator=(const ShaderDefinition& other); - ShaderDefinition(ShaderDefinition&&) = default; + ShaderDefinition(ShaderDefinition&&) = default; ShaderDefinition& operator=(ShaderDefinition&&) = default; /* @@ -86,8 +82,6 @@ public: // DATA bool mUseBuiltInShader{false}; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif // DALI_SCENE3D_LOADER_SHADER_DEFINITION_H diff --git a/dali-scene3d/public-api/loader/skeleton-definition.h b/dali-scene3d/public-api/loader/skeleton-definition.h index b2d61a8..7161a34 100644 --- a/dali-scene3d/public-api/loader/skeleton-definition.h +++ b/dali-scene3d/public-api/loader/skeleton-definition.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADERER_SKELETON_H #define DALI_SCENE3D_LOADERER_SKELETON_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,17 +18,13 @@ */ // INTERNAL INCLUDES -#include "dali-scene3d/public-api/loader/index.h" +#include // EXTERNAL INCLUDES -#include "dali/public-api/common/vector-wrapper.h" -#include "dali/public-api/math/matrix.h" +#include +#include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { /* * @brief A set of joints (stored as node indices), and an optional root node index. @@ -50,8 +46,6 @@ struct DALI_SCENE3D_API SkeletonDefinition std::vector mJoints; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADERER_SKELETON_H diff --git a/dali-scene3d/public-api/loader/skinning-details.cpp b/dali-scene3d/public-api/loader/skinning-details.cpp index e100151..0e5e499 100644 --- a/dali-scene3d/public-api/loader/skinning-details.cpp +++ b/dali-scene3d/public-api/loader/skinning-details.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,20 +14,18 @@ * limitations under the License. * */ -#include "dali-scene3d/public-api/loader/skinning-details.h" -#include "dali/public-api/animation/constraints.h" -#include "dali/public-api/object/property.h" -#include "dali/public-api/rendering/shader.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include +#include + +namespace Dali::Scene3D::Loader { const unsigned int Skinning::MAX_JOINTS = 64; const char* Skinning::BONE_UNIFORM_NAME = "uBone"; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/skinning-details.h b/dali-scene3d/public-api/loader/skinning-details.h index d754f0c..41a9790 100644 --- a/dali-scene3d/public-api/loader/skinning-details.h +++ b/dali-scene3d/public-api/loader/skinning-details.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_SKINNING_DETAILS_H_ #define DALI_SCENE3D_LOADER_SKINNING_DETAILS_H_ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,18 +17,14 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" - // EXTERNAL INCLUDES +#include #include -#include "dali/public-api/rendering/shader.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { struct DALI_SCENE3D_API Skinning { @@ -45,8 +41,6 @@ struct DALI_SCENE3D_API Skinning Skinning() = delete; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif // DALI_SCENE3D_LOADER_SKINNING_DETAILS_H_ diff --git a/dali-scene3d/public-api/loader/string-callback.cpp b/dali-scene3d/public-api/loader/string-callback.cpp index 5d46cb7..eb85bad 100644 --- a/dali-scene3d/public-api/loader/string-callback.cpp +++ b/dali-scene3d/public-api/loader/string-callback.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,20 +14,18 @@ * limitations under the License. * */ -#include "dali-scene3d/public-api/loader/string-callback.h" -#include "dali/integration-api/debug.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { void DefaultErrorCallback(const std::string& message) { DALI_LOG_ERROR("%s", message.c_str()); } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/string-callback.h b/dali-scene3d/public-api/loader/string-callback.h index 4f00a10..7a3564d 100644 --- a/dali-scene3d/public-api/loader/string-callback.h +++ b/dali-scene3d/public-api/loader/string-callback.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_STRING_CALLBACK_H #define DALI_SCENE3D_LOADER_STRING_CALLBACK_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,18 +17,14 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" - // EXTERNAL INCLUDES #include #include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { /* * @brief A callback to post strings to. @@ -40,8 +36,6 @@ using StringCallback = std::function; */ DALI_SCENE3D_API void DefaultErrorCallback(const std::string& message); -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADER_STRING_CALLBACK_H diff --git a/dali-scene3d/public-api/loader/utils.cpp b/dali-scene3d/public-api/loader/utils.cpp index 14b4150..9120b65 100644 --- a/dali-scene3d/public-api/loader/utils.cpp +++ b/dali-scene3d/public-api/loader/utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,22 +15,18 @@ * */ -// INTERNAL -#include "dali-scene3d/public-api/loader/utils.h" +// CLASS HEADER +#include -// EXTERNAL +// EXTERNAL INCLUDES +#include +#include #include #include #include #include -#include "dali/public-api/animation/constraints.h" -#include "dali/public-api/common/vector-wrapper.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +namespace Dali::Scene3D::Loader { namespace { @@ -152,6 +148,4 @@ void ToUnixFileSeparators(std::string& path) std::replace(path.begin(), path.end(), '\\', '/'); } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/utils.h b/dali-scene3d/public-api/loader/utils.h index 3a84f09..17d4261 100644 --- a/dali-scene3d/public-api/loader/utils.h +++ b/dali-scene3d/public-api/loader/utils.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_UTILS_H_ #define DALI_SCENE3D_LOADER_UTILS_H_ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,21 +17,17 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" - // EXTERNAL INCLUDES +#include +#include +#include #include #include -#include "dali/public-api/actors/actor.h" -#include "dali/public-api/common/dali-common.h" -#include "dali/public-api/rendering/renderer.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { /* * @brief Fixed size backing buffer to use with std::ostreams where control over @@ -199,8 +195,6 @@ DALI_SCENE3D_API Geometry MakeTexturedQuadGeometry(TexturedQuadOptions::Type opt */ DALI_SCENE3D_API void ToUnixFileSeparators(std::string& path); -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif /* DALI_SCENE3D_LOADER_UTILS_H_ */ diff --git a/dali-scene3d/public-api/loader/view-projection.cpp b/dali-scene3d/public-api/loader/view-projection.cpp index ac970ca..259892f 100644 --- a/dali-scene3d/public-api/loader/view-projection.cpp +++ b/dali-scene3d/public-api/loader/view-projection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,14 @@ * limitations under the License. * */ -#include "dali-scene3d/public-api/loader/view-projection.h" -#include "dali-scene3d/public-api/loader/utils.h" -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// CLASS HEADER +#include + +// INTERNAL INCLDUES +#include + +namespace Dali::Scene3D::Loader { void ViewProjection::Update() { @@ -34,6 +34,4 @@ void ViewProjection::Update() } } -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/view-projection.h b/dali-scene3d/public-api/loader/view-projection.h index db7be74..c1e5532 100644 --- a/dali-scene3d/public-api/loader/view-projection.h +++ b/dali-scene3d/public-api/loader/view-projection.h @@ -1,7 +1,7 @@ #ifndef DALI_SCENE3D_LOADER_VIEW_PROJECTION_H_ #define DALI_SCENE3D_LOADER_VIEW_PROJECTION_H_ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,17 +17,13 @@ * */ -// INTERNAL INCLUDES -#include "dali-scene3d/public-api/api.h" - // EXTERNAL INCLUDES -#include "dali/public-api/math/matrix.h" +#include -namespace Dali -{ -namespace Scene3D -{ -namespace Loader +// INTERNAL INCLUDES +#include + +namespace Dali::Scene3D::Loader { /** * @brief Contains view and projection matrices, also caching the view-projection @@ -74,8 +70,6 @@ private: Matrix mViewProjection; }; -} // namespace Loader -} // namespace Scene3D -} // namespace Dali +} // namespace Dali::Scene3D::Loader #endif //DALI_SCENE3D_LOADER_VIEW_PROJECTION_H_ diff --git a/dali-toolkit/internal/controls/image-view/image-view-impl.cpp b/dali-toolkit/internal/controls/image-view/image-view-impl.cpp index 1133211..7fcc702 100644 --- a/dali-toolkit/internal/controls/image-view/image-view-impl.cpp +++ b/dali-toolkit/internal/controls/image-view/image-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -267,9 +267,6 @@ void ImageView::OnRelayout(const Vector2& size, RelayoutContainer& container) bool zeroPadding = (padding == Extents()); - Vector2 naturalSize; - mVisual.GetNaturalSize(naturalSize); - Dali::LayoutDirection::Type layoutDirection = static_cast( Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get()); if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection) @@ -281,7 +278,7 @@ void ImageView::OnRelayout(const Vector2& size, RelayoutContainer& container) Vector2 finalSize = size - Vector2(padding.start + padding.end, padding.top + padding.bottom); Vector2 finalOffset = Vector2(padding.start, padding.top); - ApplyFittingMode(finalSize, naturalSize, finalOffset, zeroPadding, transformMap); + ApplyFittingMode(finalSize, finalOffset, zeroPadding, transformMap); mVisual.SetTransformAndSize(transformMap, size); @@ -413,7 +410,7 @@ void ImageView::SetTransformMapForFittingMode(Vector2 finalSize, Vector2 natural } } -void ImageView::ApplyFittingMode(Vector2 finalSize, Vector2 naturalSize, Vector2 finalOffset, bool zeroPadding, Property::Map& transformMap) +void ImageView::ApplyFittingMode(Vector2 finalSize, Vector2 finalOffset, bool zeroPadding, Property::Map& transformMap) { Visual::FittingMode fittingMode = Toolkit::GetImplementation(mVisual).GetFittingMode(); @@ -429,6 +426,14 @@ void ImageView::ApplyFittingMode(Vector2 finalSize, Vector2 naturalSize, Vector2 { mImageVisualPaddingSetByTransform = true; + Vector2 naturalSize; + // NaturalSize will not be used for FILL fitting mode, which is default. + // Skip GetNaturalSize + if(fittingMode != Visual::FittingMode::FILL) + { + mVisual.GetNaturalSize(naturalSize); + } + // If FittingMode use FIT_WIDTH or FIT_HEIGTH, it need to change proper fittingMode if(fittingMode == Visual::FittingMode::FIT_WIDTH) { diff --git a/dali-toolkit/internal/controls/image-view/image-view-impl.h b/dali-toolkit/internal/controls/image-view/image-view-impl.h index 47f7283..7caf9eb 100644 --- a/dali-toolkit/internal/controls/image-view/image-view-impl.h +++ b/dali-toolkit/internal/controls/image-view/image-view-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_IMAGE_VIEW_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -177,12 +177,11 @@ private: /** * @brief Apply fittingMode * param[in] finalSize The size for fittingMode - * param[in] textureSize The size of texture * param[in] offset The offset for fittingMode * param[in] zeroPadding whether padding is zero * param[in] transformMap The map for fitting image */ - void ApplyFittingMode(Vector2 finalSize, Vector2 textureSize, Vector2 offset, bool zeroPadding, Property::Map& transformMap); + void ApplyFittingMode(Vector2 finalSize, Vector2 offset, bool zeroPadding, Property::Map& transformMap); private: // Undefined diff --git a/dali-toolkit/internal/image-loader/loading-task.cpp b/dali-toolkit/internal/image-loader/loading-task.cpp index 11f83a8..e81b16f 100644 --- a/dali-toolkit/internal/image-loader/loading-task.cpp +++ b/dali-toolkit/internal/image-loader/loading-task.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,7 +76,7 @@ LoadingTask::LoadingTask(uint32_t id, Dali::AnimatedImageLoading animatedImageLo } LoadingTask::LoadingTask(uint32_t id, const VisualUrl& url, ImageDimensions dimensions, FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection, DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad, bool loadPlanes, CallbackBase* callback) -: AsyncTask(callback), +: AsyncTask(callback, url.GetProtocolType() == VisualUrl::ProtocolType::REMOTE ? AsyncTask::PriorityType::LOW : AsyncTask::PriorityType::HIGH), url(url), encodedImageBuffer(), id(id), diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp index 158ef83..40f1a64 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp @@ -46,7 +46,7 @@ Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New(Debug::NoLogging, } // unnamed namespace VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache) -: AsyncTask(MakeCallback(this, &VectorAnimationTask::TaskCompleted), AsyncTask::ThreadType::WORKER_THREAD), +: AsyncTask(MakeCallback(this, &VectorAnimationTask::TaskCompleted), AsyncTask::PriorityType::HIGH, AsyncTask::ThreadType::WORKER_THREAD), mUrl(), mVectorRenderer(VectorAnimationRenderer::New()), mAnimationData(), diff --git a/dali-toolkit/internal/visuals/image/image-visual.cpp b/dali-toolkit/internal/visuals/image/image-visual.cpp index 0669ed5..d5bc010 100644 --- a/dali-toolkit/internal/visuals/image/image-visual.cpp +++ b/dali-toolkit/internal/visuals/image/image-visual.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -97,9 +97,6 @@ DALI_ENUM_TO_STRING_TABLE_END(RELEASE_POLICY) const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f); -const float PIXEL_ALIGN_ON = 1.0f; -const float PIXEL_ALIGN_OFF = 0.0f; - constexpr uint32_t TEXTURE_COUNT_FOR_GPU_ALPHA_MASK = 2u; Geometry CreateGeometry(VisualFactoryCache& factoryCache, ImageDimensions gridSize) @@ -736,13 +733,6 @@ void ImageVisual::DoSetOnScene(Actor& actor) } mPlacementActor = actor; - // Search the Actor tree to find if Layer UI behaviour set. - Layer layer = actor.GetLayer(); - if(layer && layer.GetProperty(Layer::Property::BEHAVIOR) == Layer::LAYER_3D) - { - // Layer 3D set, do not align pixels - mImpl->mRenderer.RegisterProperty(PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_OFF); - } if(mPixelArea != FULL_TEXTURE_RECT) { @@ -762,7 +752,7 @@ void ImageVisual::DoSetOnScene(Actor& actor) Vector2 imageSize = Vector2::ZERO; if(actor) { - imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); mPlacementActorSize = imageSize; } @@ -912,7 +902,7 @@ void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureIn Vector2 imageSize = Vector2::ZERO; if(actor) { - imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); + imageSize = actor.GetProperty(Actor::Property::SIZE).Get(); mPlacementActorSize = imageSize; } else @@ -1161,11 +1151,6 @@ Shader ImageVisual::GenerateShader() const shader.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT); } - // Set pixel align off as default. - // ToDo: Pixel align causes issues such as rattling image animation. - // We should trun it off until issues are resolved - shader.RegisterProperty(PIXEL_ALIGNED_UNIFORM_NAME, PIXEL_ALIGN_OFF); - return shader; } diff --git a/dali-toolkit/internal/visuals/visual-string-constants.cpp b/dali-toolkit/internal/visuals/visual-string-constants.cpp index c79c9a6..ac898d7 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.cpp +++ b/dali-toolkit/internal/visuals/visual-string-constants.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -95,7 +95,6 @@ const char* const WRAP_MODE_UNIFORM_NAME("wrapMode"); const char* const IMAGE_WRAP_MODE_U("wrapModeU"); const char* const IMAGE_WRAP_MODE_V("wrapModeV"); const char* const IMAGE_BORDER("border"); -const char* const PIXEL_ALIGNED_UNIFORM_NAME("uPixelAligned"); const char* const ANIMATED_IMAGE_URLS_NAME("urls"); const char* const BATCH_SIZE_NAME("batchSize"); const char* const CACHE_SIZE_NAME("cacheSize"); diff --git a/dali-toolkit/internal/visuals/visual-string-constants.h b/dali-toolkit/internal/visuals/visual-string-constants.h index b65292f..0bb5840 100644 --- a/dali-toolkit/internal/visuals/visual-string-constants.h +++ b/dali-toolkit/internal/visuals/visual-string-constants.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_VISUAL_STRING_CONSTANTS_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -79,7 +79,6 @@ extern const char* const WRAP_MODE_UNIFORM_NAME; extern const char* const IMAGE_WRAP_MODE_U; extern const char* const IMAGE_WRAP_MODE_V; extern const char* const IMAGE_BORDER; -extern const char* const PIXEL_ALIGNED_UNIFORM_NAME; extern const char* const ANIMATED_IMAGE_URLS_NAME; extern const char* const BATCH_SIZE_NAME; extern const char* const CACHE_SIZE_NAME; diff --git a/dali-toolkit/public-api/dali-toolkit-version.cpp b/dali-toolkit/public-api/dali-toolkit-version.cpp index 15c7b41..7bc6ec0 100644 --- a/dali-toolkit/public-api/dali-toolkit-version.cpp +++ b/dali-toolkit/public-api/dali-toolkit-version.cpp @@ -29,7 +29,7 @@ namespace Toolkit { const unsigned int TOOLKIT_MAJOR_VERSION = 2; const unsigned int TOOLKIT_MINOR_VERSION = 2; -const unsigned int TOOLKIT_MICRO_VERSION = 16; +const unsigned int TOOLKIT_MICRO_VERSION = 17; const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/packaging/dali-toolkit.spec b/packaging/dali-toolkit.spec index fb285c7..1bba007 100644 --- a/packaging/dali-toolkit.spec +++ b/packaging/dali-toolkit.spec @@ -1,6 +1,6 @@ Name: dali2-toolkit Summary: Dali 3D engine Toolkit -Version: 2.2.16 +Version: 2.2.17 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT