void RenderTaskBase::renderTask() { if (enable_bind_shader_ == true) shader_.bindAndConfigBasicUniforms(); //config global uniforms GlobalUniformConfig & global_uniform_config = GlobalUniformConfig::getSingleton(); global_uniform_config.configGlobalUniforms(); //set model transform const Matrix4f & model_trans = transform_.transformMatrix(); openGLSetCurBindShaderMat4("model_trans", model_trans); glVerify(glPushAttrib(GL_ALL_ATTRIB_BITS)); renderTaskImpl(); glVerify(glPopAttrib()); if (enable_bind_shader_ == true) shader_.unBind(); }
void PinchGestureProcessor::Process( const Integration::PinchGestureEvent& pinchEvent ) { switch ( pinchEvent.state ) { case Gesture::Started: { // The pinch gesture should only be sent to the gesture detector which first received it so that // it can be told when the gesture ends as well. mCurrentPinchEmitters.clear(); ResetActor(); HitTestAlgorithm::Results hitTestResults; if( HitTest( mStage, pinchEvent.centerPoint, hitTestResults ) ) { // Record the current render-task for Screen->Actor coordinate conversions mCurrentRenderTask = hitTestResults.renderTask; PinchEventFunctor functor( pinchEvent, *this ); // Sets mCurrentGesturedActor GestureDetectorContainer gestureDetectors; UpCastContainer<PinchGestureDetector>( mGestureDetectors, gestureDetectors ); ProcessAndEmit( hitTestResults, gestureDetectors, functor ); } break; } case Gesture::Continuing: case Gesture::Finished: case Gesture::Cancelled: { // Only send subsequent pinch gesture signals if we processed the pinch gesture when it started. // Check if actor is still touchable. if ( mCurrentGesturedActor ) { if ( mCurrentGesturedActor->IsHittable() && !mCurrentPinchEmitters.empty() && mCurrentRenderTask ) { // Ensure actor is still attached to the emitters, if it is not then remove the emitter. PinchGestureDetectorContainer::iterator endIter = std::remove_if( mCurrentPinchEmitters.begin(), mCurrentPinchEmitters.end(), IsNotAttachedFunctor(mCurrentGesturedActor) ); mCurrentPinchEmitters.erase( endIter, mCurrentPinchEmitters.end() ); if ( !mCurrentPinchEmitters.empty() ) { Vector2 actorCoords; RenderTask& renderTaskImpl( GetImplementation(mCurrentRenderTask) ); mCurrentGesturedActor->ScreenToLocal( renderTaskImpl, actorCoords.x, actorCoords.y, pinchEvent.centerPoint.x, pinchEvent.centerPoint.y ); EmitPinchSignal( Dali::Actor(mCurrentGesturedActor), mCurrentPinchEmitters, pinchEvent, actorCoords ); } else { // If we have no current emitters then clear pinched actor as well. ResetActor(); } // Clear current emitters if pinch gesture has ended or been cancelled. if ( pinchEvent.state == Gesture::Finished || pinchEvent.state == Gesture::Cancelled ) { mCurrentPinchEmitters.clear(); ResetActor(); } } else { mCurrentPinchEmitters.clear(); ResetActor(); } } break; } case Gesture::Clear: DALI_ASSERT_ALWAYS( false && "Incorrect state received from Integration layer: Clear\n" ); break; case Gesture::Possible: DALI_ASSERT_ALWAYS( false && "Incorrect state received from Integration layer: Possible\n" ); break; } }
bool PanGestureProcessor::CheckGestureDetector( GestureDetector* detector, Actor* actor ) { DALI_ASSERT_DEBUG( mCurrentPanEvent ); bool retVal( false ); PanGestureDetector* panDetector( static_cast< PanGestureDetector* >( detector ) ); if ( ( mCurrentPanEvent->numberOfTouches >= panDetector->GetMinimumTouchesRequired() ) && ( mCurrentPanEvent->numberOfTouches <= panDetector->GetMaximumTouchesRequired() ) ) { // Check if the detector requires directional panning. if ( panDetector->RequiresDirectionalPan() && mCurrentRenderTask ) { // It does, calculate the angle of the pan in local actor coordinates and ensures it fits // the detector's criteria. RenderTask& renderTaskImpl( GetImplementation( mCurrentRenderTask ) ); Vector2 startPosition, currentPosition; actor->ScreenToLocal( renderTaskImpl, startPosition.x, startPosition.y, mPossiblePanPosition.x, mPossiblePanPosition.y ); actor->ScreenToLocal( renderTaskImpl, currentPosition.x, currentPosition.y, mCurrentPanEvent->currentPosition.x, mCurrentPanEvent->currentPosition.y ); Vector2 displacement( currentPosition - startPosition ); Radian angle( atan( displacement.y / displacement.x ) ); ///////////////////////////// // | // // | // // Q3 (-,-) | Q4 (+,-) // // | // // ----------------- +x // // | // // Q2 (-,+) | Q1 (+,+) // // | // // | // // +y // ///////////////////////////// // Quadrant 1: As is // Quadrant 2: 180 degrees + angle // Quadrant 3: angle - 180 degrees // Quadrant 4: As is ///////////////////////////// if ( displacement.x < 0.0f ) { if ( displacement.y >= 0.0f ) { // Quadrant 2 angle.radian += Math::PI; } else { // Quadrant 3 angle.radian -= Math::PI; } } if ( panDetector->CheckAngleAllowed( angle ) ) { retVal = true; } } else { // Directional panning not required so we can use this actor and gesture detector. retVal = true; } } return retVal; }
void PanGestureProcessor::EmitPanSignal( Actor* actor, const GestureDetectorContainer& gestureDetectors, const Integration::PanGestureEvent& panEvent, Vector2 localCurrent, Gesture::State state, Dali::RenderTask renderTask ) { if ( actor && !gestureDetectors.empty() ) { PanGesture pan(state); pan.time = panEvent.time; pan.numberOfTouches = panEvent.numberOfTouches; pan.screenPosition = panEvent.currentPosition; pan.position = localCurrent; RenderTask& renderTaskImpl( GetImplementation( renderTask ) ); Vector2 localPrevious; actor->ScreenToLocal( renderTaskImpl, localPrevious.x, localPrevious.y, panEvent.previousPosition.x, panEvent.previousPosition.y ); pan.displacement = localCurrent - localPrevious; Vector2 previousPos( panEvent.previousPosition ); if ( state == Gesture::Started ) { previousPos = mPossiblePanPosition; } pan.screenDisplacement = panEvent.currentPosition - previousPos; // Avoid dividing by 0 if ( panEvent.timeDelta > 0 ) { pan.velocity.x = pan.displacement.x / panEvent.timeDelta; pan.velocity.y = pan.displacement.y / panEvent.timeDelta; pan.screenVelocity.x = pan.screenDisplacement.x / panEvent.timeDelta; pan.screenVelocity.y = pan.screenDisplacement.y / panEvent.timeDelta; } // When the gesture ends, we may incorrectly get a ZERO velocity (as we have lifted our finger without any movement) // so we should use the last recorded velocity instead in this scenario. if ( ( state == Gesture::Finished ) && ( pan.screenVelocity == Vector2::ZERO ) && ( panEvent.timeDelta < MAXIMUM_TIME_WITH_VALID_LAST_VELOCITY ) ) { pan.velocity = mLastVelocity; pan.screenVelocity = mLastScreenVelocity; } else { // Store the current velocity for future iterations. mLastVelocity = pan.velocity; mLastScreenVelocity = pan.screenVelocity; } if ( mSceneObject ) { // We update the scene object directly rather than sending a message. // Sending a message could cause unnecessary delays, the scene object ensure thread safe behaviour. mSceneObject->AddGesture( pan ); } Dali::Actor actorHandle( actor ); const GestureDetectorContainer::const_iterator endIter = gestureDetectors.end(); for ( GestureDetectorContainer::const_iterator iter = gestureDetectors.begin(); iter != endIter; ++iter ) { static_cast< PanGestureDetector* >( *iter )->EmitPanGestureSignal( actorHandle, pan ); } } }