From e7d681fd6bd96fe92305c83c941ec9587605ac32 Mon Sep 17 00:00:00 2001 From: Eunki Hong Date: Thu, 31 Aug 2023 23:07:13 +0900 Subject: [PATCH] [Tizen] Property Notify for orientation changes (PoC) Allow to make Notify if Orientation changed, and we register PropertyNotification by StepCondition. TODO : Need to calculate more meanful value. Currently, we trigger by compare each EulerAngle values. Change-Id: I0aa2355c0071a8200a029b9350f6cfdad08e2c12 Signed-off-by: Eunki Hong --- .../src/dali/utc-Dali-PropertyNotification.cpp | 53 ++++++++++++++++++++++ .../event/common/property-notification-impl.cpp | 3 +- .../common/property-condition-step-functions.cpp | 39 +++++++++++++++- .../common/property-condition-step-functions.h | 12 +++++ dali/public-api/object/property-conditions.h | 1 + 5 files changed, 106 insertions(+), 2 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-PropertyNotification.cpp b/automated-tests/src/dali/utc-Dali-PropertyNotification.cpp index 460c011..3c956c7 100644 --- a/automated-tests/src/dali/utc-Dali-PropertyNotification.cpp +++ b/automated-tests/src/dali/utc-Dali-PropertyNotification.cpp @@ -1090,6 +1090,59 @@ int UtcDaliPropertyNotificationStepVector3(void) END_TEST; } +int UtcDaliPropertyNotificationStepQuaternion(void) +{ + TestApplication application; + tet_infoline(" UtcDaliPropertyNotificationStepQuaternion"); + + tet_printf("Note : Current implement is kind of POC. Should be complete in future."); + + Actor actor = Actor::New(); + application.GetScene().Add(actor); + + // TODO : Need to be meanful value in future. + const float tinyStep = 0.01f; + + PropertyNotification notification = actor.AddPropertyNotification(Actor::Property::ORIENTATION, StepCondition(tinyStep)); + notification.NotifySignal().Connect(&TestCallback); + + // Rotate big angles for current case. + actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Radian(Degree(0.0f)), Vector3::YAXIS)); + Wait(application, DEFAULT_WAIT_PERIOD); + + for(int i = 1; i <= 10; ++i) + { + // Move x to negative position + gCallBackCalled = false; + actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Radian(Degree(i * 36.0f)), Vector3::YAXIS)); + Wait(application, DEFAULT_WAIT_PERIOD); + DALI_TEST_CHECK(gCallBackCalled); + } + + tet_printf("Test for length of EulerAngle is same, but each componets are difference."); + actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Radian(Degree(90.0f)), Vector3::YAXIS)); + Wait(application, DEFAULT_WAIT_PERIOD); + + gCallBackCalled = false; + actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Radian(Degree(90.0f)), Vector3::XAXIS)); + Wait(application, DEFAULT_WAIT_PERIOD); + DALI_TEST_CHECK(gCallBackCalled); + + tet_printf("Test notify should not be called"); + gCallBackCalled = false; + Animation animation = Animation::New(RENDER_FRAME_INTERVAL); + animation.AnimateTo(Property(actor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(90.0f)), Vector3::XAXIS)); + animation.Play(); + + application.SendNotification(); + application.Render(RENDER_FRAME_INTERVAL); + application.SendNotification(); + application.Render(RENDER_FRAME_INTERVAL); + + DALI_TEST_CHECK(!gCallBackCalled); + END_TEST; +} + int UtcDaliPropertyNotificationVariableStep(void) { TestApplication application; diff --git a/dali/internal/event/common/property-notification-impl.cpp b/dali/internal/event/common/property-notification-impl.cpp index 4cd78d3..06df84c 100644 --- a/dali/internal/event/common/property-notification-impl.cpp +++ b/dali/internal/event/common/property-notification-impl.cpp @@ -99,7 +99,8 @@ PropertyNotification::PropertyNotification(UpdateManager& update } // To cover swapping components, previous and current components should be compared. - if(mObject->GetPropertyType(mObjectPropertyIndex) == Property::VECTOR3) + if(mObject->GetPropertyType(mObjectPropertyIndex) == Property::VECTOR3 || + mObject->GetPropertyType(mObjectPropertyIndex) == Property::ROTATION) { mCompare = true; for(int i = 0; i < 3; ++i) diff --git a/dali/internal/update/common/property-condition-step-functions.cpp b/dali/internal/update/common/property-condition-step-functions.cpp index 9076a8a..3b15e7b 100644 --- a/dali/internal/update/common/property-condition-step-functions.cpp +++ b/dali/internal/update/common/property-condition-step-functions.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 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. @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -37,6 +38,12 @@ const int32_t ARGINDEX_FIRST_VALUE = 3; const int32_t ARGINDEX_SECOND_VALUE = 4; const int32_t ARGINDEX_THIRD_VALUE = 5; +inline float AngleDifference(float a1, float a2, const float angleRangeHalf) +{ + float diff = fabs(a1 - a2); + return diff < angleRangeHalf ? diff : angleRangeHalf * 2.0f - diff; +} + } // namespace ConditionFunction Step::GetFunction(Property::Type valueType) @@ -87,6 +94,10 @@ ConditionFunction Step::GetCompareFunction(Property::Type valueType) { function = EvalAndCompareVector3; } + else if(valueType == Property::ROTATION) + { + function = EvalAndCompareQuaternion; + } else { function = GetFunction(valueType); @@ -161,6 +172,32 @@ bool Step::EvalVector4(const Dali::PropertyInput& value, PropertyNotification::R return Evaluate(propertyValue, arg); } +bool Step::EvalAndCompareQuaternion(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg) +{ + // TODO : Make some meaningfule calculation here + + Quaternion propertyValue = value.GetQuaternion(); + + Vector4 v = propertyValue.EulerAngles(); + const float checkValue = v.LengthSquared(); + bool result = Evaluate(checkValue, arg); + + if(result == false) + { + const float step = 1.0f / arg[ARGINDEX_STEP_SIZE]; + if((AngleDifference(arg[ARGINDEX_FIRST_VALUE], v.x, Dali::Math::PI) > step) || + (AngleDifference(arg[ARGINDEX_SECOND_VALUE], v.y, Dali::Math::PI_2) > step) || + (AngleDifference(arg[ARGINDEX_THIRD_VALUE], v.z, Dali::Math::PI) > step)) + { + result = true; + } + } + arg[ARGINDEX_FIRST_VALUE] = v.x; + arg[ARGINDEX_SECOND_VALUE] = v.y; + arg[ARGINDEX_THIRD_VALUE] = v.z; + return result; +} + bool Step::EvalDefault(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg) { return false; diff --git a/dali/internal/update/common/property-condition-step-functions.h b/dali/internal/update/common/property-condition-step-functions.h index 57fe42c..db6f9a7 100644 --- a/dali/internal/update/common/property-condition-step-functions.h +++ b/dali/internal/update/common/property-condition-step-functions.h @@ -39,6 +39,7 @@ namespace SceneGraph * Vector2 => 2 dimensional length of vector has stepped arg1 amount from arg0. * Vector3 => 3 dimensional length of vector has stepped arg1 amount from arg0. * Vector4 => 4 dimensional length of vector has stepped arg1 amount from arg0. + * Quaternion => 3 dimensional lenght of eular angle stepped arg1 amount from arg0 * Default => return false. */ class Step @@ -113,6 +114,17 @@ private: static bool EvalVector4(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg); /** + * Checks if Quaternion is Outside + * + * If previous Quaternion and current examined value are same, the raw datas are checked with comparing these values. + * + * @param[in] value The value being examined. + * @param[in] arg The supplied arguments for the condition. + * @return Condition result (true if condition met, false if not) + */ + static bool EvalAndCompareQuaternion(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg); + + /** * Default check for other types. * @param[in] value The value being examined. * @param[in] arg The supplied arguments for the condition. diff --git a/dali/public-api/object/property-conditions.h b/dali/public-api/object/property-conditions.h index 36a0df3..db0c7c3 100644 --- a/dali/public-api/object/property-conditions.h +++ b/dali/public-api/object/property-conditions.h @@ -178,6 +178,7 @@ DALI_CORE_API PropertyCondition OutsideCondition(float arg0, float arg1); * vector2 (the 2D length) * vector3 (the 3D length) * vector4 (the 4D length) + * quaternion (the 3D length of eular angle) * @SINCE_1_0.0 * @param[in] stepAmount The step size required to trigger condition * @param[in] initialValue The initial value to step from -- 2.7.4