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