1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #include <gmock/gmock.h> 16 #include <gtest/gtest.h> 17 18 #include <meta/api/animation.h> 19 #include <meta/api/curves.h> 20 #include <meta/base/namespace.h> 21 22 #include "TestRunner.h" 23 #include "helpers/animation_test_base.h" 24 25 using namespace testing; 26 using namespace testing::ext; 27 using namespace META_NS::TimeSpanLiterals; 28 29 META_BEGIN_NAMESPACE() 30 31 class BezierCurveTest : public AnimationTestBase { 32 public: SetUpTestSuite()33 static void SetUpTestSuite() 34 { 35 SetTest(); 36 } TearDownTestSuite()37 static void TearDownTestSuite() 38 { 39 TearDownTest(); 40 } SetUp()41 void SetUp() override 42 { 43 AnimationTestBase::SetUp(); 44 curve_ = interface_cast<ICurve1D>(bezier_); 45 ASSERT_NE(curve_, nullptr); 46 ASSERT_NE(interface_cast<IEasingCurve>(bezier_), nullptr); 47 ASSERT_NE(interface_cast<ICubicBezier>(bezier_), nullptr); 48 } 49 SetControlPoints()50 void SetControlPoints() 51 { 52 // Set control points to create a steeply rising curve 53 BASE_NS::Math::Vec2 cp1 = { 1.f, 0.f }; 54 BASE_NS::Math::Vec2 cp2 = { 0.0f, 1.f }; 55 bezier_.SetControlPoint1({ 1.f, 0.f }).SetControlPoint2({ 0.0f, 1.f }); 56 ASSERT_EQ(bezier_.GetControlPoint1(), cp1); 57 ASSERT_EQ(bezier_.GetControlPoint2(), cp2); 58 } 59 60 META_NS::ICurve1D* curve_ {}; 61 META_NS::Curves::CubicBezier bezier_ { META_NS::CreateNew }; 62 63 static constexpr float epsilon_ = 0.001f; 64 static constexpr auto frames_ = 20; 65 // Pre-calculated 20 cubic bezier curve values for cp1=[1.f,0.f] and cp2=[0.f, 1.f] 66 static constexpr float expected_[] = { 0.000000, 0.000882, 0.003711, 0.009070, 0.017385, 0.029723, 0.047319, 67 0.072904, 0.111333, 0.176019, 0.500000, 0.823981, 0.888667, 0.927096, 0.952681, 0.970277, 0.982615, 0.990930, 68 0.996289, 0.999118, 1.000000 }; 69 }; 70 71 /** 72 * @tc.name: BezierDefault 73 * @tc.desc: test BezierDefault 74 * @tc.type: FUNC 75 */ 76 HWTEST_F(BezierCurveTest, BezierDefault, TestSize.Level1) 77 { 78 // Linear as control points are at default [0,0], [1,1] 79 for (int i = 0; i < 100; i++) { 80 float f = i / 100.f; 81 EXPECT_NEAR(curve_->Transform(f), f, epsilon_); 82 } 83 } 84 85 /** 86 * @tc.name: BezierCurve 87 * @tc.desc: test BezierCurve 88 * @tc.type: FUNC 89 */ 90 HWTEST_F(BezierCurveTest, BezierCurve, TestSize.Level1) 91 { 92 SetControlPoints(); 93 94 for (int i = 0; i <= frames_; i++) { 95 float f = i / static_cast<float>(frames_); 96 EXPECT_NEAR(curve_->Transform(f), expected_[i], epsilon_); 97 } 98 } 99 100 /** 101 * @tc.name: BezierAnimation 102 * @tc.desc: test BezierAnimation 103 * @tc.type: FUNC 104 */ 105 HWTEST_F(BezierCurveTest, BezierAnimation, TestSize.Level1) 106 { 107 constexpr auto animationMs = 1000; 108 constexpr float frameMs = animationMs / static_cast<float>(frames_); 109 110 // Animate from 13.f->47.f 111 constexpr auto start = 13.f; 112 constexpr auto end = 47.f; 113 constexpr auto diff = end - start; 114 115 SetControlPoints(); 116 117 // Check that if we assign a bezier to an animation, the animated value follows the bezier as expected. 118 auto property = META_NS::ConstructProperty<float>("Prop", 0.f); 119 META_NS::KeyframeAnimation<float> animation(CreateNew); 120 animation.SetFrom(start).SetTo(end).SetProperty(property).SetDuration(1_s).SetCurve(bezier_); 121 122 animation.Start(); __anon4c630c580102(uint32_t frame) 123 StepAnimations({ animation }, frames_, frameMs, [&](uint32_t frame) { 124 auto expected = start + expected_[frame - 1] * diff; 125 EXPECT_NEAR(GetValue(property), expected, 0.1f) << "Frame: " << frame; 126 }); 127 } 128 129 META_END_NAMESPACE() 130