[Tizen] Property Notify for orientation changes (PoC) 91/304091/1
authorEunki Hong <eunkiki.hong@samsung.com>
Thu, 31 Aug 2023 14:07:13 +0000 (23:07 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Wed, 10 Jan 2024 03:47:42 +0000 (12:47 +0900)
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: Ic500313676730b0d3bb9004057796b66d3303079
Signed-off-by: Eunki Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali/utc-Dali-PropertyNotification.cpp
dali/internal/event/common/property-notification-impl.cpp
dali/internal/update/common/property-condition-step-functions.cpp
dali/internal/update/common/property-condition-step-functions.h
dali/internal/update/common/property-condition-variable-step-functions.cpp
dali/internal/update/common/property-condition-variable-step-functions.h
dali/public-api/object/property-conditions.h

index 460c011..3c956c7 100644 (file)
@@ -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;
index 2a93442..27fd7f9 100644 (file)
@@ -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)
index 8674b0b..7556d9b 100644 (file)
@@ -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 <dali/internal/update/common/property-condition-step-functions.h>
 #include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/math/quaternion.h>
 #include <dali/public-api/math/vector2.h>
 #include <dali/public-api/math/vector3.h>
 #include <dali/public-api/math/vector4.h>
@@ -38,6 +39,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)
@@ -71,11 +78,6 @@ ConditionFunction Step::GetFunction(Property::Type valueType)
       function = EvalVector4;
       break;
     }
-    case Property::ROTATION:
-    {
-      function = EvalQuaternion;
-      break;
-    }
     default:
     {
       function = EvalDefault;
@@ -93,6 +95,10 @@ ConditionFunction Step::GetCompareFunction(Property::Type valueType)
   {
     function = EvalAndCompareVector3;
   }
+  else if(valueType == Property::ROTATION)
+  {
+    function = EvalAndCompareQuaternion;
+  }
   else
   {
     function = GetFunction(valueType);
@@ -167,13 +173,30 @@ bool Step::EvalVector4(const Dali::PropertyInput& value, PropertyNotification::R
   return Evaluate(propertyValue, arg);
 }
 
-bool Step::EvalQuaternion(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg)
+bool Step::EvalAndCompareQuaternion(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg)
 {
-  Quaternion propertyValue = value.GetQuaternion();
   // TODO : Make some meaningfule calculation here
-  Vector4 v = propertyValue.EulerAngles();
+
+  Quaternion propertyValue = value.GetQuaternion();
+
+  Vector4     v          = propertyValue.EulerAngles();
   const float checkValue = v.LengthSquared();
-  return Evaluate(checkValue, arg);
+  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)
index 7f5dc5d..db6f9a7 100644 (file)
@@ -39,7 +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 => sum of rotation angle and axis changes has stepped arg1 amount from arg0
+ * Quaternion => 3 dimensional lenght of eular angle stepped arg1 amount from arg0
  * Default    => return false.
  */
 class Step
@@ -115,11 +115,14 @@ private:
 
   /**
    * 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 EvalQuaternion(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg);
+  static bool EvalAndCompareQuaternion(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg);
 
   /**
    * Default check for other types.
index 8f61c7a..f89aaea 100644 (file)
@@ -68,11 +68,6 @@ ConditionFunction VariableStep::GetFunction(Property::Type valueType)
       function = EvalVector4;
       break;
     }
-    case Property::ROTATION:
-    {
-      function = EvalQuaternion;
-      break;
-    }
     default:
     {
       function = EvalDefault;
@@ -178,15 +173,6 @@ bool VariableStep::EvalVector4(const Dali::PropertyInput& value, PropertyNotific
   return Evaluate(propertyValue, arg);
 }
 
-bool VariableStep::EvalQuaternion(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg)
-{
-  Quaternion propertyValue = value.GetQuaternion();
-  // TODO : Make some meaningfule calculation here
-  Vector4 v = propertyValue.EulerAngles();
-  const float checkValue = v.LengthSquared();
-  return Evaluate(checkValue, arg);
-}
-
 bool VariableStep::EvalDefault(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg)
 {
   return false;
index d404e1b..16c7640 100644 (file)
@@ -39,7 +39,6 @@ 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 => sum of rotation angle and axis changes has stepped arg1 amount from arg0
  * Default    => return false.
  */
 class VariableStep
@@ -100,14 +99,6 @@ private:
   static bool EvalVector4(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg);
 
   /**
-   * Checks if Quaternion is Outside
-   * @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 EvalQuaternion(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.
index 99ec9b7..1b84663 100644 (file)
@@ -178,7 +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 radian of rotation and axis)
+ * 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
@@ -194,7 +194,6 @@ DALI_CORE_API PropertyCondition StepCondition(float stepAmount, float initialVal
  * vector2 (the 2D length)
  * vector3 (the 3D length)
  * vector4 (the 4D length)
- * quaternion (the radian of rotation and axis)
  * @SINCE_1_0.0
  * @param[in] steps List of values to receive notifications for as a property crosses them
  * @return A property condition function object