update bouncing-effect-actor to use new mesh 18/39418/4
authorXiangyin Ma <x1.ma@samsung.com>
Thu, 14 May 2015 15:26:29 +0000 (16:26 +0100)
committerXiangyin Ma <x1.ma@samsung.com>
Thu, 21 May 2015 16:58:02 +0000 (17:58 +0100)
Change-Id: I176a19b711a0f64219592e76df601180865a6e72

dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.cpp
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-overshoot-indicator-impl.cpp

index d78801a..19dc7cc 100644 (file)
 #include <dali-toolkit/internal/controls/scrollable/bouncing-effect-actor.h>
 
 // EXTERNAL INCLUDES
-#include <math.h>
-#include <dali/public-api/animation/constraint.h>
-#include <dali/public-api/shader-effects/shader-effect.h>
+#include <dali/public-api/actors/renderer.h>
+#include <dali/public-api/geometry/geometry.h>
 #include <dali/public-api/math/vector3.h>
+#include <dali/public-api/object/property-buffer.h>
+#include <dali/public-api/object/property-map.h>
+#include <dali/public-api/shader-effects/material.h>
+#include <dali/public-api/shader-effects/shader.h>
 
 namespace Dali
 {
@@ -36,83 +39,91 @@ namespace Internal
 namespace
 {
 // Bouncing effect is presented by stacked three layers with same color and opacity
-const size_t NUM_LAYERS( 3 );
 const Vector3 LAYER_HEIGHTS( 1.f, 27.f/42.f, 13.f/42.f);
-/*
-// use the actor color to paint every layer
-const char* MESH_FRAGMENT_SHADER =
-"void main()\n"
-"{\n"
-"  gl_FragColor = uColor;\n"
-"}\n";
-*/
-// Constraint to move the vertices vertically
-struct VertexPositionConstraint
-{
-  VertexPositionConstraint( float initialY, float range )
-  : mInitialY( initialY ),
-    mRange( range )
-  {
-  }
 
-  void operator()( Vector3& current, const PropertyInputContainer& inputs )
-  {
-    current.y = mInitialY + mRange * fabsf( inputs[0]->GetFloat() );
-  }
+#define MAKE_SHADER(A)#A
+
+// Modify the vertex position according to the bounce coefficient;
+const char* MESH_VERTEX_SHADER = MAKE_SHADER(
+attribute mediump vec3    aPosition1;\n
+attribute mediump vec3    aPosition2;\n
+uniform   mediump mat4    uMvpMatrix;\n
+uniform   mediump vec3    uSize;
+uniform   mediump float   uBounceCoefficient;\n
+\n
+void main()\n
+{\n
+  gl_Position = uMvpMatrix * vec4(mix( aPosition1, aPosition2, abs(uBounceCoefficient) )*uSize, 1.0);\n
+}
+);
 
-  float mInitialY;
-  float mRange;
-};
+// use the actor color to paint every layer
+const char* MESH_FRAGMENT_SHADER = MAKE_SHADER(
+uniform lowp  vec4    uColor;\n
+void main()\n
+{\n
+  gl_FragColor = uColor;\n
+}\n;
+);
 
 } // namespace Anon
 
 Actor CreateBouncingEffectActor( Property::Index& bouncePropertyIndex )
 {
-  Actor meshActor;
-/*
-  Dali::AnimatableMesh             mesh;
-  Dali::MeshActor                  meshActor;
-
-  Dali::AnimatableMesh::Faces faces;
-  faces.reserve( NUM_LAYERS * 6 ); // 2 triangles per layer
-  for( size_t i=0; i<NUM_LAYERS; i++ )
-  {
-    size_t j=i*4;
-    faces.push_back(j); faces.push_back(j+3); faces.push_back(j+1);
-    faces.push_back(j); faces.push_back(j+2); faces.push_back(j+3);
-  }
-
-  mesh = Dali::AnimatableMesh::New(NUM_LAYERS*4, faces); // 4 vertices per layer
-  for( size_t i=0;i<NUM_LAYERS;i++ )
-  {
-    size_t j=i*4;
-    float positionZ = 0.01f*static_cast<float>( i ); // the interval between each layer is 0.01
-    mesh[j  ].SetPosition( Vector3( -0.5f, -0.5f, positionZ ) );
-    mesh[j+1].SetPosition( Vector3( 0.5f, -0.5f, positionZ ) );
-    mesh[j+2].SetPosition( Vector3( -0.5f, -0.5f, positionZ ) );
-    mesh[j+3].SetPosition( Vector3( 0.5f, -0.5f, positionZ ) );
-  }
-
-  meshActor = Dali::MeshActor::New(mesh);
-
-  Dali::ShaderEffect shaderEffect = Dali::ShaderEffect::New( "", MESH_FRAGMENT_SHADER,
-                                                             GEOMETRY_TYPE_UNTEXTURED_MESH,
-                                                             Dali::ShaderEffect::HINT_BLENDING );
-  meshActor.SetShaderEffect(shaderEffect);
-
-  // To control the movement of all vertices with one custom property
-  bouncePropertyIndex = meshActor.RegisterProperty("BounceCoeffcient", 0.f);
-  for( size_t i=0;i<NUM_LAYERS;i++ )
+  // Create the bouncing mesh geometry
+  struct VertexPosition
   {
-    size_t j=i*4;
-    Constraint constraint = Constraint::New<Vector3>( mesh, mesh.GetPropertyIndex(j+2, AnimatableVertex::Property::POSITION ), VertexPositionConstraint(-0.5f, LAYER_HEIGHTS[i]) );
-    constraint.AddSource( Source(meshActor, bouncePropertyIndex) );
-    constraint.Apply();
-
-    constraint = Constraint::New<Vector3>( mesh, mesh.GetPropertyIndex(j+3,  AnimatableVertex::Property::POSITION), VertexPositionConstraint(-0.5f, LAYER_HEIGHTS[i]) );
-    constraint.AddSource( Source(meshActor, bouncePropertyIndex) );
-    constraint.Apply();
-  }*/
+    Vector3 position1;
+    Vector3 position2;
+  };
+  // 4 vertices 2 triangles per layer. The depth interval between each layer is 0.01
+  VertexPosition vertexData[12] = {
+    //bottom layer
+    { Vector3( -0.5f, -0.5f, 0.f ),  Vector3( -0.5f, -0.5f, 0.f )  },
+    { Vector3( 0.5f, -0.5f, 0.f ),   Vector3( 0.5f, -0.5f, 0.f )   },
+    { Vector3( -0.5f, -0.5f, 0.f ),  Vector3( -0.5f, -0.5f + LAYER_HEIGHTS[0], 0.f ) },
+    { Vector3( 0.5f, -0.5f, 0.f ),   Vector3( 0.5f, -0.5f+ LAYER_HEIGHTS[0], 0.f )   },
+    // middle layer
+    { Vector3( -0.5f, -0.5f, 0.01f ),  Vector3( -0.5f, -0.5f, 0.01f )  },
+    { Vector3( 0.5f, -0.5f, 0.01f ),   Vector3( 0.5f, -0.5f, 0.01f )   },
+    { Vector3( -0.5f, -0.5f, 0.01f ),  Vector3( -0.5f, -0.5f + LAYER_HEIGHTS[1], 0.01f ) },
+    { Vector3( 0.5f, -0.5f, 0.01f ),   Vector3( 0.5f, -0.5f+ LAYER_HEIGHTS[1], 0.01f )   },
+    // top layer
+    { Vector3( -0.5f, -0.5f, 0.02f ),  Vector3( -0.5f, -0.5f, 0.02f )  },
+    { Vector3( 0.5f, -0.5f, 0.02f ),   Vector3( 0.5f, -0.5f, 0.02f )   },
+    { Vector3( -0.5f, -0.5f, 0.02f ),  Vector3( -0.5f, -0.5f + LAYER_HEIGHTS[2], 0.02f ) },
+    { Vector3( 0.5f, -0.5f, 0.02f ),   Vector3( 0.5f, -0.5f+ LAYER_HEIGHTS[2], 0.02f )   }
+  };
+  Property::Map vertexFormat;
+  vertexFormat["aPosition1"] = Property::VECTOR3;
+  vertexFormat["aPosition2"] = Property::VECTOR3;
+  PropertyBuffer vertices = PropertyBuffer::New( PropertyBuffer::STATIC, vertexFormat, 12u );
+  vertices.SetData( vertexData );
+
+  unsigned int indexData[18] = { 0,3,1,0,2,3,4,7,5,4,6,7,8,11,9,8,10,11 };
+  Property::Map indexFormat;
+  indexFormat["indices"] = Property::UNSIGNED_INTEGER;
+  PropertyBuffer indices = PropertyBuffer::New( PropertyBuffer::STATIC, indexFormat, 18u );
+  indices.SetData( indexData );
+
+  Geometry meshGeometry = Geometry::New();
+  meshGeometry.AddVertexBuffer( vertices );
+  meshGeometry.SetIndexBuffer( indices );
+
+  // Create material
+  Shader shader = Shader::New( MESH_VERTEX_SHADER, MESH_FRAGMENT_SHADER );
+  Material material = Material::New( shader );
+
+  // Create renderer
+  Renderer renderer = Renderer::New( meshGeometry, material );
+
+  // Create actor
+  Actor meshActor= Actor::New();
+  meshActor.AddRenderer( renderer );
+
+  // Register property
+  bouncePropertyIndex = meshActor.RegisterProperty("bounce-coefficient", 0.f);
+  meshActor.AddUniformMapping( bouncePropertyIndex, "uBounceCoefficient" );
 
   return meshActor;
 }
