[dali_2.1.38] Merge branch 'devel/master' 37/280737/1
authorRichard Huang <r.huang@samsung.com>
Fri, 2 Sep 2022 12:01:13 +0000 (13:01 +0100)
committerRichard Huang <r.huang@samsung.com>
Fri, 2 Sep 2022 12:01:13 +0000 (13:01 +0100)
Change-Id: I4542b47e78135319a0ac1999349eb62cf38943d6

17 files changed:
automated-tests/src/dali-scene3d/CMakeLists.txt
automated-tests/src/dali-scene3d/utc-Dali-ModelView.cpp
automated-tests/src/dali-scene3d/utc-Dali-SceneView.cpp [new file with mode: 0644]
dali-scene3d/internal/controls/model-view/model-view-impl.cpp
dali-scene3d/internal/controls/model-view/model-view-impl.h
dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp [new file with mode: 0644]
dali-scene3d/internal/controls/scene-view/scene-view-impl.h [new file with mode: 0644]
dali-scene3d/internal/file.list
dali-scene3d/public-api/controls/model-view/model-view.cpp
dali-scene3d/public-api/controls/model-view/model-view.h
dali-scene3d/public-api/controls/scene-view/scene-view.cpp [new file with mode: 0644]
dali-scene3d/public-api/controls/scene-view/scene-view.h [new file with mode: 0644]
dali-scene3d/public-api/file.list
dali-scene3d/public-api/loader/cube-map-loader.cpp
dali-scene3d/public-api/loader/cube-map-loader.h
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index d86c377..6bc5e40 100755 (executable)
@@ -20,6 +20,7 @@ SET(TC_SOURCES
   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
index 5424874..1b9833d 100644 (file)
@@ -422,14 +422,14 @@ int UtcDaliModelViewFitSize01(void)
   DALI_TEST_EQUALS(Vector3(2, 2, 2), rootSize, TEST_LOCATION);
 
   Vector3 rootScale = rootActor.GetProperty<Vector3>(Dali::Actor::Property::SCALE);
-  DALI_TEST_EQUALS(Vector3(1, 1, 1), rootScale, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector3(25, -25, 25), rootScale, TEST_LOCATION);
 
-  view.FitSize(true);
+  view.FitSize(false);
   rootSize = rootActor.GetProperty<Vector3>(Dali::Actor::Property::SIZE);
   DALI_TEST_EQUALS(Vector3(2, 2, 2), rootSize, TEST_LOCATION);
 
   rootScale = rootActor.GetProperty<Vector3>(Dali::Actor::Property::SCALE);
-  DALI_TEST_EQUALS(Vector3(25, 25, 25), rootScale, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector3(1, -1, 1), rootScale, TEST_LOCATION);
 
   END_TEST;
 }
@@ -451,14 +451,14 @@ int UtcDaliModelViewFitSize02(void)
   DALI_TEST_EQUALS(Vector3(5, 5, 5), rootSize, TEST_LOCATION);
 
   Vector3 rootScale = rootActor.GetProperty<Vector3>(Dali::Actor::Property::SCALE);
-  DALI_TEST_EQUALS(Vector3(1, 1, 1), rootScale, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector3(10, -10, 10), rootScale, TEST_LOCATION);
 
-  view.FitSize(true);
+  view.FitSize(false);
   rootSize = rootActor.GetProperty<Vector3>(Dali::Actor::Property::SIZE);
   DALI_TEST_EQUALS(Vector3(5, 5, 5), rootSize, TEST_LOCATION);
 
   rootScale = rootActor.GetProperty<Vector3>(Dali::Actor::Property::SCALE);
-  DALI_TEST_EQUALS(Vector3(10, 10, 10), rootScale, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector3(1, -1, 1), rootScale, TEST_LOCATION);
 
   END_TEST;
 }
@@ -480,14 +480,14 @@ int UtcDaliModelViewFitSize03(void)
   DALI_TEST_EQUALS(Vector3(2, 2, 2), rootSize, TEST_LOCATION);
 
   Vector3 rootScale = rootActor.GetProperty<Vector3>(Dali::Actor::Property::SCALE);
-  DALI_TEST_EQUALS(Vector3(1, 1, 1), rootScale, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector3(1, -1, 1), rootScale, TEST_LOCATION);
 
   view.FitSize(true);
   rootSize = rootActor.GetProperty<Vector3>(Dali::Actor::Property::SIZE);
   DALI_TEST_EQUALS(Vector3(2, 2, 2), rootSize, TEST_LOCATION);
 
   rootScale = rootActor.GetProperty<Vector3>(Dali::Actor::Property::SCALE);
-  DALI_TEST_EQUALS(Vector3(1, 1, 1), rootScale, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector3(1, -1, 1), rootScale, TEST_LOCATION);
 
   END_TEST;
 }
