2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <cstdint> // uint32_t, uint16_t etc
23 #include <dali/public-api/rendering/renderer.h>
24 #include <dali/public-api/rendering/texture.h>
25 #include <dali/public-api/rendering/texture-set.h>
26 #include <dali/public-api/rendering/frame-buffer.h>
29 #include "shared/utility.h" // DemoHelper::LoadTexture
33 namespace // unnamed namespace for constants
35 const char * const BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-2.jpg" );
36 const float GRAVITY_X(0);
37 const float GRAVITY_Y(-0.09);
39 // number of metaballs
40 constexpr uint32_t METABALL_NUMBER = 6;
43 * Vertex shader for metaballs
45 const char* const METABALL_VERTEX_SHADER = DALI_COMPOSE_SHADER (
46 attribute mediump vec2 aPosition;\n
47 attribute mediump vec2 aTexture;\n
48 uniform mediump mat4 uMvpMatrix;\n
49 uniform mediump vec3 uSize;\n
50 uniform lowp vec4 uColor;\n
51 varying mediump vec2 vTexCoord;\n
55 mediump vec4 vertexPosition = vec4(aPosition.x, aPosition.y, 0.0, 1.0);\n
56 vertexPosition = uMvpMatrix * vertexPosition;\n
57 gl_Position = vertexPosition;\n
58 vTexCoord = aTexture;\n
63 * Fragment shader for metaballs
65 const char* const METABALL_FRAG_SHADER = DALI_COMPOSE_SHADER (
66 precision mediump float;\n
67 varying vec2 vTexCoord;\n
68 uniform vec2 uPositionMetaball;\n
69 uniform vec2 uPositionVar;\n
70 uniform vec2 uGravityVector;\n
71 uniform float uRadius;\n
72 uniform float uRadiusVar;\n
73 uniform float uAspect;\n
76 vec2 adjustedCoords = vTexCoord * 2.0 - 1.0;\n
77 vec2 finalMetaballPosition = uPositionMetaball + uGravityVector + uPositionVar;\n
79 float distance = (adjustedCoords.x - finalMetaballPosition.x) * (adjustedCoords.x - finalMetaballPosition.x) +
80 (adjustedCoords.y - finalMetaballPosition.y) * (adjustedCoords.y - finalMetaballPosition.y);\n
81 float finalRadius = uRadius + uRadiusVar;\n
82 float color = finalRadius / sqrt( distance );\n
83 vec2 bordercolor = vec2(0.0,0.0);\n
84 if (vTexCoord.x < 0.1)\n
86 bordercolor.x = (0.1 - vTexCoord.x) * 0.8;\n
88 if (vTexCoord.x > 0.9)\n
90 bordercolor.x = (vTexCoord.x - 0.9) * 0.8;\n
92 if (vTexCoord.y < 0.1)\n
94 bordercolor.y = (0.1 - vTexCoord.y) * 0.8;\n
96 if (vTexCoord.y > (0.9 * uAspect))\n
98 bordercolor.y = (vTexCoord.y - (0.9 * uAspect)) * 0.8;\n
100 float border = (bordercolor.x + bordercolor.y) * 0.5;\n
101 gl_FragColor = vec4(color + border,color + border,color + border,1.0);\n
106 * Fragment shader code for metaball and background composition with refraction effect
108 const char* const REFRACTION_FRAG_SHADER = DALI_COMPOSE_SHADER (
109 precision mediump float;\n
110 varying vec2 vTexCoord;\n
111 uniform sampler2D sTexture;\n
112 uniform sampler2D sEffect;\n
115 vec4 metaColor = texture2D(sEffect, vTexCoord);\n
117 float bright = 1.0;\n
118 if (metaColor.r > 0.85)\n
120 zoomCoords = ((vTexCoord - 0.5) * 0.95) + 0.5;\n
122 else if (metaColor.r > 0.78)\n
124 float interpolation = mix(0.95, 1.05, (0.85 - metaColor.r) * 50.0);\n
125 zoomCoords = ((vTexCoord - 0.5) * interpolation) + 0.5;\n
130 zoomCoords = vTexCoord;\n
133 gl_FragColor = texture2D(sTexture, zoomCoords) * bright;\n
138 * Fragment shader code when there's no effect
140 const char* const FRAG_SHADER = DALI_COMPOSE_SHADER (
141 precision mediump float;\n
142 varying vec2 vTexCoord;\n
143 uniform sampler2D sTexture;\n
146 gl_FragColor = texture2D(sTexture, vTexCoord);\n
151 * Metadata for each ball
160 //Properties needed for animations
161 Property::Index positionIndex;
162 Property::Index positionVarIndex;
163 Property::Index gravityIndex;
164 Property::Index radiusIndex;
165 Property::Index radiusVarIndex;
166 Property::Index aspectIndex;
169 } // unnamed namespace
172 * Demo using Metaballs
174 * When the metaball is clicked it starts to grow and fuses into the closest edge of screen
176 class MetaballRefracController : public ConnectionTracker
184 MetaballRefracController( Application& application );
189 virtual ~MetaballRefracController();
192 * Creates the metaballs and initializes the scene
194 void Create( Application& app );
197 * Touch handler, start the grow animation and creates additional metaballs
199 bool OnTouch( Actor actor, const TouchData& touch );
202 * Key event callback to quit the application on escape or back key
204 void OnKeyEvent( const KeyEvent& event );
208 Application& mApplication;
211 Texture mBackgroundTexture;
212 FrameBuffer mMetaballFBO;
213 Texture mMetaballFBOTexture;
216 MetaballInfo mMetaballs[METABALL_NUMBER];
218 Actor mCompositionActor;
221 Vector2 mCurrentTouchPosition;
222 Vector2 mMetaballPosVariation;
223 Vector2 mMetaballPosVariationFrom;
224 Vector2 mMetaballPosVariationTo;
225 Vector2 mMetaballCenter;
230 Renderer mRendererRefraction;
231 TextureSet mTextureSetRefraction;
232 Shader mShaderRefraction;
233 TextureSet mTextureSetNormal;
234 Shader mShaderNormal;
237 Animation mGravityAnimation[METABALL_NUMBER];
238 Animation mRadiusDecAnimation[METABALL_NUMBER];
239 Animation mRadiusIncFastAnimation[METABALL_NUMBER];
240 Animation mRadiusIncSlowAnimation[METABALL_NUMBER];
241 Animation mRadiusVarAnimation[METABALL_NUMBER];
242 Animation mPositionVarAnimation[METABALL_NUMBER];
244 // Private Helper functions
247 * Create a mesh data with the geometry for the metaball rendering
248 * @param aspectMappedTexture whether texture coords should be mapped based on aspect ratio
250 Geometry CreateGeometry( bool aspectMappedTexture = true );
253 * Create a actor for the metaballs
255 void CreateMetaballActors();
258 * Create the render task and FBO to render the metaballs into a texture
260 void CreateMetaballImage();
263 * Create the the final composition
265 void CreateComposition();
268 * Create all the metaballs animations (gravity, movement, size, etc.)
270 void CreateAnimations();
273 * Function to launch the grow slow radius for the metaballs, and also the small variations for metaball[2] and [3]
275 void LaunchRadiusIncSlowAnimations( Animation& source );
278 * Function to launch the animation to get the metaball[1] back to the center
280 void LaunchGetBackToPositionAnimation( Animation& source );
283 * Function to stop all animations related to the click of the user in the screen
285 void StopClickAnimations();
288 * Function to stop all animations related to the after click of the user in the screen
290 void StopAfterClickAnimations();
293 * Function that resets the sate of the different Metaballs
295 void ResetMetaballsState();
298 * Function to set the actual position of the metaballs when the user clicks the screen
300 void SetPositionToMetaballs( const Vector2& metaballCenter );
308 MetaballRefracController::MetaballRefracController( Application& application )
309 : mApplication( application )
311 // Connect to the Application's Init signal
312 mApplication.InitSignal().Connect( this, &MetaballRefracController::Create );
315 MetaballRefracController::~MetaballRefracController()
317 // Nothing to do here;
320 void MetaballRefracController::Create( Application& app )
322 Stage stage = Stage::GetCurrent();
324 stage.KeyEventSignal().Connect( this, &MetaballRefracController::OnKeyEvent );
326 mScreenSize = stage.GetSize();
328 stage.SetBackgroundColor(Color::BLACK);
330 // Load background texture
331 mBackgroundTexture = DemoHelper::LoadTexture( BACKGROUND_IMAGE );
333 mGravity = Vector2(GRAVITY_X,GRAVITY_Y);
334 mGravityVar = Vector2(0,0);
336 CreateMetaballActors();
337 CreateMetaballImage();
341 // Connect the callback to the touch signal on the mesh actor
342 stage.GetRootLayer().TouchSignal().Connect( this, &MetaballRefracController::OnTouch );
345 Geometry MetaballRefracController::CreateGeometry( bool aspectMappedTexture )
347 const float aspect = mScreenSize.y / mScreenSize.x;
349 // Create vertices and specify their color
350 const float xsize = mScreenSize.x * 0.5;
352 // Create the meshdata for the metaballs
353 struct VertexPosition { Vector2 position; };
354 struct VertexTexture { Vector2 texture; };
356 VertexPosition vertices[] =
358 { Vector2( -xsize, -xsize * aspect ) },
359 { Vector2( xsize, -xsize * aspect ) },
360 { Vector2( -xsize, xsize * aspect ) },
361 { Vector2( xsize, xsize * aspect ) }
364 const float textureAspect = (aspectMappedTexture) ? aspect : 1.0f;
365 VertexTexture textures[] =
367 { Vector2( 0.0f, 0.0f ) },
368 { Vector2( 1.0f, 0.0f ) },
369 { Vector2( 0.0f, 1.0f * textureAspect ) },
370 { Vector2( 1.0f, 1.0f * textureAspect ) }
373 uint32_t numberOfVertices = sizeof(vertices)/sizeof(VertexPosition);
376 Property::Map positionVertexFormat;
377 positionVertexFormat["aPosition"] = Property::VECTOR2;
378 PropertyBuffer positionVertices = PropertyBuffer::New( positionVertexFormat );
379 positionVertices.SetData( vertices, numberOfVertices );
382 Property::Map textureVertexFormat;
383 textureVertexFormat["aTexture"] = Property::VECTOR2;
384 PropertyBuffer textureVertices = PropertyBuffer::New( textureVertexFormat );
385 textureVertices.SetData( textures, numberOfVertices );
388 const uint16_t indices[] = { 0, 3, 1, 0, 2, 3 };
390 // Create the geometry object
391 Geometry texturedQuadGeometry = Geometry::New();
392 texturedQuadGeometry.AddVertexBuffer( positionVertices );
393 texturedQuadGeometry.AddVertexBuffer( textureVertices );
395 texturedQuadGeometry.SetIndexBuffer ( &indices[0], sizeof( indices )/ sizeof( indices[0] ) );
397 return texturedQuadGeometry;
400 void MetaballRefracController::CreateMetaballActors()
402 const float aspect = mScreenSize.y / mScreenSize.x;
404 // Create the renderer for the metaballs
405 Shader shader = Shader::New( METABALL_VERTEX_SHADER, METABALL_FRAG_SHADER, Shader::Hint::MODIFIES_GEOMETRY );
406 Geometry metaballGeometry = CreateGeometry();
407 Renderer renderer = Renderer::New( metaballGeometry, shader );
408 renderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
409 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::ONE );
410 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ONE );
411 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE );
412 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ONE );
414 // Each metaball has a different radius
415 mMetaballs[0].radius = mMetaballs[0].initRadius = 0.0145f;
416 mMetaballs[1].radius = mMetaballs[1].initRadius = 0.012f;
417 mMetaballs[2].radius = mMetaballs[2].initRadius = 0.0135f;
418 mMetaballs[3].radius = mMetaballs[3].initRadius = 0.0135f;
420 // Initialization of each of the metaballs
421 for( uint32_t i = 0 ; i < METABALL_NUMBER ; i++ )
423 mMetaballs[i].position = Vector2(0.0f, 0.0f);
425 mMetaballs[i].actor = Actor::New();
426 mMetaballs[i].actor.SetName( "Metaball" );
427 mMetaballs[i].actor.SetScale( 1.0f );
428 mMetaballs[i].actor.SetParentOrigin( ParentOrigin::CENTER );
431 mMetaballs[i].actor.AddRenderer( renderer );
433 mMetaballs[i].positionIndex = mMetaballs[i].actor.RegisterProperty( "uPositionMetaball", mMetaballs[i].position );
434 mMetaballs[i].positionVarIndex = mMetaballs[i].actor.RegisterProperty( "uPositionVar", Vector2(0.f,0.f) );
435 mMetaballs[i].gravityIndex = mMetaballs[i].actor.RegisterProperty( "uGravityVector", Vector2(0.f,0.f) );
436 mMetaballs[i].radiusIndex = mMetaballs[i].actor.RegisterProperty( "uRadius", mMetaballs[i].radius );
437 mMetaballs[i].radiusVarIndex = mMetaballs[i].actor.RegisterProperty( "uRadiusVar", 0.f );
438 mMetaballs[i].aspectIndex = mMetaballs[i].actor.RegisterProperty( "uAspect", aspect );
442 mMetaballRoot = Actor::New();
443 mMetaballRoot.SetParentOrigin( ParentOrigin::CENTER );
444 for( uint32_t i = 0 ; i < METABALL_NUMBER ; i++ )
446 mMetaballRoot.Add( mMetaballs[i].actor );
450 void MetaballRefracController::CreateMetaballImage()
452 // Create an FBO and a render task to create to render the metaballs with a fragment shader
453 Stage stage = Stage::GetCurrent();
454 mMetaballFBO = FrameBuffer::New( mScreenSize.x, mScreenSize.y, FrameBuffer::Attachment::NONE );
455 mMetaballFBOTexture = Texture::New( Dali::TextureType::TEXTURE_2D,
457 mScreenSize.x, mScreenSize.y );
458 mMetaballFBO.AttachColorTexture( mMetaballFBOTexture );
460 stage.Add(mMetaballRoot);
462 //Creation of the render task used to render the metaballs
463 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
464 RenderTask task = taskList.CreateTask();
465 task.SetRefreshRate( RenderTask::REFRESH_ALWAYS );
466 task.SetSourceActor( mMetaballRoot );
467 task.SetExclusive( true );
468 task.SetClearColor( Color::BLACK );
469 task.SetClearEnabled( true );
470 task.SetFrameBuffer( mMetaballFBO );
473 void MetaballRefracController::CreateComposition()
475 // Create Refraction shader and renderer
476 mShaderRefraction = Shader::New( METABALL_VERTEX_SHADER, REFRACTION_FRAG_SHADER );
478 // Create new texture set
479 mTextureSetRefraction = TextureSet::New();
480 mTextureSetRefraction.SetTexture( 0u, mBackgroundTexture );
481 mTextureSetRefraction.SetTexture( 1u, mMetaballFBOTexture );
483 // Create normal shader
484 mShaderNormal = Shader::New( METABALL_VERTEX_SHADER, FRAG_SHADER );
486 // Create new texture set
487 mTextureSetNormal = TextureSet::New();
488 mTextureSetNormal.SetTexture( 0u, mBackgroundTexture );
491 mCompositionActor = Actor::New( );
492 mCompositionActor.SetParentOrigin(ParentOrigin::CENTER);
493 mCompositionActor.SetPosition(Vector3(0.0f, 0.0f, 0.0f));
494 mCompositionActor.SetSize(mScreenSize.x, mScreenSize.y);
497 Geometry metaballGeometry = CreateGeometry( false );
498 mRendererRefraction = Renderer::New( metaballGeometry, mShaderNormal );
499 mRendererRefraction.SetTextures( mTextureSetNormal );
500 mCompositionActor.AddRenderer( mRendererRefraction );
502 Stage stage = Stage::GetCurrent();
503 stage.Add( mCompositionActor );
506 void MetaballRefracController::CreateAnimations()
511 mPositionVarAnimation[1] = Animation::New( 2.f );
512 mPositionVarAnimation[1].SetLooping( false );
513 mPositionVarAnimation[1].Pause();
514 mPositionVarAnimation[1].FinishedSignal().Connect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation );
516 KeyFrames keySinCosVariation = KeyFrames::New();
517 Vector2 sinCosVariation(0,0);
518 for( i = 0 ; i < 360; i++ )
520 sinCosVariation.x = 0.05f * ( -sinf(i * Math::PI_OVER_180) + cosf(i * Math::PI_OVER_180) );
521 sinCosVariation.y = 0.05f * ( sinf(i * Math::PI_OVER_180) - cosf(i * Math::PI_OVER_180) );
523 keySinCosVariation.Add(key, sinCosVariation);
526 mPositionVarAnimation[2] = Animation::New(6.f);
527 mPositionVarAnimation[2].AnimateBetween(Property( mMetaballs[2].actor, mMetaballs[2].positionVarIndex ), keySinCosVariation);
528 mPositionVarAnimation[2].SetLooping( true );
529 mPositionVarAnimation[2].Pause();
531 KeyFrames keyCosSinVariation = KeyFrames::New();
532 Vector2 cosSinVariation(0,0);
533 for( i = 0 ; i < 360; i++ )
535 cosSinVariation.x = 0.05f * ( -sinf(i * Math::PI_OVER_180) - cosf(i * Math::PI_OVER_180) );
536 cosSinVariation.y = 0.05f * ( sinf(i * Math::PI_OVER_180) + cosf(i * Math::PI_OVER_180) );
538 keyCosSinVariation.Add(key, cosSinVariation);
541 mPositionVarAnimation[3] = Animation::New(6.f);
542 mPositionVarAnimation[3].AnimateBetween(Property( mMetaballs[3].actor, mMetaballs[3].positionVarIndex ), keyCosSinVariation);
543 mPositionVarAnimation[3].SetLooping( true );
544 mPositionVarAnimation[3].Pause();
546 //Animations for gravity
547 for( i = 0 ; i < METABALL_NUMBER; i++ )
549 mGravityAnimation[i] = Animation::New( 25.f );
550 mGravityAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].gravityIndex ), mGravity * 25.f * 3.f );
551 mGravityAnimation[i].SetLooping( false );
552 mGravityAnimation[i].Pause();
555 //Animation to decrease size of metaballs when there is no click
556 for( i = 0 ; i < METABALL_NUMBER; i++ )
558 mRadiusDecAnimation[i] = Animation::New( 25.f );
559 mRadiusDecAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), -0.004f * 25.f * 3.f );
560 mRadiusDecAnimation[i].SetLooping( false );
561 mRadiusDecAnimation[i].Pause();
564 // Animation to grow the size of the metaballs the first second of the click
565 for( i = 0 ; i < METABALL_NUMBER; i++ )
567 mRadiusIncFastAnimation[i] = Animation::New( 0.3f );
568 mRadiusIncFastAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), 0.06f );
569 mRadiusIncFastAnimation[i].SetLooping( false );
570 mRadiusIncFastAnimation[i].Pause();
572 mRadiusIncFastAnimation[0].FinishedSignal().Connect( this, &MetaballRefracController::LaunchRadiusIncSlowAnimations );
574 // Animation to grow the size of the metaballs afterwards
575 for( i = 0 ; i < METABALL_NUMBER; i++ )
577 mRadiusIncSlowAnimation[i] = Animation::New( 20.f );
578 mRadiusIncSlowAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), 0.04f );
579 mRadiusIncSlowAnimation[i].SetLooping( false );
580 mRadiusIncSlowAnimation[i].Pause();
583 // Keyframes of a sin function
584 KeyFrames keySin = KeyFrames::New();
586 for( i = 0 ; i < 360; i++ )
588 val = 0.01f * sin(i * Math::PI/180.f);
590 keySin.Add(key, val);
593 //Animation to change the size of the metaball
594 mRadiusVarAnimation[2] = Animation::New( 8.f );
595 mRadiusVarAnimation[2].AnimateBetween( Property( mMetaballs[2].actor, mMetaballs[2].radiusVarIndex ), keySin );
596 mRadiusVarAnimation[2].SetLooping( true );
598 // Keyframes of a cos function
599 KeyFrames keyCos = KeyFrames::New();
600 for( i = 0 ; i < 360; i++ )
602 val = 0.01f * cos(i * Math::PI/180.f);
604 keyCos.Add(key, val);
607 //Animation to change the size of the metaball
608 mRadiusVarAnimation[3] = Animation::New( 8.f );
609 mRadiusVarAnimation[3].AnimateBetween( Property( mMetaballs[3].actor, mMetaballs[3].radiusVarIndex ), keyCos );
610 mRadiusVarAnimation[3].SetLooping( true );
613 void MetaballRefracController::LaunchGetBackToPositionAnimation( Animation& source )
615 mMetaballPosVariationTo = Vector2(0,0);
617 mPositionVarAnimation[1] = Animation::New( 1.f );
618 mPositionVarAnimation[1].SetLooping( false );
619 mPositionVarAnimation[1].AnimateTo(Property( mMetaballs[1].actor, mMetaballs[1].positionVarIndex ), Vector2(0,0) );
620 mPositionVarAnimation[1].Play();
623 void MetaballRefracController::LaunchRadiusIncSlowAnimations( Animation& source )
625 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
627 mRadiusIncSlowAnimation[i].Play();
629 mPositionVarAnimation[2].Play();
630 mPositionVarAnimation[3].Play();
633 void MetaballRefracController::StopClickAnimations()
635 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
637 mRadiusIncSlowAnimation[i].Stop();
638 mRadiusIncFastAnimation[i].Stop();
640 mPositionVarAnimation[1].Stop();
641 mPositionVarAnimation[2].Stop();
642 mPositionVarAnimation[3].Stop();
645 void MetaballRefracController::StopAfterClickAnimations()
647 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
649 mGravityAnimation[i].Stop();
650 mRadiusDecAnimation[i].Stop();
652 mMetaballs[i].radius = mMetaballs[i].initRadius;
654 mMetaballs[i].actor.SetProperty( mMetaballs[i].gravityIndex, Vector2(0,0) );
655 mMetaballs[i].actor.SetProperty( mMetaballs[i].radiusIndex, mMetaballs[i].radius );
656 mMetaballs[i].actor.SetProperty( mMetaballs[i].radiusVarIndex, 0.f );
658 mRadiusVarAnimation[2].Stop();
659 mRadiusVarAnimation[3].Stop();
662 void MetaballRefracController::ResetMetaballsState()
664 mRendererRefraction.SetTextures( mTextureSetNormal );
665 mRendererRefraction.SetShader( mShaderNormal );
667 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
669 mMetaballs[i].radius = mMetaballs[i].initRadius;
672 mMetaballPosVariationTo = Vector2(0,0);
673 mMetaballPosVariationFrom = Vector2(0,0);
674 mMetaballPosVariation = Vector2(0,0);
675 mGravityVar = Vector2(0,0);
678 void MetaballRefracController::SetPositionToMetaballs( const Vector2& metaballCenter )
680 //We set the position for the metaballs based on click position
681 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
683 mMetaballs[i].position = metaballCenter;
684 mMetaballs[i].actor.SetProperty( mMetaballs[i].positionIndex, mMetaballs[i].position );
688 bool MetaballRefracController::OnTouch( Actor actor, const TouchData& touch )
690 const float aspect = mScreenSize.y / mScreenSize.x;
691 switch( touch.GetState( 0 ) )
693 case PointState::DOWN:
695 StopAfterClickAnimations();
696 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
698 mRadiusIncFastAnimation[i].Play();
700 mRadiusVarAnimation[2].Play();
701 mRadiusVarAnimation[3].Play();
703 //We draw with the refraction-composition shader
704 mRendererRefraction.SetTextures( mTextureSetRefraction );
705 mRendererRefraction.SetShader( mShaderRefraction );
706 mCurrentTouchPosition = touch.GetScreenPosition( 0 );
708 //we use the click position for the metaballs
709 Vector2 metaballCenter = Vector2( (mCurrentTouchPosition.x / mScreenSize.x) - 0.5f,
710 (aspect * (mScreenSize.y - mCurrentTouchPosition.y) / mScreenSize.y) - 0.5f ) * 2.0f;
711 SetPositionToMetaballs(metaballCenter);
714 case PointState::MOTION:
716 Vector2 screen = touch.GetScreenPosition( 0 );
717 Vector2 displacement = screen - mCurrentTouchPosition;
718 mCurrentTouchPosition = screen;
720 mMetaballPosVariationTo.x += ( displacement.x / mScreenSize.x ) * 2.2f;
721 mMetaballPosVariationTo.y += (-displacement.y / mScreenSize.y ) * 2.2f;
723 if (mPositionVarAnimation[1])
725 mPositionVarAnimation[1].FinishedSignal().Disconnect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation );
726 mPositionVarAnimation[1].Stop();
728 mPositionVarAnimation[1] = Animation::New( 1.f );
729 mPositionVarAnimation[1].SetLooping( false );
730 mPositionVarAnimation[1].AnimateTo(Property( mMetaballs[1].actor, mMetaballs[1].positionVarIndex ), mMetaballPosVariationTo );
731 mPositionVarAnimation[1].FinishedSignal().Connect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation );
732 mPositionVarAnimation[1].Play();
734 //we use the click position for the metaballs
735 Vector2 metaballCenter = Vector2( (screen.x / mScreenSize.x) - 0.5f,
736 (aspect * (mScreenSize.y - screen.y) / mScreenSize.y) - 0.5f) * 2.0f;
737 SetPositionToMetaballs(metaballCenter);
741 case PointState::LEAVE:
742 case PointState::INTERRUPTED:
744 //Stop click animations
745 StopClickAnimations();
747 //Launch out of screen animations
748 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
750 mGravityAnimation[i].Play();
753 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
755 mRadiusDecAnimation[i].Play();
765 void MetaballRefracController::OnKeyEvent(const KeyEvent& event)
767 if( event.state == KeyEvent::Down )
769 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
779 int32_t DALI_EXPORT_API main( int argc, char **argv )
781 Application application = Application::New( &argc, &argv );
783 MetaballRefracController test( application );
784 application.MainLoop();