/* * Copyright (c) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "interpolator.h" #include META_BEGIN_NAMESPACE() class FloatInterpolator : public Interpolator {}; class DoubleInterpolator : public Interpolator {}; class Vec2Interpolator : public Interpolator {}; class Vec3Interpolator : public Interpolator {}; class Vec4Interpolator : public Interpolator {}; class UVec2Interpolator : public Interpolator {}; class IVec2Interpolator : public Interpolator {}; class UInt8Interpolator : public Interpolator {}; class UInt16Interpolator : public Interpolator {}; class UInt32Interpolator : public Interpolator {}; class UInt64Interpolator : public Interpolator {}; class Int8Interpolator : public Interpolator {}; class Int16Interpolator : public Interpolator {}; class Int32Interpolator : public Interpolator {}; class Int64Interpolator : public Interpolator {}; class QuatInterpolator : public META_NS::BaseObjectFwd { using Type = BASE_NS::Math::Quat; AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override { if (IsSetCompatibleWith(output) && IsGetCompatibleWith(from) && IsGetCompatibleWith(to)) { Type value0 = GetValue(from); Type value1 = GetValue(to); return output.SetValue(BASE_NS::Math::Slerp(value0, value1, t)); } return AnyReturn::INCOMPATIBLE_TYPE; } bool IsCompatibleWith(TypeId id) const noexcept override { return id == UidFromType(); } }; class DefaultInterpolator : public META_NS::BaseObjectFwd { AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override { // The default interpolator doesn't know how to interpolate, so we just set the property value to either // from or to based on t if (t > .5f) { return output.CopyFrom(to); } return output.CopyFrom(from); } bool IsCompatibleWith(TypeId id) const noexcept override { // Default interpolator is compatible with any type return true; } }; // No math operations have been defined for integer type vec3/4, implement interpolators manually class UVec3Interpolator : public META_NS::BaseObjectFwd { using Type = BASE_NS::Math::UVec3; AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override { if (IsSetCompatibleWith(output) && IsGetCompatibleWith(from) && IsGetCompatibleWith(to)) { Type value0 = GetValue(from); Type value1 = GetValue(to); Type value; value.x = value0.x + (value1.x - value0.x) * t; value.y = value0.y + (value1.y - value0.y) * t; value.z = value0.z + (value1.z - value0.z) * t; return output.SetValue(value); } return AnyReturn::INCOMPATIBLE_TYPE; } bool IsCompatibleWith(TypeId id) const noexcept override { return id == UidFromType(); } }; class UVec4Interpolator : public META_NS::BaseObjectFwd { using Type = BASE_NS::Math::UVec4; AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override { if (IsSetCompatibleWith(output) && IsGetCompatibleWith(from) && IsGetCompatibleWith(to)) { Type value0 = GetValue(from); Type value1 = GetValue(to); Type value; value.x = value0.x + (value1.x - value0.x) * t; value.y = value0.y + (value1.y - value0.y) * t; value.z = value0.z + (value1.z - value0.z) * t; value.w = value0.w + (value1.w - value0.w) * t; return output.SetValue(value); } return AnyReturn::INCOMPATIBLE_TYPE; } bool IsCompatibleWith(TypeId id) const noexcept override { return id == UidFromType(); } }; class IVec3Interpolator : public META_NS::BaseObjectFwd { using Type = BASE_NS::Math::IVec3; AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override { if (IsSetCompatibleWith(output) && IsGetCompatibleWith(from) && IsGetCompatibleWith(to)) { Type value0 = GetValue(from); Type value1 = GetValue(to); Type value; value.x = value0.x + (value1.x - value0.x) * t; value.y = value0.y + (value1.y - value0.y) * t; value.z = value0.z + (value1.z - value0.z) * t; return output.SetValue(value); } return AnyReturn::INCOMPATIBLE_TYPE; } bool IsCompatibleWith(TypeId id) const noexcept override { return id == UidFromType(); } }; class IVec4Interpolator : public META_NS::BaseObjectFwd { using Type = BASE_NS::Math::IVec4; AnyReturnValue Interpolate(IAny& output, const IAny& from, const IAny& to, float t) const override { if (IsSetCompatibleWith(output) && IsGetCompatibleWith(from) && IsGetCompatibleWith(to)) { Type value0 = GetValue(from); Type value1 = GetValue(to); Type value; value.x = value0.x + (value1.x - value0.x) * t; value.y = value0.y + (value1.y - value0.y) * t; value.z = value0.z + (value1.z - value0.z) * t; value.w = value0.w + (value1.w - value0.w) * t; return output.SetValue(value); } return AnyReturn::INCOMPATIBLE_TYPE; } bool IsCompatibleWith(TypeId id) const noexcept override { return id == UidFromType(); } }; namespace BuiltInInterpolators { struct InterpolatorInfo { ObjectTypeInfo OBJECT_INFO; TypeId propertyTypeUid; ObjectId interpolatorClassUid; }; static constexpr InterpolatorInfo BUILT_IN_INTERPOLATOR_INFO[] = { { FloatInterpolator::OBJECT_INFO, UidFromType(), ClassId::FloatInterpolator }, { DoubleInterpolator::OBJECT_INFO, UidFromType(), ClassId::DoubleInterpolator }, { Vec2Interpolator::OBJECT_INFO, UidFromType(), ClassId::Vec2Interpolator }, { Vec3Interpolator::OBJECT_INFO, UidFromType(), ClassId::Vec3Interpolator }, { Vec4Interpolator::OBJECT_INFO, UidFromType(), ClassId::Vec4Interpolator }, { UVec2Interpolator::OBJECT_INFO, UidFromType(), ClassId::UVec2Interpolator }, { UVec3Interpolator::OBJECT_INFO, UidFromType(), ClassId::UVec3Interpolator }, { UVec4Interpolator::OBJECT_INFO, UidFromType(), ClassId::UVec4Interpolator }, { IVec2Interpolator::OBJECT_INFO, UidFromType(), ClassId::IVec2Interpolator }, { IVec3Interpolator::OBJECT_INFO, UidFromType(), ClassId::IVec3Interpolator }, { IVec4Interpolator::OBJECT_INFO, UidFromType(), ClassId::IVec4Interpolator }, { UInt8Interpolator::OBJECT_INFO, UidFromType(), ClassId::UInt8Interpolator }, { UInt16Interpolator::OBJECT_INFO, UidFromType(), ClassId::UInt16Interpolator }, { UInt32Interpolator::OBJECT_INFO, UidFromType(), ClassId::UInt32Interpolator }, { UInt64Interpolator::OBJECT_INFO, UidFromType(), ClassId::UInt64Interpolator }, { Int8Interpolator::OBJECT_INFO, UidFromType(), ClassId::Int8Interpolator }, { Int16Interpolator::OBJECT_INFO, UidFromType(), ClassId::Int16Interpolator }, { Int32Interpolator::OBJECT_INFO, UidFromType(), ClassId::Int32Interpolator }, { Int64Interpolator::OBJECT_INFO, UidFromType(), ClassId::Int64Interpolator }, { QuatInterpolator::OBJECT_INFO, UidFromType(), ClassId::QuatInterpolator }, }; } // namespace BuiltInInterpolators void RegisterDefaultInterpolators(IObjectRegistry& registry) { for (const auto& info : BuiltInInterpolators::BUILT_IN_INTERPOLATOR_INFO) { // Register the classes themselves registry.RegisterObjectType(info.OBJECT_INFO.GetFactory()); // Then register them as interpolators (note that default interpolator doesn't need to be registered) registry.RegisterInterpolator(info.propertyTypeUid, info.interpolatorClassUid.ToUid()); } // No need to register the default interpolator, only register the class registry.RegisterObjectType(); } void UnRegisterDefaultInterpolators(IObjectRegistry& registry) { for (const auto& info : BuiltInInterpolators::BUILT_IN_INTERPOLATOR_INFO) { // Unregister interpolator registry.UnregisterInterpolator(info.propertyTypeUid); // Unregister object registry.UnregisterObjectType(info.OBJECT_INFO.GetFactory()); } // Unregister default interpolator registry.UnregisterObjectType(); } META_END_NAMESPACE()