X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fevent%2Fanimation%2Fpath-impl.cpp;h=865c4fa97adb8fd6ee440c1bb9ac1f18c43b21ed;hb=091424324901c46a18959bfc0dd52f7ce8a0a811;hp=94477f2e60efc5fe7288387b78af935f245ccc66;hpb=33a1cfeac36d2573f106567ba8a36ed5133b59f6;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 94477f2..865c4fa 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) 2017 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. @@ -18,8 +18,31 @@ // CLASS HEADER #include +// EXTERNAL INCLUDES +#include // for strcmp + +// INTERNAL INCLUDES +#include +#include +#include + +namespace Dali +{ + +namespace Internal +{ + namespace { + +// Properties + +// 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( "controlPoints", ARRAY, true, false, false, Dali::Path::Property::CONTROL_POINTS ) +DALI_PROPERTY_TABLE_END( DEFAULT_OBJECT_PROPERTY_START_INDEX ) + /** * These coefficient arise from the cubic polynomial equations for * a bezier curve. @@ -39,30 +62,19 @@ const float BezierBasisCoeff[] = { -1.0f, 3.0f, -3.0f, 1.0f, const Dali::Matrix BezierBasis = Dali::Matrix( BezierBasisCoeff ); -struct PropertyDetails +Dali::BaseHandle Create() { - std::string name; ///< The name of the property. - Dali::Property::Type type; ///< The property type. - bool writable:1; ///< Whether the property is writable - bool animatable:1; ///< Whether the property is animatable. - bool constraintInput:1; ///< Whether the property can be used as an input to a constraint. -}; - -const PropertyDetails DEFAULT_PROPERTY_DETAILS[] = {{"points", Dali::Property::ARRAY, true, false, false }, - {"control-points", Dali::Property::ARRAY, true, false, false }, - }; - -const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_DETAILS ) / sizeof( PropertyDetails ); + return Dali::Path::New(); +} -}//Unnamed namespace +Dali::TypeRegistration mType( typeid(Dali::Path), typeid(Dali::Handle), Create ); -namespace Dali +inline bool PathIsComplete(const Dali::Vector& point, const Dali::Vector& controlPoint) { -const Property::Index Path::POINTS = 0; -const Property::Index Path::CONTROL_POINTS = 1; + return ( point.Size() > 1 && controlPoint.Size() == (point.Size()-1)*2 ); +} -namespace Internal -{ +} //Unnamed namespace Path* Path::New() { @@ -70,7 +82,7 @@ Path* Path::New() } Path::Path() -:ProxyObject() +: Object() { } @@ -94,35 +106,34 @@ unsigned int Path::GetDefaultPropertyCount() const void Path::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const { - indices.reserve( DEFAULT_PROPERTY_COUNT ); + indices.Reserve( DEFAULT_PROPERTY_COUNT ); for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i ) { - indices.push_back( i ); + indices.PushBack( i ); } } -const std::string& Path::GetDefaultPropertyName(Property::Index index) const +const char* Path::GetDefaultPropertyName(Property::Index index) const { if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) ) { return DEFAULT_PROPERTY_DETAILS[index].name; } - else - { - // index out of range - static const std::string INVALID_PROPERTY_NAME; - return INVALID_PROPERTY_NAME; - } + + // index out of range + return NULL; } Property::Index Path::GetDefaultPropertyIndex(const std::string& name) const { Property::Index index = Property::INVALID_INDEX; - for( int i(0); iname ) ) // dont want to convert rhs to string { index = i; break; @@ -137,80 +148,79 @@ Property::Type Path::GetDefaultPropertyType(Property::Index index) const { return DEFAULT_PROPERTY_DETAILS[index].type; } - else - { - // index out of range - return Property::NONE; - } + + // index out of range + return Property::NONE; } Property::Value Path::GetDefaultProperty( Property::Index index ) const { - Property::Value value; - switch ( index ) + if( index == Dali::Path::Property::POINTS ) { - case Dali::Path::POINTS: + Property::Value value( Property::ARRAY ); + Property::Array* array = value.GetArray(); + Property::Array::SizeType pointCount = mPoint.Count(); + + if( array ) { - size_t pointCount( mPoint.Size() ); - for( size_t i(0); i!=pointCount; ++i ) + array->Reserve( pointCount ); + for( Property::Array::SizeType i = 0; i < pointCount; ++i ) { - value.AppendItem( mPoint[i] ); + array->PushBack( mPoint[i] ); } - break; } - case Dali::Path::CONTROL_POINTS: + return value; + } + else if( index == Dali::Path::Property::CONTROL_POINTS ) + { + Property::Value value( Property::ARRAY ); + Property::Array* array = value.GetArray(); + Property::Array::SizeType controlpointCount = mControlPoint.Count(); + + if( array ) { - size_t controlpointCount( mControlPoint.Size() ); - for( size_t i(0); i!=controlpointCount; ++i ) + array->Reserve( controlpointCount ); + for( Property::Array::SizeType i = 0; i < controlpointCount; ++i ) { - value.AppendItem( mControlPoint[i] ); + array->PushBack( mControlPoint[i] ); } - break; - } - default: - { - DALI_ASSERT_ALWAYS(false && "Path::Property is out of bounds"); - break; } + return value; } - return value; + return Property::Value(); +} + +Property::Value Path::GetDefaultPropertyCurrentValue( Property::Index index ) const +{ + return GetDefaultProperty( index ); // Event-side only properties } void Path::SetDefaultProperty(Property::Index index, const Property::Value& propertyValue) { - switch ( index ) + const Property::Array* array = propertyValue.GetArray(); + if( array ) { - case Dali::Path::POINTS: + Property::Array::SizeType propertyArrayCount = array->Count(); + if( index == Dali::Path::Property::POINTS ) { - Property::Array propertyArray; - propertyValue.Get(propertyArray); - - size_t propertyArrayCount = propertyArray.size(); - mPoint.Resize( propertyArrayCount ); - for( size_t i(0); i!=propertyArrayCount; ++i ) + mPoint.Reserve( propertyArrayCount ); + for( Property::Array::SizeType i = 0; i < propertyArrayCount; ++i ) { - propertyArray[i].Get( mPoint[i]); + Vector3 point; + array->GetElementAt( i ).Get( point ); + mPoint.PushBack( point ); } - break; } - case Dali::Path::CONTROL_POINTS: + else if( index == Dali::Path::Property::CONTROL_POINTS ) { - Property::Array propertyArray; - propertyValue.Get(propertyArray); - - size_t propertyArrayCount = propertyArray.size(); - mControlPoint.Resize( propertyArrayCount ); - for( size_t i(0); i!=propertyArrayCount; ++i ) + mControlPoint.Reserve( propertyArrayCount ); + for( Property::Array::SizeType i = 0; i < propertyArrayCount; ++i ) { - propertyArray[i].Get( mControlPoint[i]); + Vector3 point; + array->GetElementAt( i ).Get( point ); + mControlPoint.PushBack( point ); } - break; - } - default: - { - DALI_ASSERT_ALWAYS(false && "Path::Property is out of bounds"); - break; } } } @@ -221,10 +231,8 @@ bool Path::IsDefaultPropertyWritable(Property::Index index) const { return DEFAULT_PROPERTY_DETAILS[index].writable; } - else - { - return false; - } + + return false; } bool Path::IsDefaultPropertyAnimatable(Property::Index index) const @@ -233,10 +241,8 @@ bool Path::IsDefaultPropertyAnimatable(Property::Index index) const { return DEFAULT_PROPERTY_DETAILS[index].animatable; } - else - { - return false; - } + + return false; } bool Path::IsDefaultPropertyAConstraintInput( Property::Index index ) const @@ -245,10 +251,8 @@ bool Path::IsDefaultPropertyAConstraintInput( Property::Index index ) const { return DEFAULT_PROPERTY_DETAILS[index].constraintInput; } - else - { - return false; - } + + return false; } void Path::AddPoint(const Vector3& point ) @@ -330,7 +334,7 @@ void Path::FindSegmentAndProgress( float t, unsigned int& segment, float& tLocal //Find segment and local progress unsigned int numSegs = GetNumberOfSegments(); - if( t <= 0.0f ) + if( t <= 0.0f || numSegs == 0 ) { segment = 0; tLocal = 0.0f; @@ -344,168 +348,191 @@ void Path::FindSegmentAndProgress( float t, unsigned int& segment, float& tLocal { segment = t * numSegs; float segLength = 1.0f / numSegs; - float segStart = (float)segment * segLength; + float segStart = static_cast( segment ) * segLength; tLocal = (t - segStart) * 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 ); + 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) + { + 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) ) + { + unsigned int 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) ) + { + unsigned int 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 ) @@ -527,7 +554,15 @@ size_t Path::GetPointCount() const return mPoint.Size(); } -} // Internal -} // Dali +void Path::ClearPoints() +{ + mPoint.Clear(); +} +void Path::ClearControlPoints() +{ + mControlPoint.Clear(); +} +} // Internal +} // Dali