END_TEST;
}
+int UtcDaliHitTestAlgorithmClippingActorStress(void)
+{
+ TestApplication application;
+ tet_infoline("Testing Dali::HitTestAlgorithm with many many stencil");
+
+ Stage stage = Stage::GetCurrent();
+ Actor rootLayer = stage.GetRootLayer();
+ rootLayer.SetProperty(Actor::Property::NAME, "RootLayer");
+
+ // Create a layer
+ Layer layer = Layer::New();
+ layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ layer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ layer.SetProperty(Actor::Property::NAME, "layer");
+ stage.Add(layer);
+
+ // Create a clipping actor and add it to the layer.
+ Actor clippingActor = CreateRenderableActor();
+ clippingActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ clippingActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ clippingActor.SetProperty(Actor::Property::SIZE, Vector2(220.0f, 220.0f));
+ clippingActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX);
+ clippingActor.SetProperty(Actor::Property::NAME, "clippingActor");
+ layer.Add(clippingActor);
+
+ // Create a renderable actor and add it to the clipping actor.
+ Actor latestActor = clippingActor;
+ const int depthMax = 100;
+ for(int i = 0; i < depthMax; i++)
+ {
+ char tmp[29];
+ sprintf(tmp, "depth%03d", i);
+
+ Actor childActor = CreateRenderableActor();
+ childActor.SetProperty(Actor::Property::SIZE, Vector2(220.0f, 220.0f));
+ childActor.SetProperty(Actor::Property::POSITION, Vector2(200.0f / depthMax, 200.0f / depthMax));
+ childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ childActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ childActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX);
+ childActor.SetProperty(Actor::Property::NAME, tmp);
+
+ latestActor.Add(childActor);
+ latestActor = childActor;
+ }
+ // NOTE : latestActor's TOP_LEFT position become 200.f, 200.0f
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Hit within clippingActor and latestActor.
+ HitTestAlgorithm::Results results;
+ HitTest(stage, Vector2(201.0f, 201.0f), results, &DefaultIsActorTouchableFunction);
+ tet_printf("Hit: %s\n", (results.actor ? results.actor.GetProperty<std::string>(Actor::Property::NAME).c_str() : "NULL"));
+ DALI_TEST_CHECK(results.actor == latestActor);
+
+ // Hit within childActor but outside of clippingActor, should hit the root-layer instead.
+ HitTest(stage, Vector2(221.0f, 221.0f), results, &DefaultIsActorTouchableFunction);
+ tet_printf("Hit: %s\n", (results.actor ? results.actor.GetProperty<std::string>(Actor::Property::NAME).c_str() : "NULL"));
+ DALI_TEST_CHECK(results.actor == rootLayer);
+
+ END_TEST;
+}
+
int UtcDaliHitTestAlgorithmOverlay(void)
{
TestApplication application;
const bool& overlayed,
bool& overlayHit,
bool layerIs3d,
- uint32_t clippingDepth,
- uint32_t clippingBitPlaneMask,
const RayTest& rayTest,
const Integration::Point& point,
const uint32_t eventTime)
return hit;
}
- // For clipping, regardless of whether we have hit this actor or not,
- // we increase the clipping depth if we have hit a clipping actor.
+ // For clipping, regardless of whether we have hit this actor or not.
// This is used later to ensure all nested clipped children have hit
// 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;
- }
+ bool clippingActor = actor.GetClippingMode() != ClippingMode::DISABLED;
+ bool overlayedActor = overlayed || actor.IsOverlay();
// If we are a clipping actor or hittable...
if(clippingActor || hitCheck.IsActorHittable(&actor))
// Check if cameraDepthDistance is between clipping plane
if(cameraDepthDistance >= nearClippingPlane && cameraDepthDistance <= farClippingPlane)
{
- // If the hit has happened on a clipping actor, then add this clipping depth to the mask of hit clipping depths.
- // This mask shows all the actors that have been hit at different clipping depths.
- if(clippingActor)
- {
- clippingBitPlaneMask |= 1u << clippingDepth;
- }
-
if(overlayHit && !overlayedActor)
{
// If we have already hit an overlay and current actor is not an overlay ignore current actor.
overlayHit = true;
}
- // At this point we have hit an actor.
- // Now perform checks for clipping.
- // Assume we have hit the actor first as if it is not clipped this would be the case.
- bool haveHitActor = true;
-
- // Check if we are performing clipping. IE. if any actors so far have clipping enabled - not necessarily this one.
- // We can do this by checking the clipping depth has a value 1 or above.
- if(newClippingDepth >= 1u)
- {
- // Now for us to count this actor as hit, we must have also hit
- // all CLIPPING actors up to this point in the hierarchy as well.
- // This information is stored in the clippingBitPlaneMask we updated above.
- // Here we calculate a comparison mask by setting all the bits up to the current depth value.
- // EG. a depth of 4 (10000 binary) = a mask of 1111 binary.
- // This allows us a fast way of comparing all bits are set up to this depth.
- // Note: If the current Actor has clipping, that is included in the depth mask too.
- uint32_t clippingDepthMask = (1u << newClippingDepth) - 1u;
-
- // The two masks must be equal to be a hit, as we are already assuming a hit
- // (for non-clipping mode) then they must be not-equal to disqualify the hit.
- if(clippingBitPlaneMask != clippingDepthMask)
- {
- haveHitActor = false;
- }
- }
-
// If the hit actor does not want to hit, the hit-test continues.
- if(haveHitActor && hitCheck.ActorRequiresHitResultCheck(&actor, point, hitPointLocal, eventTime))
+ if(hitCheck.ActorRequiresHitResultCheck(&actor, point, hitPointLocal, eventTime))
{
hit.actor = &actor;
hit.hitPosition = hitPointLocal;
}
}
+ // If current actor is clipping, and hit failed, We should not checkup child actors. Fast return
+ if(clippingActor && !(hit.actor))
+ {
+ return hit;
+ }
+
// Find a child hit, until we run out of actors in the current layer.
HitActor childHit;
if(actor.GetChildCount() > 0)
overlayedActor,
overlayHit,
layerIs3d,
- newClippingDepth,
- clippingBitPlaneMask,
rayTest,
point,
eventTime));
overlayHit,
overlayHit,
layer->GetBehavior() == Dali::Layer::LAYER_3D,
- 0u,
- 0u,
rayTest,
results.point,
results.eventTime);
overlayHit,
overlayHit,
layer->GetBehavior() == Dali::Layer::LAYER_3D,
- 0u,
- 0u,
rayTest,
results.point,
results.eventTime);