@@ -509,11 +509,11 @@ int UtcDaliModelViewFitCenter(void)
 
   Actor   rootActor   = view.GetModelRoot();
   Vector3 anchorPoint = rootActor.GetProperty<Vector3>(Dali::Actor::Property::ANCHOR_POINT);
-  DALI_TEST_EQUALS(Vector3(0.5, 0.5, 0.5), anchorPoint, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector3(1.0, 1.0, 0.5), anchorPoint, TEST_LOCATION);
 
-  view.FitCenter(true);
+  view.FitCenter(false);
   anchorPoint = rootActor.GetProperty<Vector3>(Dali::Actor::Property::ANCHOR_POINT);
-  DALI_TEST_EQUALS(Vector3(1.0, 1.0, 0.5), anchorPoint, TEST_LOCATION);
+  DALI_TEST_EQUALS(Vector3(0.5, 0.5, 0.5), anchorPoint, TEST_LOCATION);
 
   END_TEST;
 }
diff --git a/automated-tests/src/dali-scene3d/utc-Dali-SceneView.cpp b/automated-tests/src/dali-scene3d/utc-Dali-SceneView.cpp
new file mode 100644 (file)
index 0000000..7cabdcd
--- /dev/null
@@ -0,0 +1,505 @@
+/*
+ * 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;
+}
index 568b899..61a5303 100644 (file)
@@ -30,9 +30,9 @@
 
 // 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>
@@ -113,22 +113,6 @@ struct BoundingVolume
   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)
 {
@@ -192,13 +176,12 @@ ModelView::ModelView(const std::string& modelPath, const std::string& resourcePa
 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
   mModelPath(modelPath),
   mResourcePath(resourcePath),
-  mModelLayer(),
   mModelRoot(),
   mNaturalSize(Vector3::ZERO),
   mModelPivot(AnchorPoint::CENTER),
   mIblScaleFactor(1.0f),
-  mFitSize(false),
-  mFitCenter(false)
+  mFitSize(true),
+  mFitCenter(true)
 {
 }
 
@@ -238,18 +221,20 @@ void ModelView::FitCenter(bool fit)
 
 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();
   }
 }
 
@@ -297,24 +282,31 @@ void ModelView::OnSceneConnection(int depth)
     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::OnInitialize()
+void ModelView::OnSceneDisconnection()
 {
-  Actor self  = Self();
-  mModelLayer = Layer::New();
-  mModelLayer.SetProperty(Layer::Property::BEHAVIOR, Layer::LAYER_3D);
-  mModelLayer.SetProperty(Layer::Property::DEPTH_TEST, true);
-  mModelLayer.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
-  mModelLayer.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
-  mModelLayer.SetResizePolicy(ResizePolicy::FILL_TO_PARENT,
-                              Dimension::ALL_DIMENSIONS);
-
-  // Models in glTF and dli are defined as right hand coordinate system.
-  // DALi uses left hand coordinate system. Scaling negative is for change winding order.
-  mModelLayer.SetProperty(Dali::Actor::Property::SCALE_Y, -1.0f);
-  self.Add(mModelLayer);
+  Scene3D::SceneView sceneView = mParentSceneView.GetHandle();
+  if(sceneView)
+  {
+    GetImpl(sceneView).UnregisterModelView(Scene3D::ModelView::DownCast(Self()));
+    mParentSceneView.Reset();
+  }
+  Control::OnSceneDisconnection();
 }
 
 Vector3 ModelView::GetNaturalSize()
@@ -452,40 +444,47 @@ void ModelView::LoadModel()
     }
   }
 
-  SetImageBasedLight(mModelRoot);
+  mRenderableActors.clear();
+  CollectRenderableActor(mModelRoot);
+  UpdateImageBasedLight();
 
   mNaturalSize = AABB.CalculateSize();
   mModelPivot  = AABB.CalculatePivot();
   mModelRoot.SetProperty(Dali::Actor::Property::SIZE, mNaturalSize);
+  Vector3 controlSize = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
+  if(controlSize.x == 0.0f || controlSize.y == 0.0f)
+  {
+    Self().SetProperty(Dali::Actor::Property::SIZE, mNaturalSize);
+  }
 
   FitModelPosition();
   ScaleModel();
 
-  mModelLayer.Add(mModelRoot);
+  Self().Add(mModelRoot);
+
+  Self().SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+  Self().SetProperty(Dali::Actor::Property::ANCHOR_POINT, Vector3(mModelPivot.x, 1.0f - mModelPivot.y, mModelPivot.z));
 }
 
 void ModelView::ScaleModel()
 {
   if(mModelRoot)
   {
-    if(mFitSize)
+    Vector3 size = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
+    if(mFitSize && size.x > 0.0f && size.y > 0.0f)
     {
-      Vector3 size = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
-      if(size.x > 0.0f && size.y > 0.0f)
-      {
-        float scaleFactor = MAXFLOAT;
-        scaleFactor       = std::min(size.x / mNaturalSize.x, scaleFactor);
-        scaleFactor       = std::min(size.y / mNaturalSize.y, scaleFactor);
-        mModelRoot.SetProperty(Dali::Actor::Property::SCALE, scaleFactor);
-      }
-      else
-      {
-        DALI_LOG_ERROR("ModelView size is wrong.");
-      }
+      float scaleFactor = MAXFLOAT;
+      scaleFactor       = std::min(size.x / mNaturalSize.x, scaleFactor);
+      scaleFactor       = std::min(size.y / mNaturalSize.y, scaleFactor);
+      // Models in glTF and dli are defined as right hand coordinate system.
+      // DALi uses left hand coordinate system. Scaling negative is for change winding order.
+      mModelRoot.SetProperty(Dali::Actor::Property::SCALE, Y_DIRECTION * scaleFactor);
     }
     else
     {
-      mModelRoot.SetProperty(Dali::Actor::Property::SCALE, 1.0f);
+      // Models in glTF and dli are defined as right hand coordinate system.
+      // DALi uses left hand coordinate system. Scaling negative is for change winding order.
+      mModelRoot.SetProperty(Dali::Actor::Property::SCALE, Y_DIRECTION);
     }
   }
 }
@@ -508,43 +507,56 @@ void ModelView::FitModelPosition()
   }
 }
 
-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)
+  {
+    return;
+  }
+
+  for(auto&& actor : mRenderableActors)
   {
-    Dali::Renderer renderer = node.GetRendererAt(i);
-    if(renderer)
+    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
index 14b31f9..10d04f2 100644 (file)
 #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
 {
@@ -71,6 +73,11 @@ public:
   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()
    */
   uint32_t GetAnimationCount();
