1 #ifndef DALI_SCENE3D_SCENE_VIEW_H
2 #define DALI_SCENE3D_SCENE_VIEW_H
5 * Copyright (c) 2024 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 #include <dali-toolkit/public-api/controls/control.h>
23 #include <dali-toolkit/public-api/image-loader/image-url.h>
24 #include <dali/public-api/actors/camera-actor.h>
25 #include <dali/public-api/animation/animation.h>
26 #include <dali/public-api/common/dali-common.h>
29 #include <dali-scene3d/public-api/api.h>
30 #include <dali-scene3d/public-api/common/environment-map.h>
36 namespace Internal DALI_INTERNAL
42 * @addtogroup dali_toolkit_controls_scene_view
47 * @brief SceneView is a Dali::Toolkit::Control to show multiple 3D objects in a single 3D scene.
48 * Each SceneView has its own 3D space, and 3D objects added to SceneView are positioned in the space.
49 * SceneView has a 3D root layer internally to trigger the depth test in the rendering process.
50 * When an Actor is added to the SceneView with Add() method,
51 * the Actor and its children are actually become child of the 3D layer automatically.
55 * Dali::Layer(Layer::LAYER_3D)
59 * The children of the 3D root layer will be rendered with the SceneView's own CameraActor.
61 * SceneView can have multiple CameraActor and one of them is used to render the multiple objects as a Scene.
62 * AddCamera(), RemoveCamera(), GetCamera(), and SelectCamera() are methods to manage CameraActors of the SceneView.
63 * Users can place multiple cameras in a scene, either to show the entire scene or to show individual objects.
64 * And the user can select the currently needed camera by using the SelectCamera() method.
66 * SceneView makes one built-in CameraActor by default.
67 * The default CameraActor has index 0 and is not removed by using RemoveCamera() method.
68 * Therefore, the minimum value returned by GetCameraCount() method is 1.
70 * If the size of SceneView is changed, Some properties of CameraActor that depend on the size can be changed too.
71 * The changing properties are as follows: projectionMode, aspectRatio, leftPlaneDistance, rightPlaneDistance, topPlaneDistance, and bottomPlaneDistance.
72 * Position, near/farPlaneDistance, and FieldOfView are maintained even if the size of the SceneView is changed.
73 * The FieldOfView of Dali::CameraActor is for vertical fov. The horizontal fov is internally updated according to the SceneView size.
75 * The same light source is set for all Models added to SceneView, if SceneView has light source.
76 * The SetImageBasedLightSource() method sets the same IBL to all Models added to the SceneView.
77 * If any Model already has an IBL, it is replaced with the SceneView's IBL.
79 * SceneView provides an option to use FBO for rendering result with UseFramebuffer() method.
80 * If it is false, SceneView is always drawn in the form of a rectangle on the default window surface directly.
81 * It improves performance, but the SceneView is always drawn on top of other 2D objects regardless of Actor tree order.
82 * And it will show wrong result in case the window's default CameraActor is transformed.
83 * So, it is recommended not to change window's CameraActor.
85 * If FBO is used, the rendering result of SceneView is drawn on the FBO and it is mapped on the plane of the SceneView.
86 * It decreases performance, but it is useful to show SceneView according to the rendering order with other Actors.
87 * And it can be used in case window's CameraActor is transformed.
89 * And since SceneView is a Control, it can be placed together with other 2D UI components in the DALi window.
91 * @note We support to render model well only if glsl version is higher than 300.
92 * @note We do not support Toolkit::RenderEffect when UseFrameBuffer(false).
97 * Dali::Scene3D::SceneView sceneView = Dali::Scene3D::SceneView::New();
98 * sceneView.SetProperty(Dali::Actor::Property::SIZE, Vector2(400, 400));
99 * mWindow.Add(sceneView);
101 * Dali::Scene3D::Model model = Dali::Scene3D::Model::New(...);
102 * sceneView.Add(model);
104 * CameraActor cameraActor = CameraActor::New();
105 * sceneView.AddCamera(cameraActor);
109 class DALI_SCENE3D_API SceneView : public Dali::Toolkit::Control
113 * @brief The start and end property ranges for this control.
118 PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
119 PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000
127 * @brief URL of a masking image
128 * @details Name "alphaMaskUrl", type Property::STRING, URL of image to apply as
129 * a mask after SceneView is drawn.
130 * @note Alpha masking is only available when framebuffer is used.
133 ALPHA_MASK_URL = PROPERTY_START_INDEX,
136 * @brief The scale factor to apply to the content image before masking
137 * @details Name "maskContentScale", type Property::FLOAT, The scale factor
138 * to apply to the content before masking. Note, scaled result is cropped to
139 * the same size as the alpha mask.
145 * @brief Whether to crop rendered result to mask or scale mask to fit result
146 * @details Name "cropToMask", type Property::BOOLEAN, True if the rendered result should
147 * be cropped to match the mask size, or false if the result should remain the same size.
148 * @note Optional, Default true
149 * @note If this is false, then the mask is scaled to fit the rendered result before being applied.
158 * @brief Typedef for capture finished signals sent by this class.
162 typedef Signal<void(SceneView, int32_t, const Dali::Toolkit::ImageUrl&)> CaptureFinishedSignalType;
165 * @brief Typedef for camera transition finished signals sent by this class.
169 typedef Signal<void(SceneView)> CameraTransitionFinishedSignalType;
172 * @brief Create an initialized SceneView.
175 * @return A handle to a newly allocated Dali resource
177 static SceneView New();
180 * @brief Creates an uninitialized SceneView.
182 * Only derived versions can be instantiated. Calling member
183 * functions with an uninitialized Dali::Object is not allowed.
192 * This is non-virtual since derived Handle types must not contain data or virtual methods.
199 * @brief Copy constructor.
202 * @param[in] sceneView Handle to an object
204 SceneView(const SceneView& sceneView);
207 * @brief Move constructor
210 * @param[in] rhs A reference to the moved handle
212 SceneView(SceneView&& rhs) noexcept;
215 * @brief Assignment operator.
218 * @param[in] sceneView Handle to an object
219 * @return reference to this
221 SceneView& operator=(const SceneView& sceneView);
224 * @brief Move assignment
227 * @param[in] rhs A reference to the moved handle
228 * @return A reference to this
230 SceneView& operator=(SceneView&& rhs) noexcept;
233 * @brief Downcasts an Object handle to SceneView.
235 * If handle points to a SceneView, the downcast produces valid handle.
236 * If not, the returned handle is left uninitialized.
239 * @param[in] handle Handle to an object
240 * @return Handle to a SceneView or an uninitialized handle
242 static SceneView DownCast(BaseHandle handle);
245 * @brief Adds a CameraActor to the SceneView
246 * The CameraActor can be used as a selected camera to render the scene by using SelectCamera(uint32_t) or SelectCamera(std::string)
250 * AspectRatio property of CameraActor will be changed depending on the Size of this SceneView.
252 * For Perspective camera
253 * The FieldOfView of Dali::CameraActor is for vertical fov.
254 * When the size of the SceneView is changed, the vertical fov is maintained
255 * and the horizontal fov is automatically calculated according to the SceneView's aspect ratio.
257 * For Orthographic camera
258 * leftPlaneDistance, rightPlaneDistance, and bottomPlaneDistance properties are defined according to the topPlaneDistance and aspectRatio.
260 * @param[in] camera CameraActor added on this scene view.
262 void AddCamera(Dali::CameraActor camera);
265 * @brief Removes a CameraActor from this SceneView.
268 * @note If removed CameraActor is selected CameraActor,
269 * first camera in the list is set to selected CameraActor.
271 * @param[in] camera CameraActor to be removed from this SceneView
273 void RemoveCamera(CameraActor camera);
276 * @brief Retrieves the number of cameras.
279 * @return Number of cameras those currently the SceneView contains.
281 uint32_t GetCameraCount() const;
284 * @brief Retrieves selected CameraActor.
287 * @return CameraActor currently used in SceneView as a selected CameraActor
289 CameraActor GetSelectedCamera() const;
292 * @brief Retrieves a CameraActor of the index.
295 * @param[in] index Index of CameraActor to be retrieved.
297 * @return CameraActor of the index
299 CameraActor GetCamera(uint32_t index) const;
302 * @brief Retrieves a CameraActor of the name.
305 * @param[in] name string keyword of CameraActor to be retrieved.
307 * @return CameraActor that has the name as a Dali::Actor::Property::NAME
309 CameraActor GetCamera(const std::string& name) const;
312 * @brief Makes SceneView use a CameraActor of index as a selected camera.
315 * @param[in] index Index of CameraActor to be used as a selected camera.
316 * @note If the Camera is not added in this Scene, this method adds it on SceneView root.
318 void SelectCamera(uint32_t index);
321 * @brief Makes SceneView use a CameraActor of a name as a selected camera.
324 * @param[in] name string keyword of CameraActor to be used as a selected camera.
325 * @note If the Camera is not added in this Scene, this method adds it on SceneView root.
327 void SelectCamera(const std::string& name);
330 * @brief Starts camera transition from currently selected camera to a camera of index.
331 * Camera Position, Orientation and FieldOfView(Orthogrpahic Size) are smoothly animated.
334 * @param[in] index Index of destination Camera of Camera transition.
335 * @param[in] durationSeconds The duration in seconds.
336 * @param[in] alphaFunction The alpha function to apply.
337 * @note The selected camera is switched to the Camera of the index when the transition is finished.
338 * During camera transition, Selected Camera should not be changed by using SelectCamera() or StartCameraTransition() method.
339 * During camera transition, Camera properties of Selected Camera should not be changed.
341 void StartCameraTransition(uint32_t index, float durationSeconds, Dali::AlphaFunction alphaFunction = AlphaFunction::DEFAULT);
344 * @brief Starts camera transition from currently selected camera to a camera of index.
345 * Camera Position, Orientation and FieldOfView(Orthogrpahic Size) are smoothly animated.
348 * @param[in] name string keyword of destination Camera of Camera transition.
349 * @param[in] durationSeconds The duration in seconds.
350 * @param[in] alphaFunction The alpha function to apply.
351 * @note The selected camera is switched to the Camera of the input name when the transition is finished.
352 * During camera transition, Selected Camera should not be changed by using SelectCamera() or StartCameraTransition() method.
353 * During camera transition, Camera properties of Selected Camera should not be changed.
355 void StartCameraTransition(std::string name, float durationSeconds, Dali::AlphaFunction alphaFunction = AlphaFunction::DEFAULT);
358 * @brief Sets Image Based Light Source to apply it on the all Models those added on this SceneView.
361 * @note If any Models already have IBL, they are batch-overridden with the SceneView's IBL.
362 * If SceneView has IBL, IBL of newly added Model is also overridden.
363 * To set indivisual IBL for each Model, the Model's IBL should be set after the SceneView's IBL.
365 * @param[in] diffuseUrl cube map that can be used as a diffuse IBL source.
366 * @param[in] specularUrl cube map that can be used as a specular IBL source.
367 * @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.
369 void SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor = 1.0f);
372 * @brief Sets Scale Factor of Image Based Light Source.
375 * @note If SetImageBasedLightSource() method is called after this method, scaleFactor is overriden.
376 * @note Default value is 1.0f.
378 * @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f].
380 void SetImageBasedLightScaleFactor(float scaleFactor);
383 * @brief Gets Scale Factor of Image Based Light Source.
384 * Default value is 1.0f.
387 * @return scale factor that controls light source intensity.
389 float GetImageBasedLightScaleFactor() const;
392 * @brief Gets Enabled Light Count of this SceneView
395 * @return The number of enabled light count;
397 uint32_t GetActivatedLightCount() const;
400 * @brief Sets whether to use FBO or not for the SceneView.
401 * If useFramebuffer is true, rendering result of SceneView is drawn on FBO and it is mapping on this SceneView plane.
402 * If useFramebuffer is false, each item in SceneView is rendered on window directly.
403 * Note that Toolkit::RenderEffect is not supported in this case.
407 * @note If useFramebuffer is true, it could decrease performance but entire rendering order is satisfied.
408 * If useFramebuffer is false, performance is become better but SceneView is rendered on top of the other 2D Actors regardless tree order.
410 * @param[in] useFramebuffer True to use FBO for SceneView.
412 void UseFramebuffer(bool useFramebuffer);
415 * @brief Gets whether this SceneView uses Framebuffer or not.
418 * @return bool True if this SceneView uses Framebuffer.
420 bool IsUsingFramebuffer() const;
423 * @brief Sets SceneView's resolution manually.
424 * @note This manual resolution is only available when the SceneView uses FBO for rendering by using UseFrameBuffer(true).
425 * @note If the aspect ratio of input width/height is different with SceneView's aspect ratio, the rendered result is stretched to fill SceneView's area.
428 * @param[in] width The input width.
429 * @param[in] height The input height.
431 void SetResolution(uint32_t width, uint32_t height);
434 * @brief Retrieves width of resolution of the SceneView.
435 * @note If the SceneView not uses FBO, this method returns SceneView's width.
438 * @return Width value of resolution of the SceneView.
440 uint32_t GetResolutionWidth();
443 * @brief Retrieves height of resolution of the SceneView.
444 * @note If the SceneView not uses FBO, this method returns SceneView's height.
447 * @return Height value of resolution of the SceneView.
449 uint32_t GetResolutionHeight();
452 * @brief Resets SceneView's resolution to the current size of SceneView.
456 void ResetResolution();
459 * @brief Sets Multisampling level when we use Framebuffer.
463 * @note Only applied if SceneView is using Framebuffer and Framebuffer Multisampling extension is supported.
465 * @param[in] multiSamplingLevel Level of multisampling if we use Framebuffer.
467 void SetFramebufferMultiSamplingLevel(uint8_t multiSamplingLevel);
470 * @brief Gets Multisampling level that user set.
474 * @note This API doesn't check whether Multisampling extension is supported or not.
476 * @return MultisamplingLevel that user set.
478 uint8_t GetFramebufferMultiSamplingLevel() const;
481 * @brief Sets Skybox for this scene.
482 * Skybox texture starts to be loaded when SceneView is onScene.
483 * And Skybox texture is asynchronously loaded. When loading is finished, ResourceReady is emitted.
486 * @param[in] skyboxUrl image url for skybox.
487 * @note Default SkyboxEnvironmentMapType is Cube Map. Use SetSkyboxEnvironmentMapType method to set type explicitly.
489 void SetSkybox(const std::string& skyboxUrl);
492 * @brief Sets Skybox environment map type for this skybox.
493 * If skybox texture already starts to be loaded, when the type is changed, the load request is canceled and re-starts to load with new type.
496 * @param[in] skyboxEnvironmentMapType The environment type of skybox (by default it is cubemap).
498 void SetSkyboxEnvironmentMapType(Scene3D::EnvironmentMapType skyboxEnvironmentMapType);
501 * @brief Sets Skybox intensity.
502 * The skybox intensity is multiplied to the color of skybox texture.
503 * Default value is 1.0f.
506 * @note Intensity should be positive value.
507 * @param[in] intensity Intensity value to be multiplied to the cube map color
509 void SetSkyboxIntensity(float intensity);
512 * @brief Gets Skybox intensity.
513 * Default value is 1.0f.
516 * @return skybox intensity
518 float GetSkyboxIntensity() const;
521 * @brief Sets Orientation of Skybox.
524 * @param[in] orientation Quaternion for orientation of Skybox.
526 void SetSkyboxOrientation(const Quaternion& orientation);
529 * @brief Gets Skybox orientation.
532 * @return skybox orientation
534 Quaternion GetSkyboxOrientation() const;
537 * @brief Requests to capture this SceneView with the Camera.
540 * @param[in] camera CameraActor to be used for capture.
541 * @param[in] size captured size.
542 * @note The input camera should not be used for any other purpose during Capture.
543 * (Simultaneous usage elsewhere may result in incorrect rendering.)
544 * @note The camera is required to be added in this SceneView. (But should not be a selected camera.)
545 * @note If the SceneView is disconnected from Scene, the left capture requests are canceled.
546 * @return capture id that id unique value to distinguish each requiest.
548 int32_t Capture(Dali::CameraActor camera, const Vector2& size);
551 * @brief Get capture finished signal.
554 * @return finished signal instance.
556 CaptureFinishedSignalType& CaptureFinishedSignal();
559 * @brief Get camera transition finished signal.
562 * @return camera transition finished signal instance.
564 CameraTransitionFinishedSignalType& CameraTransitionFinishedSignal();
566 public: // Not intended for application developers
569 * @brief Creates a handle using the Toolkit::Internal implementation.
571 * @param[in] implementation The Control implementation
573 DALI_INTERNAL SceneView(Internal::SceneView& implementation);
576 * @brief Allows the creation of this Control from an Internal::CustomActor pointer.
578 * @param[in] internal A pointer to the internal CustomActor
580 DALI_INTERNAL SceneView(Dali::Internal::CustomActor* internal);
587 } // namespace Scene3D
591 #endif // DALI_SCENE3D_SCENE_VIEW_H