From af599038d0b1ce8d95ae912133e5ce2b249de74c Mon Sep 17 00:00:00 2001 From: seungho Date: Thu, 14 Jul 2022 14:26:01 +0900 Subject: [PATCH] Change dali-scene-loader to dali-scene3d --- build/tizen/CMakeLists.txt | 26 +++++++++++++------------- build/tizen/examples/CMakeLists.txt | 8 ++++---- com.samsung.dali-demo.xml | 4 ++-- demo/dali-demo.cpp | 6 +++--- examples/scene-loader/main.cpp | 29 ----------------------------- examples/scene-loader/scene-loader-example.cpp | 513 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- examples/scene-loader/scene-loader-example.h | 86 -------------------------------------------------------------------------------------- examples/scene-loader/scene-loader-extension.h | 221 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- examples/scene3d/main.cpp | 29 +++++++++++++++++++++++++++++ examples/scene3d/scene3d-example.cpp | 513 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ examples/scene3d/scene3d-example.h | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ examples/scene3d/scene3d-extension.h | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ packaging/com.samsung.dali-demo.spec | 2 +- resources/po/en_GB.po | 4 ++-- resources/po/en_US.po | 4 ++-- shared/dali-demo-strings.h | 4 ++-- 16 files changed, 878 insertions(+), 878 deletions(-) delete mode 100644 examples/scene-loader/main.cpp delete mode 100644 examples/scene-loader/scene-loader-example.cpp delete mode 100644 examples/scene-loader/scene-loader-example.h delete mode 100644 examples/scene-loader/scene-loader-extension.h create mode 100644 examples/scene3d/main.cpp create mode 100644 examples/scene3d/scene3d-example.cpp create mode 100644 examples/scene3d/scene3d-example.h create mode 100644 examples/scene3d/scene3d-extension.h diff --git a/build/tizen/CMakeLists.txt b/build/tizen/CMakeLists.txt index 5f20ac9..5198d34 100644 --- a/build/tizen/CMakeLists.txt +++ b/build/tizen/CMakeLists.txt @@ -215,19 +215,19 @@ IF( ENABLE_PKG_CONFIGURE ) SET(REQUIRED_CFLAGS "${REQUIRED_CFLAGS} ${flag}") ENDFOREACH(flag) - pkg_check_modules(DALI_SCENE_LOADER dali2-scene-loader) - IF( DALI_SCENE_LOADER_FOUND ) - FOREACH(flag ${DALI_SCENE_LOADER_CFLAGS}) + pkg_check_modules(DALI_SCENE3D dali2-scene3d) + IF( DALI_SCENE3D_FOUND ) + FOREACH(flag ${DALI_SCENE3D_CFLAGS}) SET(REQUIRED_CFLAGS "${REQUIRED_CFLAGS} ${flag}") ENDFOREACH(flag) - SET( REQUIRED_CFLAGS "${REQUIRED_CFLAGS} -DDALI_SCENE_LOADER_AVAILABLE" ) + SET( REQUIRED_CFLAGS "${REQUIRED_CFLAGS} -DDALI_SCENE3D_AVAILABLE" ) - FOREACH(flag ${DALI_SCENE_LOADER_LDFLAGS}) + FOREACH(flag ${DALI_SCENE3D_LDFLAGS}) SET(REQUIRED_PKGS_LDFLAGS "${REQUIRED_PKGS_LDFLAGS} ${flag}") ENDFOREACH(flag) - SET( ENABLE_SCENE_LOADER "ON" ) + SET( ENABLE_SCENE3D "ON" ) ENDIF() # if build as tizen platform, use capi-appfw-app-control @@ -277,7 +277,7 @@ IF( WIN32 OR APPLE ) # WIN32 includes x64 as well according to the cmake doc. FIND_PACKAGE( dali2-adaptor REQUIRED ) FIND_PACKAGE( dali2-toolkit REQUIRED ) - FIND_PACKAGE( dali2-scene-loader ) + FIND_PACKAGE( dali2-scene3d ) # Set up the include dir SET( INCLUDE_DIR $ENV{includedir} ) @@ -326,12 +326,12 @@ IF( WIN32 OR APPLE ) # WIN32 includes x64 as well according to the cmake doc. ) ENDIF() - IF (dali2-scene-loader_FOUND) + IF (dali2-scene3d_FOUND) SET(REQUIRED_LIBS ${REQUIRED_LIBS} - dali2-scene-loader::dali2-scene-loader + dali2-scene3d::dali2-scene3d ) - SET( ENABLE_SCENE_LOADER "ON" ) + SET( ENABLE_SCENE3D "ON" ) ENDIF() ELSEIF( UNIX ) SET( REQUIRED_LIBS @@ -357,8 +357,8 @@ IF( ENABLE_TRACE ) SET(DALI_DEMO_CFLAGS "${DALI_DEMO_CFLAGS} -DTRACE_ENABLED") ENDIF() -IF( ENABLE_SCENE_LOADER ) - SET(DALI_DEMO_CFLAGS "${DALI_DEMO_CFLAGS} -DDALI_SCENE_LOADER_AVAILABLE") +IF( ENABLE_SCENE3D ) + SET(DALI_DEMO_CFLAGS "${DALI_DEMO_CFLAGS} -DDALI_SCENE3D_AVAILABLE") ENDIF() IF( UNIX ) @@ -468,4 +468,4 @@ MESSAGE( " Folder DEMO_LOCALE_DIR : [" ${DEMO_LOCALE_DIR} "]" ) MESSAGE( " Folder DEMO_EXAMPLE_BIN : [" ${DEMO_EXAMPLE_BIN} "]" ) MESSAGE( " Folder DEMO_LANG : [" ${DEMO_LANG} "]" ) MESSAGE( " Current Build Platform : [" ${CURRENT_BUILD_PLATFORM} "]" ) -MESSAGE( " Scene Loader Enabled : [" ${ENABLE_SCENE_LOADER} "]" ) +MESSAGE( " Scene3D Enabled : [" ${ENABLE_SCENE3D} "]" ) diff --git a/build/tizen/examples/CMakeLists.txt b/build/tizen/examples/CMakeLists.txt index 1692226..3edebb6 100644 --- a/build/tizen/examples/CMakeLists.txt +++ b/build/tizen/examples/CMakeLists.txt @@ -13,10 +13,10 @@ MACRO(SUBDIRLIST result curdir) ENDMACRO() SUBDIRLIST(SUBDIRS ${EXAMPLES_SRC_DIR}) -SET(SCENE_LOADER_DIR "scene-loader") -IF (NOT "${ENABLE_SCENE_LOADER}" ) - IF ( ${SCENE_LOADER_DIR} IN_LIST SUBDIRS ) - LIST( REMOVE_ITEM SUBDIRS ${SCENE_LOADER_DIR} ) +SET(SCENE3D_DIR "scene3d") +IF (NOT "${ENABLE_SCENE3D}" ) + IF ( ${SCENE3D_DIR} IN_LIST SUBDIRS ) + LIST( REMOVE_ITEM SUBDIRS ${SCENE3D_DIR} ) ENDIF() ENDIF() diff --git a/com.samsung.dali-demo.xml b/com.samsung.dali-demo.xml index 40fb016..fde96a5 100644 --- a/com.samsung.dali-demo.xml +++ b/com.samsung.dali-demo.xml @@ -277,8 +277,8 @@ - - + + diff --git a/demo/dali-demo.cpp b/demo/dali-demo.cpp index b8fea35..0dd09b9 100644 --- a/demo/dali-demo.cpp +++ b/demo/dali-demo.cpp @@ -59,9 +59,9 @@ int DALI_EXPORT_API main(int argc, char** argv) demo.AddExample(Example("rendering-skybox.example", DALI_DEMO_STR_TITLE_SKYBOX)); demo.AddExample(Example("rendering-basic-pbr.example", DALI_DEMO_STR_TITLE_PBR)); demo.AddExample(Example("scene3d-view.example", DALI_DEMO_STR_TITLE_SCENE3D_VIEW)); -#ifdef DALI_SCENE_LOADER_AVAILABLE - demo.AddExample(Example("scene-loader.example", DALI_DEMO_STR_TITLE_SCENE_LOADER)); -#endif //DALI_SCENE_LOADER_AVAILABLE +#ifdef DALI_SCENE3D_AVAILABLE + demo.AddExample(Example("scene3d.example", DALI_DEMO_STR_TITLE_SCENE3D)); +#endif //DALI_SCENE3D_AVAILABLE demo.AddExample(Example("shadows-and-lights.example", DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS)); demo.AddExample(Example("sparkle.example", DALI_DEMO_STR_TITLE_SPARKLE)); demo.AddExample(Example("waves.example", DALI_DEMO_STR_TITLE_WAVES)); diff --git a/examples/scene-loader/main.cpp b/examples/scene-loader/main.cpp deleted file mode 100644 index 630aa26..0000000 --- a/examples/scene-loader/main.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#include "scene-loader-example.h" - -#include "dali/dali.h" - -using namespace Dali; - -int DALI_EXPORT_API main(int argc, char** argv) -{ - auto app = Application::New(&argc, &argv, DEMO_THEME_PATH); - SceneLoaderExample sceneLoader(app); - app.MainLoop(); - return 0; -} diff --git a/examples/scene-loader/scene-loader-example.cpp b/examples/scene-loader/scene-loader-example.cpp deleted file mode 100644 index 417ba6b..0000000 --- a/examples/scene-loader/scene-loader-example.cpp +++ /dev/null @@ -1,513 +0,0 @@ -/* - * 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. - * - */ -#include "scene-loader-example.h" -#include -#include -#include -#include -#include "dali-scene-loader/public-api/dli-loader.h" -#include "dali-scene-loader/public-api/gltf2-loader.h" -#include "dali-scene-loader/public-api/light-parameters.h" -#include "dali-scene-loader/public-api/load-result.h" -#include "dali-scene-loader/public-api/shader-definition-factory.h" -#include "dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h" -#include "dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h" -#include "dali-toolkit/public-api/controls/text-controls/text-label.h" -#include "dali-toolkit/public-api/visuals/gradient-visual-properties.h" -#include "dali/public-api/actors/layer.h" -#include "dali/public-api/adaptor-framework/key.h" -#include "dali/public-api/events/key-event.h" -#include "dali/public-api/object/property-array.h" -#include "dali/public-api/render-tasks/render-task-list.h" -#include "scene-loader-extension.h" - -using namespace Dali; -using namespace Dali::Toolkit; -using namespace Dali::SceneLoader; - -namespace -{ -const float ROTATION_SCALE = 180.f; // the amount of rotation that a swipe whose length is the width of the screen, causes, in degrees. - -const float ITEM_HEIGHT = 50.f; - -const Vector3 CAMERA_DEFAULT_POSITION(0.0f, 0.0f, 3.5f); - -const std::string_view DLI_EXTENSION = ".dli"; -const std::string_view GLTF_EXTENSION = ".gltf"; - -const std::string RESOURCE_TYPE_DIRS[]{ - "images/", - "shaders/", - "models/", - "images/", -}; - -using StringVector = std::vector; - -StringVector ListFiles( - const std::string& path, bool (*predicate)(const char*) = [](const char*) { return true; }) -{ - StringVector results; - - if(auto dirp = opendir(path.c_str())) - { - std::unique_ptr dir(dirp, closedir); - - struct dirent* ent; - while((ent = readdir(dir.get())) != nullptr) - { - if(ent->d_type == DT_REG && predicate(ent->d_name)) - { - results.push_back(ent->d_name); - } - } - } - return results; -} - -TextLabel MakeLabel(std::string msg) -{ - TextLabel label = TextLabel::New(" " + msg); - label.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); - label.SetProperty(TextLabel::Property::TEXT_COLOR, Color::WHITE); - label.SetProperty(TextLabel::Property::PIXEL_SIZE, ITEM_HEIGHT * 4 / 7); - label.SetProperty(TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER"); - SetActorCentered(label); - return label; -} - -struct ItemFactoryImpl : Dali::Toolkit::ItemFactory -{ - const std::vector& mSceneNames; - TapGestureDetector mTapDetector; - - ItemFactoryImpl(const std::vector& sceneNames, TapGestureDetector tapDetector) - : mSceneNames(sceneNames), - mTapDetector(tapDetector) - { - } - - unsigned int GetNumberOfItems() override - { - return mSceneNames.size(); - } - - Actor NewItem(unsigned int itemId) override - { - auto label = MakeLabel(mSceneNames[itemId]); - mTapDetector.Attach(label); - label.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true); - return label; - } -}; - -Actor CreateErrorMessage(std::string msg) -{ - auto label = MakeLabel(msg); - label.SetProperty(TextLabel::Property::MULTI_LINE, true); - label.SetProperty(TextLabel::Property::HORIZONTAL_ALIGNMENT, HorizontalAlignment::LEFT); - label.SetProperty(TextLabel::Property::VERTICAL_ALIGNMENT, VerticalAlignment::TOP); - return label; -} - -void ConfigureCamera(const CameraParameters& params, CameraActor camera) -{ - if(params.isPerspective) - { - camera.SetProjectionMode(Camera::PERSPECTIVE_PROJECTION); - camera.SetNearClippingPlane(params.zNear); - camera.SetFarClippingPlane(params.zFar); - camera.SetFieldOfView(Radian(Degree(params.yFov))); - } - else - { - camera.SetProjectionMode(Camera::ORTHOGRAPHIC_PROJECTION); - camera.SetOrthographicProjection(params.orthographicSize.x, - params.orthographicSize.y, - params.orthographicSize.z, - params.orthographicSize.w, - params.zNear, - params.zFar); - } - - // model - Vector3 camTranslation; - Vector3 camScale; - Quaternion camOrientation; - params.CalculateTransformComponents(camTranslation, camOrientation, camScale); - - SetActorCentered(camera); - camera.SetInvertYAxis(true); - camera.SetProperty(Actor::Property::POSITION, camTranslation); - camera.SetProperty(Actor::Property::ORIENTATION, camOrientation); - camera.SetProperty(Actor::Property::SCALE, camScale); - - camOrientation.Conjugate(); -} - -void ConfigureBlendShapeShaders(ResourceBundle& resources, const SceneDefinition& scene, Actor root, std::vector&& requests) -{ - std::vector errors; - auto onError = [&errors](const std::string& msg) { - errors.push_back(msg); - }; - if(!scene.ConfigureBlendshapeShaders(resources, root, std::move(requests), onError)) - { - ExceptionFlinger flinger(ASSERT_LOCATION); - for(auto& msg : errors) - { - flinger << msg << '\n'; - } - } -} - -Actor LoadScene(std::string sceneName, CameraActor camera, std::vector* animations, Animation& animation) -{ - ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) { - return Application::GetResourcePath() + RESOURCE_TYPE_DIRS[type]; - }; - - auto path = pathProvider(ResourceType::Mesh) + sceneName; - - ResourceBundle resources; - SceneDefinition scene; - std::vector animGroups; - std::vector cameraParameters; - std::vector lights; - - animations->clear(); - - LoadResult output{ - resources, - scene, - *animations, - animGroups, - cameraParameters, - lights}; - - if(sceneName.rfind(DLI_EXTENSION) == sceneName.size() - DLI_EXTENSION.size()) - { - DliLoader loader; - DliLoader::InputParams input{ - pathProvider(ResourceType::Mesh), - nullptr, - {}, - {}, - nullptr, - {}}; - DliLoader::LoadParams loadParams{input, output}; - if(!loader.LoadScene(path, loadParams)) - { - ExceptionFlinger(ASSERT_LOCATION) << "Failed to load scene from '" << path << "': " << loader.GetParseError(); - } - } - else - { - ShaderDefinitionFactory sdf; - sdf.SetResources(resources); - LoadGltfScene(path, sdf, output); - - resources.mEnvironmentMaps.push_back({}); - } - - if(cameraParameters.empty()) - { - cameraParameters.push_back(CameraParameters()); - cameraParameters[0].matrix.SetTranslation(CAMERA_DEFAULT_POSITION); - } - ConfigureCamera(cameraParameters[0], camera); - - ViewProjection viewProjection = cameraParameters[0].GetViewProjection(); - Transforms xforms{ - MatrixStack{}, - viewProjection}; - NodeDefinition::CreateParams nodeParams{ - resources, - xforms, - {}, - {}, - {}}; - Customization::Choices choices; - - Actor root = Actor::New(); - SetActorCentered(root); - - for(auto iRoot : scene.GetRoots()) - { - auto resourceRefs = resources.CreateRefCounter(); - scene.CountResourceRefs(iRoot, choices, resourceRefs); - resources.CountEnvironmentReferences(resourceRefs); - - resources.LoadResources(resourceRefs, pathProvider); - - if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams)) - { - scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor); - scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables)); - ConfigureBlendShapeShaders(resources, scene, actor, std::move(nodeParams.mBlendshapeRequests)); - - scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables)); - - root.Add(actor); - } - } - - if(!animations->empty()) - { - auto getActor = [&root](const std::string& name) { - return root.FindChildByName(name); - }; - - animation = (*animations)[0].ReAnimate(getActor); - animation.Play(); - } - - return root; -} - -} // namespace - -SceneLoaderExample::SceneLoaderExample(Dali::Application& app) -: mApp(app), - mSceneLoaderExtension(new SceneLoaderExtension()) -{ - if(!std::getenv("DALI_APPLICATION_PACKAGE")) - { - if(auto desktopPrefix = std::getenv("DESKTOP_PREFIX")) - { - std::stringstream sstr; - sstr << desktopPrefix << "/share/com.samsung.dali-demo/res/"; - - auto daliApplicationPackage = sstr.str(); - setenv("DALI_APPLICATION_PACKAGE", daliApplicationPackage.c_str(), 0); - } - } - - app.InitSignal().Connect(this, &SceneLoaderExample::OnInit); - app.TerminateSignal().Connect(this, &SceneLoaderExample::OnTerminate); -} - -SceneLoaderExample::~SceneLoaderExample() = default; - -void SceneLoaderExample::OnInit(Application& app) -{ - // get scenes - auto resPath = Application::GetResourcePath(); - auto scenePath = resPath + RESOURCE_TYPE_DIRS[ResourceType::Mesh]; - auto sceneNames = ListFiles(scenePath, [](const char* name) { - auto len = strlen(name); - return (len > DLI_EXTENSION.size() && DLI_EXTENSION.compare(name + (len - DLI_EXTENSION.size())) == 0) || - (len > GLTF_EXTENSION.size() && GLTF_EXTENSION.compare(name + (len - GLTF_EXTENSION.size())) == 0); - }); - mSceneNames = sceneNames; - - // create Dali objects - auto window = app.GetWindow(); - - // navigation view - auto navigationView = NavigationView::New(); - navigationView.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); - SetActorCentered(navigationView); - - // Set up the background gradient. - Property::Array stopOffsets; - stopOffsets.PushBack(0.0f); - stopOffsets.PushBack(1.0f); - Property::Array stopColors; - stopColors.PushBack(Color::BLACK); - stopColors.PushBack(Vector4(0.45f, 0.7f, 0.8f, 1.f)); // Medium bright, pastel blue - const float percentageWindowHeight = window.GetSize().GetHeight() * 0.6f; - - navigationView.SetProperty(Toolkit::Control::Property::BACKGROUND, - Dali::Property::Map() - .Add(Toolkit::Visual::Property::TYPE, Dali::Toolkit::Visual::GRADIENT) - .Add(Toolkit::GradientVisual::Property::STOP_OFFSET, stopOffsets) - .Add(Toolkit::GradientVisual::Property::STOP_COLOR, stopColors) - .Add(Toolkit::GradientVisual::Property::START_POSITION, Vector2(0.f, -percentageWindowHeight)) - .Add(Toolkit::GradientVisual::Property::END_POSITION, Vector2(0.f, percentageWindowHeight)) - .Add(Toolkit::GradientVisual::Property::UNITS, Toolkit::GradientVisual::Units::USER_SPACE)); - window.Add(navigationView); - mNavigationView = navigationView; - - // item view - auto tapDetector = TapGestureDetector::New(); - mItemFactory.reset(new ::ItemFactoryImpl(mSceneNames, tapDetector)); - - auto items = ItemView::New(*mItemFactory); - SetActorCentered(items); - items.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); - items.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true); - - Vector3 windowSize(window.GetSize()); - auto itemLayout = DefaultItemLayout::New(DefaultItemLayout::LIST); - itemLayout->SetItemSize(Vector3(windowSize.x * 0.9f, ITEM_HEIGHT, 1.f)); - items.AddLayout(*itemLayout); - navigationView.Push(items); - - mItemLayout = itemLayout; - mItemView = items; - - mItemView.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true); - KeyboardFocusManager::Get().PreFocusChangeSignal().Connect(this, &SceneLoaderExample::OnKeyboardPreFocusChange); - KeyboardFocusManager::Get().FocusedActorEnterKeySignal().Connect(this, &SceneLoaderExample::OnKeyboardFocusedActorActivated); - KeyboardFocusManager::Get().FocusChangedSignal().Connect(this, &SceneLoaderExample::OnKeyboardFocusChanged); - - SetActorCentered(KeyboardFocusManager::Get().GetFocusIndicatorActor()); - - // camera - auto camera = CameraActor::New(); - camera.SetInvertYAxis(true); - window.Add(camera); - mSceneCamera = camera; - - // event handling - window.KeyEventSignal().Connect(this, &SceneLoaderExample::OnKey); - - tapDetector.DetectedSignal().Connect(this, &SceneLoaderExample::OnTap); - mTapDetector = tapDetector; - - // activate layout - mItemView.ActivateLayout(0, windowSize, 0.f); - - mSceneLoaderExtension->SetSceneLoader(this); -} - -Actor SceneLoaderExample::OnKeyboardPreFocusChange(Actor current, Actor proposed, Control::KeyboardFocus::Direction direction) -{ - if(!current && !proposed) - { - return mItemView; - } - - return proposed; -} - -void SceneLoaderExample::OnKeyboardFocusedActorActivated(Actor activatedActor) -{ - if(activatedActor) - { - OnTap(activatedActor, Dali::TapGesture()); - } -} - -void SceneLoaderExample::OnKeyboardFocusChanged(Actor originalFocusedActor, Actor currentFocusedActor) -{ - if(currentFocusedActor) - { - auto itemId = mItemView.GetItemId(currentFocusedActor); - mItemView.ScrollToItem(itemId, 0.1f); - } -} - -void SceneLoaderExample::OnTerminate(Application& app) -{ - mTapDetector.Reset(); - mPanDetector.Reset(); - - auto window = app.GetWindow(); - auto renderTasks = window.GetRenderTaskList(); - renderTasks.RemoveTask(mSceneRender); - mSceneRender.Reset(); - - UnparentAndReset(mNavigationView); - UnparentAndReset(mSceneCamera); - - mItemFactory.reset(); -} - -void SceneLoaderExample::OnKey(const KeyEvent& e) -{ - if(e.GetState() == KeyEvent::UP) - { - if(IsKey(e, DALI_KEY_ESCAPE) || IsKey(e, DALI_KEY_BACK)) - { - if(mScene) - { - mPanDetector.Reset(); - - mNavigationView.Pop(); - mScene.Reset(); - - if(mActivatedActor) - { - KeyboardFocusManager::Get().SetCurrentFocusActor(mActivatedActor); - } - } - else - { - mApp.Quit(); - } - } - else - { - mSceneLoaderExtension->OnKey(e); - } - } -} - -void SceneLoaderExample::OnPan(Actor actor, const PanGesture& pan) -{ - auto windowSize = mApp.GetWindow().GetSize(); - Vector2 size{float(windowSize.GetWidth()), float(windowSize.GetHeight())}; - float aspect = size.y / size.x; - - size /= ROTATION_SCALE; - - Vector2 rotation{pan.GetDisplacement().x / size.x, pan.GetDisplacement().y / size.y * aspect}; - - Quaternion q = Quaternion(Radian(Degree(rotation.y)), Radian(Degree(rotation.x)), Radian(0.f)); - Quaternion q0 = mScene.GetProperty(Actor::Property::ORIENTATION).Get(); - - mScene.SetProperty(Actor::Property::ORIENTATION, q * q0); -} - -void SceneLoaderExample::OnTap(Dali::Actor actor, const Dali::TapGesture& tap) -{ - mActivatedActor = actor; - - auto id = mItemView.GetItemId(actor); - - try - { - auto window = mApp.GetWindow(); - auto renderTasks = window.GetRenderTaskList(); - renderTasks.RemoveTask(mSceneRender); - - auto scene = LoadScene(mSceneNames[id], mSceneCamera, &mSceneAnimations, mCurrentAnimation); - - auto sceneRender = renderTasks.CreateTask(); - sceneRender.SetCameraActor(mSceneCamera); - sceneRender.SetSourceActor(scene); - sceneRender.SetExclusive(true); - - mScene = scene; - mSceneRender = sceneRender; - - mPanDetector = PanGestureDetector::New(); - mPanDetector.DetectedSignal().Connect(this, &SceneLoaderExample::OnPan); - mPanDetector.Attach(mNavigationView); - } - catch(const DaliException& e) - { - mScene = CreateErrorMessage(e.condition); - } - - mNavigationView.Push(mScene); - - mSceneLoaderExtension->ConnectTouchSignals(); -} diff --git a/examples/scene-loader/scene-loader-example.h b/examples/scene-loader/scene-loader-example.h deleted file mode 100644 index a516dbe..0000000 --- a/examples/scene-loader/scene-loader-example.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef SCENE_LAUNCHER_H_ -#define SCENE_LAUNCHER_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. - * - */ - -#include -#include "dali-scene-loader/public-api/animation-definition.h" -#include "dali-scene-loader/public-api/camera-parameters.h" -#include "dali-scene-loader/public-api/node-definition.h" -#include "dali-scene-loader/public-api/scene-definition.h" -#include "dali-toolkit/devel-api/controls/navigation-view/navigation-view.h" -#include "dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h" -#include "dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h" -#include "dali-toolkit/public-api/controls/scrollable/item-view/item-view.h" -#include "dali/public-api/actors/camera-actor.h" -#include "dali/public-api/adaptor-framework/application.h" -#include "dali/public-api/common/vector-wrapper.h" -#include "dali/public-api/events/pan-gesture-detector.h" -#include "dali/public-api/render-tasks/render-task.h" -#include "dali/public-api/signals/connection-tracker.h" - -class SceneLoaderExtension; - -class SceneLoaderExample : public Dali::ConnectionTracker -{ -public: - SceneLoaderExample(Dali::Application& app); - ~SceneLoaderExample(); - -private: // data - Dali::Application& mApp; - - std::vector mSceneNames; - - Dali::Toolkit::NavigationView mNavigationView; - - std::unique_ptr mItemFactory; - Dali::Toolkit::ItemLayoutPtr mItemLayout; - Dali::Toolkit::ItemView mItemView; - - Dali::CameraActor mSceneCamera; - Dali::RenderTask mSceneRender; - - Dali::Quaternion mCameraOrientationInv; - - Dali::TapGestureDetector mTapDetector; - Dali::PanGestureDetector mPanDetector; - - Dali::Actor mActivatedActor; - -public: - Dali::Actor mScene; - - std::vector mSceneAnimations; - Dali::Animation mCurrentAnimation; - - std::unique_ptr mSceneLoaderExtension; - -private: // methods - void OnInit(Dali::Application& app); - void OnTerminate(Dali::Application& app); - - void OnKey(const Dali::KeyEvent& e); - void OnPan(Dali::Actor actor, const Dali::PanGesture& pan); - void OnTap(Dali::Actor actor, const Dali::TapGesture& tap); - - Dali::Actor OnKeyboardPreFocusChange(Dali::Actor current, Dali::Actor proposed, Dali::Toolkit::Control::KeyboardFocus::Direction direction); - void OnKeyboardFocusedActorActivated(Dali::Actor activatedActor); - void OnKeyboardFocusChanged(Dali::Actor originalFocusedActor, Dali::Actor currentFocusedActor); -}; - -#endif //SCENE_LAUNCHER_H_ diff --git a/examples/scene-loader/scene-loader-extension.h b/examples/scene-loader/scene-loader-extension.h deleted file mode 100644 index e937234..0000000 --- a/examples/scene-loader/scene-loader-extension.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * 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. - * - */ - -#include -#include -#include - -class SceneLoaderExtension : public Dali::ConnectionTracker -{ -public: - SceneLoaderExtension() - : mSceneLoader(nullptr), - mCurrentAnimationIndex(ANIMATION_IDLE) - { - } - - ~SceneLoaderExtension() = default; // Nothing to do in destructor - - void SetSceneLoader(SceneLoaderExample* sceneLoader) - { - mSceneLoader = sceneLoader; - } - - void ConnectTouchSignals() - { - // This is a temporary hack for now to manually connect these signals. - // We should connect these signals automatically when loading the scene. - - if(mSceneLoader) - { - ConnectTouchSignal(ICON_IDLE); - ConnectTouchSignal(ICON_SQUAT); - ConnectTouchSignal(ICON_JUMPING_JACK); - ConnectTouchSignal(ICON_LUNGE); - } - } - - void OnKey(const Dali::KeyEvent& e) - { - // This is a temporary hack for now to manually handle these key events. - // We should links them to the animations automatically when loading the scene. - - switch(e.GetKeyCode()) - { - case KEY_ONE: - { - PlaySceneAnimation(ANIMATION_IDLE); - break; - } - case KEY_TWO: - { - PlaySceneAnimation(ANIMATION_IDLE_TO_SQUAT); - break; - } - case KEY_THREE: - { - PlaySceneAnimation(ANIMATION_IDLE_TO_JUMPING_JACK); - break; - } - case KEY_FOUR: - { - PlaySceneAnimation(ANIMATION_IDLE_TO_LUNGE); - break; - } - default: - break; - } - } - -private: - bool PlaySceneAnimation(unsigned int animationIndex) - { - if(mSceneLoader && mSceneLoader->mScene) - { - if(mSceneLoader->mCurrentAnimation && - mCurrentAnimationIndex != ANIMATION_IDLE && - mSceneLoader->mCurrentAnimation.GetState() != Dali::Animation::STOPPED) - { - return false; - } - - auto root = mSceneLoader->mScene; - auto getActor = [&root](const std::string& name) { - return root.FindChildByName(name); - }; - - if(mSceneLoader->mSceneAnimations.size() > animationIndex) - { - mCurrentAnimationIndex = animationIndex; - mSceneLoader->mCurrentAnimation = mSceneLoader->mSceneAnimations[animationIndex].ReAnimate(getActor); - mSceneLoader->mCurrentAnimation.FinishedSignal().Connect(this, &SceneLoaderExtension::OnAnimationFinished); - mSceneLoader->mCurrentAnimation.Play(); - } - } - - return true; - } - - void ConnectTouchSignal(const std::string actorName) - { - if(mSceneLoader && mSceneLoader->mScene) - { - auto actor = mSceneLoader->mScene.FindChildByName(actorName); - if(actor) - { - actor.TouchedSignal().Connect(this, &SceneLoaderExtension::OnTouch); - } - } - } - - void OnAnimationFinished(Dali::Animation& source) - { - switch(mCurrentAnimationIndex) - { - case ANIMATION_IDLE_TO_SQUAT: - { - PlaySceneAnimation(ANIMATION_SQUAT_TO_IDLE); - break; - } - case ANIMATION_IDLE_TO_JUMPING_JACK: - { - PlaySceneAnimation(ANIMATION_JUMPING_JACK); - break; - } - case ANIMATION_JUMPING_JACK: - { - PlaySceneAnimation(ANIMATION_JUMPING_JACK_TO_IDLE); - break; - } - case ANIMATION_IDLE_TO_LUNGE: - { - PlaySceneAnimation(ANIMATION_LUNGE); - break; - } - case ANIMATION_LUNGE: - { - PlaySceneAnimation(ANIMATION_LUNGE_TO_IDLE); - break; - } - default: - { - mCurrentAnimationIndex = ANIMATION_IDLE; - break; - } - break; - } - } - - bool OnTouch(Dali::Actor actor, const Dali::TouchEvent& touch) - { - bool processed = false; - - if(touch.GetPointCount() > 0) - { - if(touch.GetState(0) == Dali::PointState::DOWN) - { - auto actorName = actor.GetProperty(Dali::Actor::Property::NAME); - - if(ICON_IDLE == actorName) - { - processed = PlaySceneAnimation(ANIMATION_IDLE); - } - else if(ICON_SQUAT == actorName) - { - processed = PlaySceneAnimation(ANIMATION_IDLE_TO_SQUAT); - } - else if(ICON_JUMPING_JACK == actorName) - { - processed = PlaySceneAnimation(ANIMATION_IDLE_TO_JUMPING_JACK); - } - else if(ICON_LUNGE == actorName) - { - processed = PlaySceneAnimation(ANIMATION_IDLE_TO_LUNGE); - } - } - } - return processed; - } - -private: - static constexpr unsigned int KEY_ONE = 10; - static constexpr unsigned int KEY_TWO = 11; - static constexpr unsigned int KEY_THREE = 12; - static constexpr unsigned int KEY_FOUR = 13; - - // Idle animation - static constexpr unsigned int ANIMATION_IDLE = 0; - // Squat animation - static constexpr unsigned int ANIMATION_IDLE_TO_SQUAT = 3; - static constexpr unsigned int ANIMATION_SQUAT_TO_IDLE = 15; - // JumpingJack animation - static constexpr unsigned int ANIMATION_IDLE_TO_JUMPING_JACK = 1; - static constexpr unsigned int ANIMATION_JUMPING_JACK = 5; - static constexpr unsigned int ANIMATION_JUMPING_JACK_TO_IDLE = 6; - // Lunge animation - static constexpr unsigned int ANIMATION_IDLE_TO_LUNGE = 2; - static constexpr unsigned int ANIMATION_LUNGE = 9; - static constexpr unsigned int ANIMATION_LUNGE_TO_IDLE = 10; - - inline static const std::string ICON_IDLE = "Idle"; - inline static const std::string ICON_SQUAT = "Squat"; - inline static const std::string ICON_JUMPING_JACK = "JumpingJack"; - inline static const std::string ICON_LUNGE = "Lunge"; - - SceneLoaderExample* mSceneLoader; - unsigned int mCurrentAnimationIndex; -}; diff --git a/examples/scene3d/main.cpp b/examples/scene3d/main.cpp new file mode 100644 index 0000000..bae3cad --- /dev/null +++ b/examples/scene3d/main.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "scene3d-example.h" + +#include "dali/dali.h" + +using namespace Dali; + +int DALI_EXPORT_API main(int argc, char** argv) +{ + auto app = Application::New(&argc, &argv, DEMO_THEME_PATH); + Scene3DExample scene3D(app); + app.MainLoop(); + return 0; +} diff --git a/examples/scene3d/scene3d-example.cpp b/examples/scene3d/scene3d-example.cpp new file mode 100644 index 0000000..2c634c8 --- /dev/null +++ b/examples/scene3d/scene3d-example.cpp @@ -0,0 +1,513 @@ +/* + * 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. + * + */ +#include "scene3d-example.h" +#include +#include +#include +#include +#include "dali-scene3d/public-api/loader/dli-loader.h" +#include "dali-scene3d/public-api/loader/gltf2-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/shader-definition-factory.h" +#include "dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h" +#include "dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h" +#include "dali-toolkit/public-api/controls/text-controls/text-label.h" +#include "dali-toolkit/public-api/visuals/gradient-visual-properties.h" +#include "dali/public-api/actors/layer.h" +#include "dali/public-api/adaptor-framework/key.h" +#include "dali/public-api/events/key-event.h" +#include "dali/public-api/object/property-array.h" +#include "dali/public-api/render-tasks/render-task-list.h" +#include "scene3d-extension.h" + +using namespace Dali; +using namespace Dali::Toolkit; +using namespace Dali::Scene3D::Loader; + +namespace +{ +const float ROTATION_SCALE = 180.f; // the amount of rotation that a swipe whose length is the width of the screen, causes, in degrees. + +const float ITEM_HEIGHT = 50.f; + +const Vector3 CAMERA_DEFAULT_POSITION(0.0f, 0.0f, 3.5f); + +const std::string_view DLI_EXTENSION = ".dli"; +const std::string_view GLTF_EXTENSION = ".gltf"; + +const std::string RESOURCE_TYPE_DIRS[]{ + "images/", + "shaders/", + "models/", + "images/", +}; + +using StringVector = std::vector; + +StringVector ListFiles( + const std::string& path, bool (*predicate)(const char*) = [](const char*) { return true; }) +{ + StringVector results; + + if(auto dirp = opendir(path.c_str())) + { + std::unique_ptr dir(dirp, closedir); + + struct dirent* ent; + while((ent = readdir(dir.get())) != nullptr) + { + if(ent->d_type == DT_REG && predicate(ent->d_name)) + { + results.push_back(ent->d_name); + } + } + } + return results; +} + +TextLabel MakeLabel(std::string msg) +{ + TextLabel label = TextLabel::New(" " + msg); + label.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + label.SetProperty(TextLabel::Property::TEXT_COLOR, Color::WHITE); + label.SetProperty(TextLabel::Property::PIXEL_SIZE, ITEM_HEIGHT * 4 / 7); + label.SetProperty(TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER"); + SetActorCentered(label); + return label; +} + +struct ItemFactoryImpl : Dali::Toolkit::ItemFactory +{ + const std::vector& mSceneNames; + TapGestureDetector mTapDetector; + + ItemFactoryImpl(const std::vector& sceneNames, TapGestureDetector tapDetector) + : mSceneNames(sceneNames), + mTapDetector(tapDetector) + { + } + + unsigned int GetNumberOfItems() override + { + return mSceneNames.size(); + } + + Actor NewItem(unsigned int itemId) override + { + auto label = MakeLabel(mSceneNames[itemId]); + mTapDetector.Attach(label); + label.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true); + return label; + } +}; + +Actor CreateErrorMessage(std::string msg) +{ + auto label = MakeLabel(msg); + label.SetProperty(TextLabel::Property::MULTI_LINE, true); + label.SetProperty(TextLabel::Property::HORIZONTAL_ALIGNMENT, HorizontalAlignment::LEFT); + label.SetProperty(TextLabel::Property::VERTICAL_ALIGNMENT, VerticalAlignment::TOP); + return label; +} + +void ConfigureCamera(const CameraParameters& params, CameraActor camera) +{ + if(params.isPerspective) + { + camera.SetProjectionMode(Camera::PERSPECTIVE_PROJECTION); + camera.SetNearClippingPlane(params.zNear); + camera.SetFarClippingPlane(params.zFar); + camera.SetFieldOfView(Radian(Degree(params.yFov))); + } + else + { + camera.SetProjectionMode(Camera::ORTHOGRAPHIC_PROJECTION); + camera.SetOrthographicProjection(params.orthographicSize.x, + params.orthographicSize.y, + params.orthographicSize.z, + params.orthographicSize.w, + params.zNear, + params.zFar); + } + + // model + Vector3 camTranslation; + Vector3 camScale; + Quaternion camOrientation; + params.CalculateTransformComponents(camTranslation, camOrientation, camScale); + + SetActorCentered(camera); + camera.SetInvertYAxis(true); + camera.SetProperty(Actor::Property::POSITION, camTranslation); + camera.SetProperty(Actor::Property::ORIENTATION, camOrientation); + camera.SetProperty(Actor::Property::SCALE, camScale); + + camOrientation.Conjugate(); +} + +void ConfigureBlendShapeShaders(ResourceBundle& resources, const SceneDefinition& scene, Actor root, std::vector&& requests) +{ + std::vector errors; + auto onError = [&errors](const std::string& msg) { + errors.push_back(msg); + }; + if(!scene.ConfigureBlendshapeShaders(resources, root, std::move(requests), onError)) + { + ExceptionFlinger flinger(ASSERT_LOCATION); + for(auto& msg : errors) + { + flinger << msg << '\n'; + } + } +} + +Actor LoadScene(std::string sceneName, CameraActor camera, std::vector* animations, Animation& animation) +{ + ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) { + return Application::GetResourcePath() + RESOURCE_TYPE_DIRS[type]; + }; + + auto path = pathProvider(ResourceType::Mesh) + sceneName; + + ResourceBundle resources; + SceneDefinition scene; + std::vector animGroups; + std::vector cameraParameters; + std::vector lights; + + animations->clear(); + + LoadResult output{ + resources, + scene, + *animations, + animGroups, + cameraParameters, + lights}; + + if(sceneName.rfind(DLI_EXTENSION) == sceneName.size() - DLI_EXTENSION.size()) + { + DliLoader loader; + DliLoader::InputParams input{ + pathProvider(ResourceType::Mesh), + nullptr, + {}, + {}, + nullptr, + {}}; + DliLoader::LoadParams loadParams{input, output}; + if(!loader.LoadScene(path, loadParams)) + { + ExceptionFlinger(ASSERT_LOCATION) << "Failed to load scene from '" << path << "': " << loader.GetParseError(); + } + } + else + { + ShaderDefinitionFactory sdf; + sdf.SetResources(resources); + LoadGltfScene(path, sdf, output); + + resources.mEnvironmentMaps.push_back({}); + } + + if(cameraParameters.empty()) + { + cameraParameters.push_back(CameraParameters()); + cameraParameters[0].matrix.SetTranslation(CAMERA_DEFAULT_POSITION); + } + ConfigureCamera(cameraParameters[0], camera); + + ViewProjection viewProjection = cameraParameters[0].GetViewProjection(); + Transforms xforms{ + MatrixStack{}, + viewProjection}; + NodeDefinition::CreateParams nodeParams{ + resources, + xforms, + {}, + {}, + {}}; + Customization::Choices choices; + + Actor root = Actor::New(); + SetActorCentered(root); + + for(auto iRoot : scene.GetRoots()) + { + auto resourceRefs = resources.CreateRefCounter(); + scene.CountResourceRefs(iRoot, choices, resourceRefs); + resources.CountEnvironmentReferences(resourceRefs); + + resources.LoadResources(resourceRefs, pathProvider); + + if(auto actor = scene.CreateNodes(iRoot, choices, nodeParams)) + { + scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor); + scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables)); + ConfigureBlendShapeShaders(resources, scene, actor, std::move(nodeParams.mBlendshapeRequests)); + + scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables)); + + root.Add(actor); + } + } + + if(!animations->empty()) + { + auto getActor = [&root](const std::string& name) { + return root.FindChildByName(name); + }; + + animation = (*animations)[0].ReAnimate(getActor); + animation.Play(); + } + + return root; +} + +} // namespace + +Scene3DExample::Scene3DExample(Dali::Application& app) +: mApp(app), + mScene3DExtension(new Scene3DExtension()) +{ + if(!std::getenv("DALI_APPLICATION_PACKAGE")) + { + if(auto desktopPrefix = std::getenv("DESKTOP_PREFIX")) + { + std::stringstream sstr; + sstr << desktopPrefix << "/share/com.samsung.dali-demo/res/"; + + auto daliApplicationPackage = sstr.str(); + setenv("DALI_APPLICATION_PACKAGE", daliApplicationPackage.c_str(), 0); + } + } + + app.InitSignal().Connect(this, &Scene3DExample::OnInit); + app.TerminateSignal().Connect(this, &Scene3DExample::OnTerminate); +} + +Scene3DExample::~Scene3DExample() = default; + +void Scene3DExample::OnInit(Application& app) +{ + // get scenes + auto resPath = Application::GetResourcePath(); + auto scenePath = resPath + RESOURCE_TYPE_DIRS[ResourceType::Mesh]; + auto sceneNames = ListFiles(scenePath, [](const char* name) { + auto len = strlen(name); + return (len > DLI_EXTENSION.size() && DLI_EXTENSION.compare(name + (len - DLI_EXTENSION.size())) == 0) || + (len > GLTF_EXTENSION.size() && GLTF_EXTENSION.compare(name + (len - GLTF_EXTENSION.size())) == 0); + }); + mSceneNames = sceneNames; + + // create Dali objects + auto window = app.GetWindow(); + + // navigation view + auto navigationView = NavigationView::New(); + navigationView.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + SetActorCentered(navigationView); + + // Set up the background gradient. + Property::Array stopOffsets; + stopOffsets.PushBack(0.0f); + stopOffsets.PushBack(1.0f); + Property::Array stopColors; + stopColors.PushBack(Color::BLACK); + stopColors.PushBack(Vector4(0.45f, 0.7f, 0.8f, 1.f)); // Medium bright, pastel blue + const float percentageWindowHeight = window.GetSize().GetHeight() * 0.6f; + + navigationView.SetProperty(Toolkit::Control::Property::BACKGROUND, + Dali::Property::Map() + .Add(Toolkit::Visual::Property::TYPE, Dali::Toolkit::Visual::GRADIENT) + .Add(Toolkit::GradientVisual::Property::STOP_OFFSET, stopOffsets) + .Add(Toolkit::GradientVisual::Property::STOP_COLOR, stopColors) + .Add(Toolkit::GradientVisual::Property::START_POSITION, Vector2(0.f, -percentageWindowHeight)) + .Add(Toolkit::GradientVisual::Property::END_POSITION, Vector2(0.f, percentageWindowHeight)) + .Add(Toolkit::GradientVisual::Property::UNITS, Toolkit::GradientVisual::Units::USER_SPACE)); + window.Add(navigationView); + mNavigationView = navigationView; + + // item view + auto tapDetector = TapGestureDetector::New(); + mItemFactory.reset(new ::ItemFactoryImpl(mSceneNames, tapDetector)); + + auto items = ItemView::New(*mItemFactory); + SetActorCentered(items); + items.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + items.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true); + + Vector3 windowSize(window.GetSize()); + auto itemLayout = DefaultItemLayout::New(DefaultItemLayout::LIST); + itemLayout->SetItemSize(Vector3(windowSize.x * 0.9f, ITEM_HEIGHT, 1.f)); + items.AddLayout(*itemLayout); + navigationView.Push(items); + + mItemLayout = itemLayout; + mItemView = items; + + mItemView.SetProperty(Actor::Property::KEYBOARD_FOCUSABLE, true); + KeyboardFocusManager::Get().PreFocusChangeSignal().Connect(this, &Scene3DExample::OnKeyboardPreFocusChange); + KeyboardFocusManager::Get().FocusedActorEnterKeySignal().Connect(this, &Scene3DExample::OnKeyboardFocusedActorActivated); + KeyboardFocusManager::Get().FocusChangedSignal().Connect(this, &Scene3DExample::OnKeyboardFocusChanged); + + SetActorCentered(KeyboardFocusManager::Get().GetFocusIndicatorActor()); + + // camera + auto camera = CameraActor::New(); + camera.SetInvertYAxis(true); + window.Add(camera); + mSceneCamera = camera; + + // event handling + window.KeyEventSignal().Connect(this, &Scene3DExample::OnKey); + + tapDetector.DetectedSignal().Connect(this, &Scene3DExample::OnTap); + mTapDetector = tapDetector; + + // activate layout + mItemView.ActivateLayout(0, windowSize, 0.f); + + mScene3DExtension->SetSceneLoader(this); +} + +Actor Scene3DExample::OnKeyboardPreFocusChange(Actor current, Actor proposed, Control::KeyboardFocus::Direction direction) +{ + if(!current && !proposed) + { + return mItemView; + } + + return proposed; +} + +void Scene3DExample::OnKeyboardFocusedActorActivated(Actor activatedActor) +{ + if(activatedActor) + { + OnTap(activatedActor, Dali::TapGesture()); + } +} + +void Scene3DExample::OnKeyboardFocusChanged(Actor originalFocusedActor, Actor currentFocusedActor) +{ + if(currentFocusedActor) + { + auto itemId = mItemView.GetItemId(currentFocusedActor); + mItemView.ScrollToItem(itemId, 0.1f); + } +} + +void Scene3DExample::OnTerminate(Application& app) +{ + mTapDetector.Reset(); + mPanDetector.Reset(); + + auto window = app.GetWindow(); + auto renderTasks = window.GetRenderTaskList(); + renderTasks.RemoveTask(mSceneRender); + mSceneRender.Reset(); + + UnparentAndReset(mNavigationView); + UnparentAndReset(mSceneCamera); + + mItemFactory.reset(); +} + +void Scene3DExample::OnKey(const KeyEvent& e) +{ + if(e.GetState() == KeyEvent::UP) + { + if(IsKey(e, DALI_KEY_ESCAPE) || IsKey(e, DALI_KEY_BACK)) + { + if(mScene) + { + mPanDetector.Reset(); + + mNavigationView.Pop(); + mScene.Reset(); + + if(mActivatedActor) + { + KeyboardFocusManager::Get().SetCurrentFocusActor(mActivatedActor); + } + } + else + { + mApp.Quit(); + } + } + else + { + mScene3DExtension->OnKey(e); + } + } +} + +void Scene3DExample::OnPan(Actor actor, const PanGesture& pan) +{ + auto windowSize = mApp.GetWindow().GetSize(); + Vector2 size{float(windowSize.GetWidth()), float(windowSize.GetHeight())}; + float aspect = size.y / size.x; + + size /= ROTATION_SCALE; + + Vector2 rotation{pan.GetDisplacement().x / size.x, pan.GetDisplacement().y / size.y * aspect}; + + Quaternion q = Quaternion(Radian(Degree(rotation.y)), Radian(Degree(rotation.x)), Radian(0.f)); + Quaternion q0 = mScene.GetProperty(Actor::Property::ORIENTATION).Get(); + + mScene.SetProperty(Actor::Property::ORIENTATION, q * q0); +} + +void Scene3DExample::OnTap(Dali::Actor actor, const Dali::TapGesture& tap) +{ + mActivatedActor = actor; + + auto id = mItemView.GetItemId(actor); + + try + { + auto window = mApp.GetWindow(); + auto renderTasks = window.GetRenderTaskList(); + renderTasks.RemoveTask(mSceneRender); + + auto scene = LoadScene(mSceneNames[id], mSceneCamera, &mSceneAnimations, mCurrentAnimation); + + auto sceneRender = renderTasks.CreateTask(); + sceneRender.SetCameraActor(mSceneCamera); + sceneRender.SetSourceActor(scene); + sceneRender.SetExclusive(true); + + mScene = scene; + mSceneRender = sceneRender; + + mPanDetector = PanGestureDetector::New(); + mPanDetector.DetectedSignal().Connect(this, &Scene3DExample::OnPan); + mPanDetector.Attach(mNavigationView); + } + catch(const DaliException& e) + { + mScene = CreateErrorMessage(e.condition); + } + + mNavigationView.Push(mScene); + + mScene3DExtension->ConnectTouchSignals(); +} diff --git a/examples/scene3d/scene3d-example.h b/examples/scene3d/scene3d-example.h new file mode 100644 index 0000000..eda40d5 --- /dev/null +++ b/examples/scene3d/scene3d-example.h @@ -0,0 +1,86 @@ +#ifndef SCENE_LAUNCHER_H_ +#define SCENE_LAUNCHER_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. + * + */ + +#include +#include "dali-scene3d/public-api/loader/animation-definition.h" +#include "dali-scene3d/public-api/loader/camera-parameters.h" +#include "dali-scene3d/public-api/loader/node-definition.h" +#include "dali-scene3d/public-api/loader/scene-definition.h" +#include "dali-toolkit/devel-api/controls/navigation-view/navigation-view.h" +#include "dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h" +#include "dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h" +#include "dali-toolkit/public-api/controls/scrollable/item-view/item-view.h" +#include "dali/public-api/actors/camera-actor.h" +#include "dali/public-api/adaptor-framework/application.h" +#include "dali/public-api/common/vector-wrapper.h" +#include "dali/public-api/events/pan-gesture-detector.h" +#include "dali/public-api/render-tasks/render-task.h" +#include "dali/public-api/signals/connection-tracker.h" + +class Scene3DExtension; + +class Scene3DExample : public Dali::ConnectionTracker +{ +public: + Scene3DExample(Dali::Application& app); + ~Scene3DExample(); + +private: // data + Dali::Application& mApp; + + std::vector mSceneNames; + + Dali::Toolkit::NavigationView mNavigationView; + + std::unique_ptr mItemFactory; + Dali::Toolkit::ItemLayoutPtr mItemLayout; + Dali::Toolkit::ItemView mItemView; + + Dali::CameraActor mSceneCamera; + Dali::RenderTask mSceneRender; + + Dali::Quaternion mCameraOrientationInv; + + Dali::TapGestureDetector mTapDetector; + Dali::PanGestureDetector mPanDetector; + + Dali::Actor mActivatedActor; + +public: + Dali::Actor mScene; + + std::vector mSceneAnimations; + Dali::Animation mCurrentAnimation; + + std::unique_ptr mScene3DExtension; + +private: // methods + void OnInit(Dali::Application& app); + void OnTerminate(Dali::Application& app); + + void OnKey(const Dali::KeyEvent& e); + void OnPan(Dali::Actor actor, const Dali::PanGesture& pan); + void OnTap(Dali::Actor actor, const Dali::TapGesture& tap); + + Dali::Actor OnKeyboardPreFocusChange(Dali::Actor current, Dali::Actor proposed, Dali::Toolkit::Control::KeyboardFocus::Direction direction); + void OnKeyboardFocusedActorActivated(Dali::Actor activatedActor); + void OnKeyboardFocusChanged(Dali::Actor originalFocusedActor, Dali::Actor currentFocusedActor); +}; + +#endif //SCENE_LAUNCHER_H_ diff --git a/examples/scene3d/scene3d-extension.h b/examples/scene3d/scene3d-extension.h new file mode 100644 index 0000000..d4cc6ca --- /dev/null +++ b/examples/scene3d/scene3d-extension.h @@ -0,0 +1,221 @@ +/* + * 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. + * + */ + +#include +#include +#include + +class Scene3DExtension : public Dali::ConnectionTracker +{ +public: + Scene3DExtension() + : mSceneLoader(nullptr), + mCurrentAnimationIndex(ANIMATION_IDLE) + { + } + + ~Scene3DExtension() = default; // Nothing to do in destructor + + void SetSceneLoader(Scene3DExample* scene3D) + { + mSceneLoader = scene3D; + } + + void ConnectTouchSignals() + { + // This is a temporary hack for now to manually connect these signals. + // We should connect these signals automatically when loading the scene. + + if(mSceneLoader) + { + ConnectTouchSignal(ICON_IDLE); + ConnectTouchSignal(ICON_SQUAT); + ConnectTouchSignal(ICON_JUMPING_JACK); + ConnectTouchSignal(ICON_LUNGE); + } + } + + void OnKey(const Dali::KeyEvent& e) + { + // This is a temporary hack for now to manually handle these key events. + // We should links them to the animations automatically when loading the scene. + + switch(e.GetKeyCode()) + { + case KEY_ONE: + { + PlaySceneAnimation(ANIMATION_IDLE); + break; + } + case KEY_TWO: + { + PlaySceneAnimation(ANIMATION_IDLE_TO_SQUAT); + break; + } + case KEY_THREE: + { + PlaySceneAnimation(ANIMATION_IDLE_TO_JUMPING_JACK); + break; + } + case KEY_FOUR: + { + PlaySceneAnimation(ANIMATION_IDLE_TO_LUNGE); + break; + } + default: + break; + } + } + +private: + bool PlaySceneAnimation(unsigned int animationIndex) + { + if(mSceneLoader && mSceneLoader->mScene) + { + if(mSceneLoader->mCurrentAnimation && + mCurrentAnimationIndex != ANIMATION_IDLE && + mSceneLoader->mCurrentAnimation.GetState() != Dali::Animation::STOPPED) + { + return false; + } + + auto root = mSceneLoader->mScene; + auto getActor = [&root](const std::string& name) { + return root.FindChildByName(name); + }; + + if(mSceneLoader->mSceneAnimations.size() > animationIndex) + { + mCurrentAnimationIndex = animationIndex; + mSceneLoader->mCurrentAnimation = mSceneLoader->mSceneAnimations[animationIndex].ReAnimate(getActor); + mSceneLoader->mCurrentAnimation.FinishedSignal().Connect(this, &Scene3DExtension::OnAnimationFinished); + mSceneLoader->mCurrentAnimation.Play(); + } + } + + return true; + } + + void ConnectTouchSignal(const std::string actorName) + { + if(mSceneLoader && mSceneLoader->mScene) + { + auto actor = mSceneLoader->mScene.FindChildByName(actorName); + if(actor) + { + actor.TouchedSignal().Connect(this, &Scene3DExtension::OnTouch); + } + } + } + + void OnAnimationFinished(Dali::Animation& source) + { + switch(mCurrentAnimationIndex) + { + case ANIMATION_IDLE_TO_SQUAT: + { + PlaySceneAnimation(ANIMATION_SQUAT_TO_IDLE); + break; + } + case ANIMATION_IDLE_TO_JUMPING_JACK: + { + PlaySceneAnimation(ANIMATION_JUMPING_JACK); + break; + } + case ANIMATION_JUMPING_JACK: + { + PlaySceneAnimation(ANIMATION_JUMPING_JACK_TO_IDLE); + break; + } + case ANIMATION_IDLE_TO_LUNGE: + { + PlaySceneAnimation(ANIMATION_LUNGE); + break; + } + case ANIMATION_LUNGE: + { + PlaySceneAnimation(ANIMATION_LUNGE_TO_IDLE); + break; + } + default: + { + mCurrentAnimationIndex = ANIMATION_IDLE; + break; + } + break; + } + } + + bool OnTouch(Dali::Actor actor, const Dali::TouchEvent& touch) + { + bool processed = false; + + if(touch.GetPointCount() > 0) + { + if(touch.GetState(0) == Dali::PointState::DOWN) + { + auto actorName = actor.GetProperty(Dali::Actor::Property::NAME); + + if(ICON_IDLE == actorName) + { + processed = PlaySceneAnimation(ANIMATION_IDLE); + } + else if(ICON_SQUAT == actorName) + { + processed = PlaySceneAnimation(ANIMATION_IDLE_TO_SQUAT); + } + else if(ICON_JUMPING_JACK == actorName) + { + processed = PlaySceneAnimation(ANIMATION_IDLE_TO_JUMPING_JACK); + } + else if(ICON_LUNGE == actorName) + { + processed = PlaySceneAnimation(ANIMATION_IDLE_TO_LUNGE); + } + } + } + return processed; + } + +private: + static constexpr unsigned int KEY_ONE = 10; + static constexpr unsigned int KEY_TWO = 11; + static constexpr unsigned int KEY_THREE = 12; + static constexpr unsigned int KEY_FOUR = 13; + + // Idle animation + static constexpr unsigned int ANIMATION_IDLE = 0; + // Squat animation + static constexpr unsigned int ANIMATION_IDLE_TO_SQUAT = 3; + static constexpr unsigned int ANIMATION_SQUAT_TO_IDLE = 15; + // JumpingJack animation + static constexpr unsigned int ANIMATION_IDLE_TO_JUMPING_JACK = 1; + static constexpr unsigned int ANIMATION_JUMPING_JACK = 5; + static constexpr unsigned int ANIMATION_JUMPING_JACK_TO_IDLE = 6; + // Lunge animation + static constexpr unsigned int ANIMATION_IDLE_TO_LUNGE = 2; + static constexpr unsigned int ANIMATION_LUNGE = 9; + static constexpr unsigned int ANIMATION_LUNGE_TO_IDLE = 10; + + inline static const std::string ICON_IDLE = "Idle"; + inline static const std::string ICON_SQUAT = "Squat"; + inline static const std::string ICON_JUMPING_JACK = "JumpingJack"; + inline static const std::string ICON_LUNGE = "Lunge"; + + Scene3DExample* mSceneLoader; + unsigned int mCurrentAnimationIndex; +}; diff --git a/packaging/com.samsung.dali-demo.spec b/packaging/com.samsung.dali-demo.spec index 4a18bf6..d4f10f2 100755 --- a/packaging/com.samsung.dali-demo.spec +++ b/packaging/com.samsung.dali-demo.spec @@ -22,7 +22,7 @@ BuildRequires: gettext-tools BuildRequires: pkgconfig(dali2-core) BuildRequires: pkgconfig(dali2-adaptor) BuildRequires: pkgconfig(dali2-toolkit) -BuildRequires: pkgconfig(dali2-scene-loader) +BuildRequires: pkgconfig(dali2-scene3d) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(gles20) BuildRequires: pkgconfig(glesv2) diff --git a/resources/po/en_GB.po b/resources/po/en_GB.po index 52ea76b..81f75ce 100755 --- a/resources/po/en_GB.po +++ b/resources/po/en_GB.po @@ -205,8 +205,8 @@ msgstr "Reflection" msgid "DALI_DEMO_STR_TITLE_RENDERER_STENCIL" msgstr "Renderer Stencil" -msgid "DALI_DEMO_STR_TITLE_SCENE_LOADER" -msgstr "Scene Loader" +msgid "DALI_DEMO_STR_TITLE_SCENE3D" +msgstr "Scene3D" msgid "DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI" msgstr "Script-based UI" diff --git a/resources/po/en_US.po b/resources/po/en_US.po index 9545053..0e4341e 100755 --- a/resources/po/en_US.po +++ b/resources/po/en_US.po @@ -211,8 +211,8 @@ msgstr "Refraction" msgid "DALI_DEMO_STR_TITLE_RENDERER_STENCIL" msgstr "Renderer Stencil" -msgid "DALI_DEMO_STR_TITLE_SCENE_LOADER" -msgstr "Scene Loader" +msgid "DALI_DEMO_STR_TITLE_SCENE3D" +msgstr "Scene3D" msgid "DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI" msgstr "Script-based UI" diff --git a/shared/dali-demo-strings.h b/shared/dali-demo-strings.h index d84effd..8639183 100644 --- a/shared/dali-demo-strings.h +++ b/shared/dali-demo-strings.h @@ -116,7 +116,7 @@ extern "C" #define DALI_DEMO_STR_TITLE_RENDERING_RAY_MARCHING dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERING_RAY_MARCHING") #define DALI_DEMO_STR_TITLE_RENDERER_STENCIL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERER_STENCIL") #define DALI_DEMO_STR_TITLE_SCENE3D_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCENE3D_VIEW") -#define DALI_DEMO_STR_TITLE_SCENE_LOADER dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCENE_LOADER") +#define DALI_DEMO_STR_TITLE_SCENE3D dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCENE3D") #define DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI") #define DALI_DEMO_STR_TITLE_SCROLL_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCROLL_VIEW") #define DALI_DEMO_STR_TITLE_SIMPLE_SCROLL_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SIMPLE_SCROLL_VIEW") @@ -228,7 +228,7 @@ extern "C" #define DALI_DEMO_STR_TITLE_RENDERING_RADIAL_PROGRESS "Radial Progress" #define DALI_DEMO_STR_TITLE_RENDERER_STENCIL "Renderer Stencils" #define DALI_DEMO_STR_TITLE_SCENE3D_VIEW "Scene3D View glTF" -#define DALI_DEMO_STR_TITLE_SCENE_LOADER "Scene Loader" +#define DALI_DEMO_STR_TITLE_SCENE3D "Scene3D" #define DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI "Script Based UI" #define DALI_DEMO_STR_TITLE_SCROLL_VIEW "Scroll View" #define DALI_DEMO_STR_TITLE_SIMPLE_SCROLL_VIEW "Simple Scroll View" -- libgit2 0.21.4