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.
21 #include <dali/dali.h>
22 #include <dali/devel-api/images/texture-set-image.h>
23 #include <dali/public-api/rendering/renderer.h>
24 #include <dali-toolkit/dali-toolkit.h>
25 #include <dali-toolkit/devel-api/controls/gaussian-blur-view/gaussian-blur-view.h>
28 #include "shared/view.h"
29 #include "shared/utility.h"
32 using namespace Dali::Toolkit;
36 const char * const BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-2.jpg" );
37 const char * const TOOLBAR_IMAGE( DEMO_IMAGE_DIR "top-bar.png" );
39 const float GRAVITY_X(0);
40 const float GRAVITY_Y(-0.09);
43 #define METABALL_NUMBER 6
46 const char*const METABALL_VERTEX_SHADER = DALI_COMPOSE_SHADER (
47 attribute mediump vec2 aPosition;\n
48 attribute mediump vec2 aTexture;\n
49 uniform mediump mat4 uMvpMatrix;\n
50 uniform mediump vec3 uSize;\n
51 uniform lowp vec4 uColor;\n
52 varying mediump vec2 vTexCoord;\n
56 vTexCoord = aTexture;\n
57 mediump vec4 vertexPosition = vec4(aPosition.x, aPosition.y, 0.0, 1.0);\n
58 gl_Position = uMvpMatrix * vertexPosition;\n
63 const char*const METABALL_FRAG_SHADER = DALI_COMPOSE_SHADER (
64 precision mediump float;\n
65 varying vec2 vTexCoord;\n
66 uniform vec2 uPositionMetaball;\n
67 uniform vec2 uPositionVar;\n
68 uniform vec2 uGravityVector;\n
69 uniform float uRadius;\n
70 uniform float uRadiusVar;\n
73 vec2 adjustedCoords = vTexCoord * 2.0 - 1.0;\n
74 vec2 finalMetaballPosition = uPositionMetaball + uGravityVector + uPositionVar;\n
76 float finalRadius = uRadius + uRadiusVar;\n
77 vec2 distanceVec = adjustedCoords - finalMetaballPosition;\n
78 float result = dot(distanceVec, distanceVec);\n
79 float color = inversesqrt(result) * finalRadius;\n
81 gl_FragColor = vec4(color,color,color,1.0);\n
85 const char*const REFRACTION_FRAG_SHADER = DALI_COMPOSE_SHADER (
86 precision highp float;\n
87 varying vec2 vTexCoord;\n
88 uniform sampler2D sTexture;\n
89 uniform sampler2D sEffect;\n
90 uniform vec2 uPositionMetaball;\n
94 vec3 normal = vec3(0.0,0.0,1.0);\n
95 vec2 fakePos = vec2(0.0,0.0);\n
96 vec3 color = vec3(1.0, 1.0, 1.0);
99 vec4 metaColor = texture2D(sEffect, vTexCoord);\n
101 vec2 adjustedCoords = vTexCoord.xy * vec2(2.0) - vec2(1.0);\n
102 fakePos = adjustedCoords.xy - vec2(uPositionMetaball.x, -uPositionMetaball.y);
103 float len = length(fakePos) + 0.01;\n
104 vec3 colorPos = vec3(0,0,1);
106 if (metaColor.r > 0.85)\n
108 zoomCoords = ((vTexCoord - 0.5) * 0.9);\n
109 zoomCoords = zoomCoords + 0.5;\n
111 float interpNormal = mix(0.7, 1.0, (metaColor.r - 0.85) * 4.);\n
112 normal.xyz = vec3(fakePos.x * (1.0 - interpNormal) / len, fakePos.y * (1.0 - interpNormal) / len, interpNormal);\n
113 normal.xyz = normalize(normal.xyz);\n
114 color = vec3(0.65, 1.0, 0);\n
115 colorPos = vec3(fakePos.x,fakePos.y,0);
117 else if (metaColor.r > 0.75)\n
119 float interpolation = mix(0.9, 1.15, (0.85 - metaColor.r) * 10.0);\n
120 zoomCoords = ((vTexCoord - 0.5) * interpolation);\n
121 zoomCoords = zoomCoords + 0.5;\n
123 float interpNormal = mix(0.7, 0.0, (0.85 - metaColor.r) * 10.0);\n
124 normal.xyz = vec3(fakePos.x * (1.0 - interpNormal) / len, fakePos.y * (1.0 - interpNormal) / len, interpNormal);\n
125 normal.xyz = normalize(normal.xyz);\n
126 color = vec3(0.65, 1.0, 0);\n
127 colorPos = vec3(fakePos.x,fakePos.y,0);
131 zoomCoords = vTexCoord;\n
132 normal = vec3(0,0,0);\n
136 vec3 lightPosition = vec3(-750.0,-1000.0,2000.0);\n
137 vec3 vertex = vec3(adjustedCoords.x,adjustedCoords.y,0.0);\n
139 vec3 vecToLight = normalize( lightPosition - vertex );\n
141 float lightDiffuse = dot( vecToLight, normal );\n
142 lightDiffuse = max(0.0,lightDiffuse);\n
143 lightDiffuse = lightDiffuse * 0.5 + 0.5;
145 vec3 vertexToEye = vec3(0,0,1) - vertex;\n
146 vertexToEye = normalize(vertexToEye);
147 vec3 lightReflect = normalize(reflect(-vecToLight, normal));\n
148 float specularFactor = max(0.0,dot(vertexToEye, lightReflect));\n
149 specularFactor = pow(specularFactor, 32.0) * 0.7;
151 vec4 texColor = texture2D(sTexture, zoomCoords);\n
152 gl_FragColor.rgb = texColor.rgb * ambient + color.rgb * texColor.rgb * lightDiffuse + vec3(specularFactor);\n
153 gl_FragColor.a = 1.0;
157 const char*const FRAG_SHADER = DALI_COMPOSE_SHADER (
158 precision mediump float;\n
161 gl_FragColor = texture2D(sTexture, vTexCoord);\n
174 Property::Index positionIndex;
175 Property::Index positionVarIndex;
179 /**************************************************************************/
180 /* Demo using Metaballs ***********/
181 /* When the metaball is clicked it explodes in different balls ***********/
182 /**************************************************************************/
183 class MetaballExplosionController : public ConnectionTracker
186 MetaballExplosionController( Application& application );
187 ~MetaballExplosionController();
190 * Main create function, it creates the metaballs and all the related data
192 void Create( Application& app );
195 * Touch event function
197 bool OnTouch( Actor actor, const TouchData& touch );
202 void OnKeyEvent(const KeyEvent& event);
206 Application& mApplication;
212 FrameBufferImage mMetaballFBO;
215 MetaballInfo mMetaballs[METABALL_NUMBER];
217 Property::Index mPositionIndex;
218 Actor mCompositionActor;
221 Vector2 mCurrentTouchPosition;
222 Vector2 mMetaballPosVariation;
223 Vector2 mMetaballPosVariationFrom;
224 Vector2 mMetaballPosVariationTo;
225 Vector2 mMetaballCenter;
228 Animation mPositionVarAnimation[METABALL_NUMBER];
231 Animation mDispersionAnimation[METABALL_NUMBER];
233 Timer mTimerDispersion;
240 * Create a mesh data with the geometry for the metaball rendering
242 Geometry CreateGeometry();
245 * Create a mesh data with the geometry for the final composition
247 Geometry CreateGeometryComposition();
250 * Create a mesh actor for the metaballs
252 void CreateMetaballActors();
255 * Create the render task and FBO to render the metaballs into a texture
257 void CreateMetaballImage();
260 * Create a mesh image to render the final composition
262 void AddRefractionImage();
265 * Function to create animations for the small variations of position inside the metaball
267 void CreateAnimations();
270 * Function to reset metaball state
272 void ResetMetaballs(bool resetAnims);
275 * Function to create disperse each of the ball that compose the metaball when exploding
277 void DisperseBallAnimation(int ball);
280 * Function to make metaballs come back to reset position
282 void LaunchResetMetaballPosition(Animation &source);
285 * Function to set things at the end of the animation
287 void EndDisperseAnimation(Animation &source);
290 * Function to init dispersion of the metaballs one by one using a timer
291 * (so not all the balls begin moving at the same time)
293 bool OnTimerDispersionTick();
296 * Function to set the actual position of the metaballs when the user clicks the screen
298 void SetPositionToMetaballs(Vector2 & metaballCenter);
302 //-----------------------------------------------------------------------------------------------
308 MetaballExplosionController::MetaballExplosionController( Application& application )
309 : mApplication( application ),
318 mCurrentTouchPosition(),
319 mMetaballPosVariation(),
320 mMetaballPosVariationFrom(),
321 mMetaballPosVariationTo(),
323 mPositionVarAnimation(),
325 mDispersionAnimation(),
329 // Connect to the Application's Init signal
330 mApplication.InitSignal().Connect( this, &MetaballExplosionController::Create );
333 MetaballExplosionController::~MetaballExplosionController()
335 // Nothing to do here;
338 void MetaballExplosionController::Create( Application& app )
340 Stage stage = Stage::GetCurrent();
342 stage.KeyEventSignal().Connect(this, &MetaballExplosionController::OnKeyEvent);
344 mScreenSize = stage.GetSize();
348 stage.SetBackgroundColor(Color::BLACK);
350 //Set background image for the view
351 mBackImage = DemoHelper::LoadImage( BACKGROUND_IMAGE );
353 srand((unsigned)time(0));
355 //Create internal data
356 CreateMetaballActors();
357 CreateMetaballImage();
358 AddRefractionImage();
363 mTimerDispersion = Timer::New( 150 );
364 mTimerDispersion.TickSignal().Connect(this, &MetaballExplosionController::OnTimerDispersionTick);
366 // Connect the callback to the touch signal on the mesh actor
367 stage.GetRootLayer().TouchSignal().Connect( this, &MetaballExplosionController::OnTouch );
370 Geometry MetaballExplosionController::CreateGeometry()
372 float aspect = (float)mScreenSize.y / (float)mScreenSize.x;
374 // Create vertices and specify their color
375 float xsize = mScreenSize.x * 0.5;
377 //We create the meshdata for the metaballs
378 struct VertexPosition { Vector2 position; };
379 struct VertexTexture { Vector2 texture; };
380 struct VertexNormal { Vector3 normal; };
382 VertexPosition vertices[] = {
383 { Vector2( -xsize, -xsize * aspect) },
384 { Vector2( xsize, -xsize * aspect) },
385 { Vector2( -xsize, xsize * aspect) },
386 { Vector2( xsize, xsize * aspect) }
389 VertexTexture textures[] = {
390 { Vector2(0.0f, 0.0f) },
391 { Vector2(1.0f, 0.0f) },
392 { Vector2(0.0f, 1.0f * aspect) },
393 { Vector2(1.0f, 1.0f * aspect) }
396 unsigned int numberOfVertices = sizeof(vertices)/sizeof(VertexPosition);
399 Property::Map positionVertexFormat;
400 positionVertexFormat["aPosition"] = Property::VECTOR2;
401 PropertyBuffer positionVertices = PropertyBuffer::New( positionVertexFormat );
402 positionVertices.SetData( vertices, numberOfVertices );
405 Property::Map textureVertexFormat;
406 textureVertexFormat["aTexture"] = Property::VECTOR2;
407 PropertyBuffer textureVertices = PropertyBuffer::New( textureVertexFormat );
408 textureVertices.SetData( textures, numberOfVertices );
411 unsigned short indices[] = { 0, 3, 1, 0, 2, 3 };
413 // Create the geometry object
414 Geometry texturedQuadGeometry = Geometry::New();
415 texturedQuadGeometry.AddVertexBuffer( positionVertices );
416 texturedQuadGeometry.AddVertexBuffer( textureVertices );
418 texturedQuadGeometry.SetIndexBuffer ( &indices[0], sizeof( indices )/ sizeof( indices[0] ) );
420 return texturedQuadGeometry;
423 Geometry MetaballExplosionController::CreateGeometryComposition()
425 float aspect = (float)mScreenSize.y / (float)mScreenSize.x;
427 // Create vertices and specify their color
428 float xsize = mScreenSize.x * 0.5;
430 //We create the meshdata for the metaballs
431 struct VertexPosition { Vector2 position; };
432 struct VertexTexture { Vector2 texture; };
433 struct VertexNormal { Vector3 normal; };
435 VertexPosition vertices[] = {
436 { Vector2( -xsize, -xsize * aspect) },
437 { Vector2( xsize, -xsize * aspect) },
438 { Vector2( -xsize, xsize * aspect) },
439 { Vector2( xsize, xsize * aspect) }
442 VertexTexture textures[] = {
443 { Vector2(0.0f, 0.0f) },
444 { Vector2(1.0f, 0.0f) },
445 { Vector2(0.0f, 1.0f) },
446 { Vector2(1.0f, 1.0f) }
449 unsigned int numberOfVertices = sizeof(vertices)/sizeof(VertexPosition);
452 Property::Map positionVertexFormat;
453 positionVertexFormat["aPosition"] = Property::VECTOR2;
454 PropertyBuffer positionVertices = PropertyBuffer::New( positionVertexFormat );
455 positionVertices.SetData( vertices, numberOfVertices );
458 Property::Map textureVertexFormat;
459 textureVertexFormat["aTexture"] = Property::VECTOR2;
460 PropertyBuffer textureVertices = PropertyBuffer::New( textureVertexFormat );
461 textureVertices.SetData( textures, numberOfVertices );
464 unsigned short indices[] = { 0, 3, 1, 0, 2, 3 };
466 // Create the geometry object
467 Geometry texturedQuadGeometry = Geometry::New();
468 texturedQuadGeometry.AddVertexBuffer( positionVertices );
469 texturedQuadGeometry.AddVertexBuffer( textureVertices );
471 texturedQuadGeometry.SetIndexBuffer ( &indices[0], sizeof( indices )/ sizeof( indices[0] ) );
473 return texturedQuadGeometry;
476 float randomNumber(float lowest, float highest)
478 float range=(highest-lowest);
479 return lowest+range*rand()/RAND_MAX;
482 void MetaballExplosionController::CreateMetaballActors()
484 //Create the shader for the metaballs
485 Shader shader = Shader::New( METABALL_VERTEX_SHADER, METABALL_FRAG_SHADER );
487 Geometry metaballGeom = CreateGeometry();
488 Renderer renderer = Renderer::New( metaballGeom, shader );
489 renderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
490 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::ONE );
491 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ONE );
492 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE );
493 renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ONE );
495 //Initialization of each of the metaballs
496 for( int i = 0; i < METABALL_NUMBER; i++ )
498 mMetaballs[i].position = Vector2(0.0f, 0.0f);
499 mMetaballs[i].radius = mMetaballs[i].initRadius = randomNumber(0.05f,0.07f);
501 mMetaballs[i].actor = Actor::New( );
502 mMetaballs[i].actor.SetName("Metaball");
503 mMetaballs[i].actor.SetScale( 1.0f );
504 mMetaballs[i].actor.SetParentOrigin( ParentOrigin::CENTER );
505 mMetaballs[i].actor.AddRenderer( renderer );
507 mMetaballs[i].positionIndex = mMetaballs[i].actor.RegisterProperty( "uPositionMetaball", mMetaballs[i].position );
509 mMetaballs[i].positionVarIndex = mMetaballs[i].actor.RegisterProperty( "uPositionVar", Vector2(0.f,0.f) );
511 mMetaballs[i].actor.RegisterProperty( "uGravityVector", Vector2(randomNumber(-0.2,0.2),randomNumber(-0.2,0.2)) );
513 mMetaballs[i].actor.RegisterProperty( "uRadius", mMetaballs[i].radius );
515 mMetaballs[i].actor.RegisterProperty( "uRadiusVar", 0.f );
517 mMetaballs[i].actor.SetSize(400, 400);
521 mMetaballRoot = Actor::New();
522 mMetaballRoot.SetParentOrigin( ParentOrigin::CENTER );
523 for( int i = 0; i < METABALL_NUMBER; i++ )
525 mMetaballRoot.Add( mMetaballs[i].actor );
528 //Initialization of variables related to metaballs
529 mMetaballPosVariation = Vector2(0,0);
530 mMetaballPosVariationFrom = Vector2(0,0);
531 mMetaballPosVariationTo = Vector2(0,0);
532 mCurrentTouchPosition = Vector2(0,0);
535 void MetaballExplosionController::CreateMetaballImage()
537 //We create an FBO and a render task to create to render the metaballs with a fragment shader
538 Stage stage = Stage::GetCurrent();
539 mMetaballFBO = FrameBufferImage::New(mScreenSize.x, mScreenSize.y, Pixel::RGBA8888, RenderBuffer::COLOR_DEPTH);
542 stage.Add(mMetaballRoot);
544 //Creation of the render task used to render the metaballs
545 RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
546 RenderTask task = taskList.CreateTask();
547 task.SetRefreshRate( RenderTask::REFRESH_ALWAYS );
548 task.SetSourceActor( mMetaballRoot );
549 task.SetExclusive(true);
550 task.SetClearColor( Color::BLACK );
551 task.SetClearEnabled( true );
552 task.SetTargetFrameBuffer( mMetaballFBO );
555 void MetaballExplosionController::AddRefractionImage()
557 //Create Gaussian blur for the rendered image
558 FrameBufferImage fbo;
559 fbo = FrameBufferImage::New( mScreenSize.x, mScreenSize.y, Pixel::RGBA8888, RenderBuffer::COLOR_DEPTH);
561 GaussianBlurView gbv = GaussianBlurView::New(5, 2.0f, Pixel::RGBA8888, 0.5f, 0.5f, true);
562 gbv.SetBackgroundColor(Color::TRANSPARENT);
563 gbv.SetUserImageAndOutputRenderTarget( mMetaballFBO, fbo );
564 gbv.SetSize(mScreenSize.x, mScreenSize.y);
565 Stage::GetCurrent().Add(gbv);
569 Shader shader = Shader::New( METABALL_VERTEX_SHADER, REFRACTION_FRAG_SHADER );
571 //Create new texture set
572 TextureSet textureSet = TextureSet::New();
573 TextureSetImage( textureSet, 0u, mBackImage );
574 TextureSetImage( textureSet, 1u, fbo );
577 Geometry metaballGeom = CreateGeometryComposition();
579 Renderer mRenderer = Renderer::New( metaballGeom, shader );
580 mRenderer.SetTextures( textureSet );
582 mCompositionActor = Actor::New( );
583 mCompositionActor.SetParentOrigin(ParentOrigin::CENTER);
584 mCompositionActor.SetPosition(Vector3(0.0f, 0.0f, 0.0f));
585 mCompositionActor.SetSize(mScreenSize.x, mScreenSize.y);
587 mCompositionActor.AddRenderer( mRenderer );
589 Vector2 metaballCenter(0.0,0);
590 metaballCenter.x = metaballCenter.x * 0.5;
591 metaballCenter.y = metaballCenter.y * 0.5;
593 mPositionIndex = mCompositionActor.RegisterProperty( "uPositionMetaball", metaballCenter );
595 SetPositionToMetaballs(metaballCenter);
597 mCompositionActor.SetSize(mScreenSize.x, mScreenSize.y);
599 Stage stage = Stage::GetCurrent();
600 stage.Add( mCompositionActor );
603 void MetaballExplosionController::CreateAnimations()
607 for( int i = 0; i < METABALL_NUMBER; i++ )
610 KeyFrames keySinCosVariation = KeyFrames::New();
611 Vector2 sinCosVariation(0,0);
613 direction.x = randomNumber(-100.f,100.f);
614 direction.y = randomNumber(-100.f,100.f);
616 direction.Normalize();
619 for( int j = 0; j < 360; j++ )
621 sinCosVariation.x = sin(j * Math::PI/180.f) * direction.x;
622 sinCosVariation.y = cos(j * Math::PI/180.f) * direction.y;
624 keySinCosVariation.Add(key, sinCosVariation);
627 mPositionVarAnimation[i] = Animation::New(3.f);
628 mPositionVarAnimation[i].AnimateBetween(Property( mMetaballs[i].actor, mMetaballs[i].positionVarIndex ), keySinCosVariation);
629 mPositionVarAnimation[i].SetLooping( true );
630 mPositionVarAnimation[i].Play();
634 void MetaballExplosionController::ResetMetaballs(bool resetAnims)
636 for( int i = 0; i < METABALL_NUMBER; i++ )
638 if (mDispersionAnimation[i])
639 mDispersionAnimation[i].Clear();
641 mMetaballs[i].position = Vector2(0.0f, 0.0f);
642 mMetaballs[i].actor.SetProperty(mMetaballs[i].positionIndex, mMetaballs[i].position);
644 mTimerDispersion.Stop();
647 mCompositionActor.SetProperty( mPositionIndex, Vector2(0,0) );
650 void MetaballExplosionController::DisperseBallAnimation(int ball)
653 position.x = randomNumber(-1.5f,1.5f);
654 position.y = randomNumber(-1.5f,1.5f);
656 mDispersionAnimation[ball] = Animation::New(2.0f * mTimeMult);
657 mDispersionAnimation[ball].AnimateTo( Property(mMetaballs[ball].actor, mMetaballs[ball].positionIndex), position);
658 mDispersionAnimation[ball].Play();
660 if( ball == METABALL_NUMBER - 1 )
661 mDispersionAnimation[ball].FinishedSignal().Connect( this, &MetaballExplosionController::LaunchResetMetaballPosition );
664 void MetaballExplosionController::LaunchResetMetaballPosition(Animation &source)
666 for( int i = 0; i < METABALL_NUMBER; i++ )
668 mDispersionAnimation[i] = Animation::New(1.5f + i*0.25f*mTimeMult);
669 mDispersionAnimation[i].AnimateTo(Property(mMetaballs[i].actor, mMetaballs[i].positionIndex), Vector2(0,0));
670 mDispersionAnimation[i].Play();
672 if( i == METABALL_NUMBER - 1 )
673 mDispersionAnimation[i].FinishedSignal().Connect( this, &MetaballExplosionController::EndDisperseAnimation );
677 void MetaballExplosionController::EndDisperseAnimation(Animation &source)
679 mCompositionActor.SetProperty( mPositionIndex, Vector2(0,0) );
682 bool MetaballExplosionController::OnTimerDispersionTick()
684 if( mDispersion < METABALL_NUMBER )
686 DisperseBallAnimation(mDispersion);
692 void MetaballExplosionController::SetPositionToMetaballs(Vector2 & metaballCenter)
694 //We set the position for the metaballs based on click position
695 for( int i = 0; i < METABALL_NUMBER; i++ )
697 mMetaballs[i].position = metaballCenter;
698 mMetaballs[i].actor.SetProperty(mMetaballs[i].positionIndex, mMetaballs[i].position);
701 mCompositionActor.SetProperty( mPositionIndex, metaballCenter );
704 bool MetaballExplosionController::OnTouch( Actor actor, const TouchData& touch )
706 float aspectR = mScreenSize.y / mScreenSize.x;
708 switch( touch.GetState( 0 ) )
710 case PointState::DOWN:
712 ResetMetaballs(true);
714 const Vector2 screen = touch.GetScreenPosition( 0 );
715 Vector2 metaballCenter = Vector2((screen.x / mScreenSize.x) - 0.5, (aspectR * (mScreenSize.y - screen.y) / mScreenSize.y) - 0.5) * 2.0;
716 SetPositionToMetaballs(metaballCenter);
720 case PointState::MOTION:
722 const Vector2 screen = touch.GetScreenPosition( 0 );
723 Vector2 metaballCenter = Vector2((screen.x / mScreenSize.x) - 0.5, (aspectR * (mScreenSize.y - screen.y) / mScreenSize.y) - 0.5) * 2.0;
724 SetPositionToMetaballs(metaballCenter);
728 case PointState::LEAVE:
729 case PointState::INTERRUPTED:
731 mTimerDispersion.Start();
740 void MetaballExplosionController::OnKeyEvent(const KeyEvent& event)
742 if(event.state == KeyEvent::Down)
744 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
752 //-----------------------------------------------------------------------------------------------
756 //-----------------------------------------------------------------------------------------------
758 void RunTest( Application& application )
760 MetaballExplosionController test( application );
762 application.MainLoop();
765 // Entry point for Linux & Tizen applications
767 int DALI_EXPORT_API main( int argc, char **argv )
769 Application application = Application::New( &argc, &argv );
771 RunTest( application );