2 * Copyright (c) 2016 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.
18 #include <dali/dali.h>
19 #include <dali/devel-api/images/texture-set-image.h>
20 #include <dali/public-api/rendering/renderer.h>
21 #include <dali-toolkit/dali-toolkit.h>
25 #include "shared/utility.h"
28 using namespace Dali::Toolkit;
32 const char * const BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-2.jpg" );
33 const char * const TOOLBAR_IMAGE( DEMO_IMAGE_DIR "top-bar.png" );
35 const float GRAVITY_X(0);
36 const float GRAVITY_Y(-0.09);
39 #define METABALL_NUMBER 4
41 const char*const METABALL_VERTEX_SHADER = DALI_COMPOSE_SHADER (
42 attribute mediump vec2 aPosition;\n
43 attribute mediump vec2 aTexture;\n
44 attribute mediump vec3 aNormal;\n
45 uniform mediump mat4 uMvpMatrix;\n
46 uniform mediump vec3 uSize;\n
47 uniform lowp vec4 uColor;\n
48 varying mediump vec2 vTexCoord;\n
52 mediump vec4 vertexPosition = vec4(aPosition.x, aPosition.y, 0.0, 1.0);\n
53 vertexPosition = uMvpMatrix * vertexPosition;\n
54 gl_Position = vertexPosition;\n
55 vTexCoord = aTexture;\n
60 const char*const METABALL_FRAG_SHADER = DALI_COMPOSE_SHADER (
61 precision mediump float;\n
62 varying vec2 vTexCoord;\n
63 uniform vec2 uPositionMetaball;\n
64 uniform vec2 uPositionVar;\n
65 uniform vec2 uGravityVector;\n
66 uniform float uRadius;\n
67 uniform float uRadiusVar;\n
68 uniform float uAspect;\n
71 vec2 adjustedCoords = vTexCoord * 2.0 - 1.0;\n
72 vec2 finalMetaballPosition = uPositionMetaball + uGravityVector + uPositionVar;\n
74 float distance = (adjustedCoords.x - finalMetaballPosition.x) * (adjustedCoords.x - finalMetaballPosition.x) +
75 (adjustedCoords.y - finalMetaballPosition.y) * (adjustedCoords.y - finalMetaballPosition.y);\n
76 float finalRadius = uRadius + uRadiusVar;\n
77 float color = finalRadius / sqrt( distance );\n
78 vec2 bordercolor = vec2(0.0,0.0);\n
79 if (vTexCoord.x < 0.1)\n
81 bordercolor.x = (0.1 - vTexCoord.x) * 0.8;\n
83 if (vTexCoord.x > 0.9)\n
85 bordercolor.x = (vTexCoord.x - 0.9) * 0.8;\n
87 if (vTexCoord.y < 0.1)\n
89 bordercolor.y = (0.1 - vTexCoord.y) * 0.8;\n
91 if (vTexCoord.y > (0.9 * uAspect))\n
93 bordercolor.y = (vTexCoord.y - (0.9 * uAspect)) * 0.8;\n
95 float border = (bordercolor.x + bordercolor.y) * 0.5;\n
96 gl_FragColor = vec4(color + border,color + border,color + border,1.0);\n
100 const char*const REFRACTION_FRAG_SHADER = DALI_COMPOSE_SHADER (
101 precision mediump float;\n
102 varying vec2 vTexCoord;\n
103 uniform sampler2D sTexture;\n
104 uniform sampler2D sEffect;\n
107 vec4 metaColor = texture2D(sEffect, vTexCoord);\n
109 float bright = 1.0;\n
110 if (metaColor.r > 0.85)\n
112 zoomCoords = ((vTexCoord - 0.5) * 0.95) + 0.5;\n
114 else if (metaColor.r > 0.81)\n
116 float interpolation = mix(0.95, 1.05, (0.85 - metaColor.r) * 50.0);\n
117 zoomCoords = ((vTexCoord - 0.5) * interpolation) + 0.5;\n
122 zoomCoords = vTexCoord;\n
125 gl_FragColor = texture2D(sTexture, zoomCoords) * bright;\n
129 const char*const FRAG_SHADER = DALI_COMPOSE_SHADER (
130 precision mediump float;\n
131 varying vec2 vTexCoord;\n
132 uniform sampler2D sTexture;\n
135 gl_FragColor = texture2D(sTexture, vTexCoord);\n
142 //ShaderEffect shader;
148 //Properties needed for animations
149 Property::Index positionIndex;
150 Property::Index positionVarIndex;
151 Property::Index gravityIndex;
152 Property::Index radiusIndex;
153 Property::Index radiusVarIndex;
154 Property::Index aspectIndex;
158 /***************************************************************************/
159 /* Demo using Metaballs for Refraction when clicking the screen ************/
160 /* The concept is similar to the Note 5 ScreenLock ************/
161 /***************************************************************************/
162 class MetaballRefracController : public ConnectionTracker
165 MetaballRefracController( Application& application );
166 ~MetaballRefracController();
168 void Create( Application& app );
169 bool OnTouch( Actor actor, const TouchData& touch );
170 void OnKeyEvent(const KeyEvent& event);
172 void SetGravity(const Vector2 & gravity);
176 Application& mApplication;
182 FrameBufferImage mMetaballFBO;
185 MetaballInfo mMetaballs[METABALL_NUMBER];
187 Actor mCompositionActor;
191 Vector2 mCurrentTouchPosition;
192 Vector2 mMetaballPosVariation;
193 Vector2 mMetaballPosVariationFrom;
194 Vector2 mMetaballPosVariationTo;
195 Vector2 mMetaballCenter;
200 Renderer mRendererRefraction;
201 TextureSet mTextureSetRefraction;
202 Shader mShaderRefraction;
203 TextureSet mTextureSetNormal;
204 Shader mShaderNormal;
207 Animation mGravityAnimation[METABALL_NUMBER];
208 Animation mRadiusDecAnimation[METABALL_NUMBER];
209 Animation mRadiusIncFastAnimation[METABALL_NUMBER];
210 Animation mRadiusIncSlowAnimation[METABALL_NUMBER];
211 Animation mRadiusVarAnimation[METABALL_NUMBER];
212 Animation mPositionVarAnimation[METABALL_NUMBER];
215 Geometry CreateGeometry();
216 Geometry CreateGeometryComposition();
218 void CreateMetaballActors();
219 void CreateMetaballImage();
220 void AddRefractionImage();
221 void CreateAnimations();
223 void LaunchRadiusIncSlowAnimations(Animation &source);
224 void LaunchGetBackToPositionAnimation(Animation &source);
226 void StopClickAnimations();
227 void StopAfterClickAnimations();
229 void ResetMetaballsState();
231 void SetPositionToMetaballs(Vector2 & metaballCenter);
235 //-----------------------------------------------------------------------------------------------
241 MetaballRefracController::MetaballRefracController( Application& application )
242 : mApplication( application )
244 // Connect to the Application's Init signal
245 mApplication.InitSignal().Connect( this, &MetaballRefracController::Create );
248 MetaballRefracController::~MetaballRefracController()
250 // Nothing to do here;
254 * Setter function for gravity
256 void MetaballRefracController::SetGravity(const Vector2 & gravity)
262 * Main create function, it creates the metaballs and all the
264 void MetaballRefracController::Create( Application& app )
266 Stage stage = Stage::GetCurrent();
268 stage.KeyEventSignal().Connect(this, &MetaballRefracController::OnKeyEvent);
270 mScreenSize = stage.GetSize();
272 stage.SetBackgroundColor(Color::BLACK);
274 //Set background image for the view
275 mBackImage = DemoHelper::LoadImage( BACKGROUND_IMAGE );
277 mGravity = Vector2(GRAVITY_X,GRAVITY_Y);
278 mGravityVar = Vector2(0,0);
280 //Create internal data
281 CreateMetaballActors();
282 CreateMetaballImage();
283 AddRefractionImage();
287 // Connect the callback to the touch signal on the mesh actor
288 stage.GetRootLayer().TouchSignal().Connect( this, &MetaballRefracController::OnTouch );
292 * Create a mesh data with the geometry for the metaball rendering
294 Geometry MetaballRefracController::CreateGeometry()
296 float aspect = (float)mScreenSize.y / (float)mScreenSize.x;
298 // Create vertices and specify their color
299 float xsize = mScreenSize.x * 0.5;
301 //We create the meshdata for the metaballs
302 struct VertexPosition { Vector2 position; };
303 struct VertexTexture { Vector2 texture; };
304 struct VertexNormal { Vector3 normal; };
306 VertexPosition vertices[] = {
307 { Vector2( -xsize, -xsize * aspect) },
308 { Vector2( xsize, -xsize * aspect) },
309 { Vector2( -xsize, xsize * aspect) },
310 { Vector2( xsize, xsize * aspect) }
313 VertexTexture textures[] = {
314 { Vector2(0.0f, 0.0f) },
315 { Vector2(1.0f, 0.0f) },
316 { Vector2(0.0f, 1.0f * aspect) },
317 { Vector2(1.0f, 1.0f * aspect) }
320 VertexNormal normals [] = {
321 { Vector3(0.0f, 0.0f, 1.0f) },
322 { Vector3(0.0f, 0.0f, 1.0f) },
323 { Vector3(0.0f, 0.0f, 1.0f) },
324 { Vector3(0.0f, 0.0f, 1.0f) }
327 unsigned int numberOfVertices = sizeof(vertices)/sizeof(VertexPosition);
330 Property::Map positionVertexFormat;
331 positionVertexFormat["aPosition"] = Property::VECTOR2;
332 PropertyBuffer positionVertices = PropertyBuffer::New( positionVertexFormat );
333 positionVertices.SetData( vertices, numberOfVertices );
336 Property::Map textureVertexFormat;
337 textureVertexFormat["aTexture"] = Property::VECTOR2;
338 PropertyBuffer textureVertices = PropertyBuffer::New( textureVertexFormat );
339 textureVertices.SetData( textures, numberOfVertices );
342 Property::Map normalVertexFormat;
343 normalVertexFormat["aNormal"] = Property::VECTOR3;
344 PropertyBuffer normalVertices = PropertyBuffer::New( normalVertexFormat );
345 normalVertices.SetData( normals, numberOfVertices );
348 unsigned short indices[] = { 0, 3, 1, 0, 2, 3 };
350 // Create the geometry object
351 Geometry texturedQuadGeometry = Geometry::New();
352 texturedQuadGeometry.AddVertexBuffer( positionVertices );
353 texturedQuadGeometry.AddVertexBuffer( textureVertices );
354 texturedQuadGeometry.AddVertexBuffer( normalVertices );
356 texturedQuadGeometry.SetIndexBuffer ( &indices[0], 6 );
358 return texturedQuadGeometry;
362 * Create a mesh data with the geometry for the metaball rendering
364 Geometry MetaballRefracController::CreateGeometryComposition()
366 float aspect = (float)mScreenSize.y / (float)mScreenSize.x;
368 // Create vertices and specify their color
369 float xsize = mScreenSize.x * 0.5;
371 //We create the meshdata for the metaballs
372 struct VertexPosition { Vector2 position; };
373 struct VertexTexture { Vector2 texture; };
374 struct VertexNormal { Vector3 normal; };
376 VertexPosition vertices[] = {
377 { Vector2( -xsize, -xsize * aspect) },
378 { Vector2( xsize, -xsize * aspect) },
379 { Vector2( -xsize, xsize * aspect) },
380 { Vector2( xsize, xsize * aspect) }
383 VertexTexture textures[] = {
384 { Vector2(0.0f, 0.0f) },
385 { Vector2(1.0f, 0.0f) },
386 { Vector2(0.0f, 1.0f) },
387 { Vector2(1.0f, 1.0f) }
390 VertexNormal normals [] = {
391 { Vector3(0.0f, 0.0f, 1.0f) },
392 { Vector3(0.0f, 0.0f, 1.0f) },
393 { Vector3(0.0f, 0.0f, 1.0f) },
394 { Vector3(0.0f, 0.0f, 1.0f) }
397 unsigned int numberOfVertices = sizeof(vertices)/sizeof(VertexPosition);
400 Property::Map positionVertexFormat;
401 positionVertexFormat["aPosition"] = Property::VECTOR2;
402 PropertyBuffer positionVertices = PropertyBuffer::New( positionVertexFormat );
403 positionVertices.SetData( vertices, numberOfVertices );
406 Property::Map textureVertexFormat;
407 textureVertexFormat["aTexture"] = Property::VECTOR2;
408 PropertyBuffer textureVertices = PropertyBuffer::New( textureVertexFormat );
409 textureVertices.SetData( textures, numberOfVertices );
412 Property::Map normalVertexFormat;
413 normalVertexFormat["aNormal"] = Property::VECTOR3;
414 PropertyBuffer normalVertices = PropertyBuffer::New( normalVertexFormat );
415 normalVertices.SetData( normals, numberOfVertices );
418 unsigned short indices[] = { 0, 3, 1, 0, 2, 3 };
420 // Create the geometry object
421 Geometry texturedQuadGeometry = Geometry::New();
422 texturedQuadGeometry.AddVertexBuffer( positionVertices );
423 texturedQuadGeometry.AddVertexBuffer( textureVertices );
424 texturedQuadGeometry.AddVertexBuffer( normalVertices );
426 texturedQuadGeometry.SetIndexBuffer ( &indices[0], sizeof( indices )/ sizeof( indices[0] ) );
428 return texturedQuadGeometry;
432 * Create a mesh actor for the metaballs
434 void MetaballRefracController::CreateMetaballActors()
436 //We create metaball structures
437 //With MeshData Textured
438 float aspect = (float)mScreenSize.y / (float)mScreenSize.x;
440 //Create the renderer for the metaballs
441 Shader shader = Shader::New( METABALL_VERTEX_SHADER, METABALL_FRAG_SHADER );
442 Geometry metaballGeom = CreateGeometry();
443 Renderer renderer = Renderer::New( metaballGeom, shader );
444 renderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
445 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::ONE );
446 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ONE );
447 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE );
448 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ONE );
450 //Each metaball has a different radius
451 mMetaballs[0].radius = mMetaballs[0].initRadius = 0.0145f;
452 mMetaballs[1].radius = mMetaballs[1].initRadius = 0.012f;
453 mMetaballs[2].radius = mMetaballs[2].initRadius = 0.0135f;
454 mMetaballs[3].radius = mMetaballs[3].initRadius = 0.0135f;
456 //Initialization of each of the metaballs
457 for (int i = 0 ; i < METABALL_NUMBER ; i++)
459 mMetaballs[i].position = Vector2(0.0f, 0.0f);
461 mMetaballs[i].actor = Actor::New( );
462 mMetaballs[i].actor.SetName("Metaball");
463 mMetaballs[i].actor.SetScale( 1.0f );
464 mMetaballs[i].actor.SetParentOrigin( ParentOrigin::CENTER );
467 mMetaballs[i].actor.AddRenderer( renderer );
469 mMetaballs[i].positionIndex = mMetaballs[i].actor.RegisterProperty( "uPositionMetaball", mMetaballs[i].position );
471 mMetaballs[i].positionVarIndex = mMetaballs[i].actor.RegisterProperty( "uPositionVar", Vector2(0.f,0.f) );
473 mMetaballs[i].gravityIndex = mMetaballs[i].actor.RegisterProperty( "uGravityVector", Vector2(0.f,0.f) );
475 mMetaballs[i].radiusIndex = mMetaballs[i].actor.RegisterProperty( "uRadius", mMetaballs[i].radius );
477 mMetaballs[i].radiusVarIndex = mMetaballs[i].actor.RegisterProperty( "uRadiusVar", 0.f );
479 mMetaballs[i].aspectIndex = mMetaballs[i].actor.RegisterProperty( "uAspect", aspect );
481 mMetaballs[i].actor.SetSize(400, 400);
485 mMetaballRoot = Actor::New();
486 mMetaballRoot.SetParentOrigin( ParentOrigin::CENTER );
487 for (int i = 0 ; i < METABALL_NUMBER ; i++)
489 mMetaballRoot.Add( mMetaballs[i].actor );
492 //Initialization of variables related to metaballs
493 mMetaballPosVariation = Vector2(0,0);
494 mMetaballPosVariationFrom = Vector2(0,0);
495 mMetaballPosVariationTo = Vector2(0,0);
496 mCurrentTouchPosition = Vector2(0,0);
500 * Create the render task and FBO to render the metaballs into a texture
502 void MetaballRefracController::CreateMetaballImage()
504 //We create an FBO and a render task to create to render the metaballs with a fragment shader
505 Stage stage = Stage::GetCurrent();
506 mMetaballFBO = FrameBufferImage::New(mScreenSize.x, mScreenSize.y );
508 stage.Add(mMetaballRoot);
510 //Creation of the render task used to render the metaballs
511 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
512 RenderTask task = taskList.CreateTask();
513 task.SetRefreshRate( RenderTask::REFRESH_ALWAYS );
514 task.SetSourceActor( mMetaballRoot );
515 task.SetExclusive(true);
516 task.SetClearColor( Color::BLACK );
517 task.SetClearEnabled( true );
518 task.SetTargetFrameBuffer( mMetaballFBO );
522 * Create a mesh image to render the final composition
524 void MetaballRefracController::AddRefractionImage()
526 //Creation of the composition image
529 Geometry metaballGeom = CreateGeometryComposition();
531 //Create Refraction shader and renderer
532 mShaderRefraction = Shader::New( METABALL_VERTEX_SHADER, REFRACTION_FRAG_SHADER );
534 //Create new texture set
535 mTextureSetRefraction = TextureSet::New();
536 TextureSetImage( mTextureSetRefraction, 0u, mBackImage );
537 TextureSetImage( mTextureSetRefraction, 1u, mMetaballFBO );
539 //Create normal shader
540 mShaderNormal = Shader::New( METABALL_VERTEX_SHADER, FRAG_SHADER );
542 //Create new texture set
543 mTextureSetNormal = TextureSet::New();
544 TextureSetImage( mTextureSetNormal, 0u, mBackImage );
547 mCompositionActor = Actor::New( );
548 mCompositionActor.SetParentOrigin(ParentOrigin::CENTER);
549 mCompositionActor.SetPosition(Vector3(0.0f, 0.0f, 0.0f));
550 mCompositionActor.SetSize(mScreenSize.x, mScreenSize.y);
552 mRendererRefraction = Renderer::New( metaballGeom, mShaderNormal );
553 mRendererRefraction.SetTextures( mTextureSetNormal );
554 mCompositionActor.AddRenderer( mRendererRefraction );
556 Stage stage = Stage::GetCurrent();
557 stage.Add( mCompositionActor );
561 * Creation of all the metaballs animations (gravity, movement, size, etc.)
563 void MetaballRefracController::CreateAnimations()
568 mPositionVarAnimation[1] = Animation::New(2.f);
569 mPositionVarAnimation[1].SetLooping( false );
570 mPositionVarAnimation[1].Pause();
571 mPositionVarAnimation[1].FinishedSignal().Connect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation );
573 KeyFrames keySinCosVariation = KeyFrames::New();
574 Vector2 sinCosVariation(0,0);
575 for ( i = 0 ; i < 360 ; i++)
577 sinCosVariation.x = 0.05f * (-sin(i * Math::PI/180.f) + cos(i * Math::PI/180.f));
578 sinCosVariation.y = 0.05f * (sin(i * Math::PI/180.f) - cos(i * Math::PI/180.f));
580 keySinCosVariation.Add(key, sinCosVariation);
583 mPositionVarAnimation[2] = Animation::New(6.f);
584 mPositionVarAnimation[2].AnimateBetween(Property( mMetaballs[2].actor, mMetaballs[2].positionVarIndex ), keySinCosVariation);
585 mPositionVarAnimation[2].SetLooping( true );
586 mPositionVarAnimation[2].Pause();
588 KeyFrames keyCosSinVariation = KeyFrames::New();
589 Vector2 cosSinVariation(0,0);
590 for ( i = 0 ; i < 360 ; i++)
592 cosSinVariation.x = 0.05f * (-sin(i * Math::PI/180.f) - cos(i * Math::PI/180.f));
593 cosSinVariation.y = 0.05f * (sin(i * Math::PI/180.f) + cos(i * Math::PI/180.f));
595 keyCosSinVariation.Add(key, cosSinVariation);
598 mPositionVarAnimation[3] = Animation::New(6.f);
599 mPositionVarAnimation[3].AnimateBetween(Property( mMetaballs[3].actor, mMetaballs[3].positionVarIndex ), keyCosSinVariation);
600 mPositionVarAnimation[3].SetLooping( true );
601 mPositionVarAnimation[3].Pause();
603 //Animations for gravity
604 for ( i = 0 ; i < METABALL_NUMBER ; i++)
606 mGravityAnimation[i] = Animation::New(25.f);
607 mGravityAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].gravityIndex ), mGravity * 25.f * 3.f);
608 mGravityAnimation[i].SetLooping( false );
609 mGravityAnimation[i].Pause();
612 //Animation to decrease size of metaballs when there is no click
613 for ( i = 0 ; i < METABALL_NUMBER ; i++)
615 mRadiusDecAnimation[i] = Animation::New(25.f);
616 mRadiusDecAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), -0.004f * 25.f * 3.f);
617 mRadiusDecAnimation[i].SetLooping( false );
618 mRadiusDecAnimation[i].Pause();
621 //Animation to grow the size of the metaballs the first second of the click
622 for ( i = 0 ; i < METABALL_NUMBER ; i++)
624 mRadiusIncFastAnimation[i] = Animation::New(0.3f);
625 mRadiusIncFastAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), 0.06f);
626 mRadiusIncFastAnimation[i].SetLooping( false );
627 mRadiusIncFastAnimation[i].Pause();
629 mRadiusIncFastAnimation[0].FinishedSignal().Connect( this, &MetaballRefracController::LaunchRadiusIncSlowAnimations );
631 //Animation to grow the size of the metaballs afterwards
632 for ( i = 0 ; i < METABALL_NUMBER ; i++)
634 mRadiusIncSlowAnimation[i] = Animation::New(20.f);
635 mRadiusIncSlowAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), 0.04f);
636 mRadiusIncSlowAnimation[i].SetLooping( false );
637 mRadiusIncSlowAnimation[i].Pause();
640 //keyframes of a sin function
641 KeyFrames keySin = KeyFrames::New();
643 for ( i = 0 ; i < 360 ; i++)
645 val = 0.01f * sin(i * Math::PI/180.f);
647 keySin.Add(key, val);
650 //Animation to change the size of the metaball
651 mRadiusVarAnimation[2] = Animation::New(8.f);
652 mRadiusVarAnimation[2].AnimateBetween(Property( mMetaballs[2].actor, mMetaballs[2].radiusVarIndex ), keySin);
653 mRadiusVarAnimation[2].SetLooping( true );
655 //keyframes of a cos function
656 KeyFrames keyCos = KeyFrames::New();
657 for ( i = 0 ; i < 360 ; i++)
659 val = 0.01f * cos(i * Math::PI/180.f);
661 keyCos.Add(key, val);
664 //Animation to change the size of the metaball
665 mRadiusVarAnimation[3] = Animation::New(8.f);
666 mRadiusVarAnimation[3].AnimateBetween(Property( mMetaballs[3].actor, mMetaballs[3].radiusVarIndex ), keyCos);
667 mRadiusVarAnimation[3].SetLooping( true );
671 * Function to launch the animation to get the metaball[1] back to the center
673 void MetaballRefracController::LaunchGetBackToPositionAnimation(Animation &source)
675 mMetaballPosVariationTo = Vector2(0,0);
677 mPositionVarAnimation[1] = Animation::New(1.f);
678 mPositionVarAnimation[1].SetLooping( false );
679 mPositionVarAnimation[1].AnimateTo(Property( mMetaballs[1].actor, mMetaballs[1].positionVarIndex ), Vector2(0,0));
680 mPositionVarAnimation[1].Play();
684 * Function to launch the gro slow radius for the metaballs, and also the small variations for metaball[2] and [3]
686 void MetaballRefracController::LaunchRadiusIncSlowAnimations(Animation &source)
688 for (int i = 0 ; i < METABALL_NUMBER ; i++)
690 mRadiusIncSlowAnimation[i].Play();
692 mPositionVarAnimation[2].Play();
693 mPositionVarAnimation[3].Play();
697 * Function to stop all animations related to the click of the user in the screen
699 void MetaballRefracController::StopClickAnimations()
701 for (int i = 0 ; i < METABALL_NUMBER ; i++)
703 mRadiusIncSlowAnimation[i].Stop();
704 mRadiusIncFastAnimation[i].Stop();
706 mPositionVarAnimation[1].Stop();
707 mPositionVarAnimation[2].Stop();
708 mPositionVarAnimation[3].Stop();
712 * Function to stop all animations related to the after click of the user in the screen
714 void MetaballRefracController::StopAfterClickAnimations()
716 for (int i = 0 ; i < METABALL_NUMBER ; i++)
718 mGravityAnimation[i].Stop();
719 mRadiusDecAnimation[i].Stop();
721 mMetaballs[i].radius = mMetaballs[i].initRadius;
723 mMetaballs[i].actor.SetProperty(mMetaballs[i].gravityIndex, Vector2(0,0));
724 mMetaballs[i].actor.SetProperty(mMetaballs[i].radiusIndex, mMetaballs[i].radius);
725 mMetaballs[i].actor.SetProperty(mMetaballs[i].radiusVarIndex, 0.f);
727 mRadiusVarAnimation[2].Stop();
728 mRadiusVarAnimation[3].Stop();
732 * Function that resets the sate of the different Metaballs
734 void MetaballRefracController::ResetMetaballsState()
736 mRendererRefraction.SetTextures(mTextureSetNormal);
737 mRendererRefraction.SetShader( mShaderNormal );
739 for (int i = 0 ; i < METABALL_NUMBER ; i++)
741 mMetaballs[i].radius = mMetaballs[i].initRadius;
744 mMetaballPosVariationTo = Vector2(0,0);
745 mMetaballPosVariationFrom = Vector2(0,0);
746 mMetaballPosVariation = Vector2(0,0);
748 mGravityVar = Vector2(0,0);
752 * Function to set the actual position of the metaballs when the user clicks the screen
754 void MetaballRefracController::SetPositionToMetaballs(Vector2 & metaballCenter)
756 //We set the position for the metaballs based on click position
757 for (int i = 0 ; i < METABALL_NUMBER ; i++)
759 mMetaballs[i].position = metaballCenter;
760 mMetaballs[i].actor.SetProperty(mMetaballs[i].positionIndex, mMetaballs[0].position); // 0 y no i ?!?!?!
764 bool MetaballRefracController::OnTouch( Actor actor, const TouchData& touch )
766 float aspectR = mScreenSize.y / mScreenSize.x;
767 switch( touch.GetState( 0 ) )
769 case PointState::DOWN:
771 StopAfterClickAnimations();
772 for (int i = 0 ; i < METABALL_NUMBER ; i++)
773 mRadiusIncFastAnimation[i].Play();
774 mRadiusVarAnimation[2].Play();
775 mRadiusVarAnimation[3].Play();
777 //We draw with the refraction-composition shader
778 mRendererRefraction.SetTextures(mTextureSetRefraction);
779 mRendererRefraction.SetShader( mShaderRefraction );
780 mCurrentTouchPosition = touch.GetScreenPosition( 0 );
782 //we use the click position for the metaballs
783 Vector2 metaballCenter = Vector2((mCurrentTouchPosition.x / mScreenSize.x) - 0.5, (aspectR * (mScreenSize.y - mCurrentTouchPosition.y) / mScreenSize.y) - 0.5) * 2.0;
784 SetPositionToMetaballs(metaballCenter);
787 case PointState::MOTION:
789 Vector2 screen = touch.GetScreenPosition( 0 );
790 Vector2 displacement = screen - mCurrentTouchPosition;
791 mCurrentTouchPosition = screen;
793 mMetaballPosVariationTo.x += (displacement.x / mScreenSize.x) * 2.2;
794 mMetaballPosVariationTo.y += (- displacement.y / mScreenSize.y) * 2.2;
796 if (mPositionVarAnimation[1])
798 mPositionVarAnimation[1].FinishedSignal().Disconnect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation );
799 mPositionVarAnimation[1].Stop();
801 mPositionVarAnimation[1] = Animation::New(1.f);
802 mPositionVarAnimation[1].SetLooping( false );
803 mPositionVarAnimation[1].AnimateTo(Property( mMetaballs[1].actor, mMetaballs[1].positionVarIndex ), mMetaballPosVariationTo);
804 mPositionVarAnimation[1].FinishedSignal().Connect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation );
805 mPositionVarAnimation[1].Play();
807 //we use the click position for the metaballs
808 Vector2 metaballCenter = Vector2((screen.x / mScreenSize.x) - 0.5, (aspectR * (mScreenSize.y - screen.y) / mScreenSize.y) - 0.5) * 2.0;
809 SetPositionToMetaballs(metaballCenter);
813 case PointState::LEAVE:
814 case PointState::INTERRUPTED:
816 //Stop click animations
817 StopClickAnimations();
819 //Launch out of screen animations
820 for (int i = 0 ; i < METABALL_NUMBER ; i++)
821 mGravityAnimation[i].Play();
823 for (int i = 0 ; i < METABALL_NUMBER ; i++)
824 mRadiusDecAnimation[i].Play();
835 void MetaballRefracController::OnKeyEvent(const KeyEvent& event)
837 if(event.state == KeyEvent::Down)
839 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
849 //-----------------------------------------------------------------------------------------------
851 void RunTest( Application& application )
853 MetaballRefracController test( application );
855 application.MainLoop();
858 // Entry point for Linux & Tizen applications
860 int DALI_EXPORT_API main( int argc, char **argv )
862 Application application = Application::New( &argc, &argv );
864 RunTest( application );