Most of model has a lot of children as Actor format.
If we don't setup something on the model view,
hit-test always try to access this child tree.
For optimization, we need to make some flag to ignore this traversal.
Change-Id: I189dfe9138c883ee43d84804dda6fa1663556dd5
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
#include <stdlib.h>
#include <iostream>
+#include <dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h>
+#include <dali/integration-api/events/touch-event-integ.h>
+
#include <dali-scene3d/public-api/controls/model/model.h>
using namespace Dali;
namespace
{
+const bool DEFAULT_MODEL_CHILDREN_SENSITIVE = false;
/**
* For the AnimatedCube.gltf and its Assets
* Donated by Norbert Nopper for glTF testing.
*/
const char* TEST_DIFFUSE_TEXTURE = TEST_RESOURCE_DIR "/forest_irradiance.ktx";
const char* TEST_SPECULAR_TEXTURE = TEST_RESOURCE_DIR "/forest_radiance.ktx";
+
+bool gTouchCallBackCalled = false;
+bool TestTouchCallback(Actor, const TouchEvent&)
+{
+ gTouchCallBackCalled = true;
+ return true;
+}
+
} // namespace
// Negative test case for a method
tet_infoline(" UtcDaliModelDownCast");
Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
- BaseHandle handle(model);
+ BaseHandle handle(model);
Scene3D::Model model2 = Scene3D::Model::DownCast(handle);
DALI_TEST_CHECK(model);
END_TEST;
}
+int UtcDaliModelChildrenSensitive01(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::Model view = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
+ view.SetProperty(Dali::Actor::Property::SIZE, Vector3(100, 100, 100));
+ view.SetProperty(Dali::Actor::Property::POSITION, Vector3(0, 0, 0));
+ view.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ view.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+
+ // Get default vaule.
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), DEFAULT_MODEL_CHILDREN_SENSITIVE, TEST_LOCATION);
+
+ // Allow children actor's event before on scene.
+ view.SetChildrenSensitive(true);
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), true, TEST_LOCATION);
+
+ application.GetScene().Add(view);
+
+ application.SendNotification();
+ application.Render();
+
+ Actor meshActor = view.FindChildByName("AnimatedCube");
+ DALI_TEST_CHECK(meshActor);
+
+ // connect hit-test signal
+ gTouchCallBackCalled = false;
+ meshActor.TouchedSignal().Connect(TestTouchCallback);
+
+ Vector2 sceneSize = application.GetScene().GetSize();
+
+ // Try to touch center of scene.
+ Dali::Integration::Point point;
+ point.SetState(PointState::DOWN);
+ point.SetScreenPosition(sceneSize * 0.5f);
+ Dali::Integration::TouchEvent event;
+ event.AddPoint(point);
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ // Not touched yet.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+ application.ProcessEvent(event);
+ // Touched.
+ DALI_TEST_CHECK(gTouchCallBackCalled);
+
+ // Clear
+ gTouchCallBackCalled = false;
+
+ // Block children actor's event
+ view.SetChildrenSensitive(false);
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), false, TEST_LOCATION);
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ // Not touched yet.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+ application.ProcessEvent(event);
+ // Also not touched.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+
+ // Clear
+ gTouchCallBackCalled = false;
+
+ // Allow again
+ view.SetChildrenSensitive(true);
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), true, TEST_LOCATION);
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ // Not touched yet.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+ application.ProcessEvent(event);
+ // Touched.
+ DALI_TEST_CHECK(gTouchCallBackCalled);
+
+ // Clear
+ gTouchCallBackCalled = false;
+
+ END_TEST;
+}
+
+int UtcDaliModelChildrenSensitive02(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::Model view = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
+ view.SetProperty(Dali::Actor::Property::SIZE, Vector3(100, 100, 100));
+ view.SetProperty(Dali::Actor::Property::POSITION, Vector3(0, 0, 0));
+ view.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ view.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+
+ // Get vaule.
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), DEFAULT_MODEL_CHILDREN_SENSITIVE, TEST_LOCATION);
+
+ // Block children actor's event before on scene.
+ view.SetChildrenSensitive(false);
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), false, TEST_LOCATION);
+
+ application.GetScene().Add(view);
+
+ application.SendNotification();
+ application.Render();
+
+ Actor meshActor = view.FindChildByName("AnimatedCube");
+ DALI_TEST_CHECK(meshActor);
+
+ // connect hit-test signal
+ gTouchCallBackCalled = false;
+ meshActor.TouchedSignal().Connect(TestTouchCallback);
+
+ Vector2 sceneSize = application.GetScene().GetSize();
+
+ // Try to touch center of scene.
+ Dali::Integration::Point point;
+ point.SetState(PointState::DOWN);
+ point.SetScreenPosition(sceneSize * 0.5f);
+ Dali::Integration::TouchEvent event;
+ event.AddPoint(point);
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ // Not touched yet.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+ application.ProcessEvent(event);
+ // Also not touched.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+
+ // Clear
+ gTouchCallBackCalled = false;
+
+ // Allow again
+ view.SetChildrenSensitive(true);
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), true, TEST_LOCATION);
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ // Not touched yet.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+ application.ProcessEvent(event);
+ // Touched.
+ DALI_TEST_CHECK(gTouchCallBackCalled);
+
+ // Clear
+ gTouchCallBackCalled = false;
+
+ END_TEST;
+}
+
int UtcDaliModelAnimation01(void)
{
ToolkitTestApplication application;
namespace
{
static bool gOnRelayoutCallBackCalled = false;
-void OnRelayoutCallback(Actor actor)
+void OnRelayoutCallback(Actor actor)
{
gOnRelayoutCallBackCalled = true;
}
static bool gResourceReadyCalled = false;
-void OnResourceReady(Control control)
+void OnResourceReady(Control control)
{
gResourceReadyCalled = true;
}
-}
+} // namespace
int UtcDaliModelResourceReady(void)
{
ToolkitTestApplication application;
gOnRelayoutCallBackCalled = false;
- gResourceReadyCalled = false;
- Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_ANIMATION_TEST_FILE_NAME);
+ gResourceReadyCalled = false;
+ Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_ANIMATION_TEST_FILE_NAME);
model.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
model.OnRelayoutSignal().Connect(OnRelayoutCallback);
model.ResourceReadySignal().Connect(OnResourceReady);
#include <dali-toolkit/dali-toolkit.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
+#include <dali/devel-api/actors/actor-devel.h>
#include <dali/integration-api/debug.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <dali/public-api/object/type-registry.h>
#include <filesystem>
// INTERNAL INCLUDES
-#include <dali-scene3d/public-api/controls/model/model.h>
#include <dali-scene3d/internal/controls/scene-view/scene-view-impl.h>
+#include <dali-scene3d/public-api/controls/model/model.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-map-loader.h>
static constexpr Vector3 Y_DIRECTION(1.0f, -1.0f, 1.0f);
+static constexpr bool DEFAULT_MODEL_CHILDREN_SENSITIVE = false;
+
static constexpr std::string_view KTX_EXTENSION = ".ktx";
static constexpr std::string_view OBJ_EXTENSION = ".obj";
static constexpr std::string_view GLTF_EXTENSION = ".gltf";
mNaturalSize(Vector3::ZERO),
mModelPivot(AnchorPoint::CENTER),
mIblScaleFactor(1.0f),
+ mModelChildrenSensitive(DEFAULT_MODEL_CHILDREN_SENSITIVE),
mModelResourceReady(false),
mIBLResourceReady(true)
{
return mModelRoot;
}
+void Model::SetChildrenSensitive(bool enable)
+{
+ if(mModelChildrenSensitive != enable)
+ {
+ mModelChildrenSensitive = enable;
+ if(mModelRoot)
+ {
+ mModelRoot.SetProperty(Dali::Actor::Property::SENSITIVE, mModelChildrenSensitive);
+ }
+ }
+}
+
+bool Model::GetChildrenSensitive() const
+{
+ return mModelChildrenSensitive;
+}
+
void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor)
{
- mIBLResourceReady = false;
+ mIBLResourceReady = false;
Texture diffuseTexture = Dali::Scene3D::Loader::LoadCubeMap(diffuseUrl);
Texture specularTexture = Dali::Scene3D::Loader::LoadCubeMap(specularUrl);
SetImageBasedLightTexture(diffuseTexture, specularTexture, scaleFactor);
mIblScaleFactor = scaleFactor;
UpdateImageBasedLightScaleFactor();
}
-
}
}
FitModelPosition();
ScaleModel();
+ mModelRoot.SetProperty(Dali::Actor::Property::SENSITIVE, mModelChildrenSensitive);
+
Self().Add(mModelRoot);
Self().SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
#include <dali-toolkit/public-api/controls/control-impl.h>
#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>
+#include <dali/public-api/rendering/texture.h>
// INTERNAL INCLUDES
#include <dali-scene3d/public-api/controls/model/model.h>
const Actor GetModelRoot() const;
/**
+ * @copydoc Model::SetChildrenSensitive()
+ */
+ void SetChildrenSensitive(bool enable);
+
+ /**
+ * @copydoc Model::GetChildrenSensitive()
+ */
+ bool GetChildrenSensitive() const;
+
+ /**
* @copydoc Model::SetImageBasedLightSource()
*/
void SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor);
Vector3 mNaturalSize;
Vector3 mModelPivot;
float mIblScaleFactor;
+ bool mModelChildrenSensitive;
bool mModelResourceReady;
bool mIBLResourceReady;
};
return GetImpl(*this).GetModelRoot();
}
+void Model::SetChildrenSensitive(bool enable)
+{
+ GetImpl(*this).SetChildrenSensitive(enable);
+}
+
+bool Model::GetChildrenSensitive() const
+{
+ return GetImpl(*this).GetChildrenSensitive();
+}
+
void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor)
{
GetImpl(*this).SetImageBasedLightSource(diffuseUrl, specularUrl, scaleFactor);
// 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>
+#include <dali/public-api/rendering/texture.h>
namespace Dali
{
*
* By default, The loaded model has its own position and size which are defined in vertex buffer regardless of the Control size.
*
+ * @SINCE_2_1.41
* @code
*
* Model model = Model::New(modelUrl);
public:
/**
* @brief Create an initialized Model.
+ *
+ * @SINCE_2_1.41
* @param[in] modelUrl model file path.(e.g., glTF, and DLI).
* @param[in] resourceDirectoryUrl resource file path that includes binary, image etc.
* @note If resourceDirectoryUrl is empty, the parent directory path of modelUrl is used for resource path.
*
* Only derived versions can be instantiated. Calling member
* functions with an uninitialized Dali::Object is not allowed.
+ *
+ * @SINCE_2_1.41
*/
Model();
* @brief Destructor.
*
* This is non-virtual since derived Handle types must not contain data or virtual methods.
+ *
+ * @SINCE_2_1.41
*/
~Model();
/**
* @brief Copy constructor.
+ *
+ * @SINCE_2_1.41
* @param[in] model Handle to an object
*/
Model(const Model& model);
/**
* @brief Move constructor
*
+ * @SINCE_2_1.41
* @param[in] rhs A reference to the moved handle
*/
Model(Model&& rhs);
/**
* @brief Assignment operator.
+ *
+ * @SINCE_2_1.41
* @param[in] model Handle to an object
* @return reference to this
*/
/**
* @brief Move assignment
*
+ * @SINCE_2_1.41
* @param[in] rhs A reference to the moved handle
* @return A reference to this
*/
* If handle points to a Model, the downcast produces valid handle.
* If not, the returned handle is left uninitialized.
*
+ * @SINCE_2_1.41
* @param[in] handle Handle to an object
* @return Handle to a Model or an uninitialized handle
*/
/**
* @brief Retrieves model root Actor.
+ *
+ * @SINCE_2_1.41
* @return Root Actor of the model.
*/
const Actor GetModelRoot() const;
/**
+ * @brief Whether allow this model's children actor to use events.
+ *
+ * Usually, 3D Model might have a lot of actors. And most of them don't need to check events.
+ * To optimize traversal, we need to setup some flag that this model don't allow (or allow) to traversal
+ * children so that child can use events.
+ *
+ * @SINCE_2_1.43
+ * @note Even if we set children sensitive as false, model itself's sensitive
+ * is depend on it's property.
+ * @note If we don't call this API, default is false. (Allow to traversal model's children during hit-test)
+ *
+ * @param[in] enable True to enable model's children can use events.
+ */
+ void SetChildrenSensitive(bool enable);
+
+ /**
+ * @brief Gets whether this Model allow model's children actor to use events or not.
+ *
+ * @SINCE_2_1.43
+ * @return bool True if this Model allow model children sensitive.
+ */
+ bool GetChildrenSensitive() const;
+
+ /**
* @brief Changes Image Based Light as the input textures.
+ *
+ * @SINCE_2_1.41
* @param[in] diffuseUrl cube map that can be used as a diffuse IBL source.
* @param[in] specularUrl 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.
/**
* @brief Sets Image Based Light Texture.
*
+ * @SINCE_2_1.41
* @param[in] diffuseTexture cube map texture that can be used as a diffuse IBL source.
* @param[in] specularTexture 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.
/**
* @brief Sets Scale Factor of Image Based Light Source.
*
+ * @SINCE_2_1.41
* @note If SetImageBasedLightSource() or SetImageBasedLightTexture() method is called after this method, scaleFactor is overrided.
*
* @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f].
* @brief Gets Scale Factor of Image Based Light Source.
* Default value is 1.0f.
*
+ * @SINCE_2_1.41
* @return scale factor that controls light source intensity.
*/
float GetImageBasedLightScaleFactor() const;
/**
* @brief Gets number of animations those loaded from model file.
+ *
+ * @SINCE_2_1.41
* @return The number of loaded animations.
* @note This method should be called after Model load finished.
*/
/**
* @brief Gets animation at the index.
+ *
+ * @SINCE_2_1.41
* @param[in] index Index of animation to be retrieved.
* @return Animation at the index.
* @note This method should be called after Model load finished.
/**
* @brief Retrieves animation with the given name.
+ *
+ * @SINCE_2_1.41
* @param[in] name string name of animation to be retrieved.
* @return Animation that has the given name.
* @note This method should be called after Model load finished.
*
* And since SceneView is a Control, it can be placed together with other 2D UI components in the DALi window.
*
+ * @SINCE_2_1.38
* @code
*
* Dali::Scene3D::SceneView sceneView = Dali::Scene3D::SceneView::New();
public:
/**
* @brief Create an initialized SceneView.
+ *
+ * @SINCE_2_1.38
* @return A handle to a newly allocated Dali resource
*/
static SceneView New();
*
* Only derived versions can be instantiated. Calling member
* functions with an uninitialized Dali::Object is not allowed.
+ *
+ * @SINCE_2_1.38
*/
SceneView();
* @brief Destructor.
*
* This is non-virtual since derived Handle types must not contain data or virtual methods.
+ *
+ * @SINCE_2_1.38
*/
~SceneView();
/**
* @brief Copy constructor.
+ *
+ * @SINCE_2_1.38
* @param[in] sceneView Handle to an object
*/
SceneView(const SceneView& sceneView);
/**
* @brief Move constructor
*
+ * @SINCE_2_1.38
* @param[in] rhs A reference to the moved handle
*/
SceneView(SceneView&& rhs);
/**
* @brief Assignment operator.
+ *
+ * @SINCE_2_1.38
* @param[in] sceneView Handle to an object
* @return reference to this
*/
/**
* @brief Move assignment
*
+ * @SINCE_2_1.38
* @param[in] rhs A reference to the moved handle
* @return A reference to this
*/
* If handle points to a SceneView, the downcast produces valid handle.
* If not, the returned handle is left uninitialized.
*
+ * @SINCE_2_1.38
* @param[in] handle Handle to an object
* @return Handle to a SceneView or an uninitialized 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)
*
+ * @SINCE_2_1.38
* @note
* AspectRatio property of CameraActor will be changed depending on the Size of this SceneView.
*
/**
* @brief Removes a CameraActor from this SceneView.
+ *
+ * @SINCE_2_1.38
* @note If removed CameraActor is selected CameraActor,
* first camera in the list is set to selected CameraActor.
*
/**
* @brief Retrieves the number of cameras.
*
+ * @SINCE_2_1.38
* @return Number of cameras those currently the SceneView contains.
*/
uint32_t GetCameraCount() const;
/**
* @brief Retrieves selected CameraActor.
*
+ * @SINCE_2_1.38
* @return CameraActor currently used in SceneView as a selected CameraActor
*/
CameraActor GetSelectedCamera() const;
/**
* @brief Retrieves a CameraActor of the index.
*
+ * @SINCE_2_1.38
* @param[in] index Index of CameraActor to be retrieved.
*
* @return CameraActor of the index
/**
* @brief Retrieves a CameraActor of the name.
*
+ * @SINCE_2_1.38
* @param[in] name string keyword of CameraActor to be retrieved.
*
* @return CameraActor that has the name as a Dali::Actor::Property::NAME
/**
* @brief Makes SceneView use a CameraActor of index as a selected camera.
*
+ * @SINCE_2_1.38
* @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.
*
+ * @SINCE_2_1.38
* @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.
*
+ * @SINCE_2_1.38
* @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.
/**
* @brief Sets Scale Factor of Image Based Light Source.
*
+ * @SINCE_2_1.41
* @note If SetImageBasedLightSource() or SetImageBasedLightTexture() method is called after this method, scaleFactor is overriden.
* @note Default value is 1.0f.
*
* @brief Gets Scale Factor of Image Based Light Source.
* Default value is 1.0f.
*
+ * @SINCE_2_1.41
* @return scale factor that controls light source intensity.
*/
float GetImageBasedLightScaleFactor() const;
* If useFramebuffer is false, each item in SceneView is rendered on window directly.
* Default is false.
*
+ * @SINCE_2_1.38
* @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.
*
/**
* @brief Gets whether this SceneView uses Framebuffer or not.
*
+ * @SINCE_2_1.38
* @return bool True if this SceneView uses Framebuffer.
*/
bool IsUsingFramebuffer() const;