summaryrefslogtreecommitdiffstats
path: root/src/dm/systems/Qt3DSDMAnimation.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/dm/systems/Qt3DSDMAnimation.h')
-rw-r--r--src/dm/systems/Qt3DSDMAnimation.h841
1 files changed, 841 insertions, 0 deletions
diff --git a/src/dm/systems/Qt3DSDMAnimation.h b/src/dm/systems/Qt3DSDMAnimation.h
new file mode 100644
index 0000000..457b042
--- /dev/null
+++ b/src/dm/systems/Qt3DSDMAnimation.h
@@ -0,0 +1,841 @@
+/****************************************************************************
+**
+** Copyright (C) 1993-2009 NVIDIA Corporation.
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QT3DSDM_ANIMATION_H
+#define QT3DSDM_ANIMATION_H
+
+#include "Qt3DSDMHandles.h"
+#include "Qt3DSDMDataTypes.h"
+#include "Qt3DSDMValue.h"
+
+namespace qt3dsdm {
+
+struct SLinearKeyframe
+{
+ float m_KeyframeSeconds;
+ float m_KeyframeValue;
+};
+
+struct SBezierKeyframe : public SLinearKeyframe
+{
+ float m_InTangentTime; // time
+ float m_InTangentValue; // value offset
+ float m_OutTangentTime; // time offset in seconds
+ float m_OutTangentValue; // value offset
+};
+
+typedef std::vector<SBezierKeyframe> TBezierKeyframeList;
+
+/**
+ * Ease in/out are parameters that affect the bezier evaluation.
+ * Ease in/out at 100 means that the control values are at the end points thus creating
+ * a gradual deceleration. Ease in/out at 0 means that interpolation is linear, the
+ * control points are at 1/3 and 2/3's the distance to the next value.
+ * Ease in/out go from 0.f to 100.0f
+ */
+struct SEaseInEaseOutKeyframe : public SLinearKeyframe
+{
+ float m_EaseIn;
+ float m_EaseOut;
+};
+
+} // namespace qt3dsdm
+
+namespace qt3ds {
+namespace foundation {
+ // Disable calling destructor of these pod types
+ template <>
+ struct DestructTraits<qt3dsdm::SEaseInEaseOutKeyframe>
+ {
+ void destruct(qt3dsdm::SEaseInEaseOutKeyframe &) {}
+ };
+ template <>
+ struct DestructTraits<qt3dsdm::SBezierKeyframe>
+ {
+ void destruct(qt3dsdm::SBezierKeyframe &) {}
+ };
+ template <>
+ struct DestructTraits<qt3dsdm::SLinearKeyframe>
+ {
+ void destruct(qt3dsdm::SLinearKeyframe &) {}
+ };
+}
+}
+
+namespace qt3dsdm {
+
+enum EAnimationType {
+ EAnimationTypeNone = 0,
+ EAnimationTypeLinear,
+ EAnimationTypeBezier,
+ EAnimationTypeEaseInOut,
+};
+
+template <typename TDataType>
+struct SAnimationTypeTraits
+{
+};
+
+template <>
+struct SAnimationTypeTraits<SBezierKeyframe>
+{
+ EAnimationType getType() { return EAnimationTypeBezier; }
+};
+template <>
+struct SAnimationTypeTraits<SLinearKeyframe>
+{
+ EAnimationType getType() { return EAnimationTypeLinear; }
+};
+template <>
+struct SAnimationTypeTraits<SEaseInEaseOutKeyframe>
+{
+ EAnimationType getType() { return EAnimationTypeEaseInOut; }
+};
+
+struct SKeyframeUnionTraits
+{
+ typedef EAnimationType TIdType;
+ enum {
+ TBufferSize = sizeof(SBezierKeyframe),
+ };
+ static TIdType getNoDataId() { return EAnimationTypeNone; }
+ template <typename TDataType>
+ static TIdType getType()
+ {
+ return SAnimationTypeTraits<TDataType>().getType();
+ }
+
+ template <typename TRetType, typename TVisitorType>
+ static TRetType visit(char *inData, TIdType inType, TVisitorType inVisitor)
+ {
+ switch (inType) {
+ case EAnimationTypeBezier:
+ return inVisitor(*reinterpret_cast<SBezierKeyframe *>(inData));
+ case EAnimationTypeLinear:
+ return inVisitor(*reinterpret_cast<SLinearKeyframe *>(inData));
+ case EAnimationTypeEaseInOut:
+ return inVisitor(*reinterpret_cast<SEaseInEaseOutKeyframe *>(inData));
+ default:
+ QT3DS_ASSERT(false);
+ case EAnimationTypeNone:
+ return inVisitor();
+ }
+ }
+
+ template <typename TRetType, typename TVisitorType>
+ static TRetType visit(const char *inData, TIdType inType, TVisitorType inVisitor)
+ {
+ switch (inType) {
+ case EAnimationTypeBezier:
+ return inVisitor(*reinterpret_cast<const SBezierKeyframe *>(inData));
+ case EAnimationTypeLinear:
+ return inVisitor(*reinterpret_cast<const SLinearKeyframe *>(inData));
+ case EAnimationTypeEaseInOut:
+ return inVisitor(*reinterpret_cast<const SEaseInEaseOutKeyframe *>(inData));
+ default:
+ QT3DS_ASSERT(false);
+ case EAnimationTypeNone:
+ return inVisitor();
+ }
+ }
+};
+
+typedef qt3ds::foundation::
+ DiscriminatedUnion<qt3ds::foundation::
+ DiscriminatedUnionGenericBase<SKeyframeUnionTraits,
+ SKeyframeUnionTraits::TBufferSize>,
+ SKeyframeUnionTraits::TBufferSize>
+ TKeyframe;
+
+template <>
+struct Qt3DSDMGetter<TKeyframe>
+{
+ template <typename TRetType>
+ TRetType doGet(const TKeyframe &inValue)
+ {
+ return inValue.getData<TRetType>();
+ }
+};
+
+typedef std::vector<TKeyframe> TKeyframeList;
+
+struct SAnimationInfo
+{
+ Qt3DSDMSlideHandle m_Slide;
+ Qt3DSDMInstanceHandle m_Instance;
+ Qt3DSDMPropertyHandle m_Property;
+ size_t m_Index;
+ EAnimationType m_AnimationType;
+ // Use the existing value for the value of the first keyframe.
+ // Not reflected in studio at this time, purely a runtime problem.
+ // Defaults to false
+ bool m_DynamicFirstKeyframe;
+ bool m_ArtistEdited;
+ SAnimationInfo()
+ : m_Index(0)
+ , m_AnimationType(EAnimationTypeLinear)
+ , m_DynamicFirstKeyframe(false)
+ // Animations are assumed to be artist edited.
+ // And any change will force this flag to true.
+ , m_ArtistEdited(true)
+
+ {
+ }
+ SAnimationInfo(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex, EAnimationType inAnimationType,
+ bool inDynamicFirstKeyframe, bool inArtistEdited)
+ : m_Slide(inSlide)
+ , m_Instance(inInstance)
+ , m_Property(inProperty)
+ , m_Index(inIndex)
+ , m_AnimationType(inAnimationType)
+ , m_DynamicFirstKeyframe(inDynamicFirstKeyframe)
+ , m_ArtistEdited(inArtistEdited)
+ {
+ }
+};
+
+typedef std::pair<SAnimationInfo, TKeyframeList> TAnimationKeyframesPair;
+typedef std::vector<TAnimationKeyframesPair> TAnimationKeyframesPairList;
+typedef std::vector<SAnimationInfo> TAnimationInfoList;
+
+/**
+ * Pure animation core. Not wrapped in any niceties.
+ */
+class IAnimationCore
+{
+public:
+ virtual ~IAnimationCore() {}
+ virtual Qt3DSDMAnimationHandle CreateAnimation(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType,
+ bool inFirstKeyframeDynamic) = 0;
+ virtual void DeleteAnimation(Qt3DSDMAnimationHandle inAnimation) = 0;
+ virtual Qt3DSDMAnimationHandle GetAnimation(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ size_t inIndex) const = 0;
+ virtual SAnimationInfo GetAnimationInfo(Qt3DSDMAnimationHandle inAnimation) const = 0;
+ virtual void GetAnimations(TAnimationHandleList &outAnimations) const = 0;
+ virtual void GetAnimations(TAnimationInfoList &outAnimations,
+ Qt3DSDMSlideHandle inMaster = Qt3DSDMSlideHandle(),
+ Qt3DSDMSlideHandle inSlide = Qt3DSDMSlideHandle()) const = 0;
+
+ virtual void GetSpecificInstanceAnimations(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ TAnimationHandleList &outAnimations) = 0;
+
+ virtual void SetFirstKeyframeDynamic(Qt3DSDMAnimationHandle inAnimation, bool inValue) = 0;
+
+ // keyframe manipulation
+ virtual Qt3DSDMKeyframeHandle InsertKeyframe(Qt3DSDMAnimationHandle inAnimation,
+ const TKeyframe &inKeyframe) = 0;
+ virtual void EraseKeyframe(Qt3DSDMKeyframeHandle inKeyframe) = 0;
+ virtual void DeleteAllKeyframes(Qt3DSDMAnimationHandle inAnimation) = 0;
+
+ // All of these mutators will force the artist edited property
+ // of the animation to true.
+ virtual Qt3DSDMAnimationHandle
+ GetAnimationForKeyframe(Qt3DSDMKeyframeHandle inKeyframe) const = 0;
+ virtual TKeyframe GetKeyframeData(Qt3DSDMKeyframeHandle inKeyframe) const = 0;
+ virtual void SetKeyframeData(Qt3DSDMKeyframeHandle inKeyframe, const TKeyframe &inData) = 0;
+ virtual void GetKeyframes(Qt3DSDMAnimationHandle inAnimation,
+ TKeyframeHandleList &outKeyframes) const = 0;
+ virtual size_t GetKeyframeCount(Qt3DSDMAnimationHandle inAnimation) const = 0;
+ virtual bool IsFirstKeyframe(Qt3DSDMKeyframeHandle inKeyframe) const = 0;
+
+ virtual void OffsetAnimations(Qt3DSDMSlideHandle inSlide, Qt3DSDMInstanceHandle inInstance,
+ long inOffset) = 0;
+
+ // Direct mutators of the artist edited feature of animations
+ virtual void SetIsArtistEdited(Qt3DSDMAnimationHandle inAnimation, bool inEdited = true) = 0;
+ virtual bool IsArtistEdited(Qt3DSDMAnimationHandle inAnimation) const = 0;
+
+ // Animation Evaluation.
+ virtual float EvaluateAnimation(Qt3DSDMAnimationHandle inAnimation, float inSeconds) const = 0;
+
+ virtual bool KeyframeValid(Qt3DSDMKeyframeHandle inKeyframe) const = 0;
+ virtual bool AnimationValid(Qt3DSDMAnimationHandle inAnimation) const = 0;
+
+ virtual void CopyAnimations(Qt3DSDMSlideHandle inSourceSlide,
+ Qt3DSDMInstanceHandle inSourceInstance,
+ Qt3DSDMSlideHandle inDestSlide,
+ Qt3DSDMInstanceHandle inDestInstance) = 0;
+};
+
+typedef std::shared_ptr<IAnimationCore> TAnimationCorePtr;
+
+struct SGetOrSetKeyframeInfo
+{
+ float m_Value = 0.0;
+ float m_EaseIn = -1.f;
+ float m_EaseOut = -1.f;
+ bool m_AnimationTrackIsDynamic = false;
+
+ SGetOrSetKeyframeInfo(float inValue, float inEaseIn = -1.f, float inEaseOut = -1.f,
+ bool inDynamic = false)
+ : m_Value(inValue)
+ , m_EaseIn(inEaseIn)
+ , m_EaseOut(inEaseOut)
+ , m_AnimationTrackIsDynamic(inDynamic)
+ {
+ }
+ SGetOrSetKeyframeInfo() = default;
+
+};
+/**
+ * Interface from studio into the animation system that speaks
+ * a language near to that of studio. Public interface.
+ */
+class IStudioAnimationSystem
+{
+public:
+ virtual ~IStudioAnimationSystem() {}
+
+ /**
+ * When auto-keyframing is on, all calls to setinstancepropertyvalue will
+ * case a keyframe to be set if the instance is a member of a slide graph.
+ */
+ virtual void SetAutoKeyframe(bool inAutoKeyframe) = 0;
+ /**
+ * Returns true when auto keyframing is set.
+ */
+ virtual bool GetAutoKeyframe() const = 0;
+ /**
+ * Create animation on the property on this instance. If the property was animated and had
+ *keyframes previously,
+ * this function will also set the keyframes accordingly.
+ */
+ virtual void Animate(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty) = 0;
+ /**
+ * Delete animation on the property on this instance
+ */
+ virtual void Deanimate(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty) = 0;
+ /**
+ * Set a keyframe on this property. Uses the current time of the slide graph.
+ * If the keyframe is within a given time distance of another, this function will simply change
+ * the keyframed value of the other property to match the current value of this property.
+ */
+ virtual void KeyframeProperty(Qt3DSDMInstanceHandle inInstance, Qt3DSDMPropertyHandle inProperty,
+ bool inDoDiffValue) = 0;
+ /**
+ * Set the value of a existing a keyframe or create a new one, on this property, at the given
+ *time.
+ * If ease in or ease out are unset then the keyframe gets the default ease in or out.
+ */
+ virtual void SetOrCreateKeyframe(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, float inTimeInSeconds,
+ SGetOrSetKeyframeInfo *inKeyframeInfo, size_t inNumInfos) = 0;
+ /**
+ * Return the animation that is currently controlling this property. This function will return
+ * an invalid handle value if there is currently no animation controlling this property.
+ */
+ virtual Qt3DSDMAnimationHandle GetControllingAnimation(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ size_t inIndex) const = 0;
+
+ /**
+ * Return true if the given property is animatable. You can begin animation by calling
+ *KeyframeProperty *or*
+ * by setting auto keyframe to on and setting a property value through the
+ *IInstancePropertyCore system.
+ */
+ virtual bool IsPropertyAnimatable(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const = 0;
+
+ /**
+ * Return true if the given property is animated. Currently, either 0 or ALL channels are
+ *animated. Hence, checking for index = 0 suffices.
+ * And if that changes, this function can be updated accordingly.
+ */
+ virtual bool IsPropertyAnimated(Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty) const = 0;
+
+ /**
+ * Specify if new keyframes should be created with smooth ( ie Ease In/Out values = 100 ) or
+ *linear ( Ease In/Out values = 0 )
+ */
+ virtual void SetInterpolation(bool inSmooth) = 0;
+
+ /**
+ * Get an instance property value. Will override outValue only if the slide, instance,
+ *property is animated.
+ */
+ virtual bool GetAnimatedInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ SValue &outValue) const = 0;
+ /**
+ * Set an instance property value. Will return true in the cases where
+ * the property is actually animated. May only set local values, or may auto set a keyframed
+ *value.
+ */
+ virtual bool SetAnimatedInstancePropertyValue(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty,
+ const SValue &inValue) = 0;
+
+ typedef std::function<void(Qt3DSDMInstanceHandle instance)> TRefreshCallbackFunc;
+ virtual void setRefreshCallback(TRefreshCallbackFunc func) = 0;
+};
+
+typedef std::shared_ptr<IStudioAnimationSystem> TStudioAnimationSystemPtr;
+
+inline SLinearKeyframe CreateLinearKeyframe(float inSeconds, float inValue)
+{
+ SLinearKeyframe retval = { inSeconds, inValue };
+ return retval;
+}
+
+inline SBezierKeyframe CreateBezierKeyframe(float inSeconds, float inValue, float inInTangentTime,
+ float inInTangentValue, float inOutTangentTime,
+ float inOutTangentValue)
+{
+ SBezierKeyframe theBezierKeyframe;
+ theBezierKeyframe.m_KeyframeSeconds = inSeconds;
+ theBezierKeyframe.m_KeyframeValue = inValue;
+ theBezierKeyframe.m_InTangentTime = inInTangentTime;
+ theBezierKeyframe.m_InTangentValue = inInTangentValue;
+ theBezierKeyframe.m_OutTangentTime = inOutTangentTime;
+ theBezierKeyframe.m_OutTangentValue = inOutTangentValue;
+ return theBezierKeyframe;
+}
+
+inline SEaseInEaseOutKeyframe CreateEaseInEaseOutKeyframe(float inSeconds, float inValue,
+ float inEaseIn, float inEaseOut)
+{
+ SEaseInEaseOutKeyframe retval;
+ retval.m_KeyframeSeconds = inSeconds;
+ retval.m_KeyframeValue = inValue;
+ retval.m_EaseIn = inEaseIn;
+ retval.m_EaseOut = inEaseOut;
+ return retval;
+}
+
+inline SAnimationInfo CreateAnimationInfo(Qt3DSDMSlideHandle inSlide,
+ Qt3DSDMInstanceHandle inInstance,
+ Qt3DSDMPropertyHandle inProperty, size_t inIndex,
+ EAnimationType inAnimationType,
+ bool inFirstKeyframeDynamic, bool inArtistEdited)
+{
+ SAnimationInfo retval(inSlide, inInstance, inProperty, inIndex, inAnimationType,
+ inFirstKeyframeDynamic, inArtistEdited);
+ return retval;
+}
+
+struct SKeyframeValueVisitor
+{
+ float operator()(const SLinearKeyframe &inKeyframe) const { return inKeyframe.m_KeyframeValue; }
+ float operator()(const SBezierKeyframe &inKeyframe) const { return inKeyframe.m_KeyframeValue; }
+ float operator()(const SEaseInEaseOutKeyframe &inKeyframe) const
+ {
+ return inKeyframe.m_KeyframeValue;
+ }
+ float operator()()
+ {
+ QT3DS_ASSERT(false);
+ return 0.0f;
+ }
+};
+
+inline float KeyframeValueValue(const TKeyframe &inKeyframe)
+{
+ return inKeyframe.visit<float>(SKeyframeValueVisitor());
+}
+
+struct SKeyframeTimeAnalyzer
+{
+ float operator()(const SLinearKeyframe &inValue) const { return inValue.m_KeyframeSeconds; }
+ float operator()(const SBezierKeyframe &inValue) const { return inValue.m_KeyframeSeconds; }
+ float operator()(const SEaseInEaseOutKeyframe &inValue) const
+ {
+ return inValue.m_KeyframeSeconds;
+ }
+ float operator()()
+ {
+ QT3DS_ASSERT(false);
+ return 0.0f;
+ }
+};
+
+inline float KeyframeTime(const TKeyframe &inValue)
+{
+ return inValue.visit<float>(SKeyframeTimeAnalyzer());
+}
+
+inline EAnimationType GetKeyframeType(const TKeyframe &inKeyframe)
+{
+ return inKeyframe.getType();
+}
+
+struct SAnimatableArityVisitor
+{
+ std::tuple<bool, size_t> operator()(bool) const
+ {
+ return std::tuple<bool, size_t>(true, 1);
+ }
+ std::tuple<bool, size_t> operator()(long) const
+ {
+ return std::tuple<bool, size_t>(true, 1);
+ }
+ std::tuple<bool, size_t> operator()(float) const
+ {
+ return std::tuple<bool, size_t>(true, 1);
+ }
+ std::tuple<bool, size_t> operator()(const SFloat2 &) const
+ {
+ return std::tuple<bool, size_t>(true, 2);
+ }
+ std::tuple<bool, size_t> operator()(const SFloat3 &) const
+ {
+ return std::tuple<bool, size_t>(true, 3);
+ }
+ std::tuple<bool, size_t> operator()(const SFloat4 &) const
+ {
+ return std::tuple<bool, size_t>(true, 4);
+ }
+ template <typename TDataType>
+ std::tuple<bool, size_t> operator()(const TDataType &) const
+ {
+ return std::tuple<bool, size_t>(false, 0);
+ }
+ std::tuple<bool, size_t> operator()()
+ {
+ QT3DS_ASSERT(false);
+ return std::tuple<bool, size_t>(false, 0);
+ }
+};
+
+inline std::tuple<bool, size_t> GetVariantAnimatableAndArity(const SValue &inValue)
+{
+ return inValue.visit<std::tuple<bool, size_t>>(SAnimatableArityVisitor());
+}
+
+inline std::tuple<bool, size_t> GetDatatypeAnimatableAndArity(DataModelDataType::Value inDataType)
+{
+ switch (inDataType) {
+ case DataModelDataType::Long:
+ case DataModelDataType::Float:
+ return std::make_tuple(true, 1);
+
+ case DataModelDataType::Float2:
+ return std::make_tuple(true, 2);
+
+ case DataModelDataType::Float3:
+ return std::make_tuple(true, 3);
+
+ case DataModelDataType::Float4:
+ return std::make_tuple(true, 4);
+
+ default:
+ return std::make_tuple(false, 0);
+ }
+}
+
+template <typename TDataType>
+inline TDataType SetFloatValue(float inValue, size_t inIndex, const TDataType &inDataType)
+{
+ TDataType retval(inDataType);
+ retval[inIndex] = inValue;
+ return retval;
+}
+
+struct SAnimationApplier
+{
+ float m_Value;
+ size_t m_Index;
+ SValue operator()(const bool &) { return m_Value > 0.5f; }
+ SValue operator()(const qt3ds::QT3DSI32 &) { return static_cast<qt3ds::QT3DSI32>(m_Value + .5f); }
+ SValue operator()(const float &) { return m_Value; }
+ SValue operator()(const SFloat2 &inValue) { return SetFloatValue(m_Value, m_Index, inValue); }
+ SValue operator()(const SFloat3 &inValue) { return SetFloatValue(m_Value, m_Index, inValue); }
+ SValue operator()(const SFloat4 &inValue) { return SetFloatValue(m_Value, m_Index, inValue); }
+ template <typename TDataType>
+ SValue operator()(const TDataType &inValue)
+ {
+ return inValue;
+ }
+ SValue operator()()
+ {
+ QT3DS_ASSERT(false);
+ return SValue();
+ }
+};
+
+inline void SetAnimationValue(float inValue, size_t inIndex, SValue &ioValue)
+{
+ using namespace std;
+ SAnimationApplier theApplier;
+ theApplier.m_Value = inValue;
+ theApplier.m_Index = inIndex;
+ ioValue = ioValue.visit<SValue>(theApplier);
+}
+
+template <typename TDataType>
+inline float GetFloatValue(const TDataType &inValue, size_t inIndex)
+{
+ return inValue[inIndex];
+}
+
+struct SAnimationGetter
+{
+ size_t m_Index;
+ float operator()(const bool &inValue) const { return inValue ? 1.f : 0.f; }
+ float operator()(const long &inValue) const { return static_cast<float>(inValue); }
+ float operator()(const float &inValue) const { return inValue; }
+ float operator()(const SFloat2 &inValue) const { return GetFloatValue(inValue, m_Index); }
+ float operator()(const SFloat3 &inValue) const { return GetFloatValue(inValue, m_Index); }
+ float operator()(const SFloat4 &inValue) const { return GetFloatValue(inValue, m_Index); }
+ template <typename TDataType>
+ float operator()(const TDataType & /*inValue*/) const
+ {
+ return 0.f;
+ }
+ float operator()()
+ {
+ QT3DS_ASSERT(false);
+ return 0.0f;
+ }
+};
+
+inline float GetAnimationValue(size_t inIndex, const SValue &ioValue)
+{
+ SAnimationGetter theGetter;
+ theGetter.m_Index = inIndex;
+ return ioValue.visit<float>(theGetter);
+}
+
+struct SKeyframeTimeSetter
+{
+ float m_Seconds;
+ TKeyframe operator()(const SLinearKeyframe &inValue) const
+ {
+ return CreateLinearKeyframe(m_Seconds, inValue.m_KeyframeValue);
+ }
+ TKeyframe operator()(const SBezierKeyframe &inValue) const
+ {
+ return CreateBezierKeyframe(m_Seconds, inValue.m_KeyframeValue, inValue.m_InTangentTime,
+ inValue.m_InTangentValue, inValue.m_OutTangentTime,
+ inValue.m_OutTangentValue);
+ }
+ TKeyframe operator()(const SEaseInEaseOutKeyframe &inValue) const
+ {
+ return CreateEaseInEaseOutKeyframe(m_Seconds, inValue.m_KeyframeValue, inValue.m_EaseIn,
+ inValue.m_EaseOut);
+ }
+ TKeyframe operator()()
+ {
+ QT3DS_ASSERT(false);
+ return TKeyframe();
+ }
+};
+
+inline TKeyframe SetKeyframeSeconds(const TKeyframe &inKeyframe, float inSeconds)
+{
+ SKeyframeTimeSetter theSetter;
+ theSetter.m_Seconds = inSeconds;
+ return inKeyframe.visit<TKeyframe>(theSetter);
+}
+
+struct SKeyframeTimeGetter
+{
+ template <typename TKeyframeType>
+ float operator()(const TKeyframeType &inValue) const
+ {
+ return inValue.m_KeyframeSeconds;
+ }
+ float operator()()
+ {
+ QT3DS_ASSERT(false);
+ return 0.0f;
+ }
+};
+
+inline float GetKeyframeSeconds(const TKeyframe &inKeyframe)
+{
+ SKeyframeTimeGetter theGetter;
+ return inKeyframe.visit<float>(theGetter);
+}
+
+struct SKeyframeValueSetter
+{
+ float m_Value;
+ TKeyframe operator()(const SLinearKeyframe &inValue) const
+ {
+ return CreateLinearKeyframe(inValue.m_KeyframeSeconds, m_Value);
+ }
+ TKeyframe operator()(const SBezierKeyframe &inValue) const
+ {
+ return CreateBezierKeyframe(inValue.m_KeyframeSeconds, m_Value, inValue.m_InTangentTime,
+ inValue.m_InTangentValue, inValue.m_OutTangentTime,
+ inValue.m_OutTangentValue);
+ }
+ TKeyframe operator()(const SEaseInEaseOutKeyframe &inValue) const
+ {
+ return CreateEaseInEaseOutKeyframe(inValue.m_KeyframeSeconds, m_Value, inValue.m_EaseIn,
+ inValue.m_EaseOut);
+ }
+ TKeyframe operator()()
+ {
+ QT3DS_ASSERT(false);
+ return TKeyframe();
+ }
+};
+
+inline TKeyframe SetKeyframeValue(const TKeyframe &inKeyframe, float inValue)
+{
+ SKeyframeValueSetter theSetter;
+ theSetter.m_Value = inValue;
+ return inKeyframe.visit<TKeyframe>(theSetter);
+}
+
+inline float AnimationClamp(float inLowerBound, float inUpperBound, float inValue)
+{
+ if (inValue < inLowerBound)
+ return inLowerBound;
+ if (inValue > inUpperBound)
+ return inUpperBound;
+ return inValue;
+}
+
+inline SBezierKeyframe
+CreateBezierKeyframeFromEaseInEaseOutKeyframe(float *inPreviousValue,
+ SEaseInEaseOutKeyframe inCurrent, float *inNextValue)
+{
+ float theValue = inCurrent.m_KeyframeValue;
+ float theSeconds = inCurrent.m_KeyframeSeconds;
+ float inSeconds = 0.f;
+ float inValue = 0.f;
+ float outSeconds = 0.f;
+ float outValue = 0.f;
+ if (inPreviousValue) {
+ float thePercent = 1.0f - AnimationClamp(0.0f, 1.0f, inCurrent.m_EaseIn / 100.f);
+ double theAmount = 1.0f - thePercent * .333333333334;
+ inValue = (float)(*inPreviousValue
+ + ((inCurrent.m_KeyframeValue - *inPreviousValue) * theAmount));
+ }
+ if (inNextValue) {
+ float thePercent = 1.0f - AnimationClamp(0.0f, 1.0f, inCurrent.m_EaseOut / 100.f);
+ double theAmount = thePercent * .3333333333334;
+ outValue = (float)(inCurrent.m_KeyframeValue
+ + ((*inNextValue - inCurrent.m_KeyframeValue) * theAmount));
+ }
+ return CreateBezierKeyframe(theSeconds, theValue, inSeconds, inValue, outSeconds, outValue);
+}
+
+void CopyKeyframes(const IAnimationCore &inSourceAnimationCore, IAnimationCore &inDestAnimationCore,
+ Qt3DSDMAnimationHandle inDestAnimation, const TKeyframeHandleList &inKeyframes);
+
+Qt3DSDMAnimationHandle CopyAnimation(TAnimationCorePtr inSourceAnimationCore,
+ Qt3DSDMAnimationHandle inAnimation,
+ Qt3DSDMSlideHandle inNewSlide,
+ Qt3DSDMInstanceHandle inNewInstance,
+ Qt3DSDMPropertyHandle inNewProperty, size_t inNewIndex);
+
+struct SEaseInGetter
+{
+ float operator()(const SLinearKeyframe &) const { return 0.f; }
+ float operator()(const SBezierKeyframe &) const { return 0.f; }
+ float operator()(const SEaseInEaseOutKeyframe &inValue) const { return inValue.m_EaseIn; }
+ float operator()()
+ {
+ QT3DS_ASSERT(false);
+ return 0.0f;
+ }
+};
+struct SEaseOutGetter
+{
+ float operator()(const SLinearKeyframe &) const { return 0.f; }
+ float operator()(const SBezierKeyframe &) const { return 0.f; }
+ float operator()(const SEaseInEaseOutKeyframe &inValue) const { return inValue.m_EaseOut; }
+ float operator()()
+ {
+ QT3DS_ASSERT(false);
+ return 0.0f;
+ }
+};
+inline void GetEaseInOutValues(const TKeyframe &inValue, float &outEaseIn, float &outEaseOut)
+{
+ SEaseInGetter theGetter;
+ outEaseIn = inValue.visit<float>(theGetter);
+
+ SEaseOutGetter theEaseOutGetter;
+ outEaseOut = inValue.visit<float>(theEaseOutGetter);
+}
+
+struct SEaseInSetter
+{
+ float m_Value;
+ TKeyframe operator()(SLinearKeyframe &inValue) const { return inValue; }
+ TKeyframe operator()(SBezierKeyframe &inValue) const { return inValue; }
+ TKeyframe operator()(SEaseInEaseOutKeyframe &inKeyframe) const
+ {
+ inKeyframe.m_EaseIn = m_Value;
+ return inKeyframe;
+ }
+ TKeyframe operator()()
+ {
+ QT3DS_ASSERT(false);
+ return TKeyframe();
+ }
+};
+struct SEaseOutSetter
+{
+ float m_Value;
+ TKeyframe operator()(SLinearKeyframe &inValue) const { return inValue; }
+ TKeyframe operator()(SBezierKeyframe &inValue) const { return inValue; }
+ TKeyframe operator()(SEaseInEaseOutKeyframe &inKeyframe) const
+ {
+ inKeyframe.m_EaseOut = m_Value;
+ return inKeyframe;
+ }
+ TKeyframe operator()()
+ {
+ QT3DS_ASSERT(false);
+ return TKeyframe();
+ }
+};
+inline TKeyframe SetEaseInOutValues(TKeyframe &inKeyframe, float inEaseIn, float inEaseOut)
+{
+ SEaseInSetter theSetter;
+ theSetter.m_Value = inEaseIn;
+ inKeyframe.visit<TKeyframe>(theSetter);
+
+ SEaseOutSetter theEaseOutSetter;
+ theEaseOutSetter.m_Value = inEaseOut;
+ inKeyframe.visit<TKeyframe>(theEaseOutSetter);
+
+ return inKeyframe;
+}
+
+void GetKeyframesAsBezier(Qt3DSDMAnimationHandle inAnimation, const IAnimationCore &inAnimationCore,
+ TBezierKeyframeList &outKeyframes);
+}
+
+#endif