X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fevent%2Fanimation%2Fpath-impl.cpp;h=865c4fa97adb8fd6ee440c1bb9ac1f18c43b21ed;hb=091424324901c46a18959bfc0dd52f7ce8a0a811;hp=b599b33d507e7fe062e8af1141c7190df185e491;hpb=87dd02c448ac263d947dca5bb0f2b08572b30f59;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 b599b33..865c4fa 100644 --- a/dali/internal/event/animation/path-impl.cpp +++ b/dali/internal/event/animation/path-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 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. @@ -23,6 +23,8 @@ // INTERNAL INCLUDES #include +#include +#include namespace Dali { @@ -38,7 +40,7 @@ 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( "controlPoints", ARRAY, true, false, false, Dali::Path::Property::CONTROL_POINTS ) DALI_PROPERTY_TABLE_END( DEFAULT_OBJECT_PROPERTY_START_INDEX ) /** @@ -60,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(); +} + +Dali::TypeRegistration mType( typeid(Dali::Path), typeid(Dali::Handle), Create ); + +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() @@ -92,11 +106,11 @@ 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 ); } } @@ -141,55 +155,72 @@ Property::Type Path::GetDefaultPropertyType(Property::Index index) const Property::Value Path::GetDefaultProperty( Property::Index index ) const { - Property::Value value; if( index == Dali::Path::Property::POINTS ) { - Property::Array propertyArray; - value = Property::Value(propertyArray); - size_t pointCount( mPoint.Size() ); - for( size_t i( 0 ); i != pointCount; ++i ) + Property::Value value( Property::ARRAY ); + Property::Array* array = value.GetArray(); + Property::Array::SizeType pointCount = mPoint.Count(); + + if( array ) { - value.AppendItem( mPoint[i] ); + array->Reserve( pointCount ); + for( Property::Array::SizeType i = 0; i < pointCount; ++i ) + { + array->PushBack( mPoint[i] ); + } } + return value; } else if( index == Dali::Path::Property::CONTROL_POINTS ) { - Property::Array propertyArray; - value = Property::Value(propertyArray); - size_t controlpointCount( mControlPoint.Size() ); - for( size_t i( 0 ); i != controlpointCount; ++i ) + Property::Value value( Property::ARRAY ); + Property::Array* array = value.GetArray(); + Property::Array::SizeType controlpointCount = mControlPoint.Count(); + + 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(); +} + +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) { - 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::CONTROL_POINTS ) - { - 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 ); + } } } } @@ -303,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; @@ -317,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 ); - //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) ) + { + 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 ) @@ -500,5 +554,15 @@ size_t Path::GetPointCount() const return mPoint.Size(); } +void Path::ClearPoints() +{ + mPoint.Clear(); +} + +void Path::ClearControlPoints() +{ + mControlPoint.Clear(); +} + } // Internal } // Dali