1 /*
2  * Copyright (c) 2024 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 
16 #include "interpolator.h"
17 
18 #include <base/math/quaternion_util.h>
19 
20 META_BEGIN_NAMESPACE()
21 
22 class FloatInterpolator : public Interpolator<float, FloatInterpolator, ClassId::FloatInterpolator> {};
23 class DoubleInterpolator : public Interpolator<double, DoubleInterpolator, ClassId::DoubleInterpolator> {};
24 class Vec2Interpolator : public Interpolator<BASE_NS::Math::Vec2, Vec2Interpolator, ClassId::Vec2Interpolator> {};
25 class Vec3Interpolator : public Interpolator<BASE_NS::Math::Vec3, Vec3Interpolator, ClassId::Vec3Interpolator> {};
26 class Vec4Interpolator : public Interpolator<BASE_NS::Math::Vec4, Vec4Interpolator, ClassId::Vec4Interpolator> {};
27 class UVec2Interpolator : public Interpolator<BASE_NS::Math::UVec2, UVec2Interpolator, ClassId::UVec2Interpolator> {};
28 class IVec2Interpolator : public Interpolator<BASE_NS::Math::IVec2, IVec2Interpolator, ClassId::IVec2Interpolator> {};
29 class UInt8Interpolator : public Interpolator<uint8_t, UInt8Interpolator, ClassId::UInt8Interpolator> {};
30 class UInt16Interpolator : public Interpolator<uint16_t, UInt16Interpolator, ClassId::UInt16Interpolator> {};
31 class UInt32Interpolator : public Interpolator<uint32_t, UInt32Interpolator, ClassId::UInt32Interpolator> {};
32 class UInt64Interpolator : public Interpolator<uint64_t, UInt64Interpolator, ClassId::UInt64Interpolator> {};
33 class Int8Interpolator : public Interpolator<int8_t, Int8Interpolator, ClassId::Int8Interpolator> {};
34 class Int16Interpolator : public Interpolator<int16_t, Int16Interpolator, ClassId::Int16Interpolator> {};
35 class Int32Interpolator : public Interpolator<int32_t, Int32Interpolator, ClassId::Int32Interpolator> {};
36 class Int64Interpolator : public Interpolator<int64_t, Int64Interpolator, ClassId::Int64Interpolator> {};
37 
38 class QuatInterpolator : public META_NS::BaseObjectFwd<QuatInterpolator, ClassId::QuatInterpolator,
39                              META_NS::ClassId::BaseObject, IInterpolator> {
40     using Type = BASE_NS::Math::Quat;
Interpolate(IAny & output,const IAny & from,const IAny & to,float t) const41     AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override
42     {
43         if (IsSetCompatibleWith<Type>(output) && IsGetCompatibleWith<Type>(from) && IsGetCompatibleWith<Type>(to)) {
44             Type value0 = GetValue<Type>(from);
45             Type value1 = GetValue<Type>(to);
46             return output.SetValue<Type>(BASE_NS::Math::Slerp(value0, value1, t));
47         }
48         return AnyReturn::INCOMPATIBLE_TYPE;
49     }
50 
IsCompatibleWith(TypeId id) const51     bool IsCompatibleWith(TypeId id) const noexcept override
52     {
53         return id == UidFromType<Type>();
54     }
55 };
56 
57 class DefaultInterpolator : public META_NS::BaseObjectFwd<DefaultInterpolator, ClassId::DefaultInterpolator,
58                                 META_NS::ClassId::BaseObject, IInterpolator> {
Interpolate(IAny & output,const IAny & from,const IAny & to,float t) const59     AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override
60     {
61         // The default interpolator doesn't know how to interpolate, so we just set the property value to either
62         // from or to based on t
63         if (t > .5f) {
64             return output.CopyFrom(to);
65         }
66         return output.CopyFrom(from);
67     }
IsCompatibleWith(TypeId id) const68     bool IsCompatibleWith(TypeId id) const noexcept override
69     {
70         // Default interpolator is compatible with any type
71         return true;
72     }
73 };
74 
75 // No math operations have been defined for integer type vec3/4, implement interpolators manually
76 class UVec3Interpolator : public META_NS::BaseObjectFwd<UVec3Interpolator, ClassId::UVec3Interpolator,
77                               META_NS::ClassId::BaseObject, IInterpolator> {
78     using Type = BASE_NS::Math::UVec3;
Interpolate(IAny & output,const IAny & from,const IAny & to,float t) const79     AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override
80     {
81         if (IsSetCompatibleWith<Type>(output) && IsGetCompatibleWith<Type>(from) && IsGetCompatibleWith<Type>(to)) {
82             Type value0 = GetValue<Type>(from);
83             Type value1 = GetValue<Type>(to);
84             Type value;
85             value.x = value0.x + (value1.x - value0.x) * t;
86             value.y = value0.y + (value1.y - value0.y) * t;
87             value.z = value0.z + (value1.z - value0.z) * t;
88             return output.SetValue<Type>(value);
89         }
90         return AnyReturn::INCOMPATIBLE_TYPE;
91     }
IsCompatibleWith(TypeId id) const92     bool IsCompatibleWith(TypeId id) const noexcept override
93     {
94         return id == UidFromType<Type>();
95     }
96 };
97 
98 class UVec4Interpolator : public META_NS::BaseObjectFwd<UVec4Interpolator, ClassId::UVec4Interpolator,
99                               META_NS::ClassId::BaseObject, IInterpolator> {
100     using Type = BASE_NS::Math::UVec4;
Interpolate(IAny & output,const IAny & from,const IAny & to,float t) const101     AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override
102     {
103         if (IsSetCompatibleWith<Type>(output) && IsGetCompatibleWith<Type>(from) && IsGetCompatibleWith<Type>(to)) {
104             Type value0 = GetValue<Type>(from);
105             Type value1 = GetValue<Type>(to);
106             Type value;
107             value.x = value0.x + (value1.x - value0.x) * t;
108             value.y = value0.y + (value1.y - value0.y) * t;
109             value.z = value0.z + (value1.z - value0.z) * t;
110             value.w = value0.w + (value1.w - value0.w) * t;
111             return output.SetValue<Type>(value);
112         }
113         return AnyReturn::INCOMPATIBLE_TYPE;
114     }
IsCompatibleWith(TypeId id) const115     bool IsCompatibleWith(TypeId id) const noexcept override
116     {
117         return id == UidFromType<Type>();
118     }
119 };
120 
121 class IVec3Interpolator : public META_NS::BaseObjectFwd<IVec3Interpolator, ClassId::IVec3Interpolator,
122                               META_NS::ClassId::BaseObject, IInterpolator> {
123     using Type = BASE_NS::Math::IVec3;
Interpolate(IAny & output,const IAny & from,const IAny & to,float t) const124     AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override
125     {
126         if (IsSetCompatibleWith<Type>(output) && IsGetCompatibleWith<Type>(from) && IsGetCompatibleWith<Type>(to)) {
127             Type value0 = GetValue<Type>(from);
128             Type value1 = GetValue<Type>(to);
129             Type value;
130             value.x = value0.x + (value1.x - value0.x) * t;
131             value.y = value0.y + (value1.y - value0.y) * t;
132             value.z = value0.z + (value1.z - value0.z) * t;
133             return output.SetValue<Type>(value);
134         }
135         return AnyReturn::INCOMPATIBLE_TYPE;
136     }
IsCompatibleWith(TypeId id) const137     bool IsCompatibleWith(TypeId id) const noexcept override
138     {
139         return id == UidFromType<Type>();
140     }
141 };
142 class IVec4Interpolator : public META_NS::BaseObjectFwd<IVec4Interpolator, ClassId::IVec4Interpolator,
143                               META_NS::ClassId::BaseObject, IInterpolator> {
144     using Type = BASE_NS::Math::IVec4;
Interpolate(IAny & output,const IAny & from,const IAny & to,float t) const145     AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override
146     {
147         if (IsSetCompatibleWith<Type>(output) && IsGetCompatibleWith<Type>(from) && IsGetCompatibleWith<Type>(to)) {
148             Type value0 = GetValue<Type>(from);
149             Type value1 = GetValue<Type>(to);
150             Type value;
151             value.x = value0.x + (value1.x - value0.x) * t;
152             value.y = value0.y + (value1.y - value0.y) * t;
153             value.z = value0.z + (value1.z - value0.z) * t;
154             value.w = value0.w + (value1.w - value0.w) * t;
155             return output.SetValue<Type>(value);
156         }
157         return AnyReturn::INCOMPATIBLE_TYPE;
158     }
IsCompatibleWith(TypeId id) const159     bool IsCompatibleWith(TypeId id) const noexcept override
160     {
161         return id == UidFromType<Type>();
162     }
163 };
164 
165 namespace BuiltInInterpolators {
166 
167 struct InterpolatorInfo {
168     ObjectTypeInfo OBJECT_INFO;
169     TypeId propertyTypeUid;
170     ObjectId interpolatorClassUid;
171 };
172 
173 static constexpr InterpolatorInfo BUILT_IN_INTERPOLATOR_INFO[] = {
174     { FloatInterpolator::OBJECT_INFO, UidFromType<float>(), ClassId::FloatInterpolator },
175     { DoubleInterpolator::OBJECT_INFO, UidFromType<double>(), ClassId::DoubleInterpolator },
176     { Vec2Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::Vec2>(), ClassId::Vec2Interpolator },
177     { Vec3Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::Vec3>(), ClassId::Vec3Interpolator },
178     { Vec4Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::Vec4>(), ClassId::Vec4Interpolator },
179     { UVec2Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::UVec2>(), ClassId::UVec2Interpolator },
180     { UVec3Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::UVec3>(), ClassId::UVec3Interpolator },
181     { UVec4Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::UVec4>(), ClassId::UVec4Interpolator },
182     { IVec2Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::IVec2>(), ClassId::IVec2Interpolator },
183     { IVec3Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::IVec3>(), ClassId::IVec3Interpolator },
184     { IVec4Interpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::IVec4>(), ClassId::IVec4Interpolator },
185     { UInt8Interpolator::OBJECT_INFO, UidFromType<uint8_t>(), ClassId::UInt8Interpolator },
186     { UInt16Interpolator::OBJECT_INFO, UidFromType<uint16_t>(), ClassId::UInt16Interpolator },
187     { UInt32Interpolator::OBJECT_INFO, UidFromType<uint32_t>(), ClassId::UInt32Interpolator },
188     { UInt64Interpolator::OBJECT_INFO, UidFromType<uint64_t>(), ClassId::UInt64Interpolator },
189     { Int8Interpolator::OBJECT_INFO, UidFromType<int8_t>(), ClassId::Int8Interpolator },
190     { Int16Interpolator::OBJECT_INFO, UidFromType<int16_t>(), ClassId::Int16Interpolator },
191     { Int32Interpolator::OBJECT_INFO, UidFromType<int32_t>(), ClassId::Int32Interpolator },
192     { Int64Interpolator::OBJECT_INFO, UidFromType<int64_t>(), ClassId::Int64Interpolator },
193     { QuatInterpolator::OBJECT_INFO, UidFromType<BASE_NS::Math::Quat>(), ClassId::QuatInterpolator },
194 };
195 
196 } // namespace BuiltInInterpolators
197 
RegisterDefaultInterpolators(IObjectRegistry & registry)198 void RegisterDefaultInterpolators(IObjectRegistry& registry)
199 {
200     for (const auto& info : BuiltInInterpolators::BUILT_IN_INTERPOLATOR_INFO) {
201         // Register the classes themselves
202         registry.RegisterObjectType(info.OBJECT_INFO.GetFactory());
203         // Then register them as interpolators (note that default interpolator doesn't need to be registered)
204         registry.RegisterInterpolator(info.propertyTypeUid, info.interpolatorClassUid.ToUid());
205     }
206 
207     // No need to register the default interpolator, only register the class
208     registry.RegisterObjectType<DefaultInterpolator>();
209 }
UnRegisterDefaultInterpolators(IObjectRegistry & registry)210 void UnRegisterDefaultInterpolators(IObjectRegistry& registry)
211 {
212     for (const auto& info : BuiltInInterpolators::BUILT_IN_INTERPOLATOR_INFO) {
213         // Unregister interpolator
214         registry.UnregisterInterpolator(info.propertyTypeUid);
215         // Unregister object
216         registry.UnregisterObjectType(info.OBJECT_INFO.GetFactory());
217     }
218     // Unregister default interpolator
219     registry.UnregisterObjectType<DefaultInterpolator>();
220 }
221 
222 META_END_NAMESPACE()
223