2 * Copyright (c) 2020 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 TouchEvent& 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;
215 MetaballInfo mMetaballs[METABALL_NUMBER];
217 Actor mCompositionActor;
220 Vector2 mCurrentTouchPosition;
221 Vector2 mMetaballPosVariation;
222 Vector2 mMetaballPosVariationFrom;
223 Vector2 mMetaballPosVariationTo;
224 Vector2 mMetaballCenter;
229 Renderer mRendererRefraction;
230 TextureSet mTextureSetRefraction;
231 Shader mShaderRefraction;
232 TextureSet mTextureSetNormal;
233 Shader mShaderNormal;
236 Animation mGravityAnimation[METABALL_NUMBER];
237 Animation mRadiusDecAnimation[METABALL_NUMBER];
238 Animation mRadiusIncFastAnimation[METABALL_NUMBER];
239 Animation mRadiusIncSlowAnimation[METABALL_NUMBER];
240 Animation mRadiusVarAnimation[METABALL_NUMBER];
241 Animation mPositionVarAnimation[METABALL_NUMBER];
243 // Private Helper functions
246 * Create a mesh data with the geometry for the metaball rendering
247 * @param aspectMappedTexture whether texture coords should be mapped based on aspect ratio
249 Geometry CreateGeometry( bool aspectMappedTexture = true );
252 * Create a actor for the metaballs
254 void CreateMetaballActors();
257 * Create the render task and FBO to render the metaballs into a texture
259 void CreateMetaballImage();
262 * Create the the final composition
264 void CreateComposition();
267 * Create all the metaballs animations (gravity, movement, size, etc.)
269 void CreateAnimations();
272 * Function to launch the grow slow radius for the metaballs, and also the small variations for metaball[2] and [3]
274 void LaunchRadiusIncSlowAnimations( Animation& source );
277 * Function to launch the animation to get the metaball[1] back to the center
279 void LaunchGetBackToPositionAnimation( Animation& source );
282 * Function to stop all animations related to the click of the user in the screen
284 void StopClickAnimations();
287 * Function to stop all animations related to the after click of the user in the screen
289 void StopAfterClickAnimations();
292 * Function that resets the sate of the different Metaballs
294 void ResetMetaballsState();
297 * Function to set the actual position of the metaballs when the user clicks the screen
299 void SetPositionToMetaballs( const Vector2& metaballCenter );
307 MetaballRefracController::MetaballRefracController( Application& application )
308 : mApplication( application )
310 // Connect to the Application's Init signal
311 mApplication.InitSignal().Connect( this, &MetaballRefracController::Create );
314 MetaballRefracController::~MetaballRefracController()
316 // Nothing to do here;
319 void MetaballRefracController::Create( Application& app )
321 Window window = app.GetWindow();
323 window.KeyEventSignal().Connect( this, &MetaballRefracController::OnKeyEvent );
325 mScreenSize = window.GetSize();
327 window.SetBackgroundColor(Color::BLACK);
329 // Load background texture
330 mBackgroundTexture = DemoHelper::LoadTexture( BACKGROUND_IMAGE );
332 mGravity = Vector2(GRAVITY_X,GRAVITY_Y);
333 mGravityVar = Vector2(0,0);
335 CreateMetaballActors();
336 CreateMetaballImage();
340 // Connect the callback to the touch signal on the mesh actor
341 window.GetRootLayer().TouchSignal().Connect( this, &MetaballRefracController::OnTouch );
344 Geometry MetaballRefracController::CreateGeometry( bool aspectMappedTexture )
346 const float aspect = mScreenSize.y / mScreenSize.x;
348 // Create vertices and specify their color
349 const float xsize = mScreenSize.x * 0.5;
351 // Create the meshdata for the metaballs
352 struct VertexPosition { Vector2 position; };
353 struct VertexTexture { Vector2 texture; };
355 VertexPosition vertices[] =
357 { Vector2( -xsize, -xsize * aspect ) },
358 { Vector2( xsize, -xsize * aspect ) },
359 { Vector2( -xsize, xsize * aspect ) },
360 { Vector2( xsize, xsize * aspect ) }
363 const float textureAspect = (aspectMappedTexture) ? aspect : 1.0f;
364 VertexTexture textures[] =
366 { Vector2( 0.0f, 0.0f ) },
367 { Vector2( 1.0f, 0.0f ) },
368 { Vector2( 0.0f, 1.0f * textureAspect ) },
369 { Vector2( 1.0f, 1.0f * textureAspect ) }
372 uint32_t numberOfVertices = sizeof(vertices)/sizeof(VertexPosition);
375 Property::Map positionVertexFormat;
376 positionVertexFormat["aPosition"] = Property::VECTOR2;
377 PropertyBuffer positionVertices = PropertyBuffer::New( positionVertexFormat );
378 positionVertices.SetData( vertices, numberOfVertices );
381 Property::Map textureVertexFormat;
382 textureVertexFormat["aTexture"] = Property::VECTOR2;
383 PropertyBuffer textureVertices = PropertyBuffer::New( textureVertexFormat );
384 textureVertices.SetData( textures, numberOfVertices );
387 const uint16_t indices[] = { 0, 3, 1, 0, 2, 3 };
389 // Create the geometry object
390 Geometry texturedQuadGeometry = Geometry::New();
391 texturedQuadGeometry.AddVertexBuffer( positionVertices );
392 texturedQuadGeometry.AddVertexBuffer( textureVertices );
394 texturedQuadGeometry.SetIndexBuffer ( &indices[0], sizeof( indices )/ sizeof( indices[0] ) );
396 return texturedQuadGeometry;
399 void MetaballRefracController::CreateMetaballActors()
401 const float aspect = mScreenSize.y / mScreenSize.x;
403 // Create the renderer for the metaballs
404 Shader shader = Shader::New( METABALL_VERTEX_SHADER, METABALL_FRAG_SHADER, Shader::Hint::MODIFIES_GEOMETRY );
405 Geometry metaballGeometry = CreateGeometry();
406 Renderer renderer = Renderer::New( metaballGeometry, shader );
407 renderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
408 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::ONE );
409 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ONE );
410 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE );
411 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ONE );
413 // Each metaball has a different radius
414 mMetaballs[0].radius = mMetaballs[0].initRadius = 0.0145f;
415 mMetaballs[1].radius = mMetaballs[1].initRadius = 0.012f;
416 mMetaballs[2].radius = mMetaballs[2].initRadius = 0.0135f;
417 mMetaballs[3].radius = mMetaballs[3].initRadius = 0.0135f;
419 // Initialization of each of the metaballs
420 for( uint32_t i = 0 ; i < METABALL_NUMBER ; i++ )
422 mMetaballs[i].position = Vector2(0.0f, 0.0f);
424 mMetaballs[i].actor = Actor::New();
425 mMetaballs[i].actor.SetProperty( Dali::Actor::Property::NAME, "Metaball" );
426 mMetaballs[i].actor.SetProperty( Actor::Property::SCALE, 1.0f );
427 mMetaballs[i].actor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
430 mMetaballs[i].actor.AddRenderer( renderer );
432 mMetaballs[i].positionIndex = mMetaballs[i].actor.RegisterProperty( "uPositionMetaball", mMetaballs[i].position );
433 mMetaballs[i].positionVarIndex = mMetaballs[i].actor.RegisterProperty( "uPositionVar", Vector2(0.f,0.f) );
434 mMetaballs[i].gravityIndex = mMetaballs[i].actor.RegisterProperty( "uGravityVector", Vector2(0.f,0.f) );
435 mMetaballs[i].radiusIndex = mMetaballs[i].actor.RegisterProperty( "uRadius", mMetaballs[i].radius );
436 mMetaballs[i].radiusVarIndex = mMetaballs[i].actor.RegisterProperty( "uRadiusVar", 0.f );
437 mMetaballs[i].aspectIndex = mMetaballs[i].actor.RegisterProperty( "uAspect", aspect );
441 mMetaballRoot = Actor::New();
442 mMetaballRoot.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
443 for( uint32_t i = 0 ; i < METABALL_NUMBER ; i++ )
445 mMetaballRoot.Add( mMetaballs[i].actor );
449 void MetaballRefracController::CreateMetaballImage()
451 // Create an FBO and a render task to create to render the metaballs with a fragment shader
452 Window window = mApplication.GetWindow();
453 mMetaballFBO = FrameBuffer::New( mScreenSize.x, mScreenSize.y );
455 window.Add(mMetaballRoot);
457 //Creation of the render task used to render the metaballs
458 RenderTaskList taskList = window.GetRenderTaskList();
459 RenderTask task = taskList.CreateTask();
460 task.SetRefreshRate( RenderTask::REFRESH_ALWAYS );
461 task.SetSourceActor( mMetaballRoot );
462 task.SetExclusive( true );
463 task.SetClearColor( Color::BLACK );
464 task.SetClearEnabled( true );
465 task.SetFrameBuffer( mMetaballFBO );
468 void MetaballRefracController::CreateComposition()
470 // Create Refraction shader and renderer
471 mShaderRefraction = Shader::New( METABALL_VERTEX_SHADER, REFRACTION_FRAG_SHADER );
473 // Create new texture set
474 mTextureSetRefraction = TextureSet::New();
475 mTextureSetRefraction.SetTexture( 0u, mBackgroundTexture );
476 mTextureSetRefraction.SetTexture( 1u, mMetaballFBO.GetColorTexture() );
478 // Create normal shader
479 mShaderNormal = Shader::New( METABALL_VERTEX_SHADER, FRAG_SHADER );
481 // Create new texture set
482 mTextureSetNormal = TextureSet::New();
483 mTextureSetNormal.SetTexture( 0u, mBackgroundTexture );
486 mCompositionActor = Actor::New( );
487 mCompositionActor.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::CENTER);
488 mCompositionActor.SetProperty( Actor::Property::POSITION, Vector3(0.0f, 0.0f, 0.0f));
489 mCompositionActor.SetProperty( Actor::Property::SIZE, Vector2(mScreenSize.x, mScreenSize.y) );
492 Geometry metaballGeometry = CreateGeometry( false );
493 mRendererRefraction = Renderer::New( metaballGeometry, mShaderNormal );
494 mRendererRefraction.SetTextures( mTextureSetNormal );
495 mCompositionActor.AddRenderer( mRendererRefraction );
497 Window window = mApplication.GetWindow();
498 window.Add( mCompositionActor );
501 void MetaballRefracController::CreateAnimations()
506 mPositionVarAnimation[1] = Animation::New( 2.f );
507 mPositionVarAnimation[1].SetLooping( false );
508 mPositionVarAnimation[1].Pause();
509 mPositionVarAnimation[1].FinishedSignal().Connect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation );
511 KeyFrames keySinCosVariation = KeyFrames::New();
512 Vector2 sinCosVariation(0,0);
513 for( i = 0 ; i < 360; i++ )
515 sinCosVariation.x = 0.05f * ( -sinf(i * Math::PI_OVER_180) + cosf(i * Math::PI_OVER_180) );
516 sinCosVariation.y = 0.05f * ( sinf(i * Math::PI_OVER_180) - cosf(i * Math::PI_OVER_180) );
518 keySinCosVariation.Add(key, sinCosVariation);
521 mPositionVarAnimation[2] = Animation::New(6.f);
522 mPositionVarAnimation[2].AnimateBetween(Property( mMetaballs[2].actor, mMetaballs[2].positionVarIndex ), keySinCosVariation);
523 mPositionVarAnimation[2].SetLooping( true );
524 mPositionVarAnimation[2].Pause();
526 KeyFrames keyCosSinVariation = KeyFrames::New();
527 Vector2 cosSinVariation(0,0);
528 for( i = 0 ; i < 360; i++ )
530 cosSinVariation.x = 0.05f * ( -sinf(i * Math::PI_OVER_180) - cosf(i * Math::PI_OVER_180) );
531 cosSinVariation.y = 0.05f * ( sinf(i * Math::PI_OVER_180) + cosf(i * Math::PI_OVER_180) );
533 keyCosSinVariation.Add(key, cosSinVariation);
536 mPositionVarAnimation[3] = Animation::New(6.f);
537 mPositionVarAnimation[3].AnimateBetween(Property( mMetaballs[3].actor, mMetaballs[3].positionVarIndex ), keyCosSinVariation);
538 mPositionVarAnimation[3].SetLooping( true );
539 mPositionVarAnimation[3].Pause();
541 //Animations for gravity
542 for( i = 0 ; i < METABALL_NUMBER; i++ )
544 mGravityAnimation[i] = Animation::New( 25.f );
545 mGravityAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].gravityIndex ), mGravity * 25.f * 3.f );
546 mGravityAnimation[i].SetLooping( false );
547 mGravityAnimation[i].Pause();
550 //Animation to decrease size of metaballs when there is no click
551 for( i = 0 ; i < METABALL_NUMBER; i++ )
553 mRadiusDecAnimation[i] = Animation::New( 25.f );
554 mRadiusDecAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), -0.004f * 25.f * 3.f );
555 mRadiusDecAnimation[i].SetLooping( false );
556 mRadiusDecAnimation[i].Pause();
559 // Animation to grow the size of the metaballs the first second of the click
560 for( i = 0 ; i < METABALL_NUMBER; i++ )
562 mRadiusIncFastAnimation[i] = Animation::New( 0.3f );
563 mRadiusIncFastAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), 0.06f );
564 mRadiusIncFastAnimation[i].SetLooping( false );
565 mRadiusIncFastAnimation[i].Pause();
567 mRadiusIncFastAnimation[0].FinishedSignal().Connect( this, &MetaballRefracController::LaunchRadiusIncSlowAnimations );
569 // Animation to grow the size of the metaballs afterwards
570 for( i = 0 ; i < METABALL_NUMBER; i++ )
572 mRadiusIncSlowAnimation[i] = Animation::New( 20.f );
573 mRadiusIncSlowAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), 0.04f );
574 mRadiusIncSlowAnimation[i].SetLooping( false );
575 mRadiusIncSlowAnimation[i].Pause();
578 // Keyframes of a sin function
579 KeyFrames keySin = KeyFrames::New();
581 for( i = 0 ; i < 360; i++ )
583 val = 0.01f * sin(i * Math::PI/180.f);
585 keySin.Add(key, val);
588 //Animation to change the size of the metaball
589 mRadiusVarAnimation[2] = Animation::New( 8.f );
590 mRadiusVarAnimation[2].AnimateBetween( Property( mMetaballs[2].actor, mMetaballs[2].radiusVarIndex ), keySin );
591 mRadiusVarAnimation[2].SetLooping( true );
593 // Keyframes of a cos function
594 KeyFrames keyCos = KeyFrames::New();
595 for( i = 0 ; i < 360; i++ )
597 val = 0.01f * cos(i * Math::PI/180.f);
599 keyCos.Add(key, val);
602 //Animation to change the size of the metaball
603 mRadiusVarAnimation[3] = Animation::New( 8.f );
604 mRadiusVarAnimation[3].AnimateBetween( Property( mMetaballs[3].actor, mMetaballs[3].radiusVarIndex ), keyCos );
605 mRadiusVarAnimation[3].SetLooping( true );
608 void MetaballRefracController::LaunchGetBackToPositionAnimation( Animation& source )
610 mMetaballPosVariationTo = Vector2(0,0);
612 mPositionVarAnimation[1] = Animation::New( 1.f );
613 mPositionVarAnimation[1].SetLooping( false );
614 mPositionVarAnimation[1].AnimateTo(Property( mMetaballs[1].actor, mMetaballs[1].positionVarIndex ), Vector2(0,0) );
615 mPositionVarAnimation[1].Play();
618 void MetaballRefracController::LaunchRadiusIncSlowAnimations( Animation& source )
620 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
622 mRadiusIncSlowAnimation[i].Play();
624 mPositionVarAnimation[2].Play();
625 mPositionVarAnimation[3].Play();
628 void MetaballRefracController::StopClickAnimations()
630 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
632 mRadiusIncSlowAnimation[i].Stop();
633 mRadiusIncFastAnimation[i].Stop();
635 mPositionVarAnimation[1].Stop();
636 mPositionVarAnimation[2].Stop();
637 mPositionVarAnimation[3].Stop();
640 void MetaballRefracController::StopAfterClickAnimations()
642 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
644 mGravityAnimation[i].Stop();
645 mRadiusDecAnimation[i].Stop();
647 mMetaballs[i].radius = mMetaballs[i].initRadius;
649 mMetaballs[i].actor.SetProperty( mMetaballs[i].gravityIndex, Vector2(0,0) );
650 mMetaballs[i].actor.SetProperty( mMetaballs[i].radiusIndex, mMetaballs[i].radius );
651 mMetaballs[i].actor.SetProperty( mMetaballs[i].radiusVarIndex, 0.f );
653 mRadiusVarAnimation[2].Stop();
654 mRadiusVarAnimation[3].Stop();
657 void MetaballRefracController::ResetMetaballsState()
659 mRendererRefraction.SetTextures( mTextureSetNormal );
660 mRendererRefraction.SetShader( mShaderNormal );
662 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
664 mMetaballs[i].radius = mMetaballs[i].initRadius;
667 mMetaballPosVariationTo = Vector2(0,0);
668 mMetaballPosVariationFrom = Vector2(0,0);
669 mMetaballPosVariation = Vector2(0,0);
670 mGravityVar = Vector2(0,0);
673 void MetaballRefracController::SetPositionToMetaballs( const Vector2& metaballCenter )
675 //We set the position for the metaballs based on click position
676 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
678 mMetaballs[i].position = metaballCenter;
679 mMetaballs[i].actor.SetProperty( mMetaballs[i].positionIndex, mMetaballs[i].position );
683 bool MetaballRefracController::OnTouch( Actor actor, const TouchEvent& touch )
685 const float aspect = mScreenSize.y / mScreenSize.x;
686 switch( touch.GetState( 0 ) )
688 case PointState::DOWN:
690 StopAfterClickAnimations();
691 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
693 mRadiusIncFastAnimation[i].Play();
695 mRadiusVarAnimation[2].Play();
696 mRadiusVarAnimation[3].Play();
698 //We draw with the refraction-composition shader
699 mRendererRefraction.SetTextures( mTextureSetRefraction );
700 mRendererRefraction.SetShader( mShaderRefraction );
701 mCurrentTouchPosition = touch.GetScreenPosition( 0 );
703 //we use the click position for the metaballs
704 Vector2 metaballCenter = Vector2( (mCurrentTouchPosition.x / mScreenSize.x) - 0.5f,
705 (aspect * (mScreenSize.y - mCurrentTouchPosition.y) / mScreenSize.y) - 0.5f ) * 2.0f;
706 SetPositionToMetaballs(metaballCenter);
709 case PointState::MOTION:
711 Vector2 screen = touch.GetScreenPosition( 0 );
712 Vector2 displacement = screen - mCurrentTouchPosition;
713 mCurrentTouchPosition = screen;
715 mMetaballPosVariationTo.x += ( displacement.x / mScreenSize.x ) * 2.2f;
716 mMetaballPosVariationTo.y += (-displacement.y / mScreenSize.y ) * 2.2f;
718 if (mPositionVarAnimation[1])
720 mPositionVarAnimation[1].FinishedSignal().Disconnect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation );
721 mPositionVarAnimation[1].Stop();
723 mPositionVarAnimation[1] = Animation::New( 1.f );
724 mPositionVarAnimation[1].SetLooping( false );
725 mPositionVarAnimation[1].AnimateTo(Property( mMetaballs[1].actor, mMetaballs[1].positionVarIndex ), mMetaballPosVariationTo );
726 mPositionVarAnimation[1].FinishedSignal().Connect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation );
727 mPositionVarAnimation[1].Play();
729 //we use the click position for the metaballs
730 Vector2 metaballCenter = Vector2( (screen.x / mScreenSize.x) - 0.5f,
731 (aspect * (mScreenSize.y - screen.y) / mScreenSize.y) - 0.5f) * 2.0f;
732 SetPositionToMetaballs(metaballCenter);
736 case PointState::LEAVE:
737 case PointState::INTERRUPTED:
739 //Stop click animations
740 StopClickAnimations();
742 //Launch out of screen animations
743 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
745 mGravityAnimation[i].Play();
748 for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ )
750 mRadiusDecAnimation[i].Play();
760 void MetaballRefracController::OnKeyEvent(const KeyEvent& event)
762 if( event.state == KeyEvent::Down )
764 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
774 int32_t DALI_EXPORT_API main( int argc, char **argv )
776 Application application = Application::New( &argc, &argv );
778 MetaballRefracController test( application );
779 application.MainLoop();