From: David Steele Date: Fri, 21 Oct 2016 14:18:24 +0000 (+0100) Subject: Added bezier curve control points to TransitionData X-Git-Tag: dali_1.2.12~12^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=2ce0f3882dcfcbd046642f526ae0f3f481b6a0b5 Added bezier curve control points to TransitionData Allows stylesheets to specify alpha functions for transitions using bezier control points in addition to the builtin easing functions. Change-Id: I2f407b8692384ea89ba3bea112cce8ea391f2545 Signed-off-by: David Steele --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TransitionData.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TransitionData.cpp index 7f3d8aa..71851de 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TransitionData.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TransitionData.cpp @@ -53,6 +53,38 @@ Property::Map CreateMap() return map; } +void CHECK_ARRAY_EQUALS( Property::Array test, Property::Value result ) +{ + if( result.GetType() == Property::ARRAY ) + { + // Compare arrays + Property::Array *resultArray = result.GetArray(); + DALI_TEST_EQUALS( test.Count(), resultArray->Count(), TEST_LOCATION ); + for( size_t i=0; i < std::min(test.Count(), resultArray->Count()); ++i ) + { + Property::Value a = test.GetElementAt(i); + Property::Value b = resultArray->GetElementAt(i); + DALI_TEST_EQUALS( a.GetType(), b.GetType(), TEST_LOCATION ); + DALI_TEST_EQUALS( a, b, 0.001, TEST_LOCATION ); + } + } + else if( result.GetType() == Property::VECTOR4 ) + { + Vector4 value = result.Get(); + DALI_TEST_CHECK( test.Count() >= 4 ); + for( size_t i=0; i < 4; ++i ) + { + Property::Value a = test.GetElementAt(i); + DALI_TEST_EQUALS( a.GetType(), Property::FLOAT, TEST_LOCATION ); + DALI_TEST_EQUALS( a.Get(), value[i], 0.001, TEST_LOCATION ); + } + } + else + { + DALI_TEST_CHECK( 0 ); + } +} + void CHECK_MAP_EQUALS( Property::Map test, Property::Map result ) { DALI_TEST_EQUALS(test.Count(), result.Count(), TEST_LOCATION); @@ -74,22 +106,25 @@ void CHECK_MAP_EQUALS( Property::Map test, Property::Map result ) DALI_TEST_CHECK( value != NULL ); if( value != NULL ) { - DALI_TEST_EQUALS( keyValue.second.GetType(), value->GetType(), TEST_LOCATION ); if( keyValue.second.GetType() == Property::MAP ) { + DALI_TEST_EQUALS( keyValue.second.GetType(), value->GetType(), TEST_LOCATION ); CHECK_MAP_EQUALS( *(keyValue.second.GetMap()), *(value->GetMap()) ); } else if( keyValue.second.GetType() == Property::ARRAY ) { + CHECK_ARRAY_EQUALS( *(keyValue.second.GetArray()), *value ); } else if( keyValue.second.GetType() == Property::STRING ) { + DALI_TEST_EQUALS( keyValue.second.GetType(), value->GetType(), TEST_LOCATION ); std::string str; value->Get(str); DALI_TEST_EQUALS( keyValue.second, str.c_str(), TEST_LOCATION ); } else { + DALI_TEST_EQUALS( keyValue.second.GetType(), value->GetType(), TEST_LOCATION ); DALI_TEST_EQUALS( keyValue.second, *value, 0.001f, TEST_LOCATION ); } } @@ -303,7 +338,7 @@ int UtcDaliTransitionDataMap2P(void) } -int UtcDaliTransitionDataMapP3(void) +int UtcDaliTransitionDataMap3P(void) { TestApplication application; @@ -361,6 +396,62 @@ int UtcDaliTransitionDataMapP3(void) END_TEST; } + +int UtcDaliTransitionDataMap4P(void) +{ + TestApplication application; + + tet_printf("Testing animation of a visual's placement actor property using bezier curve\n"); + + Property::Map map; + map["target"] = "Actor1"; + map["property"] = "position"; + map["initialValue"] = Vector3(0, 0, 0); + map["targetValue"] = Vector3(100, 100, 0); + map["animator"] = Property::Map() + .Add("alphaFunction", Vector4(0.71, -0.57, 0.42, 1.38) ) + .Add("timePeriod", Property::Map() + .Add("delay", 0.0f) + .Add("duration", 1.0f)); + + Dali::Toolkit::TransitionData transition = TransitionData::New( map ); + + DummyControl actor = DummyControl::New(); + actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + actor.SetName("Actor1"); + Stage::GetCurrent().Add(actor); + + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + Animation anim = dummyImpl.CreateTransition( transition ); + DALI_TEST_CHECK( anim ); + + application.SendNotification(); + application.Render(0); + DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(0,0,0), 0.001f, TEST_LOCATION); + + anim.Play(); + + application.SendNotification(); + application.Render(0); + + application.Render(250); // 25% + application.SendNotification(); + DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(-10,-10,0), 1.0, TEST_LOCATION); // High epsilon as we don't have exact figure for bezier curve at 50% + + application.Render(250); // Halfway thru map1 anim + application.SendNotification(); + DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(24,24,0), 1.0, TEST_LOCATION); // High epsilon as we don't have exact figure for bezier curve at 50% + + application.Render(250); // End of map1 anim + application.SendNotification(); + DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(100,100,0), 1.0, TEST_LOCATION); // High epsilon as we don't have exact figure for bezier curve + + application.Render(250); // End of map1 anim + application.SendNotification(); + DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(100,100,0), TEST_LOCATION ); + END_TEST; +} + int UtcDaliTransitionDataMap1N(void) { TestApplication application; @@ -434,6 +525,161 @@ int UtcDaliTransitionDataMapN3(void) END_TEST; } + +int UtcDaliTransitionDataMapN4(void) +{ + TestApplication application; + + tet_printf("Testing visual doesn't animate with duff bezier data \n"); + + Property::Map map; + map["target"] = "visual1"; + map["property"] = "mixColor"; + map["initialValue"] = Color::MAGENTA; + map["targetValue"] = Color::RED; + map["animator"] = Property::Map() + .Add("alphaFunction", Vector3(.1f,1.0f,0.5f)) + .Add("timePeriod", Property::Map() + .Add("delay", 0.5f) + .Add("duration", 1.0f)); + + Dali::Toolkit::TransitionData transition = TransitionData::New( map ); + + DummyControl actor = DummyControl::New(); + actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + actor.SetName("Actor1"); + actor.SetColor(Color::CYAN); + Stage::GetCurrent().Add(actor); + + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + Property::Map visualMap; + visualMap[Visual::Property::TYPE] = Visual::COLOR; + visualMap[ColorVisual::Property::MIX_COLOR] = Color::MAGENTA; + Visual::Base visual = VisualFactory::Get().CreateVisual( visualMap ); + visual.SetName( "visual1" ); + + Property::Index visualIndex = Control::CONTROL_PROPERTY_END_INDEX + 1; + dummyImpl.RegisterVisual( visualIndex, actor, visual ); + + Animation anim = dummyImpl.CreateTransition( transition ); + DALI_TEST_CHECK( !anim ); + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + + Renderer renderer = actor.GetRendererAt(0); + Property::Index mixColorIdx = renderer.GetPropertyIndex(ColorVisual::Property::MIX_COLOR); + + tet_printf( "Test that the property has been set to target value\n"); + DALI_TEST_EQUALS(renderer.GetProperty(mixColorIdx), Color::RED, 0.001, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliTransitionDataMapN5(void) +{ + TestApplication application; + + tet_printf("Testing visual doesn't animate with duff bezier data \n"); + + Property::Map map; + map["target"] = "visual1"; + map["property"] = "mixColor"; + map["initialValue"] = Color::MAGENTA; + map["targetValue"] = Color::RED; + map["animator"] = Property::Map() + .Add("alphaFunction", Property::Array().Add(.1f).Add(1.0f).Add(0.5f)) + .Add("timePeriod", Property::Map() + .Add("delay", 0.5f) + .Add("duration", 1.0f)); + + Dali::Toolkit::TransitionData transition = TransitionData::New( map ); + + DummyControl actor = DummyControl::New(); + actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + actor.SetName("Actor1"); + actor.SetColor(Color::CYAN); + Stage::GetCurrent().Add(actor); + + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + Property::Map visualMap; + visualMap[Visual::Property::TYPE] = Visual::COLOR; + visualMap[ColorVisual::Property::MIX_COLOR] = Color::MAGENTA; + Visual::Base visual = VisualFactory::Get().CreateVisual( visualMap ); + visual.SetName( "visual1" ); + + Property::Index visualIndex = Control::CONTROL_PROPERTY_END_INDEX + 1; + dummyImpl.RegisterVisual( visualIndex, actor, visual ); + + Animation anim = dummyImpl.CreateTransition( transition ); + DALI_TEST_CHECK( !anim ); + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + + Renderer renderer = actor.GetRendererAt(0); + Property::Index mixColorIdx = renderer.GetPropertyIndex(ColorVisual::Property::MIX_COLOR); + + tet_printf( "Test that the property has been set to target value\n"); + DALI_TEST_EQUALS(renderer.GetProperty(mixColorIdx), Color::RED, 0.001, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliTransitionDataMapN6(void) +{ + TestApplication application; + + tet_printf("Testing visual doesn't animate with duff bezier data \n"); + + Property::Map map; + map["target"] = "visual1"; + map["property"] = "mixColor"; + map["initialValue"] = Color::MAGENTA; + map["targetValue"] = Color::RED; + map["animator"] = Property::Map() + .Add("alphaFunction", Property::Array().Add("1").Add("Two").Add("3").Add("4")) + .Add("timePeriod", Property::Map() + .Add("delay", 0.5f) + .Add("duration", 1.0f)); + + Dali::Toolkit::TransitionData transition = TransitionData::New( map ); + + DummyControl actor = DummyControl::New(); + actor.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + actor.SetName("Actor1"); + actor.SetColor(Color::CYAN); + Stage::GetCurrent().Add(actor); + + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + Property::Map visualMap; + visualMap[Visual::Property::TYPE] = Visual::COLOR; + visualMap[ColorVisual::Property::MIX_COLOR] = Color::MAGENTA; + Visual::Base visual = VisualFactory::Get().CreateVisual( visualMap ); + visual.SetName( "visual1" ); + + Property::Index visualIndex = Control::CONTROL_PROPERTY_END_INDEX + 1; + dummyImpl.RegisterVisual( visualIndex, actor, visual ); + + Animation anim = dummyImpl.CreateTransition( transition ); + DALI_TEST_CHECK( !anim ); + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + + Renderer renderer = actor.GetRendererAt(0); + Property::Index mixColorIdx = renderer.GetPropertyIndex(ColorVisual::Property::MIX_COLOR); + + tet_printf( "Test that the property has been set to target value\n"); + DALI_TEST_EQUALS(renderer.GetProperty(mixColorIdx), Color::RED, 0.001, TEST_LOCATION); + + END_TEST; +} + + int UtcDaliTransitionDataArrayP(void) { TestApplication application; @@ -613,9 +859,31 @@ int UtcDaliTransitionDataGetAnimatorP(void) .Add("duration", 1.0f)); Property::Map map10; - map10["target"] = "Actor1"; - map10["property"] = "orientation"; - map10["targetValue"] = Quaternion( Radian(Math::PI_2), Vector3::ZAXIS ); + map10["target"] = "Actor2"; + map10["property"] = "scale"; + map10["initialValue"] = Vector3(0,0,0); + map10["targetValue"] = Vector3(1,1,1); + map10["animator"] = Property::Map() + .Add("alphaFunction", Vector4(.23,.4,.8,1.2)) + .Add("timePeriod", Property::Map() + .Add("delay", 0.0f) + .Add("duration", 1.0f)); + + Property::Map map11; + map11["target"] = "Actor2"; + map11["property"] = "scale"; + map11["initialValue"] = Vector3(0,0,0); + map11["targetValue"] = Vector3(1,1,1); + map11["animator"] = Property::Map() + .Add("alphaFunction", Property::Array().Add(.23f).Add(.4f).Add(.8f).Add(.2f)) + .Add("timePeriod", Property::Map() + .Add("delay", 0.0f) + .Add("duration", 1.0f)); + + Property::Map map12; + map12["target"] = "Actor1"; + map12["property"] = "orientation"; + map12["targetValue"] = Quaternion( Radian(Math::PI_2), Vector3::ZAXIS ); Property::Array array; array.PushBack(map1); @@ -628,6 +896,8 @@ int UtcDaliTransitionDataGetAnimatorP(void) array.PushBack(map8); array.PushBack(map9); array.PushBack(map10); + array.PushBack(map11); + array.PushBack(map12); Dali::Toolkit::TransitionData transition = TransitionData::New( array ); diff --git a/dali-toolkit/internal/visuals/transition-data-impl.cpp b/dali-toolkit/internal/visuals/transition-data-impl.cpp index 30c0dee..8ccb354 100644 --- a/dali-toolkit/internal/visuals/transition-data-impl.cpp +++ b/dali-toolkit/internal/visuals/transition-data-impl.cpp @@ -169,68 +169,119 @@ TransitionData::Animator* TransitionData::ConvertMap( const Property::Map& map) if( key == TOKEN_ALPHA_FUNCTION ) { - std::string alphaFunctionValue = value.Get< std::string >(); + if( value.GetType() == Property::ARRAY ) + { + bool valid = true; + Vector4 controlPoints; + Property::Array *array = value.GetArray(); + if( array->Count() >= 4 ) + { + for( size_t vecIdx = 0; vecIdx < 4; ++vecIdx ) + { + Property::Value& v = array->GetElementAt(vecIdx); + if( v.GetType() == Property::FLOAT ) + { + controlPoints[vecIdx] = v.Get(); + } + else + { + valid = false; + break; + } + } + } + else + { + valid = false; + } - if( alphaFunctionValue == "LINEAR" ) + if( valid ) + { + Vector2 controlPoint1( controlPoints.x, controlPoints.y ); + Vector2 controlPoint2( controlPoints.z, controlPoints.w ); + animator->alphaFunction = AlphaFunction( controlPoint1, controlPoint2 ); + } + else + { + animator->animate = false; + } + } + else if( value.GetType() == Property::VECTOR4 ) { - animator->alphaFunction = AlphaFunction::LINEAR; + Vector4 controlPoints = value.Get(); + Vector2 controlPoint1( controlPoints.x, controlPoints.y ); + Vector2 controlPoint2( controlPoints.z, controlPoints.w ); + animator->alphaFunction = AlphaFunction( controlPoint1, controlPoint2 ); } - else if( ! alphaFunctionValue.compare(0, 5, "EASE_" ) ) + else if( value.GetType() == Property::STRING ) { - if( alphaFunctionValue == "EASE_IN" ) - { - animator->alphaFunction = AlphaFunction::EASE_IN; - } - else if( alphaFunctionValue == "EASE_OUT" ) + std::string alphaFunctionValue = value.Get< std::string >(); + + if( alphaFunctionValue == "LINEAR" ) { - animator->alphaFunction = AlphaFunction::EASE_OUT; + animator->alphaFunction = AlphaFunction(AlphaFunction::LINEAR); } - else if( ! alphaFunctionValue.compare( 5, 3, "IN_" ) ) + else if( ! alphaFunctionValue.compare(0, 5, "EASE_" ) ) { - if( ! alphaFunctionValue.compare(8, -1, "SQUARE" )) + if( alphaFunctionValue == "EASE_IN" ) { - animator->alphaFunction = AlphaFunction::EASE_IN_SQUARE; + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN); } - else if( ! alphaFunctionValue.compare(8, -1, "OUT" )) + else if( alphaFunctionValue == "EASE_OUT" ) { - animator->alphaFunction = AlphaFunction::EASE_IN_OUT; + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT); } - else if( ! alphaFunctionValue.compare(8, -1, "OUT_SINE" )) + else if( ! alphaFunctionValue.compare( 5, 3, "IN_" ) ) { - animator->alphaFunction = AlphaFunction::EASE_IN_OUT_SINE; + if( ! alphaFunctionValue.compare(8, -1, "SQUARE" )) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_SQUARE); + } + else if( ! alphaFunctionValue.compare(8, -1, "OUT" )) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_OUT); + } + else if( ! alphaFunctionValue.compare(8, -1, "OUT_SINE" )) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_OUT_SINE); + } + else if( ! alphaFunctionValue.compare(8, -1, "SINE" )) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_IN_SINE); + } } - else if( ! alphaFunctionValue.compare(8, -1, "SINE" )) + else if( ! alphaFunctionValue.compare( 5, 4, "OUT_" ) ) { - animator->alphaFunction = AlphaFunction::EASE_IN_SINE; + if( ! alphaFunctionValue.compare(9, -1, "SQUARE" ) ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_SQUARE); + } + else if( ! alphaFunctionValue.compare(9, -1, "SINE" ) ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_SINE); + } + else if( ! alphaFunctionValue.compare(9, -1, "BACK" ) ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::EASE_OUT_BACK); + } } } - else if( ! alphaFunctionValue.compare( 5, 4, "OUT_" ) ) + else if( alphaFunctionValue == "REVERSE" ) { - if( ! alphaFunctionValue.compare(9, -1, "SQUARE" ) ) - { - animator->alphaFunction = AlphaFunction::EASE_OUT_SQUARE; - } - else if( ! alphaFunctionValue.compare(9, -1, "SINE" ) ) - { - animator->alphaFunction = AlphaFunction::EASE_OUT_SINE; - } - else if( ! alphaFunctionValue.compare(9, -1, "BACK" ) ) - { - animator->alphaFunction = AlphaFunction::EASE_OUT_BACK; - } + animator->alphaFunction = AlphaFunction(AlphaFunction::REVERSE); + } + else if( alphaFunctionValue == "BOUNCE" ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::BOUNCE); + } + else if( alphaFunctionValue == "SIN" ) + { + animator->alphaFunction = AlphaFunction(AlphaFunction::SIN); } } - else if( alphaFunctionValue == "REVERSE" ) - { - animator->alphaFunction = AlphaFunction::REVERSE; - } - else if( alphaFunctionValue == "BOUNCE" ) - { - animator->alphaFunction = AlphaFunction::BOUNCE; - } - else if( alphaFunctionValue == "SIN" ) + else { - animator->alphaFunction = AlphaFunction::SIN; + animator->animate = false; } } else if( key == TOKEN_TIME_PERIOD ) @@ -306,13 +357,24 @@ Property::Map TransitionData::GetAnimatorAt( size_t index ) } if( animator->animate ) { - map[TOKEN_ANIMATOR] = Property::Map() - .Add(TOKEN_ALPHA_FUNCTION, GetEnumerationName( animator->alphaFunction, - ALPHA_FUNCTION_BUILTIN_TABLE, - ALPHA_FUNCTION_BUILTIN_TABLE_COUNT )) - .Add(TOKEN_TIME_PERIOD, Property::Map() - .Add( TOKEN_DELAY, animator->timePeriodDelay ) - .Add( TOKEN_DURATION, animator->timePeriodDuration )); + Property::Map animateMap; + + if( animator->alphaFunction.GetMode() == AlphaFunction::BUILTIN_FUNCTION ) + { + animateMap.Add(TOKEN_ALPHA_FUNCTION, GetEnumerationName( animator->alphaFunction.GetBuiltinFunction(), + ALPHA_FUNCTION_BUILTIN_TABLE, + ALPHA_FUNCTION_BUILTIN_TABLE_COUNT )); + } + else if( animator->alphaFunction.GetMode() == AlphaFunction::BEZIER ) + { + Vector4 controlPoints = animator->alphaFunction.GetBezierControlPoints(); + animateMap.Add( TOKEN_ALPHA_FUNCTION, controlPoints ); + } + animateMap.Add(TOKEN_TIME_PERIOD, Property::Map() + .Add( TOKEN_DELAY, animator->timePeriodDelay ) + .Add( TOKEN_DURATION, animator->timePeriodDuration )); + + map[TOKEN_ANIMATOR] = animateMap; } return map; diff --git a/dali-toolkit/internal/visuals/transition-data-impl.h b/dali-toolkit/internal/visuals/transition-data-impl.h index 9622951..9ca8193 100644 --- a/dali-toolkit/internal/visuals/transition-data-impl.h +++ b/dali-toolkit/internal/visuals/transition-data-impl.h @@ -61,7 +61,7 @@ public: Property::Key propertyKey; ///< A property key of the property owner Property::Value initialValue; ///< The value to set at the start of the transition Property::Value targetValue; ///< The value to set or animate to - Dali::AlphaFunction::BuiltinFunction alphaFunction; + Dali::AlphaFunction alphaFunction; float timePeriodDelay; float timePeriodDuration; bool animate;