From: Eunki, Hong Date: Mon, 28 Mar 2022 10:44:34 +0000 (+0900) Subject: Fix hit-test bug when overlay2D child is not overlayed X-Git-Tag: dali_2.1.16~2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=ae03e08a89391b257701d79ae87b92dec7d950d9 Fix hit-test bug when overlay2D child is not overlayed Let's image some case like below scene tree. root --- A (overlay2D) --- A1 (normal) |- B (normal) When A1 and B is overlaped, B will be drawn under the A1. (Because A is overlay) But, in hit-test-algorithm, overlay2D information doesn't propagated. This patch make hit-test can propagate overlay2D property, so the hit test result return reasonable as what we can see. Change-Id: I123d3bbc2c6ba27df3f10829ebaf16b80eb0f987 Signed-off-by: Eunki, Hong --- diff --git a/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp b/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp index 1bac5af..2229015 100644 --- a/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp +++ b/automated-tests/src/dali/utc-Dali-HitTestAlgorithm.cpp @@ -379,6 +379,77 @@ int UtcDaliHitTestAlgorithmOverlay(void) HitTest(stage, stageSize * 2.0f / 3.0f, results, &DefaultIsActorTouchableFunction); DALI_TEST_CHECK(results.actor == green); DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 0.5f, TEST_LOCATION); + + // Create new actor child as blue. It will be shown over the blue, and green. + Actor red = Actor::New(); + red.SetProperty(Actor::Property::NAME, "Red"); + red.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + red.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + red.SetProperty(Actor::Property::POSITION, Vector2(actorSize.x * 5.0f / 6.0f, -actorSize.y * 1.0f / 6.0f)); + red.SetProperty(Actor::Property::SIZE, actorSize); + + blue.Add(red); + + // Render and notify + application.SendNotification(); + application.Render(0); + application.Render(10); + + //Hit in the intersection red, green, blue. Should pick the red actor since it is an child of overlay. + HitTest(stage, Vector2(stageSize.x * 13.0f / 24.0f, stageSize.y * 11.0f / 24.0f), results, &DefaultIsActorTouchableFunction); + tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y); + DALI_TEST_CHECK(results.actor == red); + DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 1.0f / 12.0f, actorSize.y * 11.0f / 12.0f), TEST_LOCATION); + + //Hit in the intersection red, blue. Should pick the red actor since it is an child of blue. + HitTest(stage, Vector2(stageSize.x * 13.0f / 24.0f, stageSize.y * 9.0f / 24.0f), results, &DefaultIsActorTouchableFunction); + tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y); + DALI_TEST_CHECK(results.actor == red); + DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 1.0f / 12.0f, actorSize.y * 9.0f / 12.0f), TEST_LOCATION); + + //Hit in the intersection red, green. Should pick the red actor since it is an child of overlay. + HitTest(stage, Vector2(stageSize.x * 15.0f / 24.0f, stageSize.y * 11.0f / 24.0f), results, &DefaultIsActorTouchableFunction); + tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y); + DALI_TEST_CHECK(results.actor == red); + DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 3.0f / 12.0f, actorSize.y * 11.0f / 12.0f), TEST_LOCATION); + + //Hit in the intersection blue, green. Should pick the blue actor since it is an overlay. + HitTest(stage, Vector2(stageSize.x * 11.0f / 24.0f, stageSize.y * 13.0f / 24.0f), results, &DefaultIsActorTouchableFunction); + tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y); + DALI_TEST_CHECK(results.actor == blue); + DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 9.0f / 12.0f, actorSize.y * 11.0f / 12.0f), TEST_LOCATION); + + // Change blue's draw mode as normal. now blue < red < green + blue.SetProperty(Actor::Property::DRAW_MODE, DrawMode::NORMAL); + + // Render and notify + application.SendNotification(); + application.Render(0); + application.Render(10); + + //Hit in the intersection red, green, blue. Should pick the green actor since it is latest ordered actor. + HitTest(stage, Vector2(stageSize.x * 13.0f / 24.0f, stageSize.y * 11.0f / 24.0f), results, &DefaultIsActorTouchableFunction); + tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y); + DALI_TEST_CHECK(results.actor == green); + DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 3.0f / 12.0f, actorSize.y * 1.0f / 12.0f), TEST_LOCATION); + + //Hit in the intersection red, blue. Should pick the red actor since it is an child of blue. + HitTest(stage, Vector2(stageSize.x * 13.0f / 24.0f, stageSize.y * 9.0f / 24.0f), results, &DefaultIsActorTouchableFunction); + tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y); + DALI_TEST_CHECK(results.actor == red); + DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 1.0f / 12.0f, actorSize.y * 9.0f / 12.0f), TEST_LOCATION); + + //Hit in the intersection red, green. Should pick the green actor since it is latest ordered actor. + HitTest(stage, Vector2(stageSize.x * 15.0f / 24.0f, stageSize.y * 11.0f / 24.0f), results, &DefaultIsActorTouchableFunction); + tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y); + DALI_TEST_CHECK(results.actor == green); + DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 5.0f / 12.0f, actorSize.y * 1.0f / 12.0f), TEST_LOCATION); + + //Hit in the intersection blue, green. Should pick the green actor since it is latest ordered actor. + HitTest(stage, Vector2(stageSize.x * 11.0f / 24.0f, stageSize.y * 13.0f / 24.0f), results, &DefaultIsActorTouchableFunction); + tet_printf("%d %d %d , %f %f\n", results.actor == red ? 1 : 0, results.actor == green ? 1 : 0, results.actor == blue ? 1 : 0, results.actorCoordinates.x, results.actorCoordinates.y); + DALI_TEST_CHECK(results.actor == green); + DALI_TEST_EQUALS(results.actorCoordinates, Vector2(actorSize.x * 1.0f / 12.0f, actorSize.y * 3.0f / 12.0f), TEST_LOCATION); END_TEST; } diff --git a/dali/internal/event/events/hit-test-algorithm-impl.cpp b/dali/internal/event/events/hit-test-algorithm-impl.cpp index 5330fe3..045b390 100644 --- a/dali/internal/event/events/hit-test-algorithm-impl.cpp +++ b/dali/internal/event/events/hit-test-algorithm-impl.cpp @@ -161,9 +161,10 @@ HitActor HitTestWithinLayer(Actor& actor, const RenderTaskList::ExclusivesContainer& exclusives, const Vector4& rayOrigin, const Vector4& rayDir, - float& nearClippingPlane, - float& farClippingPlane, + const float& nearClippingPlane, + const float& farClippingPlane, HitTestInterface& hitCheck, + const bool& overlayed, bool& overlayHit, bool layerIs3d, uint32_t clippingDepth, @@ -185,6 +186,7 @@ HitActor HitTestWithinLayer(Actor& actor, // all clipping actors also for them to be counted as hit. uint32_t newClippingDepth = clippingDepth; bool clippingActor = actor.GetClippingMode() != ClippingMode::DISABLED; + bool overlayedActor = overlayed || actor.IsOverlay(); if(clippingActor) { ++newClippingDepth; @@ -220,13 +222,13 @@ HitActor HitTestWithinLayer(Actor& actor, clippingBitPlaneMask |= 1u << clippingDepth; } - if(overlayHit && !actor.IsOverlay()) + if(overlayHit && !overlayedActor) { // If we have already hit an overlay and current actor is not an overlay ignore current actor. } else { - if(actor.IsOverlay()) + if(overlayedActor) { overlayHit = true; } @@ -318,6 +320,7 @@ HitActor HitTestWithinLayer(Actor& actor, nearClippingPlane, farClippingPlane, hitCheck, + overlayedActor, overlayHit, layerIs3d, newClippingDepth, @@ -507,6 +510,7 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives, farClippingPlane, hitCheck, overlayHit, + overlayHit, layer->GetBehavior() == Dali::Layer::LAYER_3D, 0u, 0u, @@ -526,6 +530,7 @@ bool HitTestRenderTask(const RenderTaskList::ExclusivesContainer& exclusives, farClippingPlane, hitCheck, overlayHit, + overlayHit, layer->GetBehavior() == Dali::Layer::LAYER_3D, 0u, 0u,