index 344a761..0d2e728 100644 (file)
@@ -143,14 +143,13 @@ ScrollOvershootEffectRipple::ScrollOvershootEffectRipple( bool vertical, Scrolla
     mOvershoot(0.0f),
     mAnimationStateFlags(0)
 {
-  /*
   mOvershootOverlay = CreateBouncingEffectActor(mEffectOvershootProperty);
   mOvershootOverlay.SetColor(mAttachedScrollView.GetOvershootEffectColor());
   mOvershootOverlay.SetParentOrigin(ParentOrigin::TOP_LEFT);
   mOvershootOverlay.SetAnchorPoint(AnchorPoint::TOP_LEFT);
   mOvershootOverlay.SetDrawMode(DrawMode::OVERLAY);
   mOvershootOverlay.SetVisible(false);
-  */
+
 }
 
 void ScrollOvershootEffectRipple::Apply()
@@ -159,16 +158,16 @@ void ScrollOvershootEffectRipple::Apply()
   mOvershootProperty = IsVertical() ? Toolkit::ScrollView::Property::OVERSHOOT_Y : Toolkit::ScrollView::Property::OVERSHOOT_X;
 
   // make sure height is set, since we only create a constraint for image width
-  //mOvershootOverlay.SetSize(OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.width, OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height);
+  mOvershootOverlay.SetSize(OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.width, OVERSHOOT_BOUNCE_ACTOR_DEFAULT_SIZE.height);
 
-  //mAttachedScrollView.AddOverlay(mOvershootOverlay);
+  mAttachedScrollView.AddOverlay(mOvershootOverlay);
 
   UpdatePropertyNotifications();
 }
 
 void ScrollOvershootEffectRipple::Remove( Scrollable& scrollable )
 {
-//  if(mOvershootOverlay)
+  if(mOvershootOverlay)
   {
     if(mOvershootIncreaseNotification)
     {
@@ -180,14 +179,14 @@ void ScrollOvershootEffectRipple::Remove( Scrollable& scrollable )
       scrollable.Self().RemovePropertyNotification(mOvershootDecreaseNotification);
       mOvershootDecreaseNotification.Reset();
     }
-    //scrollable.RemoveOverlay(mOvershootOverlay);
+    scrollable.RemoveOverlay(mOvershootOverlay);
   }
 }
 
 void ScrollOvershootEffectRipple::Reset()
 {
-//  mOvershootOverlay.SetVisible(false);
-//  mOvershootOverlay.SetProperty( mEffectOvershootProperty, 0.f);
+  mOvershootOverlay.SetVisible(false);
+  mOvershootOverlay.SetProperty( mEffectOvershootProperty, 0.f);
 }
 
 void ScrollOvershootEffectRipple::UpdatePropertyNotifications()
