Skip to content

Commit

Permalink
Add support for using keyframe extrapolator as source of procedural a…
Browse files Browse the repository at this point in the history
…nimation.
  • Loading branch information
cjhoward committed Jun 19, 2024
1 parent 924beb7 commit ec935cb
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 9 deletions.
8 changes: 1 addition & 7 deletions src/engine/animation/animation-curve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,11 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#include <engine/animation/animation-curve.hpp>
#include <stdexcept>

float animation_curve::evaluate(float time) const
{
if (m_keyframes.empty())
{
throw std::runtime_error("Failed to evaluate animation curve: no keyframes.");
}

// Check if time is outside keyframe range
if (time < m_keyframes.begin()->time || time > m_keyframes.rbegin()->time)
if (m_keyframes.empty() || time < m_keyframes.begin()->time || time > m_keyframes.rbegin()->time)
{
// Extrapolate outside keyframe range
return m_extrapolator(m_keyframes, time);
Expand Down
8 changes: 7 additions & 1 deletion src/engine/animation/animation-curve.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class animation_curve
* Keyframe extrapolator function type.
*
* An extrapolator function takes two parameters: a reference to the keyframe container, and a time outside the interval formed by the first and last keyframe times. An extrapolator function should return an extrapolated value according to the given time.
*
* @warning Keyframe container may be empty.
*/
using keyframe_extrapolator_type = std::function<float(const keyframe_container&, float)>;

Expand Down Expand Up @@ -63,7 +65,11 @@ class animation_curve
return m_interpolator;
}

/** Returns a reference to the keyframe extrapolator function object. */
/**
* Returns a reference to the keyframe extrapolator function object.
*
* @note The extrapolator may be utilized as a source of procedural animation: if a curve with no keyframes is evaluated, the extrapolator will be called with the empty keyframe container and evaluation time as parameters.
*/
[[nodiscard]] inline constexpr auto& extrapolator() noexcept
{
return m_extrapolator;
Expand Down
6 changes: 6 additions & 0 deletions src/engine/animation/keyframe-extrapolation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
// SPDX-License-Identifier: GPL-3.0-or-later

#include <engine/animation/keyframe-extrapolation.hpp>
#include <stdexcept>

float extrapolate_keyframes_clamp(const keyframe_container& keyframes, float time)
{
if (keyframes.empty())
{
throw std::runtime_error("Failed clamp extrapolation of keyframes: no keyframes provided.");
}

if (time < keyframes.begin()->time)
{
return keyframes.begin()->value;
Expand Down
2 changes: 1 addition & 1 deletion src/engine/animation/keyframe-extrapolation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*
* @return Extrapolated value.
*
* @warning @p keyframes must not be empty!
* @exception std::runtime_error Failed clamp extrapolation of keyframes: no keyframes provided.
*/
[[nodiscard]] float extrapolate_keyframes_clamp(const keyframe_container& keyframes, float time);

Expand Down

0 comments on commit ec935cb

Please sign in to comment.