X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fevent%2Fanimation%2Fpath-impl.cpp;h=865c4fa97adb8fd6ee440c1bb9ac1f18c43b21ed;hb=091424324901c46a18959bfc0dd52f7ce8a0a811;hp=ad1c7962e1df9273fafb7b241688fa46e524ea7e;hpb=4d21bcf5c87a225729c6700144ee3e6f8af18d57;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 ad1c796..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. @@ -24,6 +24,7 @@ // INTERNAL INCLUDES #include #include +#include namespace Dali { @@ -39,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 ) /** @@ -61,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() @@ -147,10 +160,14 @@ Property::Value Path::GetDefaultProperty( Property::Index index ) const Property::Value value( Property::ARRAY ); Property::Array* array = value.GetArray(); Property::Array::SizeType pointCount = mPoint.Count(); - array->Reserve( pointCount ); - for( Property::Array::SizeType i = 0; i < pointCount; ++i ) + + if( array ) { - array->PushBack( mPoint[i] ); + array->Reserve( pointCount ); + for( Property::Array::SizeType i = 0; i < pointCount; ++i ) + { + array->PushBack( mPoint[i] ); + } } return value; } @@ -159,10 +176,14 @@ Property::Value Path::GetDefaultProperty( Property::Index index ) const Property::Value value( Property::ARRAY ); Property::Array* array = value.GetArray(); Property::Array::SizeType controlpointCount = mControlPoint.Count(); - array->Reserve( controlpointCount ); - for( Property::Array::SizeType i = 0; i < controlpointCount; ++i ) + + if( array ) { - array->PushBack( mControlPoint[i] ); + array->Reserve( controlpointCount ); + for( Property::Array::SizeType i = 0; i < controlpointCount; ++i ) + { + array->PushBack( mControlPoint[i] ); + } } return value; } @@ -170,6 +191,11 @@ Property::Value Path::GetDefaultProperty( Property::Index index ) const 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) { const Property::Array* array = propertyValue.GetArray(); @@ -322,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 )