@@ -234,10 +233,59 @@ void ScrollOvershootEffectRipple::UpdatePropertyNotifications()
 
 void ScrollOvershootEffectRipple::SetOvershootEffectColor( const Vector4& color )
 {
+  if(mOvershootOverlay)
+  {
+    mOvershootOverlay.SetColor(color);
+  }
 }
 
 void ScrollOvershootEffectRipple::UpdateVisibility( bool visible )
 {
+  mOvershootOverlay.SetVisible(visible);
+  // make sure overshoot image is correctly placed
+  if( visible )
+  {
+    Actor self = mAttachedScrollView.Self();
+    if(mOvershoot > 0.0f)
+    {
+      // positive overshoot
+      const Vector3 size = mOvershootOverlay.GetCurrentSize();
+      Vector3 relativeOffset;
+      const Vector3 parentSize = self.GetCurrentSize();
+      if(IsVertical())
+      {
+        mOvershootOverlay.SetOrientation( Quaternion( Radian( 0.0f ), Vector3::ZAXIS ) );
+        mOvershootOverlay.SetSize(parentSize.width, GetBounceActorHeight(parentSize.width), size.depth);
+      }
+      else
+      {
+        mOvershootOverlay.SetOrientation( Quaternion( Radian( 1.5f * Math::PI ), Vector3::ZAXIS ) );
+        mOvershootOverlay.SetSize(parentSize.height, GetBounceActorHeight(parentSize.height), size.depth);
+        relativeOffset = Vector3(0.0f, 1.0f, 0.0f);
+      }
+      mOvershootOverlay.SetPosition(relativeOffset * parentSize);
+    }
+    else
+    {
+      // negative overshoot
+      const Vector3 size = mOvershootOverlay.GetCurrentSize();
+      Vector3 relativeOffset;
+      const Vector3 parentSize = self.GetCurrentSize();
+      if(IsVertical())
+      {
+        mOvershootOverlay.SetOrientation( Quaternion( Radian( Math::PI ), Vector3::ZAXIS ) );
+        mOvershootOverlay.SetSize(parentSize.width, GetBounceActorHeight(parentSize.width), size.depth);
+        relativeOffset = Vector3(1.0f, 1.0f, 0.0f);
+      }
+      else
+      {
+        mOvershootOverlay.SetOrientation( Quaternion( Radian( 0.5f * Math::PI ), Vector3::ZAXIS ) );
+        mOvershootOverlay.SetSize(parentSize.height, GetBounceActorHeight(parentSize.height), size.depth);
+        relativeOffset = Vector3(1.0f, 0.0f, 0.0f);
+      }
+      mOvershootOverlay.SetPosition(relativeOffset * parentSize);
+    }
+  }
 }
 
 void ScrollOvershootEffectRipple::OnOvershootNotification(PropertyNotification& source)
