18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#include "interpolator.h" 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include <base/math/quaternion_util.h> 198bf80f4bSopenharmony_ci 208bf80f4bSopenharmony_ciMETA_BEGIN_NAMESPACE() 218bf80f4bSopenharmony_ci 228bf80f4bSopenharmony_ciclass FloatInterpolator : public Interpolator<float, FloatInterpolator, ClassId::FloatInterpolator> {}; 238bf80f4bSopenharmony_ciclass DoubleInterpolator : public Interpolator<double, DoubleInterpolator, ClassId::DoubleInterpolator> {}; 248bf80f4bSopenharmony_ciclass Vec2Interpolator : public Interpolator<BASE_NS::Math::Vec2, Vec2Interpolator, ClassId::Vec2Interpolator> {}; 258bf80f4bSopenharmony_ciclass Vec3Interpolator : public Interpolator<BASE_NS::Math::Vec3, Vec3Interpolator, ClassId::Vec3Interpolator> {}; 268bf80f4bSopenharmony_ciclass Vec4Interpolator : public Interpolator<BASE_NS::Math::Vec4, Vec4Interpolator, ClassId::Vec4Interpolator> {}; 278bf80f4bSopenharmony_ciclass UVec2Interpolator : public Interpolator<BASE_NS::Math::UVec2, UVec2Interpolator, ClassId::UVec2Interpolator> {}; 288bf80f4bSopenharmony_ciclass IVec2Interpolator : public Interpolator<BASE_NS::Math::IVec2, IVec2Interpolator, ClassId::IVec2Interpolator> {}; 298bf80f4bSopenharmony_ciclass UInt8Interpolator : public Interpolator<uint8_t, UInt8Interpolator, ClassId::UInt8Interpolator> {}; 308bf80f4bSopenharmony_ciclass UInt16Interpolator : public Interpolator<uint16_t, UInt16Interpolator, ClassId::UInt16Interpolator> {}; 318bf80f4bSopenharmony_ciclass UInt32Interpolator : public Interpolator<uint32_t, UInt32Interpolator, ClassId::UInt32Interpolator> {}; 328bf80f4bSopenharmony_ciclass UInt64Interpolator : public Interpolator<uint64_t, UInt64Interpolator, ClassId::UInt64Interpolator> {}; 338bf80f4bSopenharmony_ciclass Int8Interpolator : public Interpolator<int8_t, Int8Interpolator, ClassId::Int8Interpolator> {}; 348bf80f4bSopenharmony_ciclass Int16Interpolator : public Interpolator<int16_t, Int16Interpolator, ClassId::Int16Interpolator> {}; 358bf80f4bSopenharmony_ciclass Int32Interpolator : public Interpolator<int32_t, Int32Interpolator, ClassId::Int32Interpolator> {}; 368bf80f4bSopenharmony_ciclass Int64Interpolator : public Interpolator<int64_t, Int64Interpolator, ClassId::Int64Interpolator> {}; 378bf80f4bSopenharmony_ci 388bf80f4bSopenharmony_ciclass QuatInterpolator : public META_NS::BaseObjectFwd<QuatInterpolator, ClassId::QuatInterpolator, 398bf80f4bSopenharmony_ci META_NS::ClassId::BaseObject, IInterpolator> { 408bf80f4bSopenharmony_ci using Type = BASE_NS::Math::Quat; 418bf80f4bSopenharmony_ci AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override 428bf80f4bSopenharmony_ci { 438bf80f4bSopenharmony_ci if (IsSetCompatibleWith<Type>(output) && IsGetCompatibleWith<Type>(from) && IsGetCompatibleWith<Type>(to)) { 448bf80f4bSopenharmony_ci Type value0 = GetValue<Type>(from); 458bf80f4bSopenharmony_ci Type value1 = GetValue<Type>(to); 468bf80f4bSopenharmony_ci return output.SetValue<Type>(BASE_NS::Math::Slerp(value0, value1, t)); 478bf80f4bSopenharmony_ci } 488bf80f4bSopenharmony_ci return AnyReturn::INCOMPATIBLE_TYPE; 498bf80f4bSopenharmony_ci } 508bf80f4bSopenharmony_ci 518bf80f4bSopenharmony_ci bool IsCompatibleWith(TypeId id) const noexcept override 528bf80f4bSopenharmony_ci { 538bf80f4bSopenharmony_ci return id == UidFromType<Type>(); 548bf80f4bSopenharmony_ci } 558bf80f4bSopenharmony_ci}; 568bf80f4bSopenharmony_ci 578bf80f4bSopenharmony_ciclass DefaultInterpolator : public META_NS::BaseObjectFwd<DefaultInterpolator, ClassId::DefaultInterpolator, 588bf80f4bSopenharmony_ci META_NS::ClassId::BaseObject, IInterpolator> { 598bf80f4bSopenharmony_ci AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override 608bf80f4bSopenharmony_ci { 618bf80f4bSopenharmony_ci // The default interpolator doesn't know how to interpolate, so we just set the property value to either 628bf80f4bSopenharmony_ci // from or to based on t 638bf80f4bSopenharmony_ci if (t > .5f) { 648bf80f4bSopenharmony_ci return output.CopyFrom(to); 658bf80f4bSopenharmony_ci } 668bf80f4bSopenharmony_ci return output.CopyFrom(from); 678bf80f4bSopenharmony_ci } 688bf80f4bSopenharmony_ci bool IsCompatibleWith(TypeId id) const noexcept override 698bf80f4bSopenharmony_ci { 708bf80f4bSopenharmony_ci // Default interpolator is compatible with any type 718bf80f4bSopenharmony_ci return true; 728bf80f4bSopenharmony_ci } 738bf80f4bSopenharmony_ci}; 748bf80f4bSopenharmony_ci 758bf80f4bSopenharmony_ci// No math operations have been defined for integer type vec3/4, implement interpolators manually 768bf80f4bSopenharmony_ciclass UVec3Interpolator : public META_NS::BaseObjectFwd<UVec3Interpolator, ClassId::UVec3Interpolator, 778bf80f4bSopenharmony_ci META_NS::ClassId::BaseObject, IInterpolator> { 788bf80f4bSopenharmony_ci using Type = BASE_NS::Math::UVec3; 798bf80f4bSopenharmony_ci AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override 808bf80f4bSopenharmony_ci { 818bf80f4bSopenharmony_ci if (IsSetCompatibleWith<Type>(output) && IsGetCompatibleWith<Type>(from) && IsGetCompatibleWith<Type>(to)) { 828bf80f4bSopenharmony_ci Type value0 = GetValue<Type>(from); 838bf80f4bSopenharmony_ci Type value1 = GetValue<Type>(to); 848bf80f4bSopenharmony_ci Type value; 858bf80f4bSopenharmony_ci value.x = value0.x + (value1.x - value0.x) * t; 868bf80f4bSopenharmony_ci value.y = value0.y + (value1.y - value0.y) * t; 878bf80f4bSopenharmony_ci value.z = value0.z + (value1.z - value0.z) * t; 888bf80f4bSopenharmony_ci return output.SetValue<Type>(value); 898bf80f4bSopenharmony_ci } 908bf80f4bSopenharmony_ci return AnyReturn::INCOMPATIBLE_TYPE; 918bf80f4bSopenharmony_ci } 928bf80f4bSopenharmony_ci bool IsCompatibleWith(TypeId id) const noexcept override 938bf80f4bSopenharmony_ci { 948bf80f4bSopenharmony_ci return id == UidFromType<Type>(); 958bf80f4bSopenharmony_ci } 968bf80f4bSopenharmony_ci}; 978bf80f4bSopenharmony_ci 988bf80f4bSopenharmony_ciclass UVec4Interpolator : public META_NS::BaseObjectFwd<UVec4Interpolator, ClassId::UVec4Interpolator, 998bf80f4bSopenharmony_ci META_NS::ClassId::BaseObject, IInterpolator> { 1008bf80f4bSopenharmony_ci using Type = BASE_NS::Math::UVec4; 1018bf80f4bSopenharmony_ci AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override 1028bf80f4bSopenharmony_ci { 1038bf80f4bSopenharmony_ci if (IsSetCompatibleWith<Type>(output) && IsGetCompatibleWith<Type>(from) && IsGetCompatibleWith<Type>(to)) { 1048bf80f4bSopenharmony_ci Type value0 = GetValue<Type>(from); 1058bf80f4bSopenharmony_ci Type value1 = GetValue<Type>(to); 1068bf80f4bSopenharmony_ci Type value; 1078bf80f4bSopenharmony_ci value.x = value0.x + (value1.x - value0.x) * t; 1088bf80f4bSopenharmony_ci value.y = value0.y + (value1.y - value0.y) * t; 1098bf80f4bSopenharmony_ci value.z = value0.z + (value1.z - value0.z) * t; 1108bf80f4bSopenharmony_ci value.w = value0.w + (value1.w - value0.w) * t; 1118bf80f4bSopenharmony_ci return output.SetValue<Type>(value); 1128bf80f4bSopenharmony_ci } 1138bf80f4bSopenharmony_ci return AnyReturn::INCOMPATIBLE_TYPE; 1148bf80f4bSopenharmony_ci } 1158bf80f4bSopenharmony_ci bool IsCompatibleWith(TypeId id) const noexcept override 1168bf80f4bSopenharmony_ci { 1178bf80f4bSopenharmony_ci return id == UidFromType<Type>(); 1188bf80f4bSopenharmony_ci } 1198bf80f4bSopenharmony_ci}; 1208bf80f4bSopenharmony_ci 1218bf80f4bSopenharmony_ciclass IVec3Interpolator : public META_NS::BaseObjectFwd<IVec3Interpolator, ClassId::IVec3Interpolator, 1228bf80f4bSopenharmony_ci META_NS::ClassId::BaseObject, IInterpolator> { 1238bf80f4bSopenharmony_ci using Type = BASE_NS::Math::IVec3; 1248bf80f4bSopenharmony_ci AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override 1258bf80f4bSopenharmony_ci { 1268bf80f4bSopenharmony_ci if (IsSetCompatibleWith<Type>(output) && IsGetCompatibleWith<Type>(from) && IsGetCompatibleWith<Type>(to)) { 1278bf80f4bSopenharmony_ci Type value0 = GetValue<Type>(from); 1288bf80f4bSopenharmony_ci Type value1 = GetValue<Type>(to); 1298bf80f4bSopenharmony_ci Type value; 1308bf80f4bSopenharmony_ci value.x = value0.x + (value1.x - value0.x) * t; 1318bf80f4bSopenharmony_ci value.y = value0.y + (value1.y - value0.y) * t; 1328bf80f4bSopenharmony_ci value.z = value0.z + (value1.z - value0.z) * t; 1338bf80f4bSopenharmony_ci return output.SetValue<Type>(value); 1348bf80f4bSopenharmony_ci } 1358bf80f4bSopenharmony_ci return AnyReturn::INCOMPATIBLE_TYPE; 1368bf80f4bSopenharmony_ci } 1378bf80f4bSopenharmony_ci bool IsCompatibleWith(TypeId id) const noexcept override 1388bf80f4bSopenharmony_ci { 1398bf80f4bSopenharmony_ci return id == UidFromType<Type>(); 1408bf80f4bSopenharmony_ci } 1418bf80f4bSopenharmony_ci}; 1428bf80f4bSopenharmony_ciclass IVec4Interpolator : public META_NS::BaseObjectFwd<IVec4Interpolator, ClassId::IVec4Interpolator, 1438bf80f4bSopenharmony_ci META_NS::ClassId::BaseObject, IInterpolator> { 1448bf80f4bSopenharmony_ci using Type = BASE_NS::Math::IVec4; 1458bf80f4bSopenharmony_ci AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override 1468bf80f4bSopenharmony_ci { 1478bf80f4bSopenharmony_ci if (IsSetCompatibleWith<Type>(output) && IsGetCompatibleWith<Type>(from) && IsGetCompatibleWith<Type>(to)) { 1488bf80f4bSopenharmony_ci Type value0 = GetValue<Type>(from); 1498bf80f4bSopenharmony_ci Type value1 = GetValue<Type>(to); 1508bf80f4bSopenharmony_ci Type value; 1518bf80f4bSopenharmony_ci value.x = value0.x + (value1.x - value0.x) * t; 1528bf80f4bSopenharmony_ci value.y = value0.y + (value1.y - value0.y) * t; 1538bf80f4bSopenharmony_ci value.z = value0.z + (value1.z - value0.z) * t; 1548bf80f4bSopenharmony_ci value.w = value0.w + (value1.w - value0.w) * t; 1558bf80f4bSopenharmony_ci return output.SetValue<Type>(value); 1568bf80f4bSopenharmony_ci } 1578bf80f4bSopenharmony_ci return AnyReturn::INCOMPATIBLE_TYPE; 1588bf80f4bSopenharmony_ci } 1598bf80f4bSopenharmony_ci bool IsCompatibleWith(TypeId id) const noexcept override 1608bf80f4bSopenharmony_ci { 1618bf80f4bSopenharmony_ci return id == UidFromType<Type>(); 1628bf80f4bSopenharmony_ci } 1638bf80f4bSopenharmony_ci}; 1648bf80f4bSopenharmony_ci 1658bf80f4bSopenharmony_cinamespace BuiltInInterpolators { 1668bf80f4bSopenharmony_ci 1678bf80f4bSopenharmony_cistruct InterpolatorInfo { 1688bf80f4bSopenharmony_ci ObjectTypeInfo OBJECT_INFO; 1698bf80f4bSopenharmony_ci TypeId propertyTypeUid; 1708bf80f4bSopenharmony_ci ObjectId interpolatorClassUid; 1718bf80f4bSopenharmony_ci}; 1728bf80f4bSopenharmony_ci 1738bf80f4bSopenharmony_cistatic constexpr InterpolatorInfo BUILT_IN_INTERPOLATOR_INFO[] = { 1748bf80f4bSopenharmony_ci { FloatInterpolator::OBJECT_INFO, UidFromType<float>(), ClassId::FloatInterpolator }, 1758bf80f4bSopenharmony_ci { DoubleInterpolator::OBJECT_INFO, UidFromType<double>(), ClassId::DoubleInterpolator }, 1768bf80f4bSopenharmony_ci { Vec2Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::Vec2>(), ClassId::Vec2Interpolator }, 1778bf80f4bSopenharmony_ci { Vec3Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::Vec3>(), ClassId::Vec3Interpolator }, 1788bf80f4bSopenharmony_ci { Vec4Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::Vec4>(), ClassId::Vec4Interpolator }, 1798bf80f4bSopenharmony_ci { UVec2Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::UVec2>(), ClassId::UVec2Interpolator }, 1808bf80f4bSopenharmony_ci { UVec3Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::UVec3>(), ClassId::UVec3Interpolator }, 1818bf80f4bSopenharmony_ci { UVec4Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::UVec4>(), ClassId::UVec4Interpolator }, 1828bf80f4bSopenharmony_ci { IVec2Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::IVec2>(), ClassId::IVec2Interpolator }, 1838bf80f4bSopenharmony_ci { IVec3Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::IVec3>(), ClassId::IVec3Interpolator }, 1848bf80f4bSopenharmony_ci { IVec4Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::IVec4>(), ClassId::IVec4Interpolator }, 1858bf80f4bSopenharmony_ci { UInt8Interpolator::OBJECT_INFO, UidFromType<uint8_t>(), ClassId::UInt8Interpolator }, 1868bf80f4bSopenharmony_ci { UInt16Interpolator::OBJECT_INFO, UidFromType<uint16_t>(), ClassId::UInt16Interpolator }, 1878bf80f4bSopenharmony_ci { UInt32Interpolator::OBJECT_INFO, UidFromType<uint32_t>(), ClassId::UInt32Interpolator }, 1888bf80f4bSopenharmony_ci { UInt64Interpolator::OBJECT_INFO, UidFromType<uint64_t>(), ClassId::UInt64Interpolator }, 1898bf80f4bSopenharmony_ci { Int8Interpolator::OBJECT_INFO, UidFromType<int8_t>(), ClassId::Int8Interpolator }, 1908bf80f4bSopenharmony_ci { Int16Interpolator::OBJECT_INFO, UidFromType<int16_t>(), ClassId::Int16Interpolator }, 1918bf80f4bSopenharmony_ci { Int32Interpolator::OBJECT_INFO, UidFromType<int32_t>(), ClassId::Int32Interpolator }, 1928bf80f4bSopenharmony_ci { Int64Interpolator::OBJECT_INFO, UidFromType<int64_t>(), ClassId::Int64Interpolator }, 1938bf80f4bSopenharmony_ci { QuatInterpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::Quat>(), ClassId::QuatInterpolator }, 1948bf80f4bSopenharmony_ci}; 1958bf80f4bSopenharmony_ci 1968bf80f4bSopenharmony_ci} // namespace BuiltInInterpolators 1978bf80f4bSopenharmony_ci 1988bf80f4bSopenharmony_civoid RegisterDefaultInterpolators(IObjectRegistry& registry) 1998bf80f4bSopenharmony_ci{ 2008bf80f4bSopenharmony_ci for (const auto& info : BuiltInInterpolators::BUILT_IN_INTERPOLATOR_INFO) { 2018bf80f4bSopenharmony_ci // Register the classes themselves 2028bf80f4bSopenharmony_ci registry.RegisterObjectType(info.OBJECT_INFO.GetFactory()); 2038bf80f4bSopenharmony_ci // Then register them as interpolators (note that default interpolator doesn't need to be registered) 2048bf80f4bSopenharmony_ci registry.RegisterInterpolator(info.propertyTypeUid, info.interpolatorClassUid.ToUid()); 2058bf80f4bSopenharmony_ci } 2068bf80f4bSopenharmony_ci 2078bf80f4bSopenharmony_ci // No need to register the default interpolator, only register the class 2088bf80f4bSopenharmony_ci registry.RegisterObjectType<DefaultInterpolator>(); 2098bf80f4bSopenharmony_ci} 2108bf80f4bSopenharmony_civoid UnRegisterDefaultInterpolators(IObjectRegistry& registry) 2118bf80f4bSopenharmony_ci{ 2128bf80f4bSopenharmony_ci for (const auto& info : BuiltInInterpolators::BUILT_IN_INTERPOLATOR_INFO) { 2138bf80f4bSopenharmony_ci // Unregister interpolator 2148bf80f4bSopenharmony_ci registry.UnregisterInterpolator(info.propertyTypeUid); 2158bf80f4bSopenharmony_ci // Unregister object 2168bf80f4bSopenharmony_ci registry.UnregisterObjectType(info.OBJECT_INFO.GetFactory()); 2178bf80f4bSopenharmony_ci } 2188bf80f4bSopenharmony_ci // Unregister default interpolator 2198bf80f4bSopenharmony_ci registry.UnregisterObjectType<DefaultInterpolator>(); 2208bf80f4bSopenharmony_ci} 2218bf80f4bSopenharmony_ci 2228bf80f4bSopenharmony_ciMETA_END_NAMESPACE() 223