/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
return false;
}
+ bool ActorRequiresHitResultCheck(Actor* actor, Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp) override
+ {
+ return actor->EmitHitTestResultSignal(point, hitPointLocal, timeStamp);
+ }
+
Dali::HitTestAlgorithm::HitTestFunction mFunc;
};
{
bool IsActorHittable(Actor* actor) override
{
- return actor->GetTouchRequired() && // Does the Application or derived actor type require a touch event?
- actor->IsHittable(); // Is actor sensitive, visible and on the scene?
+ return (actor->GetTouchRequired() || actor->GetInterceptTouchRequired() || actor->IsTouchFocusable()) && // Does the Application or derived actor type require a touch event or a intercept touch event? or focusable by touch?
+ actor->IsHittable(); // Is actor sensitive, visible and on the scene?
}
bool DescendActorHierarchy(Actor* actor) override
{
return layer->IsTouchConsumed();
}
+
+ bool ActorRequiresHitResultCheck(Actor* actor, Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp) override
+ {
+ return actor->EmitHitTestResultSignal(point, hitPointLocal, timeStamp);
+ }
};
/**
bool layerIs3d,
uint32_t clippingDepth,
uint32_t clippingBitPlaneMask,
- const RayTest& rayTest)
+ const RayTest& rayTest,
+ const Integration::Point& point,
+ const uint32_t eventTime)
{
HitActor hit;
// Finally, perform a more accurate ray test to see if our ray actually hits the actor.
if(rayTest.ActorTest(actor, rayOrigin, rayDir, hitPointLocal, distance))
{
- if(distance >= nearClippingPlane && distance <= farClippingPlane)
+ // Calculate z coordinate value in Camera Space.
+ const Matrix& viewMatrix = renderTask.GetCameraActor()->GetViewMatrix();
+ const Vector4& hitDir = Vector4(rayDir.x * distance, rayDir.y * distance, rayDir.z * distance, 0.0f);
+ const float cameraDepthDistance = (viewMatrix * hitDir).z;
+
+ // 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(haveHitActor)
+ // If CapturesAllTouchAfterStart() is true, it should be hit only after touchdown.
+ // If the touch moves after another actor has been touched so that the current actor is hit, it should behave as if it didn't hit.
+ if(actor.CapturesAllTouchAfterStart() && point.GetState() != PointState::STARTED)
+ {
+ haveHitActor = false;
+ }
+
+ // If the hit actor does not want to hit, the hit-test continues.
+ if(haveHitActor && hitCheck.ActorRequiresHitResultCheck(&actor, point, hitPointLocal, eventTime))
{
hit.actor = &actor;
hit.hitPosition = hitPointLocal;
layerIs3d,
newClippingDepth,
clippingBitPlaneMask,
- rayTest));
+ rayTest,
+ point,
+ eventTime));
// Make sure the set hit actor is actually hittable. This is usually required when we have some
// clipping as we need to hit-test all actors as we descend the tree regardless of whether they
// are hittable or not.
- if(currentHit.actor && !hitCheck.IsActorHittable(currentHit.actor))
+ if(currentHit.actor && (!hitCheck.IsActorHittable(currentHit.actor)))
{
continue;
}
layer->GetBehavior() == Dali::Layer::LAYER_3D,
0u,
0u,
- rayTest);
+ rayTest,
+ results.point,
+ results.eventTime);
}
else if(IsWithinSourceActors(*sourceActor, *layer))
{
layer->GetBehavior() == Dali::Layer::LAYER_3D,
0u,
0u,
- rayTest);
+ rayTest,
+ results.point,
+ results.eventTime);
}
// If this layer is set to consume the hit, then do not check any layers behind it
// Skip to next task
continue;
}
-
if(HitTestRenderTask(exclusives, sceneSize, layers, renderTask, screenCoordinates, results, hitCheck, rayTest))
{
// Return true when an actor is hit (or layer in our render-task consumes the hit)