@@ -103,9 +110,9 @@ private:
   void OnSceneConnection(int depth) override;
 
   /**
-   * @copydoc Toolkit::Control::OnInitialize()
+   * @copydoc CustomActorImpl::OnSceneDisconnection()
    */
-  void OnInitialize() override;
+  void OnSceneDisconnection() override;
 
   /**
    * @copydoc Toolkit::Control::GetNaturalSize
@@ -145,14 +152,20 @@ private:
   /**
    * @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::Actor                    mModelRoot;
+  std::vector<AnimationData>     mAnimations;
+  std::vector<WeakHandle<Actor>> mRenderableActors;
+  WeakHandle<Scene3D::SceneView> mParentSceneView;
 
   Dali::Texture mSpecularTexture;
   Dali::Texture mDiffuseTexture;
diff --git a/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp b/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp
new file mode 100644 (file)
index 0000000..c43334e
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * 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
diff --git a/dali-scene3d/internal/controls/scene-view/scene-view-impl.h b/dali-scene3d/internal/controls/scene-view/scene-view-impl.h
new file mode 100644 (file)
index 0000000..724bc7d
--- /dev/null
@@ -0,0 +1,236 @@
+#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
index b236f3c..f1bcfd8 100644 (file)
@@ -6,4 +6,5 @@ set(scene3d_src_files ${scene3d_src_files}
        ${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
 )
index b21726e..a799377 100644 (file)
@@ -82,6 +82,11 @@ void ModelView::SetImageBasedLightSource(const std::string& diffuse, const std::
   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();
index 4c27f1a..ce5e249 100644 (file)
@@ -23,6 +23,7 @@
 
 // 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
@@ -164,6 +165,17 @@ public:
   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.
    * @note This method should be called after Model load finished.
diff --git a/dali-scene3d/public-api/controls/scene-view/scene-view.cpp b/dali-scene3d/public-api/controls/scene-view/scene-view.cpp
new file mode 100644 (file)
index 0000000..cb07590
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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
diff --git a/dali-scene3d/public-api/controls/scene-view/scene-view.h b/dali-scene3d/public-api/controls/scene-view/scene-view.h
new file mode 100644 (file)
index 0000000..15a28d4
--- /dev/null
@@ -0,0 +1,295 @@
+#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
index 23d4702..c80e43f 100644 (file)
@@ -2,6 +2,7 @@ set(scene3d_public_api_dir "${scene3d_dir}/public-api")
 
 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
index c4aae09..f3a5aa0 100644 (file)
@@ -23,6 +23,7 @@
 #include <dali-scene3d/public-api/loader/ktx-loader.h>
 
 // EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
 #include <filesystem>
 
 namespace Dali
@@ -36,13 +37,29 @@ namespace Scene3D
 {
 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
index ec7fd24..0ead0a5 100644 (file)
@@ -28,13 +28,21 @@ namespace Scene3D
 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
index a3bdd3c..7639b88 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 37;
+const unsigned int TOOLKIT_MICRO_VERSION = 38;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 93d710d..954e171 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.1.37
+Version:    2.1.38
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT