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