utc-Dali-Gltf2Loader.cpp
utc-Dali-KtxLoader.cpp
utc-Dali-ModelView.cpp
+ utc-Dali-SceneView.cpp
utc-Dali-MatrixStack.cpp
utc-Dali-MeshDefinition.cpp
utc-Dali-NodeDefinition.cpp
--- /dev/null
+/*
+ * 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 <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <stdlib.h>
+#include <iostream>
+
+#include <dali-scene3d/public-api/controls/model-view/model-view.h>
+#include <dali-scene3d/public-api/controls/scene-view/scene-view.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+void scene_view_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void scene_view_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+namespace
+{
+/**
+ * For the AnimatedCube.gltf and its Assets
+ * Donated by Norbert Nopper for glTF testing.
+ * Take from https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/AnimatedCube
+ */
+const char* TEST_GLTF_FILE_NAME = TEST_RESOURCE_DIR "/AnimatedCube.gltf";
+
+/**
+ * For the diffuse and specular cube map texture.
+ * These textures are based off version of Wave engine sample
+ * Take from https://github.com/WaveEngine/Samples
+ *
+ * Copyright (c) 2022 Wave Coorporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+const char* TEST_DIFFUSE_TEXTURE = TEST_RESOURCE_DIR "/forest_irradiance.ktx";
+const char* TEST_SPECULAR_TEXTURE = TEST_RESOURCE_DIR "/forest_radiance.ktx";
+
+Dali::Texture GetDiffuseTexture(Dali::Scene3D::ModelView modelView)
+{
+ Dali::Texture texture;
+
+ Actor meshActor = modelView.FindChildByName("AnimatedCube");
+ if(meshActor)
+ {
+ Renderer renderer = meshActor.GetRendererAt(0u);
+ if(renderer)
+ {
+ TextureSet textureSet = renderer.GetTextures();
+ if(textureSet.GetTextureCount() == 7u)
+ {
+ texture = textureSet.GetTexture(5u);
+ }
+ }
+ }
+
+ return texture;
+}
+
+Dali::Texture GetSpecularTexture(Dali::Scene3D::ModelView modelView)
+{
+ Dali::Texture texture;
+
+ Actor meshActor = modelView.FindChildByName("AnimatedCube");
+ if(meshActor)
+ {
+ Renderer renderer = meshActor.GetRendererAt(0u);
+ if(renderer)
+ {
+ TextureSet textureSet = renderer.GetTextures();
+ if(textureSet.GetTextureCount() == 7u)
+ {
+ texture = textureSet.GetTexture(6u);
+ }
+ }
+ }
+
+ return texture;
+}
+} // namespace
+
+// Negative test case for a method
+int UtcDaliSceneViewUninitialized(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliSceneViewUninitialized");
+
+ Scene3D::SceneView view;
+
+ try
+ {
+ // New() must be called to create a ModelView or it wont be valid.
+ Actor a = Actor::New();
+ view.Add(a);
+ DALI_TEST_CHECK(false);
+ }
+ catch(Dali::DaliException& e)
+ {
+ // Tests that a negative test of an assertion succeeds
+ DALI_TEST_PRINT_ASSERT(e);
+ DALI_TEST_CHECK(!view);
+ }
+ END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliSceneViewNew(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliSceneViewNew");
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+ DALI_TEST_CHECK(view);
+ END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliSceneViewDownCast(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliSceneViewDownCast");
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+ BaseHandle handle(view);
+
+ Scene3D::SceneView sceneView = Scene3D::SceneView::DownCast(handle);
+ DALI_TEST_CHECK(view);
+ DALI_TEST_CHECK(sceneView);
+ DALI_TEST_CHECK(sceneView == view);
+ END_TEST;
+}
+
+int UtcDaliSceneViewTypeRegistry(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliSceneViewTypeRegistry");
+
+ TypeRegistry typeRegistry = TypeRegistry::Get();
+ DALI_TEST_CHECK(typeRegistry);
+
+ TypeInfo typeInfo = typeRegistry.GetTypeInfo("SceneView");
+ DALI_TEST_CHECK(typeInfo);
+
+ BaseHandle handle = typeInfo.CreateInstance();
+ DALI_TEST_CHECK(handle);
+
+ Scene3D::SceneView modelView = Scene3D::SceneView::DownCast(handle);
+ DALI_TEST_CHECK(modelView);
+
+ END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliSceneViewAddRemove(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliSceneViewAddRemove");
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+ DALI_TEST_CHECK(view);
+ DALI_TEST_EQUALS(1u, view.GetChildCount(), TEST_LOCATION);
+
+ Actor actor = Actor::New();
+
+ view.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ view.SetProperty(Actor::Property::SIZE, application.GetScene().GetSize());
+ view.Add(actor);
+
+ DALI_TEST_EQUALS(1u, view.GetChildCount(), TEST_LOCATION);
+ Actor layer = view.GetChildAt(0u);
+
+ DALI_TEST_EQUALS(2u, layer.GetChildCount(), TEST_LOCATION);
+ DALI_TEST_EQUALS(actor, layer.GetChildAt(1u), TEST_LOCATION); // index 0u is default camera
+
+ view.Remove(actor);
+ DALI_TEST_EQUALS(1u, layer.GetChildCount(), TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliSceneViewCopyAndAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+ DALI_TEST_CHECK(view);
+
+ Scene3D::SceneView copy(view);
+ DALI_TEST_CHECK(view == copy);
+
+ Scene3D::SceneView assign;
+ DALI_TEST_CHECK(!assign);
+
+ assign = copy;
+ DALI_TEST_CHECK(assign == view);
+
+ END_TEST;
+}
+
+int UtcDaliSceneViewMoveConstructor(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+ DALI_TEST_EQUALS(1, view.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ view.SetProperty(Actor::Property::SENSITIVE, false);
+ DALI_TEST_CHECK(false == view.GetProperty<bool>(Actor::Property::SENSITIVE));
+
+ Scene3D::SceneView moved = std::move(view);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_CHECK(false == moved.GetProperty<bool>(Actor::Property::SENSITIVE));
+ DALI_TEST_CHECK(!view);
+
+ END_TEST;
+}
+
+int UtcDaliSceneViewMoveAssignment(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+ DALI_TEST_EQUALS(1, view.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ view.SetProperty(Actor::Property::SENSITIVE, false);
+ DALI_TEST_CHECK(false == view.GetProperty<bool>(Actor::Property::SENSITIVE));
+
+ Scene3D::SceneView moved;
+ moved = std::move(view);
+ DALI_TEST_CHECK(moved);
+ DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_CHECK(false == moved.GetProperty<bool>(Actor::Property::SENSITIVE));
+ DALI_TEST_CHECK(!view);
+
+ END_TEST;
+}
+
+int UtcDaliSceneViewOnScene01(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+
+ DALI_TEST_EQUALS(1u, view.GetChildCount(), TEST_LOCATION);
+ Actor layer = view.GetChildAt(0u);
+
+ DALI_TEST_EQUALS(1u, layer.GetChildCount(), TEST_LOCATION);
+
+ application.GetScene().Add(view);
+
+ application.SendNotification();
+ application.Render();
+
+ // CameraActor is added on layer when on scene
+ DALI_TEST_EQUALS(1u, layer.GetChildCount(), TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliSceneViewOnScene02(void)
+{
+ ToolkitTestApplication application;
+
+ uint32_t renderTaskCount = application.GetScene().GetRenderTaskList().GetTaskCount();
+ DALI_TEST_EQUALS(1u, renderTaskCount, TEST_LOCATION);
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+
+ renderTaskCount = application.GetScene().GetRenderTaskList().GetTaskCount();
+ DALI_TEST_EQUALS(2u, renderTaskCount, TEST_LOCATION);
+
+ RenderTask renderTask = application.GetScene().GetRenderTaskList().GetTask(1u);
+ CameraActor camera = renderTask.GetCameraActor();
+
+ application.GetScene().Add(view);
+
+ application.SendNotification();
+ application.Render();
+
+ CameraActor defaultCamera = renderTask.GetCameraActor();
+ DALI_TEST_CHECK(defaultCamera);
+ DALI_TEST_EQUALS(camera, defaultCamera, TEST_LOCATION);
+ DALI_TEST_EQUALS(defaultCamera, view.GetSelectedCamera(), TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliSceneViewUserCamera(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+ view.SetProperty(Dali::Actor::Property::SIZE, Vector2(100, 100));
+
+ application.GetScene().Add(view);
+
+ application.SendNotification();
+ application.Render();
+
+ CameraActor defaultCamera = view.GetSelectedCamera();
+ CameraActor camera = Dali::CameraActor::New();
+ camera.SetProperty(Dali::Actor::Property::NAME, "camera");
+ view.AddCamera(camera);
+ view.SelectCamera("camera");
+
+ DALI_TEST_NOT_EQUALS(defaultCamera, view.GetSelectedCamera(), 0.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(camera, view.GetSelectedCamera(), TEST_LOCATION);
+
+ camera.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ camera.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ camera.SetFieldOfView(0.5f);
+ camera.SetNearClippingPlane(1.0f);
+ camera.SetFarClippingPlane(5000.0f);
+ camera.SetProperty(Dali::Actor::Property::POSITION, Vector3(20, 30, 40));
+
+ float fov = camera[Dali::CameraActor::Property::FIELD_OF_VIEW];
+ float nearPlain = camera[Dali::CameraActor::Property::NEAR_PLANE_DISTANCE];
+ float farPlain = camera[Dali::CameraActor::Property::FAR_PLANE_DISTANCE];
+ Vector3 cameraPosition = camera[Dali::Actor::Property::POSITION];
+
+ view.SetProperty(Dali::Actor::Property::SIZE, Vector2(400, 300));
+
+ DALI_TEST_EQUALS(fov, camera.GetProperty<float>(Dali::CameraActor::Property::FIELD_OF_VIEW), TEST_LOCATION);
+ DALI_TEST_EQUALS(nearPlain, camera.GetProperty<float>(Dali::CameraActor::Property::NEAR_PLANE_DISTANCE), TEST_LOCATION);
+ DALI_TEST_EQUALS(farPlain, camera.GetProperty<float>(Dali::CameraActor::Property::FAR_PLANE_DISTANCE), TEST_LOCATION);
+ DALI_TEST_EQUALS(cameraPosition, camera.GetProperty<Vector3>(Dali::Actor::Property::POSITION), TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliSceneViewAddRemoveCamera(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+ view.SetProperty(Dali::Actor::Property::SIZE, Vector2(100, 100));
+
+ application.GetScene().Add(view);
+
+ application.SendNotification();
+ application.Render();
+
+ CameraActor camera0 = view.GetSelectedCamera();
+ camera0.SetProperty(Dali::Actor::Property::NAME, "camera0");
+ CameraActor camera1 = Dali::CameraActor::New();
+ camera1.SetProperty(Dali::Actor::Property::NAME, "camera1");
+
+ DALI_TEST_EQUALS(1u, view.GetCameraCount(), TEST_LOCATION);
+ view.AddCamera(camera1);
+ DALI_TEST_EQUALS(2u, view.GetCameraCount(), TEST_LOCATION);
+
+ DALI_TEST_EQUALS(camera0, view.GetCamera(0), TEST_LOCATION);
+ DALI_TEST_EQUALS(camera0, view.GetCamera("camera0"), TEST_LOCATION);
+ DALI_TEST_EQUALS(camera1, view.GetCamera(1), TEST_LOCATION);
+ DALI_TEST_EQUALS(camera1, view.GetCamera("camera1"), TEST_LOCATION);
+
+ DALI_TEST_EQUALS(camera0, view.GetSelectedCamera(), TEST_LOCATION);
+ view.SelectCamera(1); // 0 -> 1
+ DALI_TEST_EQUALS(camera1, view.GetSelectedCamera(), TEST_LOCATION);
+ view.SelectCamera("camera0"); // 1 -> 0
+ DALI_TEST_EQUALS(camera0, view.GetSelectedCamera(), TEST_LOCATION);
+ view.SelectCamera("camera1"); // 0 -> 1
+ DALI_TEST_EQUALS(camera1, view.GetSelectedCamera(), TEST_LOCATION);
+ view.SelectCamera(0); // 1 -> 0
+ DALI_TEST_EQUALS(camera0, view.GetSelectedCamera(), TEST_LOCATION);
+
+ view.SelectCamera(1); // 0 -> 1
+ DALI_TEST_EQUALS(camera1, view.GetSelectedCamera(), TEST_LOCATION);
+ DALI_TEST_EQUALS(2u, view.GetCameraCount(), TEST_LOCATION);
+ view.RemoveCamera(camera1); // 1 -> 0
+ DALI_TEST_EQUALS(camera0, view.GetSelectedCamera(), TEST_LOCATION);
+ DALI_TEST_EQUALS(1u, view.GetCameraCount(), TEST_LOCATION);
+
+ CameraActor defaultCamera = view.GetSelectedCamera();
+ DALI_TEST_CHECK(defaultCamera);
+ DALI_TEST_EQUALS(camera0, defaultCamera, TEST_LOCATION);
+ DALI_TEST_NOT_EQUALS(camera1, defaultCamera, 0.0f, TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliSceneViewImageBasedLight(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+ view.SetProperty(Dali::Actor::Property::SIZE, Vector2(100, 100));
+
+ application.GetScene().Add(view);
+
+ application.SendNotification();
+ application.Render();
+
+ Scene3D::ModelView modelView1 = Scene3D::ModelView::New(TEST_GLTF_FILE_NAME);
+ Scene3D::ModelView modelView2 = Scene3D::ModelView::New(TEST_GLTF_FILE_NAME);
+ Scene3D::ModelView modelView3 = Scene3D::ModelView::New(TEST_GLTF_FILE_NAME);
+ view.Add(modelView1);
+ view.Add(modelView2);
+
+ DALI_TEST_NOT_EQUALS(GetDiffuseTexture(modelView1), GetDiffuseTexture(modelView2), 0.0f, TEST_LOCATION);
+ DALI_TEST_NOT_EQUALS(GetSpecularTexture(modelView1), GetSpecularTexture(modelView2), 0.0f, TEST_LOCATION);
+ DALI_TEST_NOT_EQUALS(GetDiffuseTexture(modelView1), GetDiffuseTexture(modelView3), 0.0f, TEST_LOCATION);
+ DALI_TEST_NOT_EQUALS(GetSpecularTexture(modelView1), GetSpecularTexture(modelView3), 0.0f, TEST_LOCATION);
+
+ view.SetImageBasedLightSource(TEST_DIFFUSE_TEXTURE, TEST_SPECULAR_TEXTURE);
+
+ DALI_TEST_EQUALS(GetDiffuseTexture(modelView1), GetDiffuseTexture(modelView2), TEST_LOCATION);
+ DALI_TEST_EQUALS(GetSpecularTexture(modelView1), GetSpecularTexture(modelView2), TEST_LOCATION);
+ DALI_TEST_NOT_EQUALS(GetDiffuseTexture(modelView1), GetDiffuseTexture(modelView3), 0.0f, TEST_LOCATION);
+ DALI_TEST_NOT_EQUALS(GetSpecularTexture(modelView1), GetSpecularTexture(modelView3), 0.0f, TEST_LOCATION);
+
+ view.Add(modelView3);
+
+ DALI_TEST_EQUALS(GetDiffuseTexture(modelView1), GetDiffuseTexture(modelView3), TEST_LOCATION);
+ DALI_TEST_EQUALS(GetSpecularTexture(modelView1), GetSpecularTexture(modelView3), TEST_LOCATION);
+
+ view.Remove(modelView1);
+ view.SetImageBasedLightSource(TEST_DIFFUSE_TEXTURE, TEST_SPECULAR_TEXTURE);
+
+ DALI_TEST_NOT_EQUALS(GetDiffuseTexture(modelView1), GetDiffuseTexture(modelView2), 0.0f, TEST_LOCATION);
+ DALI_TEST_NOT_EQUALS(GetSpecularTexture(modelView1), GetSpecularTexture(modelView2), 0.0f, TEST_LOCATION);
+ DALI_TEST_NOT_EQUALS(GetDiffuseTexture(modelView1), GetDiffuseTexture(modelView3), 0.0f, TEST_LOCATION);
+ DALI_TEST_NOT_EQUALS(GetSpecularTexture(modelView1), GetSpecularTexture(modelView3), 0.0f, TEST_LOCATION);
+ DALI_TEST_EQUALS(GetDiffuseTexture(modelView2), GetDiffuseTexture(modelView3), TEST_LOCATION);
+ DALI_TEST_EQUALS(GetSpecularTexture(modelView2), GetSpecularTexture(modelView3), TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliSceneViewUseFramebuffer01(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+ view.SetProperty(Dali::Actor::Property::SIZE, Vector2(100, 100));
+
+ application.GetScene().Add(view);
+
+ application.SendNotification();
+ application.Render();
+
+ bool useFramebuffer = view.IsUsingFramebuffer();
+ view.UseFramebuffer(true);
+ DALI_TEST_NOT_EQUALS(useFramebuffer, view.IsUsingFramebuffer(), 0.0f, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliSceneViewUseFramebuffer02(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+ view.SetProperty(Dali::Actor::Property::SIZE, Vector2(100, 100));
+
+ application.GetScene().Add(view);
+
+ application.SendNotification();
+ application.Render();
+
+ RenderTask renderTask = application.GetScene().GetRenderTaskList().GetTask(1u);
+ DALI_TEST_CHECK(!renderTask.GetFrameBuffer());
+
+ view.UseFramebuffer(true);
+ DALI_TEST_CHECK(renderTask.GetFrameBuffer());
+
+ view.UseFramebuffer(false);
+ DALI_TEST_CHECK(!renderTask.GetFrameBuffer());
+
+ END_TEST;
+}
// INTERNAL INCLUDES
#include <dali-scene3d/public-api/controls/model-view/model-view.h>
+#include <dali-scene3d/internal/controls/scene-view/scene-view-impl.h>
#include <dali-scene3d/public-api/loader/animation-definition.h>
#include <dali-scene3d/public-api/loader/camera-parameters.h>
-#include <dali-scene3d/public-api/loader/cube-data.h>
#include <dali-scene3d/public-api/loader/cube-map-loader.h>
#include <dali-scene3d/public-api/loader/dli-loader.h>
#include <dali-scene3d/public-api/loader/gltf2-loader.h>
Vector3 pointMax;
};
-Texture LoadCubeMap(const std::string& cubeMapPath)
-{
- Texture cubeTexture;
- Dali::Scene3D::Loader::CubeData cubeData;
- if(Dali::Scene3D::Loader::LoadCubeMapData(cubeMapPath, cubeData))
- {
- cubeTexture = cubeData.CreateTexture();
- }
- else
- {
- DALI_LOG_ERROR("Fail to load cube map, %s\n", cubeMapPath.c_str());
- }
-
- return cubeTexture;
-}
-
void ConfigureBlendShapeShaders(
Dali::Scene3D::Loader::ResourceBundle& resources, const Dali::Scene3D::Loader::SceneDefinition& scene, Actor root, std::vector<Dali::Scene3D::Loader::BlendshapeShaderConfigurationRequest>&& requests)
{
void ModelView::SetImageBasedLightSource(const std::string& diffuse, const std::string& specular, float scaleFactor)
{
- Texture diffuseTexture = LoadCubeMap(diffuse);
- if(diffuseTexture)
+ Texture diffuseTexture = Dali::Scene3D::Loader::LoadCubeMap(diffuse);
+ Texture specularTexture = Dali::Scene3D::Loader::LoadCubeMap(specular);
+ SetImageBasedLightTexture(diffuseTexture, specularTexture, scaleFactor);
+}
+
+void ModelView::SetImageBasedLightTexture(Dali::Texture diffuse, Dali::Texture specular, float scaleFactor)
+{
+ if(diffuse && specular)
{
- Texture specularTexture = LoadCubeMap(specular);
- if(specularTexture)
- {
- mDiffuseTexture = diffuseTexture;
- mSpecularTexture = specularTexture;
- mIblScaleFactor = scaleFactor;
+ mDiffuseTexture = diffuse;
+ mSpecularTexture = specular;
+ mIblScaleFactor = scaleFactor;
- SetImageBasedLight(mModelRoot);
- }
+ UpdateImageBasedLight();
}
}
LoadModel();
}
+ Actor parent = Self().GetParent();
+ while(parent)
+ {
+ Scene3D::SceneView sceneView = Scene3D::SceneView::DownCast(parent);
+ if(sceneView)
+ {
+ GetImpl(sceneView).RegisterModelView(Scene3D::ModelView::DownCast(Self()));
+ mParentSceneView = sceneView;
+ break;
+ }
+ parent = parent.GetParent();
+ }
+
Control::OnSceneConnection(depth);
}
+void ModelView::OnSceneDisconnection()
+{
+ Scene3D::SceneView sceneView = mParentSceneView.GetHandle();
+ if(sceneView)
+ {
+ GetImpl(sceneView).UnregisterModelView(Scene3D::ModelView::DownCast(Self()));
+ mParentSceneView.Reset();
+ }
+ Control::OnSceneDisconnection();
+}
+
void ModelView::OnInitialize()
{
Actor self = Self();
}
}
- SetImageBasedLight(mModelRoot);
+ mRenderableActors.clear();
+ CollectRenderableActor(mModelRoot);
+ UpdateImageBasedLight();
mNaturalSize = AABB.CalculateSize();
mModelPivot = AABB.CalculatePivot();
}
}
-void ModelView::SetImageBasedLight(Actor node)
+void ModelView::CollectRenderableActor(Actor actor)
{
- if(!mDiffuseTexture || !mSpecularTexture || !node)
+ uint32_t rendererCount = actor.GetRendererCount();
+ if(rendererCount)
{
- return;
+ mRenderableActors.push_back(actor);
}
- uint32_t rendererCount = node.GetRendererCount();
- if(rendererCount)
+ uint32_t childrenCount = actor.GetChildCount();
+ for(uint32_t i = 0; i < childrenCount; ++i)
{
- node.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), mIblScaleFactor);
+ CollectRenderableActor(actor.GetChildAt(i));
}
+}
- for(uint32_t i = 0; i < rendererCount; ++i)
+void ModelView::UpdateImageBasedLight()
+{
+ if(!mDiffuseTexture || !mSpecularTexture)
{
- Dali::Renderer renderer = node.GetRendererAt(i);
- if(renderer)
+ return;
+ }
+
+ for(auto&& actor : mRenderableActors)
+ {
+ Actor renderableActor = actor.GetHandle();
+ if(renderableActor)
{
- Dali::TextureSet textures = renderer.GetTextures();
- if(textures)
+ renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), mIblScaleFactor);
+
+ uint32_t rendererCount = renderableActor.GetRendererCount();
+ for(uint32_t i = 0; i < rendererCount; ++i)
{
- uint32_t textureCount = textures.GetTextureCount();
- // EnvMap requires at least 2 texture, diffuse and specular
- if(textureCount > 2u)
+ Dali::Renderer renderer = renderableActor.GetRendererAt(i);
+ if(renderer)
{
- textures.SetTexture(textureCount - OFFSET_FOR_DIFFUSE_CUBE_TEXTURE, mDiffuseTexture);
- textures.SetTexture(textureCount - OFFSET_FOR_SPECULAR_CUBE_TEXTURE, mSpecularTexture);
+ Dali::TextureSet textures = renderer.GetTextures();
+ if(textures)
+ {
+ uint32_t textureCount = textures.GetTextureCount();
+ // EnvMap requires at least 2 texture, diffuse and specular
+ if(textureCount > 2u)
+ {
+ textures.SetTexture(textureCount - OFFSET_FOR_DIFFUSE_CUBE_TEXTURE, mDiffuseTexture);
+ textures.SetTexture(textureCount - OFFSET_FOR_SPECULAR_CUBE_TEXTURE, mSpecularTexture);
+ }
+ }
}
}
}
}
-
- uint32_t childrenCount = node.GetChildCount();
- for(uint32_t i = 0; i < childrenCount; ++i)
- {
- SetImageBasedLight(node.GetChildAt(i));
- }
}
} // namespace Internal
#include <dali/public-api/actors/layer.h>
#include <dali/public-api/animation/animation.h>
#include <dali/public-api/rendering/texture.h>
+#include <dali/public-api/object/weak-handle.h>
// INTERNAL INCLUDES
#include <dali-scene3d/public-api/controls/model-view/model-view.h>
+#include <dali-scene3d/public-api/controls/scene-view/scene-view.h>
namespace Dali
{
*/
void SetImageBasedLightSource(const std::string& diffuse, const std::string& specular, float scaleFactor);
+ /**
+ * @copydoc ModelView::SetImageBasedLightTexture()
+ */
+ void SetImageBasedLightTexture(Dali::Texture diffuse, Dali::Texture specular, float scaleFactor);
+
/**
* @copydoc ModelView::GetAnimationCount()
*/
*/
void OnSceneConnection(int depth) override;
+ /**
+ * @copydoc CustomActorImpl::OnSceneDisconnection()
+ */
+ void OnSceneDisconnection() override;
+
/**
* @copydoc Toolkit::Control::OnInitialize()
*/
/**
* @brief Changes IBL information of the input node.
*/
- void SetImageBasedLight(Actor node);
+ void CollectRenderableActor(Actor actor);
+
+ /**
+ * @brief Changes IBL information of the input node.
+ */
+ void UpdateImageBasedLight();
private:
- std::string mModelPath;
- std::string mResourcePath;
- Dali::Layer mModelLayer;
- Dali::Actor mModelRoot;
- std::vector<AnimationData> mAnimations;
+ std::string mModelPath;
+ std::string mResourcePath;
+ Dali::Layer mModelLayer;
+ Dali::Actor mModelRoot;
+ std::vector<AnimationData> mAnimations;
+ std::vector<WeakHandle<Actor>> mRenderableActors;
+ WeakHandle<Scene3D::SceneView> mParentSceneView;
Dali::Texture mSpecularTexture;
Dali::Texture mDiffuseTexture;
--- /dev/null
+/*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/internal/controls/scene-view/scene-view-impl.h>
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/public-api/image-loader/image-url.h>
+#include <dali-toolkit/public-api/image-loader/image.h>
+#include <dali/devel-api/common/stage.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/public-api/object/type-registry.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/controls/model-view/model-view-impl.h>
+#include <dali-scene3d/public-api/loader/cube-map-loader.h>
+
+#include <dali/integration-api/debug.h>
+
+using namespace Dali;
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal
+{
+namespace
+{
+BaseHandle Create()
+{
+ return Scene3D::SceneView::New();
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN(Scene3D::SceneView, Toolkit::Control, Create);
+DALI_TYPE_REGISTRATION_END()
+
+Property::Index RENDERING_BUFFER = Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX + 1;
+
+} // anonymous namespace
+
+SceneView::SceneView()
+: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT))
+{
+}
+
+SceneView::~SceneView() = default;
+
+Dali::Scene3D::SceneView SceneView::New()
+{
+ SceneView* impl = new SceneView();
+
+ Dali::Scene3D::SceneView handle = Dali::Scene3D::SceneView(*impl);
+
+ // Second-phase init of the implementation
+ // This can only be done after the CustomActor connection has been made...
+ impl->Initialize();
+
+ return handle;
+}
+
+void SceneView::AddCamera(CameraActor camera)
+{
+ if(camera)
+ {
+ if(mCameras.empty())
+ {
+ UpdateCamera(camera);
+ }
+ mCameras.push_back(camera);
+ }
+}
+
+void SceneView::RemoveCamera(CameraActor camera)
+{
+ if(camera == mDefaultCamera)
+ {
+ DALI_LOG_ERROR("Default Camera cannot removed.\n");
+ return;
+ }
+
+ if(camera)
+ {
+ for(uint32_t i = 0; i < mCameras.size(); ++i)
+ {
+ if(mCameras[i] == camera)
+ {
+ mCameras.erase(mCameras.begin() + i);
+ break;
+ }
+ }
+
+ if(mSelectedCamera == camera)
+ {
+ CameraActor newCurrentCamera = *mCameras.begin();
+ UpdateCamera(newCurrentCamera);
+ }
+ }
+}
+
+uint32_t SceneView::GetCameraCount()
+{
+ return mCameras.size();
+}
+
+CameraActor SceneView::GetSelectedCamera()
+{
+ return mSelectedCamera;
+}
+
+CameraActor SceneView::GetCamera(uint32_t index)
+{
+ if(index < mCameras.size())
+ {
+ return mCameras[index];
+ }
+ DALI_LOG_ERROR("Input index is out of bounds\n");
+ return CameraActor();
+}
+
+CameraActor SceneView::GetCamera(const std::string& name)
+{
+ CameraActor returnCamera;
+ for(auto&& camera : mCameras)
+ {
+ if(camera.GetProperty<std::string>(Actor::Property::NAME) == name)
+ {
+ returnCamera = camera;
+ break;
+ }
+ }
+ return returnCamera;
+}
+
+void SceneView::SelectCamera(uint32_t index)
+{
+ UpdateCamera(GetCamera(index));
+}
+
+void SceneView::SelectCamera(const std::string& name)
+{
+ UpdateCamera(GetCamera(name));
+}
+
+void SceneView::RegisterModelView(Scene3D::ModelView modelView)
+{
+ if(modelView)
+ {
+ modelView.SetImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor);
+ mModels.push_back(modelView);
+ }
+}
+
+void SceneView::UnregisterModelView(Scene3D::ModelView modelView)
+{
+ if(modelView)
+ {
+ for(uint32_t i = 0; i < mModels.size(); ++i)
+ {
+ if(mModels[i] == modelView)
+ {
+ mModels.erase(mModels.begin() + i);
+ break;
+ }
+ }
+ }
+}
+
+void SceneView::SetImageBasedLightSource(const std::string& diffuse, const std::string& specular, float scaleFactor)
+{
+ Texture diffuseTexture = Dali::Scene3D::Loader::LoadCubeMap(diffuse);
+ if(diffuseTexture)
+ {
+ Texture specularTexture = Dali::Scene3D::Loader::LoadCubeMap(specular);
+ if(specularTexture)
+ {
+ mDiffuseTexture = diffuseTexture;
+ mSpecularTexture = specularTexture;
+ mIblScaleFactor = scaleFactor;
+
+ for(auto&& model : mModels)
+ {
+ if(model)
+ {
+ model.SetImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor);
+ }
+ }
+ }
+ }
+}
+
+void SceneView::UseFramebuffer(bool useFramebuffer)
+{
+ if(mUseFrameBuffer != useFramebuffer)
+ {
+ mUseFrameBuffer = useFramebuffer;
+ UpdateRenderTask();
+ }
+}
+
+bool SceneView::IsUsingFramebuffer()
+{
+ return mUseFrameBuffer;
+}
+
+///////////////////////////////////////////////////////////
+//
+// Private methods
+//
+
+void SceneView::OnSceneConnection(int depth)
+{
+ UpdateRenderTask();
+
+ Control::OnSceneConnection(depth);
+}
+
+void SceneView::OnSceneDisconnection()
+{
+ mModels.clear();
+ Control::OnSceneDisconnection();
+}
+
+void SceneView::OnInitialize()
+{
+ Actor self = Self();
+ mRootLayer = Layer::New();
+ mRootLayer.SetProperty(Layer::Property::BEHAVIOR, Layer::LAYER_3D);
+ mRootLayer.SetProperty(Layer::Property::DEPTH_TEST, true);
+ // The models in the SceneView should be have independent coordinate with DALi default coordinate.
+ mRootLayer.SetProperty(Dali::Actor::Property::INHERIT_POSITION, false);
+ mRootLayer.SetProperty(Dali::Actor::Property::INHERIT_ORIENTATION, false);
+ mRootLayer.SetProperty(Dali::Actor::Property::INHERIT_SCALE, false);
+ self.Add(mRootLayer);
+
+ RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
+ mRenderTask = taskList.CreateTask();
+ mRenderTask.SetSourceActor(mRootLayer);
+ mRenderTask.SetExclusive(true);
+ mRenderTask.SetInputEnabled(true);
+ mRenderTask.SetScreenToFrameBufferMappingActor(Self());
+
+ mDefaultCamera = Dali::CameraActor::New();
+ mDefaultCamera.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ mDefaultCamera.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ mDefaultCamera.SetNearClippingPlane(1.0f);
+ AddCamera(mDefaultCamera);
+ UpdateCamera(mDefaultCamera);
+}
+
+void SceneView::OnChildAdd(Actor& child)
+{
+ if(child != mRootLayer)
+ {
+ mRootLayer.Add(child);
+ }
+ Control::OnChildAdd(child);
+}
+
+void SceneView::OnChildRemove(Actor& child)
+{
+ mRootLayer.Remove(child);
+ Control::OnChildRemove(child);
+}
+
+float SceneView::GetHeightForWidth(float width)
+{
+ Extents padding;
+ padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
+ return Control::GetHeightForWidth(width) + padding.top + padding.bottom;
+}
+
+float SceneView::GetWidthForHeight(float height)
+{
+ Extents padding;
+ padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
+ return Control::GetWidthForHeight(height) + padding.start + padding.end;
+}
+
+void SceneView::OnRelayout(const Vector2& size, RelayoutContainer& container)
+{
+ Control::OnRelayout(size, container);
+ // Change canvas size of camera actor.
+ UpdateRenderTask();
+}
+
+void SceneView::UpdateCamera(CameraActor camera)
+{
+ if(camera)
+ {
+ if(mSelectedCamera && mSelectedCamera.GetParent())
+ {
+ mSelectedCamera.Unparent();
+ }
+ mRootLayer.Add(camera);
+ }
+
+ mSelectedCamera = camera;
+ UpdateRenderTask();
+}
+
+void SceneView::UpdateRenderTask()
+{
+ if(mRenderTask)
+ {
+ if(mSelectedCamera != mRenderTask.GetCameraActor())
+ {
+ mRenderTask.SetCameraActor(mSelectedCamera);
+ }
+
+ Vector3 size = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
+ float fov = 0.0f;
+ Vector3 cameraPosition(Vector3::ZERO);
+ float nearPlain = 1.0f;
+ float farPlain = 1.0f;
+
+ // Several properties such as fov, nearPlane, farPlane, and position should not be changed after SetPerspectiveProjection is called.
+ // In the 3D scene, the properties are not changed by the changes of canvas size.
+ fov = mSelectedCamera[Dali::CameraActor::Property::FIELD_OF_VIEW];
+ nearPlain = mSelectedCamera[Dali::CameraActor::Property::NEAR_PLANE_DISTANCE];
+ farPlain = mSelectedCamera[Dali::CameraActor::Property::FAR_PLANE_DISTANCE];
+ cameraPosition = Vector3(mSelectedCamera[Dali::Actor::Property::POSITION]);
+
+ mSelectedCamera.SetPerspectiveProjection(Dali::Size(size));
+
+ mSelectedCamera[Dali::CameraActor::Property::FIELD_OF_VIEW] = fov;
+ mSelectedCamera[Dali::CameraActor::Property::NEAR_PLANE_DISTANCE] = nearPlain;
+ mSelectedCamera[Dali::CameraActor::Property::FAR_PLANE_DISTANCE] = farPlain;
+ mSelectedCamera[Dali::Actor::Property::POSITION] = cameraPosition;
+
+ if(mUseFrameBuffer)
+ {
+ Dali::FrameBuffer currentFrameBuffer = mRenderTask.GetFrameBuffer();
+ if(!currentFrameBuffer ||
+ currentFrameBuffer.GetColorTexture().GetWidth() != size.width ||
+ currentFrameBuffer.GetColorTexture().GetHeight() != size.height)
+ {
+ mRenderTask.ResetViewportGuideActor();
+ mRenderTask.SetViewport(Dali::Viewport(Vector4::ZERO));
+
+ // create offscreen buffer of new size to render our child actors to
+ mTexture = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, unsigned(size.width), unsigned(size.height));
+ mRenderTarget = FrameBuffer::New(size.width, size.height, FrameBuffer::Attachment::DEPTH);
+ mRenderTarget.AttachColorTexture(mTexture);
+ Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(mRenderTarget, 0u);
+
+ Property::Map imagePropertyMap;
+ imagePropertyMap.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE);
+ imagePropertyMap.Insert(Toolkit::ImageVisual::Property::URL, imageUrl.GetUrl());
+ // To flip rendered scene without CameraActor::SetInvertYAxis() to avoid backface culling.
+ imagePropertyMap.Insert(Toolkit::ImageVisual::Property::PIXEL_AREA, Vector4(0.0f, 1.0f, 1.0f, -1.0f));
+ mVisual = Toolkit::VisualFactory::Get().CreateVisual(imagePropertyMap);
+
+ Toolkit::DevelControl::RegisterVisual(*this, RENDERING_BUFFER, mVisual);
+
+ mRenderTask.SetFrameBuffer(mRenderTarget);
+ mRenderTask.SetClearEnabled(true);
+ mRenderTask.SetClearColor(Color::TRANSPARENT);
+ }
+ }
+ else
+ {
+ mRenderTask.SetViewportGuideActor(Self());
+ if(mRenderTask.GetFrameBuffer())
+ {
+ FrameBuffer framebuffer;
+ mRenderTask.SetFrameBuffer(framebuffer);
+ mRenderTask.SetClearEnabled(false);
+ }
+ }
+ }
+}
+
+} // namespace Internal
+} // namespace Scene3D
+} // namespace Dali
--- /dev/null
+#ifndef DALI_SCENE3D_INTERNAL_SCENE_VIEW_H
+#define DALI_SCENE3D_INTERNAL_SCENE_VIEW_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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali-toolkit/internal/visuals/image/image-visual.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali/public-api/actors/camera-actor.h>
+#include <dali/public-api/actors/layer.h>
+#include <dali/public-api/animation/animation.h>
+#include <dali/public-api/object/weak-handle.h>
+#include <dali/public-api/render-tasks/render-task.h>
+#include <dali/public-api/rendering/frame-buffer.h>
+#include <dali/public-api/rendering/texture.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/public-api/controls/model-view/model-view.h>
+#include <dali-scene3d/public-api/controls/scene-view/scene-view.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+class SceneView;
+
+namespace Internal
+{
+/**
+ * @brief Impl class for SceneView.
+ */
+class SceneView : public Dali::Toolkit::Internal::Control
+{
+public:
+ /**
+ * @brief Creates a new SceneView.
+ *
+ * @return A public handle to the newly allocated SceneView.
+ */
+ static Dali::Scene3D::SceneView New();
+
+ /**
+ * @copydoc SceneView::AddCamera()
+ */
+ void AddCamera(Dali::CameraActor camera);
+
+ /**
+ * @copydoc SceneView::RemoveCamera()
+ */
+ void RemoveCamera(CameraActor camera);
+
+ /**
+ * @copydoc SceneView::GetCameraCount()
+ */
+ uint32_t GetCameraCount();
+
+ /**
+ * @copydoc SceneView::GetSelectedCamera()
+ */
+ CameraActor GetSelectedCamera();
+
+ /**
+ * @copydoc SceneView::GetCamera()
+ */
+ CameraActor GetCamera(uint32_t index);
+
+ /**
+ * @copydoc SceneView::GetCamera()
+ */
+ CameraActor GetCamera(const std::string& name);
+
+ /**
+ * @copydoc SceneView::SelectCamera()
+ */
+ void SelectCamera(uint32_t index);
+
+ /**
+ * @copydoc SceneView::SelectCamera()
+ */
+ void SelectCamera(const std::string& name);
+
+ /**
+ * @brief Register a ModelView.
+ * Some works like ibl setting should be applied on the only ModelView not the all child actors.
+ * SceneView contains child ModelView list to apply the works effectively.
+ *
+ * @param[in] modelView ModelView to be registered.
+ */
+ void RegisterModelView(Scene3D::ModelView modelView);
+
+ /**
+ * @brief Unregister a ModelView
+ *
+ * @param[in] modelView ModelView to be unregistered.
+ */
+ void UnregisterModelView(Scene3D::ModelView modelView);
+
+ /**
+ * @copydoc SceneView::SetImageBasedLightSource()
+ */
+ void SetImageBasedLightSource(const std::string& diffuse, const std::string& specular, float scaleFactor);
+
+ /**
+ * @copydoc SceneView::UseFramebuffer()
+ */
+ void UseFramebuffer(bool useFramebuffer);
+
+ /**
+ * @copydoc SceneView::IsUsingFramebuffer()
+ */
+ bool IsUsingFramebuffer();
+
+protected:
+ /**
+ * @brief Constructs a new SceneView.
+ */
+ SceneView();
+
+ /**
+ * A reference counted object may only be deleted by calling Unreference()
+ */
+ virtual ~SceneView();
+
+private:
+ /**
+ * @copydoc CustomActorImpl::OnSceneConnection()
+ */
+ void OnSceneConnection(int depth) override;
+
+ /**
+ * @copydoc CustomActorImpl::OnSceneDisconnection()
+ */
+ void OnSceneDisconnection() override;
+
+ /**
+ * @copydoc Toolkit::Control::OnInitialize()
+ */
+ void OnInitialize() override;
+
+ /**
+ * @copydoc Toolkit::Control::OnChildAdd()
+ */
+ void OnChildAdd(Actor& child) override;
+
+ /**
+ * @copydoc Toolkit::Control::OnChildRemove()
+ */
+ void OnChildRemove(Actor& child) override;
+
+ /**
+ * @copydoc Toolkit::Control::GetHeightForWidth()
+ */
+ float GetHeightForWidth(float width) override;
+
+ /**
+ * @copydoc Toolkit::Control::GetWidthForHeight()
+ */
+ float GetWidthForHeight(float height) override;
+
+ /**
+ * @copydoc Toolkit::Control::OnRelayout()
+ */
+ void OnRelayout(const Vector2& size, RelayoutContainer& container) override;
+
+ /**
+ * @brief Changes main camera as a input camera
+ *
+ * @param camera CameraActor that will be a main camera of the SceneView
+ */
+ void UpdateCamera(CameraActor camera);
+
+ /**
+ * @brief Updates RenderTask to use selected camera and to make framebuffer
+ */
+ void UpdateRenderTask();
+
+private:
+ Toolkit::Visual::Base mVisual;
+
+ /////////////////////////////////////////////////////////////
+ // FrameBuffer and Rendertask to render child objects as a 3D Scene
+ CameraActor mDefaultCamera;
+ CameraActor mSelectedCamera;
+ std::vector<CameraActor> mCameras;
+ std::vector<Scene3D::ModelView> mModels;
+ Dali::FrameBuffer mRenderTarget;
+ Dali::Texture mTexture;
+ Dali::RenderTask mRenderTask;
+
+ Layer mRootLayer;
+
+ Dali::Texture mSpecularTexture;
+ Dali::Texture mDiffuseTexture;
+ float mIblScaleFactor{1.0f};
+ bool mUseFrameBuffer{false};
+
+ // TODO : Light Source
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+inline Dali::Scene3D::Internal::SceneView& GetImpl(Dali::Scene3D::SceneView& obj)
+{
+ DALI_ASSERT_ALWAYS(obj);
+ Dali::RefObject& handle = obj.GetImplementation();
+ return static_cast<Dali::Scene3D::Internal::SceneView&>(handle);
+}
+
+inline const Dali::Scene3D::Internal::SceneView& GetImpl(const Dali::Scene3D::SceneView& obj)
+{
+ DALI_ASSERT_ALWAYS(obj);
+ const Dali::RefObject& handle = obj.GetImplementation();
+ return static_cast<const Dali::Scene3D::Internal::SceneView&>(handle);
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_INTERNAL_SCENE_VIEW_H
${scene3d_internal_dir}/loader/json-reader.cpp
${scene3d_internal_dir}/loader/json-util.cpp
${scene3d_internal_dir}/controls/model-view/model-view-impl.cpp
+ ${scene3d_internal_dir}/controls/scene-view/scene-view-impl.cpp
)
GetImpl(*this).SetImageBasedLightSource(diffuse, specular, scaleFactor);
}
+void ModelView::SetImageBasedLightTexture(Texture diffuse, Texture specular, float scaleFactor)
+{
+ GetImpl(*this).SetImageBasedLightTexture(diffuse, specular, scaleFactor);
+}
+
uint32_t ModelView::GetAnimationCount()
{
return GetImpl(*this).GetAnimationCount();
// EXTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control.h>
+#include <dali/public-api/rendering/texture.h>
#include <dali/public-api/common/dali-common.h>
namespace Dali
*/
void SetImageBasedLightSource(const std::string& diffuse, const std::string& specular, float scaleFactor = 1.0f);
+ /**
+ * @brief Set Image Based Light Texture.
+ *
+ * @param[in] diffuse cube map texture that can be used as a diffuse IBL source.
+ * @param[in] specular cube map texture that can be used as a specular IBL source.
+ * @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.
+ *
+ * @note Both of diffuse and specular should be available. If not, nothing applied.
+ */
+ void SetImageBasedLightTexture(Texture diffuse, Texture specular, float scaleFactor = 1.0f);
+
/**
* @brief Gets number of animations those loaded from model file.
* @return The number of loaded animations.
--- /dev/null
+/*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-scene3d/public-api/controls/scene-view/scene-view.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/controls/scene-view/scene-view-impl.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+SceneView::SceneView()
+{
+}
+
+SceneView::SceneView(const SceneView& sceneView) = default;
+
+SceneView::SceneView(SceneView&& rhs) = default;
+
+SceneView& SceneView::operator=(const SceneView& sceneView) = default;
+
+SceneView& SceneView::operator=(SceneView&& rhs) = default;
+
+SceneView::~SceneView()
+{
+}
+
+SceneView SceneView::New()
+{
+ return Internal::SceneView::New();
+}
+
+SceneView SceneView::DownCast(BaseHandle handle)
+{
+ return Control::DownCast<SceneView, Internal::SceneView>(handle);
+}
+
+SceneView::SceneView(Internal::SceneView& implementation)
+: Control(implementation)
+{
+}
+
+SceneView::SceneView(Dali::Internal::CustomActor* internal)
+: Control(internal)
+{
+ VerifyCustomActorPointer<Internal::SceneView>(internal);
+}
+
+void SceneView::AddCamera(Dali::CameraActor camera)
+{
+ GetImpl(*this).AddCamera(camera);
+}
+
+void SceneView::RemoveCamera(CameraActor camera)
+{
+ GetImpl(*this).RemoveCamera(camera);
+}
+
+uint32_t SceneView::GetCameraCount()
+{
+ return GetImpl(*this).GetCameraCount();
+}
+
+CameraActor SceneView::GetSelectedCamera()
+{
+ return GetImpl(*this).GetSelectedCamera();
+}
+
+CameraActor SceneView::GetCamera(uint32_t index)
+{
+ return GetImpl(*this).GetCamera(index);
+}
+
+CameraActor SceneView::GetCamera(const std::string& name)
+{
+ return GetImpl(*this).GetCamera(name);
+}
+
+void SceneView::SelectCamera(uint32_t index)
+{
+ GetImpl(*this).SelectCamera(index);
+}
+
+void SceneView::SelectCamera(const std::string& name)
+{
+ GetImpl(*this).SelectCamera(name);
+}
+
+void SceneView::SetImageBasedLightSource(const std::string& diffuse, const std::string& specular, float scaleFactor)
+{
+ GetImpl(*this).SetImageBasedLightSource(diffuse, specular, scaleFactor);
+}
+
+void SceneView::UseFramebuffer(bool useFramebuffer)
+{
+ GetImpl(*this).UseFramebuffer(useFramebuffer);
+}
+
+bool SceneView::IsUsingFramebuffer()
+{
+ return GetImpl(*this).IsUsingFramebuffer();
+}
+
+} // namespace Scene3D
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_SCENE3D_SCENE_VIEW_H
+#define DALI_SCENE3D_SCENE_VIEW_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 <dali-toolkit/public-api/controls/control.h>
+#include <dali/public-api/actors/camera-actor.h>
+#include <dali/public-api/common/dali-common.h>
+
+namespace Dali
+{
+namespace Scene3D
+{
+namespace Internal DALI_INTERNAL
+{
+class SceneView;
+}
+
+/**
+ * @addtogroup dali_toolkit_controls_scene_view
+ * @{
+ */
+
+/**
+ * @brief SceneView is a Dali::Toolkit::Control to show multiple 3D objects in a single 3D scene.
+ * Each SceneView has its own 3D space, and 3D objects added to SceneView are positioned in the space.
+ * SceneView has a 3D root layer internally to trigger the depth test in the rendering process.
+ * When an Actor is added to the SceneView with Add() method,
+ * the Actor and its children are actually become child of the 3D layer automatically.
+ *
+ * SceneView
+ * |
+ * Dali::Layer(Layer::LAYER_3D)
+ * |
+ * Actor
+ *
+ * The children of the 3D root layer will be rendered with the SceneView's own CameraActor.
+ *
+ * SceneView can have multiple CameraActor and one of them is used to render the multiple objects as a Scene.
+ * AddCamera(), RemoveCamera(), GetCamera(), and SelectCamera() are methods to manage CameraActors of the SceneView.
+ * Users can place multiple cameras in a scene, either to show the entire scene or to show individual objects.
+ * And the user can select the currently needed camera by using the SelectCamera() method.
+ *
+ * SceneView has one CameraActor built-in by default at the (0, 0, -z).
+ * The default CameraActor has index 0 and is not removed by using RemoveCamera() method.
+ * Therefore, the minimum value returned by GetCameraCount() method is 1.
+ *
+ * If the size of SceneView is changed, Some properties of CameraActor that depend on the size can be changed too.
+ * The changing properties are as follows: projectionMode, aspectRatio, leftPlaneDistance, rightPlaneDistance, topPlaneDistance, and bottomPlaneDistance.
+ * Position, near/farPlaneDistance, and FieldOfView are maintained even if the size of the SceneView is changed.
+ * The FieldOfView of Dali::CameraActor is for vertical fov. The horizontal fov is internally updated according to the SceneView size.
+ *
+ * The same light source is set for all Models added to SceneView, if SceneView has light source.
+ * The SetImageBasedLightSource() method sets the same IBL to all Models added to the SceneView.
+ * If any Model already has an IBL, it is replaced with the SceneView's IBL.
+ *
+ * SceneView provides an option to use FBO for rendering result with UseFramebuffer() method.
+ * If it is false, SceneView is always drawn in the form of a rectangle on the default window surface directly.
+ * It improves performance, but the SceneView is always drawn on top of other 2D objects regardless of Actor tree order.
+ * And it will show wrong result in case the window's default CameraActor is transformed.
+ * So, it is recommended not to change window's CameraActor.
+ *
+ * If FBO is used, the rendering result of SceneView is drawn on the FBO and it is mapped on the plane of the SceneView.
+ * It decreases performance, but it is useful to show SceneView according to the rendering order with other Actors.
+ * And it can be used in case window's CameraActor is transformed.
+ *
+ * And since SceneView is a Control, it can be placed together with other 2D UI components in the DALi window.
+ *
+ * @code
+ *
+ * Dali::Scene3D::SceneView sceneView = Dali::Scene3D::SceneView::New();
+ * sceneView.SetProperty(Dali::Actor::Property::SIZE, Vector2(400, 400));
+ * mWindow.Add(sceneView);
+ *
+ * Dali::Scene3D::ModelView model = Dali::Scene3D::ModelView::New(...);
+ * sceneView.Add(model);
+ *
+ * CameraActor cameraActor = CameraActor::New();
+ * // Setting CameraActor.
+ * sceneView.AddCamera(cameraActor);
+ *
+ * @endcode
+ */
+class DALI_SCENE3D_API SceneView : public Dali::Toolkit::Control
+{
+public:
+ /**
+ * @brief Create an initialized SceneView.
+ * @return A handle to a newly allocated Dali resource
+ */
+ static SceneView New();
+
+ /**
+ * @brief Creates an uninitialized SceneView.
+ *
+ * Only derived versions can be instantiated. Calling member
+ * functions with an uninitialized Dali::Object is not allowed.
+ */
+ SceneView();
+
+ /**
+ * @brief Destructor.
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~SceneView();
+
+ /**
+ * @brief Copy constructor.
+ * @param[in] sceneView Handle to an object
+ */
+ SceneView(const SceneView& sceneView);
+
+ /**
+ * @brief Move constructor
+ *
+ * @param[in] rhs A reference to the moved handle
+ */
+ SceneView(SceneView&& rhs);
+
+ /**
+ * @brief Assignment operator.
+ * @param[in] sceneView Handle to an object
+ * @return reference to this
+ */
+ SceneView& operator=(const SceneView& sceneView);
+
+ /**
+ * @brief Move assignment
+ *
+ * @param[in] rhs A reference to the moved handle
+ * @return A reference to this
+ */
+ SceneView& operator=(SceneView&& rhs);
+
+ /**
+ * @brief Downcasts an Object handle to SceneView.
+ *
+ * If handle points to a SceneView, the downcast produces valid handle.
+ * If not, the returned handle is left uninitialized.
+ *
+ * @param[in] handle Handle to an object
+ * @return Handle to a SceneView or an uninitialized handle
+ */
+ static SceneView DownCast(BaseHandle handle);
+
+ /**
+ * @brief Adds a CameraActor to the SceneView
+ * The CameraActor can be used as a selected camera to render the scene by using SelectCamera(uint32_t) or SelectCamera(std::string)
+ *
+ * @note Some properties of the CameraActor will be change depending on the Size of this SceneView.
+ * Those properties are as follows:
+ * projectionMode, aspectRatio, nearPlaneDistance, farPlaneDistance, leftPlaneDistance, rightPlaneDistance, topPlaneDistance, and bottomPlaneDistance.
+ *
+ * The FieldOfView of Dali::CameraActor is for vertical fov.
+ * When the size of the SceneView is changed, the vertical fov is maintained
+ * and the horizontal fov is automatically calculated according to the SceneView's aspect ratio.
+ *
+ * @param[in] camera CameraActor added on this scene view.
+ */
+ void AddCamera(Dali::CameraActor camera);
+
+ /**
+ * @brief Removes a CameraActor from this SceneView.
+ * @note If removed CameraActor is selected CameraActor,
+ * first camera in the list is set to selected CameraActor.
+ *
+ * @param[in] camera CameraActor to be removed from this SceneView
+ */
+ void RemoveCamera(CameraActor camera);
+
+ /**
+ * @brief Retrieves the number of cameras.
+ *
+ * @return Number of cameras those currently the SceneView contains.
+ */
+ uint32_t GetCameraCount();
+
+ /**
+ * @brief Retrieves selected CameraActor.
+ *
+ * @return CameraActor currently used in SceneView as a selected CameraActor
+ */
+ CameraActor GetSelectedCamera();
+
+ /**
+ * @brief Retrieves a CameraActor of the index.
+ *
+ * @param[in] index Index of CameraActor to be retrieved.
+ *
+ * @return CameraActor of the index
+ */
+ CameraActor GetCamera(uint32_t index);
+
+ /**
+ * @brief Retrieves a CameraActor of the name.
+ *
+ * @param[in] name string keyword of CameraActor to be retrieved.
+ *
+ * @return CameraActor that has the name as a Dali::Actor::Property::NAME
+ */
+ CameraActor GetCamera(const std::string& name);
+
+ /**
+ * @brief Makes SceneView use a CameraActor of index as a selected camera.
+ *
+ * @param[in] index Index of CameraActor to be used as a selected camera.
+ */
+ void SelectCamera(uint32_t index);
+
+ /**
+ * @brief Makes SceneView use a CameraActor of a name as a selected camera.
+ *
+ * @param[in] name string keyword of CameraActor to be used as a selected camera.
+ */
+ void SelectCamera(const std::string& name);
+
+ /**
+ * @brief Sets Image Based Light Source to apply it on the all Models those added on this SceneView.
+ *
+ * @note If any Models already have IBL, they are batch-overridden with the SceneView's IBL.
+ * If SceneView has IBL, IBL of newly added Model is also overridden.
+ * To set indivisual IBL for each Model, the Model's IBL should be set after the SceneView's IBL.
+ *
+ * @param[in] diffuse cube map that can be used as a diffuse IBL source.
+ * @param[in] specular cube map that can be used as a specular IBL source.
+ * @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.
+ */
+ void SetImageBasedLightSource(const std::string& diffuse, const std::string& specular, float scaleFactor = 1.0f);
+
+ /**
+ * @brief Sets whether to use FBO or not for the SceneView.
+ * If useFramebuffer is true, rendering result of SceneView is drawn on FBO and it is mapping on this SceneView plane.
+ * If useFramebuffer is false, each item in SceneView is rendered on window directly.
+ * Default is false.
+ *
+ * @note If useFramebuffer is true, it could decrease performance but entire rendering order is satisfied.
+ * If useFramebuffer is false, performance is become better but SceneView is rendered on top of the other 2D Actors regardless tree order.
+ *
+ * @param[in] useFramebuffer True to use FBO for SceneView.
+ */
+ void UseFramebuffer(bool useFramebuffer);
+
+ /**
+ * @brief Gets whether this SceneView uses Framebuffer or not.
+ *
+ * @return bool True if this SceneView uses Framebuffer.
+ */
+ bool IsUsingFramebuffer();
+
+public: // Not intended for application developers
+ /// @cond internal
+ /**
+ * @brief Creates a handle using the Toolkit::Internal implementation.
+ *
+ * @param[in] implementation The Control implementation
+ */
+ DALI_INTERNAL SceneView(Internal::SceneView& implementation);
+
+ /**
+ * @brief Allows the creation of this Control from an Internal::CustomActor pointer.
+ *
+ * @param[in] internal A pointer to the internal CustomActor
+ */
+ DALI_INTERNAL SceneView(Dali::Internal::CustomActor* internal);
+ /// @endcond
+};
+
+/**
+ * @}
+ */
+} // namespace Scene3D
+
+} // namespace Dali
+
+#endif // DALI_SCENE3D_SCENE_VIEW_H
set(scene3d_src_files ${scene3d_src_files}
${scene3d_public_api_dir}/controls/model-view/model-view.cpp
+ ${scene3d_public_api_dir}/controls/scene-view/scene-view.cpp
${scene3d_public_api_dir}/loader/alpha-function-helper.cpp
${scene3d_public_api_dir}/loader/animated-property.cpp
${scene3d_public_api_dir}/loader/animation-definition.cpp
#include <dali-scene3d/public-api/loader/ktx-loader.h>
// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
#include <filesystem>
namespace Dali
{
namespace Loader
{
-bool LoadCubeMapData(const std::string& path, CubeData& cubedata)
+bool LoadCubeMapData(const std::string& cubeMapUrl, CubeData& cubedata)
{
- std::filesystem::path modelPath(path);
+ std::filesystem::path modelPath(cubeMapUrl);
std::string extension = modelPath.extension();
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
- return (extension == KTX_EXTENSION) ? Dali::Scene3D::Loader::LoadKtxData(path, cubedata) : Dali::Scene3D::Loader::LoadCubeData(path, cubedata);
+ return (extension == KTX_EXTENSION) ? Dali::Scene3D::Loader::LoadKtxData(cubeMapUrl, cubedata) : Dali::Scene3D::Loader::LoadCubeData(cubeMapUrl, cubedata);
+}
+
+Texture LoadCubeMap(const std::string& cubeMapUrl)
+{
+ Texture cubeTexture;
+ Dali::Scene3D::Loader::CubeData cubeData;
+ if(Dali::Scene3D::Loader::LoadCubeMapData(cubeMapUrl, cubeData))
+ {
+ cubeTexture = cubeData.CreateTexture();
+ }
+ else
+ {
+ DALI_LOG_ERROR("Fail to load cube map, %s\n", cubeMapUrl.c_str());
+ }
+
+ return cubeTexture;
}
} // namespace Loader
namespace Loader
{
/**
- * @brief Loads cube map data texture from a cube map file.
+ * @brief Loads cube map data from a cube map file.
*
- * @param[in] path The file path.
+ * @param[in] cubeMapUrl The cube map file url.
* @param[out] cubedata The data structure with all pixel data objects.
* @return bool True if the loading is succeded.
*/
-bool LoadCubeMapData(const std::string& path, CubeData& cubedata);
+bool LoadCubeMapData(const std::string& cubeMapUrl, CubeData& cubedata);
+
+/**
+ * @brief Loads cube map data from a cube map file and return texture.
+ *
+ * @param[in] cubeMapUrl The cube map file path.
+ * @return Texture the loaded cube map texture.
+ */
+Texture LoadCubeMap(const std::string& cubeMapUrl);
} // namespace Loader
} // namespace Scene3D