@@ -282,8 +330,8 @@ void ScrollOvershootEffectRipple::SetOvershoot(float amount, bool animate)
 
   if( animate && overshootAnimationSpeed > Math::MACHINE_EPSILON_0 )
   {
-    //float currentOvershoot = 0.0f;//fabsf( mOvershootOverlay.GetProperty( mEffectOvershootProperty ).Get<float>() );
-    float duration = 0.05f;//mOvershootOverlay.GetCurrentSize().height * (animatingOn ? (1.0f - currentOvershoot) : currentOvershoot) / overshootAnimationSpeed;
+    float currentOvershoot = fabsf( mOvershootOverlay.GetProperty( mEffectOvershootProperty ).Get<float>() );
+    float duration = mOvershootOverlay.GetCurrentSize().height * (animatingOn ? (1.0f - currentOvershoot) : currentOvershoot) / overshootAnimationSpeed;
 
     if( duration > Math::MACHINE_EPSILON_0 )
     {
@@ -295,14 +343,14 @@ void ScrollOvershootEffectRipple::SetOvershoot(float amount, bool animate)
       }
       mScrollOvershootAnimation = Animation::New(duration);
       mScrollOvershootAnimation.FinishedSignal().Connect( this, &ScrollOvershootEffectRipple::OnOvershootAnimFinished );
-      //mScrollOvershootAnimation.AnimateTo( Property(mOvershootOverlay, mEffectOvershootProperty), amount, TimePeriod(duration) );
+      mScrollOvershootAnimation.AnimateTo( Property(mOvershootOverlay, mEffectOvershootProperty), amount, TimePeriod(duration) );
       mScrollOvershootAnimation.Play();
       mAnimationStateFlags = animatingOn ? AnimatingIn : AnimatingOut;
     }
   }
   else
   {
-    //mOvershootOverlay.SetProperty( mEffectOvershootProperty, amount);
+    mOvershootOverlay.SetProperty( mEffectOvershootProperty, amount);
   }
 }
 
@@ -312,7 +360,7 @@ void ScrollOvershootEffectRipple::OnOvershootAnimFinished(Animation& animation)
   if( mAnimationStateFlags & AnimatingOut )
   {
     // should now be offscreen
-    //mOvershootOverlay.SetVisible(false);
+    mOvershootOverlay.SetVisible(false);
   }
   if( (mAnimationStateFlags & AnimateBack) )
   {