X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fevent%2Fanimation%2Fpath-impl.cpp;h=c891349034581ba2f78a009a59fc63f7e93ef9de;hb=53f9fe2ef16f8124ab976c9995146a0fd342775e;hp=3d0a46c71b8beb4aaf5eff77aee266eaf81924a7;hpb=ee3018b578065010be4c56cacf99a294140ab120;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/event/animation/path-impl.cpp b/dali/internal/event/animation/path-impl.cpp index 3d0a46c..c891349 100644 --- a/dali/internal/event/animation/path-impl.cpp +++ b/dali/internal/event/animation/path-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 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. @@ -17,6 +17,13 @@ // CLASS HEADER #include + +// EXTERNAL INCLUDES +#include // for strcmp + +// INTERNAL INCLUDES +#include +#include #include namespace Dali @@ -32,9 +39,9 @@ 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::ControlPoints ) -DALI_PROPERTY_TABLE_END( DEFAULT_DERIVED_HANDLE_PROPERTY_START_INDEX ) +DALI_PROPERTY( "points", ARRAY, true, false, false, Dali::Path::Property::POINTS ) +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 @@ -55,6 +62,18 @@ 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(); +} + +TypeRegistration mType( typeid(Dali::Path), typeid(Dali::Handle), Create, PathDefaultProperties ); + +inline bool PathIsComplete(const Dali::Vector& point, const Dali::Vector& controlPoint) +{ + return ( point.Size() > 1 && controlPoint.Size() == (point.Size()-1)*2 ); +} + } //Unnamed namespace Path* Path::New() @@ -63,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) { @@ -80,141 +97,73 @@ 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.push_back( i ); - } -} - -const char* Path::GetDefaultPropertyName(Property::Index index) const +Property::Value Path::GetDefaultProperty( Property::Index index ) const { - if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) ) + if( index == Dali::Path::Property::POINTS ) { - return DEFAULT_PROPERTY_DETAILS[index].name; - } - - // index out of range - return NULL; -} + Property::Value value( Property::ARRAY ); + Property::Array* array = value.GetArray(); + Property::Array::SizeType pointCount = mPoint.Count(); -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 + if( array ) { - index = i; - break; + array->Reserve( pointCount ); + for( Property::Array::SizeType i = 0; i < pointCount; ++i ) + { + array->PushBack( mPoint[i] ); + } } + return value; } - return index; -} - -Property::Type Path::GetDefaultPropertyType(Property::Index index) const -{ - if( index < DEFAULT_PROPERTY_COUNT ) + else if( index == Dali::Path::Property::CONTROL_POINTS ) { - return DEFAULT_PROPERTY_DETAILS[index].type; - } + Property::Value value( Property::ARRAY ); + Property::Array* array = value.GetArray(); + Property::Array::SizeType controlpointCount = mControlPoint.Count(); - // index out of range - return Property::NONE; -} - -Property::Value Path::GetDefaultProperty( Property::Index index ) const -{ - Property::Value value; - if( index == Dali::Path::Property::Points ) - { - size_t pointCount( mPoint.Size() ); - for( size_t i( 0 ); i != pointCount; ++i ) - { - value.AppendItem( mPoint[i] ); - } - } - else if( index == Dali::Path::Property::ControlPoints ) - { - size_t controlpointCount( mControlPoint.Size() ); - for( size_t i( 0 ); i != controlpointCount; ++i ) + if( array ) { - value.AppendItem( mControlPoint[i] ); + array->Reserve( controlpointCount ); + for( Property::Array::SizeType i = 0; i < controlpointCount; ++i ) + { + array->PushBack( mControlPoint[i] ); + } } + return value; } - return value; + return Property::Value(); } void Path::SetDefaultProperty(Property::Index index, const Property::Value& propertyValue) { - if( index == Dali::Path::Property::Points ) + const Property::Array* array = propertyValue.GetArray(); + if( array ) { - Property::Array propertyArray; - propertyValue.Get(propertyArray); - - size_t propertyArrayCount = propertyArray.size(); - mPoint.Resize( propertyArrayCount ); - for( size_t i(0); i!=propertyArrayCount; ++i ) + Property::Array::SizeType propertyArrayCount = array->Count(); + if( index == Dali::Path::Property::POINTS ) { - propertyArray[i].Get( mPoint[i]); + mPoint.Reserve( propertyArrayCount ); + for( Property::Array::SizeType i = 0; i < propertyArrayCount; ++i ) + { + Vector3 point; + array->GetElementAt( i ).Get( point ); + mPoint.PushBack( point ); + } } - } - else if( index == Dali::Path::Property::ControlPoints ) - { - Property::Array propertyArray; - propertyValue.Get(propertyArray); - - size_t propertyArrayCount = propertyArray.size(); - mControlPoint.Resize( propertyArrayCount ); - for( size_t i(0); i!=propertyArrayCount; ++i ) + else if( index == Dali::Path::Property::CONTROL_POINTS ) { - propertyArray[i].Get( mControlPoint[i]); + mControlPoint.Reserve( propertyArrayCount ); + for( Property::Array::SizeType i = 0; i < propertyArrayCount; ++i ) + { + Vector3 point; + array->GetElementAt( i ).Get( point ); + mControlPoint.PushBack( point ); + } } } } -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 ); @@ -225,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( (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( t * static_cast( numSegs ) ); + float segLength = 1.0f / static_cast( numSegs ); + float segStart = static_cast( segment ) * segLength; + tLocal = (t - segStart) * static_cast( 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) - { - position = point0; - tangent = ( controlPoint0 - point0 ) * 3.0f; - tangent.Normalize(); - } - else if( (1.0 - tLocal) < Math::MACHINE_EPSILON_1) + if( !SampleAt(t, position, tangent) ) { - 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 ); - //X - Vector4 cVect( point0.x, controlPoint0.x, controlPoint1.x, point1.x); + //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]; - Vector4 A = BezierBasis * cVect; - position.x = sVect.Dot4(A); - tangent.x = sVectDerivative.Dot(Vector3(A)); + 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 ); - //Y - cVect.x = point0.y; - cVect.y = controlPoint0.y; - cVect.z = controlPoint1.y; - cVect.w = point1.y; + //X + Vector4 cVect( point0.x, controlPoint0.x, controlPoint1.x, point1.x); - A = BezierBasis * cVect; - position.y = sVect.Dot4(A); - tangent.y = sVectDerivative.Dot(Vector3(A)); + Vector4 A = BezierBasis * cVect; + position.x = sVect.Dot4(A); + tangent.x = sVectDerivative.Dot(Vector3(A)); - //Z - cVect.x = point0.z; - cVect.y = controlPoint0.z; - cVect.z = controlPoint1.z; - cVect.w = point1.z; + //Y + cVect.x = point0.y; + cVect.y = controlPoint0.y; + cVect.z = controlPoint1.y; + cVect.w = point1.y; - A = BezierBasis * cVect; - position.z = sVect.Dot4(A); - tangent.z = sVectDerivative.Dot(Vector3(A)); + A = BezierBasis * cVect; + position.y = sVect.Dot4(A); + tangent.y = sVectDerivative.Dot(Vector3(A)); - tangent.Normalize(); + //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)); + + 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( mPoint.Size() ); } -} // Internal -} // Dali +void Path::ClearPoints() +{ + mPoint.Clear(); +} +void Path::ClearControlPoints() +{ + mControlPoint.Clear(); +} +} // Internal +} // Dali