use modern construct '= default' for special functions.
[platform/core/uifw/dali-core.git] / dali / internal / event / animation / path-impl.cpp
index afd9d99..c891349 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,9 +22,9 @@
 #include <cstring> // for strcmp
 
 // INTERNAL INCLUDES
-#include <dali/internal/event/common/property-helper.h>
 #include <dali/public-api/object/property-array.h>
 #include <dali/public-api/object/type-registry.h>
+#include <dali/internal/event/common/property-helper.h>
 
 namespace Dali
 {
@@ -40,8 +40,8 @@ namespace
 //              Name             Type   writable animatable constraint-input  enum for index-checking
 DALI_PROPERTY_TABLE_BEGIN
 DALI_PROPERTY( "points",         ARRAY, true, false, false,   Dali::Path::Property::POINTS         )
-DALI_PROPERTY( "control-points", ARRAY, true, false, false,   Dali::Path::Property::CONTROL_POINTS )
-DALI_PROPERTY_TABLE_END( DEFAULT_OBJECT_PROPERTY_START_INDEX )
+DALI_PROPERTY( "controlPoints",  ARRAY, true, false, false,   Dali::Path::Property::CONTROL_POINTS )
+DALI_PROPERTY_TABLE_END( DEFAULT_OBJECT_PROPERTY_START_INDEX, PathDefaultProperties )
 
 /**
  * These coefficient arise from the cubic polynomial equations for
@@ -62,13 +62,17 @@ const float BezierBasisCoeff[] = {  -1.0f,  3.0f, -3.0f, 1.0f,
 
 const Dali::Matrix BezierBasis = Dali::Matrix( BezierBasisCoeff );
 
-
 Dali::BaseHandle Create()
 {
   return Dali::Path::New();
 }
 
-Dali::TypeRegistration mType( typeid(Dali::Path), typeid(Dali::Handle), Create );
+TypeRegistration mType( typeid(Dali::Path), typeid(Dali::Handle), Create, PathDefaultProperties );
+
+inline bool PathIsComplete(const Dali::Vector<Vector3>& point, const Dali::Vector<Vector3>& controlPoint)
+{
+  return ( point.Size() > 1 && controlPoint.Size() == (point.Size()-1)*2 );
+}
 
 } //Unnamed namespace
 
@@ -78,13 +82,11 @@ Path* Path::New()
 }
 
 Path::Path()
-: Object()
+: Object( nullptr ) // we don't have our own scene object
 {
 }
 
-Path::~Path()
-{
-}
+Path::~Path() = default;
 
 Path* Path::Clone(const Path& path)
 {
@@ -95,60 +97,6 @@ Path* Path::Clone(const Path& path)
   return clone;
 }
 
-unsigned int Path::GetDefaultPropertyCount() const
-{
-  return DEFAULT_PROPERTY_COUNT;
-}
-
-void Path::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
-{
-  indices.Reserve( DEFAULT_PROPERTY_COUNT );
-
-  for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
-  {
-    indices.PushBack( i );
-  }
-}
-
-const char* Path::GetDefaultPropertyName(Property::Index index) const
-{
-  if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
-  {
-    return DEFAULT_PROPERTY_DETAILS[index].name;
-  }
-
-  // index out of range
-  return NULL;
-}
-
-Property::Index Path::GetDefaultPropertyIndex(const std::string& name) const
-{
-  Property::Index index = Property::INVALID_INDEX;
-
-  // Look for name in default properties
-  for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
-  {
-    const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
-    if( 0 == strcmp( name.c_str(), property->name ) ) // dont want to convert rhs to string
-    {
-      index = i;
-      break;
-    }
-  }
-  return index;
-}
-
-Property::Type Path::GetDefaultPropertyType(Property::Index index) const
-{
-  if( index < DEFAULT_PROPERTY_COUNT )
-  {
-    return DEFAULT_PROPERTY_DETAILS[index].type;
-  }
-
-  // index out of range
-  return Property::NONE;
-}
-
 Property::Value Path::GetDefaultProperty( Property::Index index ) const
 {
   if( index == Dali::Path::Property::POINTS )
@@ -216,36 +164,6 @@ void Path::SetDefaultProperty(Property::Index index, const Property::Value& prop
   }
 }
 
-bool Path::IsDefaultPropertyWritable(Property::Index index) const
-{
-  if( index < DEFAULT_PROPERTY_COUNT )
-  {
-    return DEFAULT_PROPERTY_DETAILS[index].writable;
-  }
-
-  return false;
-}
-
-bool Path::IsDefaultPropertyAnimatable(Property::Index index) const
-{
-  if( index < DEFAULT_PROPERTY_COUNT )
-  {
-    return DEFAULT_PROPERTY_DETAILS[index].animatable;
-  }
-
-  return false;
-}
-
-bool Path::IsDefaultPropertyAConstraintInput( Property::Index index ) const
-{
-  if( index < DEFAULT_PROPERTY_COUNT )
-  {
-    return DEFAULT_PROPERTY_DETAILS[index].constraintInput;
-  }
-
-  return false;
-}
-
 void Path::AddPoint(const Vector3& point )
 {
   mPoint.PushBack( point );
@@ -256,20 +174,20 @@ void Path::AddControlPoint(const Vector3& point )
   mControlPoint.PushBack( point );
 }
 
-unsigned int Path::GetNumberOfSegments() const
+uint32_t Path::GetNumberOfSegments() const
 {
-  return (mPoint.Size()>1)?mPoint.Size()-1:0;
+  return static_cast<uint32_t>( (mPoint.Size()>1) ? mPoint.Size()-1 : 0 );
 }
 
 void Path::GenerateControlPoints( float curvature )
 {
-  unsigned int numSegments = GetNumberOfSegments();
+  uint32_t numSegments = GetNumberOfSegments();
   DALI_ASSERT_ALWAYS( numSegments > 0 && "Need at least 1 segment to generate control points" ); // need at least 1 segment
 
   mControlPoint.Resize( numSegments * 2);
 
   //Generate two control points for each segment
-  for( unsigned int i(0); i<numSegments; ++i )
+  for( uint32_t i(0); i<numSegments; ++i )
   {
     //Segment end-points
     Vector3 p1 = mPoint[i];
@@ -320,10 +238,10 @@ void Path::GenerateControlPoints( float curvature )
   }
 }
 
-void Path::FindSegmentAndProgress( float t, unsigned int& segment, float& tLocal ) const
+void Path::FindSegmentAndProgress( float t, uint32_t& segment, float& tLocal ) const
 {
   //Find segment and local progress
-  unsigned int numSegs = GetNumberOfSegments();
+  uint32_t numSegs = GetNumberOfSegments();
 
   if( t <= 0.0f || numSegs == 0 )
   {
@@ -337,189 +255,212 @@ void Path::FindSegmentAndProgress( float t, unsigned int& segment, float& tLocal
   }
   else
   {
-    segment = t * numSegs;
-    float segLength = 1.0f / numSegs;
-    float segStart  = (float)segment * segLength;
-    tLocal = (t - segStart) * numSegs;
+    segment = static_cast<uint32_t>( t * static_cast<float>( numSegs ) );
+    float segLength = 1.0f / static_cast<float>( numSegs );
+    float segStart  = static_cast<float>( segment ) * segLength;
+    tLocal = (t - segStart) * static_cast<float>( numSegs );
   }
 }
 
 void Path::Sample( float t, Vector3& position, Vector3& tangent ) const
 {
-  DALI_ASSERT_ALWAYS(mPoint.Size() > 1 && mControlPoint.Size() == (mPoint.Size()-1)*2 && "Spline not fully initialized" );
-
-  unsigned int segment;
-  float tLocal;
-  FindSegmentAndProgress( t, segment, tLocal );
-
-  //Get points and control points in the segment
-  const Vector3& controlPoint0 = mControlPoint[2*segment];
-  const Vector3& controlPoint1 = mControlPoint[2*segment+1];
-  const Vector3& point0 = mPoint[segment];
-  const Vector3& point1 = mPoint[segment+1];
-
-  if(tLocal < Math::MACHINE_EPSILON_1)
+  if( !SampleAt(t, position, tangent) )
   {
-    position = point0;
-    tangent = ( controlPoint0 - point0 ) * 3.0f;
-    tangent.Normalize();
-  }
-  else if( (1.0 - tLocal) < Math::MACHINE_EPSILON_1)
-  {
-    position = point1;
-    tangent = ( point1 - controlPoint1 ) * 3.0f;
-    tangent.Normalize();
+    DALI_ASSERT_ALWAYS(!"Spline not fully initialized" );
   }
-  else
+}
+
+bool Path::SampleAt( float t, Vector3& position, Vector3& tangent ) const
+{
+  bool done = false;
+
+  if( PathIsComplete(mPoint, mControlPoint) )
   {
-    const Vector4 sVect(tLocal*tLocal*tLocal, tLocal*tLocal, tLocal, 1.0f );
-    const Vector3 sVectDerivative(3.0f*tLocal*tLocal, 2.0f*tLocal, 1.0f );
+    uint32_t segment;
+    float tLocal;
+    FindSegmentAndProgress( t, segment, tLocal );
+
+    //Get points and control points in the segment
+    const Vector3& controlPoint0 = mControlPoint[2*segment];
+    const Vector3& controlPoint1 = mControlPoint[2*segment+1];
+    const Vector3& point0 = mPoint[segment];
+    const Vector3& point1 = mPoint[segment+1];
+
+    if(tLocal < Math::MACHINE_EPSILON_1)
+    {
+      position = point0;
+      tangent = ( controlPoint0 - point0 ) * 3.0f;
+      tangent.Normalize();
+    }
+    else if( (1.0 - tLocal) < Math::MACHINE_EPSILON_1)
+    {
+      position = point1;
+      tangent = ( point1 - controlPoint1 ) * 3.0f;
+      tangent.Normalize();
+    }
+    else
+    {
+      const Vector4 sVect(tLocal*tLocal*tLocal, tLocal*tLocal, tLocal, 1.0f );
+      const Vector3 sVectDerivative(3.0f*tLocal*tLocal, 2.0f*tLocal, 1.0f );
 
-    //X
-    Vector4  cVect( point0.x, controlPoint0.x, controlPoint1.x,  point1.x);
+      //X
+      Vector4  cVect( point0.x, controlPoint0.x, controlPoint1.x,  point1.x);
 
-    Vector4 A = BezierBasis * cVect;
-    position.x = sVect.Dot4(A);
-    tangent.x  = sVectDerivative.Dot(Vector3(A));
+      Vector4 A = BezierBasis * cVect;
+      position.x = sVect.Dot4(A);
+      tangent.x  = sVectDerivative.Dot(Vector3(A));
 
-    //Y
-    cVect.x  = point0.y;
-    cVect.y  = controlPoint0.y;
-    cVect.z  = controlPoint1.y;
-    cVect.w  = point1.y;
+      //Y
+      cVect.x  = point0.y;
+      cVect.y  = controlPoint0.y;
+      cVect.z  = controlPoint1.y;
+      cVect.w  = point1.y;
 
-    A = BezierBasis * cVect;
-    position.y = sVect.Dot4(A);
-    tangent.y  = sVectDerivative.Dot(Vector3(A));
+      A = BezierBasis * cVect;
+      position.y = sVect.Dot4(A);
+      tangent.y  = sVectDerivative.Dot(Vector3(A));
 
-    //Z
-    cVect.x  = point0.z;
-    cVect.y  = controlPoint0.z;
-    cVect.z  = controlPoint1.z;
-    cVect.w  = point1.z;
+      //Z
+      cVect.x  = point0.z;
+      cVect.y  = controlPoint0.z;
+      cVect.z  = controlPoint1.z;
+      cVect.w  = point1.z;
 
-    A = BezierBasis * cVect;
-    position.z = sVect.Dot4(A);
-    tangent.z  = sVectDerivative.Dot(Vector3(A));
+      A = BezierBasis * cVect;
+      position.z = sVect.Dot4(A);
+      tangent.z  = sVectDerivative.Dot(Vector3(A));
 
-    tangent.Normalize();
+      tangent.Normalize();
+    }
+
+    done = true;
   }
+
+  return done;
 }
 
-Vector3 Path::SamplePosition( float t ) const
+bool Path::SamplePosition( float t, Vector3& position ) const
 {
-  DALI_ASSERT_ALWAYS(mPoint.Size() > 1 && mControlPoint.Size() == (mPoint.Size()-1)*2 && "Spline not fully initialized" );
+  bool done = false;
 
-  unsigned int segment;
-  float tLocal;
-  FindSegmentAndProgress( t, segment, tLocal );
+  if( PathIsComplete(mPoint, mControlPoint) )
+  {
+    uint32_t segment;
+    float tLocal;
+    FindSegmentAndProgress( t, segment, tLocal );
 
-  const Vector3& controlPoint0 = mControlPoint[2*segment];
-  const Vector3& controlPoint1 = mControlPoint[2*segment+1];
-  const Vector3& point0 = mPoint[segment];
-  const Vector3& point1 = mPoint[segment+1];
+    const Vector3& controlPoint0 = mControlPoint[2*segment];
+    const Vector3& controlPoint1 = mControlPoint[2*segment+1];
+    const Vector3& point0 = mPoint[segment];
+    const Vector3& point1 = mPoint[segment+1];
 
-  Vector3 position;
-  if(tLocal < Math::MACHINE_EPSILON_1)
-  {
-    position = point0;
-  }
-  else if( (1.0 - tLocal) < Math::MACHINE_EPSILON_1)
-  {
-    position = point1;
-  }
-  else
-  {
-    const Vector4 sVect(tLocal*tLocal*tLocal, tLocal*tLocal, tLocal, 1.0f );
-
-    //X
-    Vector4  cVect( point0.x, controlPoint0.x, controlPoint1.x,  point1.x);
-    position.x = sVect.Dot4(BezierBasis * cVect);
-
-    //Y
-    cVect.x  = point0.y;
-    cVect.y  = controlPoint0.y;
-    cVect.z  = controlPoint1.y;
-    cVect.w  = point1.y;
-    position.y = sVect.Dot4(BezierBasis * cVect);
-
-    //Z
-    cVect.x  = point0.z;
-    cVect.y  = controlPoint0.z;
-    cVect.z  = controlPoint1.z;
-    cVect.w  = point1.z;
-    position.z = sVect.Dot4(BezierBasis * cVect);
+    if(tLocal < Math::MACHINE_EPSILON_1)
+    {
+      position = point0;
+    }
+    else if( (1.0 - tLocal) < Math::MACHINE_EPSILON_1)
+    {
+      position = point1;
+    }
+    else
+    {
+      const Vector4 sVect(tLocal*tLocal*tLocal, tLocal*tLocal, tLocal, 1.0f );
+
+      //X
+      Vector4  cVect( point0.x, controlPoint0.x, controlPoint1.x,  point1.x);
+      position.x = sVect.Dot4(BezierBasis * cVect);
+
+      //Y
+      cVect.x  = point0.y;
+      cVect.y  = controlPoint0.y;
+      cVect.z  = controlPoint1.y;
+      cVect.w  = point1.y;
+      position.y = sVect.Dot4(BezierBasis * cVect);
+
+      //Z
+      cVect.x  = point0.z;
+      cVect.y  = controlPoint0.z;
+      cVect.z  = controlPoint1.z;
+      cVect.w  = point1.z;
+      position.z = sVect.Dot4(BezierBasis * cVect);
+    }
+
+    done = true;
   }
 
-  return position;
+  return done;
 }
 
-Vector3 Path::SampleTangent( float t ) const
+bool Path::SampleTangent( float t, Vector3& tangent ) const
 {
-  DALI_ASSERT_ALWAYS(mPoint.Size() > 1 && mControlPoint.Size() == (mPoint.Size()-1)*2 && "Spline not fully initialized" );
+  bool done = false;
 
-  unsigned int segment;
-  float tLocal;
-  FindSegmentAndProgress( t, segment, tLocal );
+  if( PathIsComplete(mPoint, mControlPoint) )
+  {
+    uint32_t segment;
+    float tLocal;
+    FindSegmentAndProgress( t, segment, tLocal );
 
-  const Vector3& controlPoint0 = mControlPoint[2*segment];
-  const Vector3& controlPoint1 = mControlPoint[2*segment+1];
-  const Vector3& point0 = mPoint[segment];
-  const Vector3& point1 = mPoint[segment+1];
+    const Vector3& controlPoint0 = mControlPoint[2*segment];
+    const Vector3& controlPoint1 = mControlPoint[2*segment+1];
+    const Vector3& point0 = mPoint[segment];
+    const Vector3& point1 = mPoint[segment+1];
 
-  Vector3 tangent;
-  if(tLocal < Math::MACHINE_EPSILON_1)
-  {
-    tangent = ( controlPoint0 - point0 ) * 3.0f;
-  }
-  else if( (1.0f - tLocal) < Math::MACHINE_EPSILON_1)
-  {
-    tangent = ( point1 - controlPoint1 ) * 3.0f;
-  }
-  else
-  {
-    const Vector3 sVectDerivative(3.0f*tLocal*tLocal, 2.0f*tLocal, 1.0f );
-
-    //X
-    Vector4  cVect( point0.x, controlPoint0.x, controlPoint1.x,  point1.x);
-    tangent.x  = sVectDerivative.Dot(Vector3(BezierBasis * cVect));
-
-    //Y
-    cVect.x  = point0.y;
-    cVect.y  = controlPoint0.y;
-    cVect.z  = controlPoint1.y;
-    cVect.w  = point1.y;
-    tangent.y  = sVectDerivative.Dot(Vector3(BezierBasis * cVect));
-
-    //Z
-    cVect.x  = point0.z;
-    cVect.y  = controlPoint0.z;
-    cVect.z  = controlPoint1.z;
-    cVect.w  = point1.z;
-    tangent.z  = sVectDerivative.Dot(Vector3(BezierBasis * cVect));
+    if(tLocal < Math::MACHINE_EPSILON_1)
+    {
+      tangent = ( controlPoint0 - point0 ) * 3.0f;
+    }
+    else if( (1.0f - tLocal) < Math::MACHINE_EPSILON_1)
+    {
+      tangent = ( point1 - controlPoint1 ) * 3.0f;
+    }
+    else
+    {
+      const Vector3 sVectDerivative(3.0f*tLocal*tLocal, 2.0f*tLocal, 1.0f );
+
+      //X
+      Vector4  cVect( point0.x, controlPoint0.x, controlPoint1.x,  point1.x);
+      tangent.x  = sVectDerivative.Dot(Vector3(BezierBasis * cVect));
+
+      //Y
+      cVect.x  = point0.y;
+      cVect.y  = controlPoint0.y;
+      cVect.z  = controlPoint1.y;
+      cVect.w  = point1.y;
+      tangent.y  = sVectDerivative.Dot(Vector3(BezierBasis * cVect));
+
+      //Z
+      cVect.x  = point0.z;
+      cVect.y  = controlPoint0.z;
+      cVect.z  = controlPoint1.z;
+      cVect.w  = point1.z;
+      tangent.z  = sVectDerivative.Dot(Vector3(BezierBasis * cVect));
+    }
+
+    tangent.Normalize();
+    done = true;
   }
 
-  tangent.Normalize();
-  return tangent;
+  return done;
 }
 
-Vector3& Path::GetPoint( size_t index )
+Vector3& Path::GetPoint( uint32_t index )
 {
   DALI_ASSERT_ALWAYS( index < mPoint.Size() && "Path: Point index out of bounds" );
 
   return mPoint[index];
 }
 
-Vector3& Path::GetControlPoint( size_t index )
+Vector3& Path::GetControlPoint( uint32_t index )
 {
   DALI_ASSERT_ALWAYS( index < mControlPoint.Size() && "Path: Control Point index out of bounds" );
 
   return mControlPoint[index];
 }
 
-size_t Path::GetPointCount() const
+uint32_t Path::GetPointCount() const
 {
-  return mPoint.Size();
+  return static_cast<uint32_t>( mPoint.Size() );
 }
 
 void Path::ClearPoints()