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 20META_BEGIN_NAMESPACE() 21 22class FloatInterpolator : public Interpolator<float, FloatInterpolator, ClassId::FloatInterpolator> {}; 23class DoubleInterpolator : public Interpolator<double, DoubleInterpolator, ClassId::DoubleInterpolator> {}; 24class Vec2Interpolator : public Interpolator<BASE_NS::Math::Vec2, Vec2Interpolator, ClassId::Vec2Interpolator> {}; 25class Vec3Interpolator : public Interpolator<BASE_NS::Math::Vec3, Vec3Interpolator, ClassId::Vec3Interpolator> {}; 26class Vec4Interpolator : public Interpolator<BASE_NS::Math::Vec4, Vec4Interpolator, ClassId::Vec4Interpolator> {}; 27class UVec2Interpolator : public Interpolator<BASE_NS::Math::UVec2, UVec2Interpolator, ClassId::UVec2Interpolator> {}; 28class IVec2Interpolator : public Interpolator<BASE_NS::Math::IVec2, IVec2Interpolator, ClassId::IVec2Interpolator> {}; 29class UInt8Interpolator : public Interpolator<uint8_t, UInt8Interpolator, ClassId::UInt8Interpolator> {}; 30class UInt16Interpolator : public Interpolator<uint16_t, UInt16Interpolator, ClassId::UInt16Interpolator> {}; 31class UInt32Interpolator : public Interpolator<uint32_t, UInt32Interpolator, ClassId::UInt32Interpolator> {}; 32class UInt64Interpolator : public Interpolator<uint64_t, UInt64Interpolator, ClassId::UInt64Interpolator> {}; 33class Int8Interpolator : public Interpolator<int8_t, Int8Interpolator, ClassId::Int8Interpolator> {}; 34class Int16Interpolator : public Interpolator<int16_t, Int16Interpolator, ClassId::Int16Interpolator> {}; 35class Int32Interpolator : public Interpolator<int32_t, Int32Interpolator, ClassId::Int32Interpolator> {}; 36class Int64Interpolator : public Interpolator<int64_t, Int64Interpolator, ClassId::Int64Interpolator> {}; 37 38class QuatInterpolator : public META_NS::BaseObjectFwd<QuatInterpolator, ClassId::QuatInterpolator, 39 META_NS::ClassId::BaseObject, IInterpolator> { 40 using Type = BASE_NS::Math::Quat; 41 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 51 bool IsCompatibleWith(TypeId id) const noexcept override 52 { 53 return id == UidFromType<Type>(); 54 } 55}; 56 57class DefaultInterpolator : public META_NS::BaseObjectFwd<DefaultInterpolator, ClassId::DefaultInterpolator, 58 META_NS::ClassId::BaseObject, IInterpolator> { 59 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 } 68 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 76class UVec3Interpolator : public META_NS::BaseObjectFwd<UVec3Interpolator, ClassId::UVec3Interpolator, 77 META_NS::ClassId::BaseObject, IInterpolator> { 78 using Type = BASE_NS::Math::UVec3; 79 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 } 92 bool IsCompatibleWith(TypeId id) const noexcept override 93 { 94 return id == UidFromType<Type>(); 95 } 96}; 97 98class UVec4Interpolator : public META_NS::BaseObjectFwd<UVec4Interpolator, ClassId::UVec4Interpolator, 99 META_NS::ClassId::BaseObject, IInterpolator> { 100 using Type = BASE_NS::Math::UVec4; 101 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 } 115 bool IsCompatibleWith(TypeId id) const noexcept override 116 { 117 return id == UidFromType<Type>(); 118 } 119}; 120 121class IVec3Interpolator : public META_NS::BaseObjectFwd<IVec3Interpolator, ClassId::IVec3Interpolator, 122 META_NS::ClassId::BaseObject, IInterpolator> { 123 using Type = BASE_NS::Math::IVec3; 124 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 } 137 bool IsCompatibleWith(TypeId id) const noexcept override 138 { 139 return id == UidFromType<Type>(); 140 } 141}; 142class IVec4Interpolator : public META_NS::BaseObjectFwd<IVec4Interpolator, ClassId::IVec4Interpolator, 143 META_NS::ClassId::BaseObject, IInterpolator> { 144 using Type = BASE_NS::Math::IVec4; 145 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 } 159 bool IsCompatibleWith(TypeId id) const noexcept override 160 { 161 return id == UidFromType<Type>(); 162 } 163}; 164 165namespace BuiltInInterpolators { 166 167struct InterpolatorInfo { 168 ObjectTypeInfo OBJECT_INFO; 169 TypeId propertyTypeUid; 170 ObjectId interpolatorClassUid; 171}; 172 173static 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 198void 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} 210void 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 222META_END_NAMESPACE() 223