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