• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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