/*
- * 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.
#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
{
// 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
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
}
Path::Path()
-: Object()
+: Object( nullptr ) // we don't have our own scene object
{
}
-Path::~Path()
-{
-}
+Path::~Path() = default;
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 )
}
}
-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 );
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];
}
}
-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 )
{
}
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()