/*
* 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()