X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fevent%2Fevents%2Fhit-test-algorithm-impl.cpp;h=f6858379e505356f1d82cb039747cdb938547b43;hb=c1df908470fc3dd242fef202248e56009727bca4;hp=c0edd51b3b5d8081a331d135e1cb0e522af8c83c;hpb=54dff6a35a504884c076a370b660ed9a0a6c6bdb;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/event/events/hit-test-algorithm-impl.cpp b/dali/internal/event/events/hit-test-algorithm-impl.cpp index c0edd51..f685837 100644 --- a/dali/internal/event/events/hit-test-algorithm-impl.cpp +++ b/dali/internal/event/events/hit-test-algorithm-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -19,18 +19,14 @@ #include // INTERNAL INCLUDES -#include #include #include #include #include #include #include -#include #include #include -#include -#include #include #include #include @@ -52,19 +48,15 @@ struct HitActor { HitActor() : actor( NULL ), - x( 0 ), - y( 0 ), distance( std::numeric_limits::max() ), depth( std::numeric_limits::min() ) { } - Actor *actor; ///< the actor hit. (if actor hit, then initialised) - float x; ///< x position of hit (only valid if actor valid) - float y; ///< y position of hit (only valid if actor valid) - float distance; ///< distance from ray origin to hit actor - int depth; ///< depth index of this actor - + Actor *actor; ///< The actor hit (if actor is hit, then this is initialised). + Vector2 hitPosition; ///< Position of hit (only valid if actor valid). + float distance; ///< Distance from ray origin to hit actor. + int32_t depth; ///< Depth index of this actor. }; /** @@ -132,19 +124,16 @@ struct ActorTouchableCheck : public HitTestInterface */ bool IsActorExclusiveToAnotherRenderTask( const Actor& actor, const RenderTask& renderTask, - const Vector< RenderTaskList::Exclusive >& exclusives ) + const RenderTaskList::ExclusivesContainer& exclusives ) { - if ( exclusives.Size() ) + if( exclusives.size() ) { - for ( Vector< RenderTaskList::Exclusive >::Iterator exclusiveIt = exclusives.Begin(); exclusives.End() != exclusiveIt; ++exclusiveIt ) + for( const auto& exclusive : exclusives ) { - if ( exclusiveIt->renderTaskPtr != &renderTask ) + if( ( exclusive.renderTaskPtr != &renderTask ) && ( exclusive.actor.GetActor() == &actor ) ) { - if ( exclusiveIt->actorPtr == &actor ) - { - return true; - } + return true; } } } @@ -162,42 +151,45 @@ bool IsActorExclusiveToAnotherRenderTask( const Actor& actor, */ HitActor HitTestWithinLayer( Actor& actor, const RenderTask& renderTask, - const Vector< RenderTaskList::Exclusive >& exclusives, + const RenderTaskList::ExclusivesContainer& exclusives, const Vector4& rayOrigin, const Vector4& rayDir, float& nearClippingPlane, float& farClippingPlane, HitTestInterface& hitCheck, - bool& stencilOnLayer, - bool& stencilHit, - bool parentIsStencil, - bool layerIs3d ) + bool& overlayHit, + bool layerIs3d, + uint32_t clippingDepth, + uint32_t clippingBitPlaneMask ) { HitActor hit; - if ( IsActorExclusiveToAnotherRenderTask( actor, renderTask, exclusives ) ) + if( IsActorExclusiveToAnotherRenderTask( actor, renderTask, exclusives ) ) { return hit; } - // Children should inherit the stencil draw mode - bool isStencil = parentIsStencil; - - if ( actor.GetDrawMode() == DrawMode::STENCIL && actor.IsVisible() ) + // For clipping, regardless of whether we have hit this actor or not, + // we increase the clipping depth if we have hit a clipping actor. + // 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; + if( clippingActor ) { - isStencil = true; - stencilOnLayer = true; + ++newClippingDepth; } - // If we are a stencil or hittable... - if ( isStencil || hitCheck.IsActorHittable( &actor ) ) + // If we are a clipping actor or hittable... + if( clippingActor || hitCheck.IsActorHittable( &actor ) ) { Vector3 size( actor.GetCurrentSize() ); - if ( size.x > 0.0f && size.y > 0.0f && // Ensure the actor has a valid size. - actor.RaySphereTest( rayOrigin, rayDir ) ) // Perform quicker ray sphere test to see if our ray is close to the actor. + // Ensure the actor has a valid size. + // If so, perform a quick ray sphere test to see if our ray is close to the actor. + if( size.x > 0.0f && size.y > 0.0f && actor.RaySphereTest( rayOrigin, rayDir ) ) { - Vector4 hitPointLocal; + Vector2 hitPointLocal; float distance; // Finally, perform a more accurate ray test to see if our ray actually hits the actor. @@ -205,27 +197,71 @@ HitActor HitTestWithinLayer( Actor& actor, { if( distance >= nearClippingPlane && distance <= farClippingPlane ) { - // If the hit has happened on a stencil then register, but don't record as hit result - if ( isStencil ) + // 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 && !actor.IsOverlay() ) { - stencilHit = true; + // If we have already hit an overlay and current actor is not an overlay ignore current actor. } else { - hit.actor = &actor; - hit.x = hitPointLocal.x; - hit.y = hitPointLocal.y; - hit.distance = distance; - hit.depth = actor.GetHierarchyDepth() * Dali::Layer::TREE_DEPTH_MULTIPLIER; - - // Is this actor an Image Actor or contains a renderer? - if ( ImageActor* imageActor = dynamic_cast< ImageActor* >( &actor ) ) + if( actor.IsOverlay() ) { - hit.depth += imageActor->GetDepthIndex(); + overlayHit = true; } - else if ( actor.GetRendererCount() ) + + // 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 ) { - hit.depth += actor.GetRendererAt( 0 ).GetDepthIndex(); + // 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( haveHitActor ) + { + hit.actor = &actor; + hit.hitPosition = hitPointLocal; + hit.distance = distance; + hit.depth = actor.GetSortingDepth() ; + + if( actor.GetRendererCount() > 0 ) + { + //Get renderer with maximum depth + int rendererMaxDepth(actor.GetRendererAt( 0 ).Get()->GetDepthIndex()); + for( uint32_t i(1); i < actor.GetRendererCount(); ++i ) + { + int depth = actor.GetRendererAt( i ).Get()->GetDepthIndex(); + if( depth > rendererMaxDepth ) + { + rendererMaxDepth = depth; + } + } + hit.depth += rendererMaxDepth; + } } } } @@ -233,18 +269,12 @@ HitActor HitTestWithinLayer( Actor& actor, } } - // If we are a stencil (or a child of a stencil) and we have already ascertained that the stencil has been hit then there is no need to hit-test the children of this stencil-actor - if ( isStencil && stencilHit ) - { - return hit; - } - // Find a child hit, until we run out of actors in the current layer. HitActor childHit; if( actor.GetChildCount() > 0 ) { childHit.distance = std::numeric_limits::max(); - childHit.depth = std::numeric_limits::min(); + childHit.depth = std::numeric_limits::min(); ActorContainer& children = actor.GetChildrenInternal(); // Hit test ALL children and calculate their distance. @@ -253,29 +283,29 @@ HitActor HitTestWithinLayer( Actor& actor, for( ActorIter iter = children.begin(), endIter = children.end(); iter != endIter; ++iter ) { // Descend tree only if... - if ( !(*iter)->IsLayer() && // Child is NOT a layer, hit testing current layer only or Child is not a layer and we've inherited the stencil draw mode - ( isStencil || hitCheck.DescendActorHierarchy( ( *iter ).Get() ) ) ) // We are a stencil OR we can descend into child hierarchy + if ( !( *iter )->IsLayer() && // Child is NOT a layer, hit testing current layer only + ( hitCheck.DescendActorHierarchy( ( *iter ).Get() ) ) ) // We can descend into child hierarchy { - HitActor currentHit( HitTestWithinLayer( (*iter->Get()), - renderTask, - exclusives, - rayOrigin, - rayDir, - nearClippingPlane, - farClippingPlane, - hitCheck, - stencilOnLayer, - stencilHit, - isStencil, - layerIs3d) ); + HitActor currentHit( HitTestWithinLayer( ( *iter->Get() ), + renderTask, + exclusives, + rayOrigin, + rayDir, + nearClippingPlane, + farClippingPlane, + hitCheck, + overlayHit, + layerIs3d, + newClippingDepth, + clippingBitPlaneMask ) ); bool updateChildHit = false; - if ( currentHit.distance >= 0.0f ) + if( currentHit.distance >= 0.0f ) { if( layerIs3d ) { updateChildHit = ( ( currentHit.depth > childHit.depth ) || - ( ( currentHit.depth == childHit.depth ) && ( currentHit.distance < childHit.distance ) ) ); + ( ( currentHit.depth == childHit.depth ) && ( currentHit.distance < childHit.distance ) ) ); } else { @@ -283,17 +313,18 @@ HitActor HitTestWithinLayer( Actor& actor, } } - if ( updateChildHit ) + if( updateChildHit ) { if( !parentIsRenderable || currentHit.depth > hit.depth || ( layerIs3d && ( currentHit.depth == hit.depth && currentHit.distance < hit.distance )) ) - { - childHit = currentHit; - } + { + childHit = currentHit; + } } } } } + return ( childHit.actor ) ? childHit : hit; } @@ -306,13 +337,11 @@ bool IsWithinSourceActors( const Actor& sourceActor, const Actor& actor ) { return true; } - else + + Actor* parent = actor.GetParent(); + if ( parent ) { - Actor* parent = actor.GetParent(); - if ( parent ) - { - return IsWithinSourceActors( sourceActor, *parent ); - } + return IsWithinSourceActors( sourceActor, *parent ); } // Not within source actors @@ -326,28 +355,28 @@ inline bool IsActuallyHittable( Layer& layer, const Vector2& screenCoordinates, { bool hittable( true ); - if(layer.IsClipping()) + if( layer.IsClipping() ) { ClippingBox box = layer.GetClippingBox(); - if( screenCoordinates.x < box.x || - screenCoordinates.x > box.x + box.width || - screenCoordinates.y < stageSize.y - (box.y + box.height) || - screenCoordinates.y > stageSize.y - box.y) + if( screenCoordinates.x < static_cast( box.x )|| + screenCoordinates.x > static_cast( box.x + box.width )|| + screenCoordinates.y < stageSize.y - static_cast( box.y + box.height ) || + screenCoordinates.y > stageSize.y - static_cast( box.y ) ) { // Not touchable if clipping is enabled in the layer and the screen coordinate is outside the clip region. hittable = false; } } - if(hittable) + if( hittable ) { Actor* actor( &layer ); // Ensure that we can descend into the layer's (or any of its parent's) hierarchy. - while ( actor && hittable ) + while( actor && hittable ) { - if ( ! hitCheck.DescendActorHierarchy( actor ) ) + if( ! hitCheck.DescendActorHierarchy( actor ) ) { hittable = false; break; @@ -372,8 +401,8 @@ void GetCameraClippingPlane( RenderTask& renderTask, float& nearClippingPlane, f /** * Hit test a RenderTask */ -bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives, - Stage& stage, +bool HitTestRenderTask( const RenderTaskList::ExclusivesContainer& exclusives, + const Vector2& sceneSize, LayerList& layers, RenderTask& renderTask, Vector2 screenCoordinates, @@ -384,26 +413,26 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives, { Viewport viewport; renderTask.GetViewport( viewport ); - if( screenCoordinates.x < viewport.x || - screenCoordinates.x > viewport.x + viewport.width || - screenCoordinates.y < viewport.y || - screenCoordinates.y > viewport.y + viewport.height ) + if( screenCoordinates.x < static_cast( viewport.x ) || + screenCoordinates.x > static_cast( viewport.x + viewport.width ) || + screenCoordinates.y < static_cast( viewport.y ) || + screenCoordinates.y > static_cast( viewport.y + viewport.height ) ) { // The screen coordinate is outside the viewport of render task. The viewport clips all layers. return false; } float nearClippingPlane, farClippingPlane; - GetCameraClippingPlane(renderTask, nearClippingPlane, farClippingPlane); + GetCameraClippingPlane( renderTask, nearClippingPlane, farClippingPlane ); // Determine the layer depth of the source actor Actor* sourceActor( renderTask.GetSourceActor() ); - if ( sourceActor ) + if( sourceActor ) { Dali::Layer layer( sourceActor->GetLayer() ); - if ( layer ) + if( layer ) { - const unsigned int sourceActorDepth( layer.GetDepth() ); + const uint32_t sourceActorDepth( layer.GetDepth() ); CameraActor* cameraActor = renderTask.GetCameraActor(); bool pickingPossible = cameraActor->BuildPickingRay( @@ -418,24 +447,19 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives, // Hit test starting with the top layer, working towards the bottom layer. HitActor hit; - bool stencilOnLayer = false; - bool stencilHit = false; + bool overlayHit = false; bool layerConsumesHit = false; - const Vector2& stageSize = stage.GetSize(); - - for (int i=layers.GetLayerCount()-1; i>=0 && !(hit.actor); --i) + for( int32_t i = layers.GetLayerCount() - 1; i >= 0 && !( hit.actor ); --i ) { - Layer* layer( layers.GetLayer(i) ); - HitActor previousHit = hit; - stencilOnLayer = false; - stencilHit = false; + Layer* layer( layers.GetLayer( i ) ); + overlayHit = false; // Ensure layer is touchable (also checks whether ancestors are also touchable) - if ( IsActuallyHittable ( *layer, screenCoordinates, stageSize, hitCheck ) ) + if( IsActuallyHittable( *layer, screenCoordinates, sceneSize, hitCheck ) ) { // Always hit-test the source actor; otherwise test whether the layer is below the source actor in the hierarchy - if ( sourceActorDepth == static_cast(i) ) + if( sourceActorDepth == static_cast( i ) ) { // Recursively hit test the source actor & children, without crossing into other layers. hit = HitTestWithinLayer( *sourceActor, @@ -446,12 +470,12 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives, nearClippingPlane, farClippingPlane, hitCheck, - stencilOnLayer, - stencilHit, - false, - layer->GetBehavior() == Dali::Layer::LAYER_3D); + overlayHit, + layer->GetBehavior() == Dali::Layer::LAYER_3D, + 0u, + 0u ); } - else if ( IsWithinSourceActors( *sourceActor, *layer ) ) + else if( IsWithinSourceActors( *sourceActor, *layer ) ) { // Recursively hit test all the actors, without crossing into other layers. hit = HitTestWithinLayer( *layer, @@ -462,36 +486,31 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives, nearClippingPlane, farClippingPlane, hitCheck, - stencilOnLayer, - stencilHit, - false, - layer->GetBehavior() == Dali::Layer::LAYER_3D); - } - - // If a stencil on this layer hasn't been hit, then discard hit results for this layer if our current hit actor is renderable - if ( stencilOnLayer && !stencilHit && - hit.actor && hit.actor->IsRenderable() ) - { - hit = previousHit; + overlayHit, + layer->GetBehavior() == Dali::Layer::LAYER_3D, + 0u, + 0u ); } // If this layer is set to consume the hit, then do not check any layers behind it - if ( hitCheck.DoesLayerConsumeHit( layer ) ) + if( hitCheck.DoesLayerConsumeHit( layer ) ) { layerConsumesHit = true; break; } } } - if ( hit.actor ) + + if( hit.actor ) { - results.renderTask = Dali::RenderTask(&renderTask); - results.actor = Dali::Actor(hit.actor); - results.actorCoordinates.x = hit.x; - results.actorCoordinates.y = hit.y; + results.renderTask = RenderTaskPtr( &renderTask ); + results.actor = Dali::Actor( hit.actor ); + results.actorCoordinates = hit.hitPosition; + return true; // Success } - else if ( layerConsumesHit ) + + if( layerConsumesHit ) { return true; // Also success if layer is consuming the hit } @@ -502,90 +521,93 @@ bool HitTestRenderTask( const Vector< RenderTaskList::Exclusive >& exclusives, } /** - * Iterate through RenderTaskList and perform hit test. + * Iterate through the RenderTaskList and perform hit testing. * - * @return true if we have a hit, false otherwise + * @param[in] sceneSize The scene size the tests will be performed in + * @param[in] layers The list of layers to test + * @param[in] taskList The list of render tasks + * @param[out] results Ray information calculated by the camera + * @param[in] hitCheck The hit testing interface object to use + * @param[in] onScreen True to test on-screen, false to test off-screen + * @return True if we have a hit, false otherwise */ -bool HitTestForEachRenderTask( Stage& stage, - LayerList& layers, - RenderTaskList& taskList, - const Vector2& screenCoordinates, - Results& results, - HitTestInterface& hitCheck ) +bool HitTestRenderTaskList( const Vector2& sceneSize, + LayerList& layers, + RenderTaskList& taskList, + const Vector2& screenCoordinates, + Results& results, + HitTestInterface& hitCheck, + bool onScreen ) { RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks(); RenderTaskList::RenderTaskContainer::reverse_iterator endIter = tasks.rend(); + const auto& exclusives = taskList.GetExclusivesList(); - const Vector< RenderTaskList::Exclusive >& exclusives = taskList.GetExclusivesList(); - - // Check onscreen tasks before offscreen ones, hit test order should be reverse of draw order (see ProcessRenderTasks() where offscreen tasks are drawn first). - - // on screen - for ( RenderTaskList::RenderTaskContainer::reverse_iterator iter = tasks.rbegin(); endIter != iter; ++iter ) + for( RenderTaskList::RenderTaskContainer::reverse_iterator iter = tasks.rbegin(); endIter != iter; ++iter ) { - RenderTask& renderTask = GetImplementation( *iter ); - Dali::FrameBufferImage frameBufferImage = renderTask.GetTargetFrameBuffer(); - - // Note that if frameBufferImage is NULL we are using the default (on screen) render target - if(frameBufferImage) + RenderTask& renderTask = *iter->Get(); + bool isOffscreenRenderTask = ( renderTask.GetTargetFrameBuffer() || renderTask.GetFrameBuffer() ); + if( (onScreen && isOffscreenRenderTask) || (!onScreen && !isOffscreenRenderTask) ) { - ResourceId id = GetImplementation(frameBufferImage).GetResourceId(); - - // on screen only - if(0 != id) - { - // Skip to next task - continue; - } + // Skip to next task + continue; } - if ( HitTestRenderTask( exclusives, stage, layers, renderTask, screenCoordinates, results, hitCheck ) ) + if( HitTestRenderTask( exclusives, sceneSize, layers, renderTask, screenCoordinates, results, hitCheck ) ) { // Return true when an actor is hit (or layer in our render-task consumes the hit) return true; // don't bother checking off screen tasks } } - // off screen - for ( RenderTaskList::RenderTaskContainer::reverse_iterator iter = tasks.rbegin(); endIter != iter; ++iter ) - { - RenderTask& renderTask = GetImplementation( *iter ); - Dali::FrameBufferImage frameBufferImage = renderTask.GetTargetFrameBuffer(); - - // Note that if frameBufferImage is NULL we are using the default (on screen) render target - if(frameBufferImage) - { - ResourceId id = GetImplementation(frameBufferImage).GetResourceId(); + return false; +} - // off screen only - if(0 == id) - { - // Skip to next task - continue; - } +/** + * Iterate through the RenderTaskList and perform hit testing for both on-screen and off-screen. + * + * @param[in] sceneSize The scene size the tests will be performed in + * @param[in] layers The list of layers to test + * @param[in] taskList The list of render tasks + * @param[out] results Ray information calculated by the camera + * @param[in] hitCheck The hit testing interface object to use + * @param[in] onScreen True to test on-screen, false to test off-screen + * @return True if we have a hit, false otherwise + */ +bool HitTestForEachRenderTask( const Vector2& sceneSize, + LayerList& layers, + RenderTaskList& taskList, + const Vector2& screenCoordinates, + Results& results, + HitTestInterface& hitCheck ) +{ + bool result = false; - if ( HitTestRenderTask( exclusives, stage, layers, renderTask, screenCoordinates, results, hitCheck ) ) - { - // Return true when an actor is hit (or a layer in our render-task consumes the hit) - return true; - } - } + // Check on-screen tasks before off-screen ones. + // Hit test order should be reverse of draw order (see ProcessRenderTasks() where off-screen tasks are drawn first). + if( HitTestRenderTaskList( sceneSize, layers, taskList, screenCoordinates, results, hitCheck, true ) || + HitTestRenderTaskList( sceneSize, layers, taskList, screenCoordinates, results, hitCheck, false ) ) + { + // Found hit. + result = true; } - return false; + + return result; } } // unnamed namespace -bool HitTest( Stage& stage, const Vector2& screenCoordinates, Dali::HitTestAlgorithm::Results& results, Dali::HitTestAlgorithm::HitTestFunction func ) +HitTestInterface::~HitTestInterface() { - bool wasHit( false ); - // Hit-test the regular on-stage actors - RenderTaskList& taskList = stage.GetRenderTaskList(); - LayerList& layerList = stage.GetLayerList(); +} +bool HitTest( const Vector2& sceneSize, RenderTaskList& taskList, LayerList& layerList, const Vector2& screenCoordinates, Dali::HitTestAlgorithm::Results& results, Dali::HitTestAlgorithm::HitTestFunction func ) +{ + bool wasHit( false ); + // Hit-test the regular on-scene actors Results hitTestResults; HitTestFunctionWrapper hitTestFunctionWrapper( func ); - if ( HitTestForEachRenderTask( stage, layerList, taskList, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) ) + if( HitTestForEachRenderTask( sceneSize, layerList, taskList, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) ) { results.actor = hitTestResults.actor; results.actorCoordinates = hitTestResults.actorCoordinates; @@ -594,53 +616,22 @@ bool HitTest( Stage& stage, const Vector2& screenCoordinates, Dali::HitTestAlgor return wasHit; } -bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results, HitTestInterface& hitTestInterface ) +bool HitTest( const Vector2& sceneSize, RenderTaskList& renderTaskList, LayerList& layerList, const Vector2& screenCoordinates, Results& results, HitTestInterface& hitTestInterface ) { bool wasHit( false ); - // Hit-test the system-overlay actors first - SystemOverlay* systemOverlay = stage.GetSystemOverlayInternal(); - - if ( systemOverlay ) + // Hit-test the regular on-scene actors + if( !wasHit ) { - RenderTaskList& overlayTaskList = systemOverlay->GetOverlayRenderTasks(); - LayerList& overlayLayerList = systemOverlay->GetLayerList(); - - wasHit = HitTestForEachRenderTask( stage, overlayLayerList, overlayTaskList, screenCoordinates, results, hitTestInterface ); - } - - // Hit-test the regular on-stage actors - if ( !wasHit ) - { - RenderTaskList& taskList = stage.GetRenderTaskList(); - LayerList& layerList = stage.GetLayerList(); - - wasHit = HitTestForEachRenderTask( stage, layerList, taskList, screenCoordinates, results, hitTestInterface ); + wasHit = HitTestForEachRenderTask( sceneSize, layerList, renderTaskList, screenCoordinates, results, hitTestInterface ); } return wasHit; } -bool HitTest( Stage& stage, const Vector2& screenCoordinates, Results& results ) +bool HitTest( const Vector2& sceneSize, RenderTaskList& renderTaskList, LayerList& layerList, const Vector2& screenCoordinates, Results& results ) { ActorTouchableCheck actorTouchableCheck; - return HitTest( stage, screenCoordinates, results, actorTouchableCheck ); -} - -bool HitTest( Stage& stage, RenderTask& renderTask, const Vector2& screenCoordinates, - Dali::HitTestAlgorithm::Results& results, Dali::HitTestAlgorithm::HitTestFunction func ) -{ - bool wasHit( false ); - Results hitTestResults; - - const Vector< RenderTaskList::Exclusive >& exclusives = stage.GetRenderTaskList().GetExclusivesList(); - HitTestFunctionWrapper hitTestFunctionWrapper( func ); - if ( HitTestRenderTask( exclusives, stage, stage.GetLayerList(), renderTask, screenCoordinates, hitTestResults, hitTestFunctionWrapper ) ) - { - results.actor = hitTestResults.actor; - results.actorCoordinates = hitTestResults.actorCoordinates; - wasHit = true; - } - return wasHit; + return HitTest( sceneSize, renderTaskList, layerList, screenCoordinates, results, actorTouchableCheck ); } } // namespace HitTestAlgorithm