Skip to content

Commit

Permalink
[wip] cubic hermite
Browse files Browse the repository at this point in the history
TODO: split to multiple commits
TODO: test
TODO: cubic hermite quat
  • Loading branch information
mosra committed Aug 5, 2018
1 parent 1eb4f6a commit 63d3684
Show file tree
Hide file tree
Showing 14 changed files with 605 additions and 2 deletions.
13 changes: 13 additions & 0 deletions doc/snippets/MagnumMath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include "Magnum/Magnum.h"
#include "Magnum/Math/Color.h"
#include "Magnum/Math/CubicHermite.h"
#include "Magnum/Math/DualComplex.h"
#include "Magnum/Math/DualQuaternion.h"
#include "Magnum/Math/Half.h"
Expand Down Expand Up @@ -593,6 +594,18 @@ static_cast<void>(q1);
static_cast<void>(q2);
}

{
/* [CubicHermitePoint-fromBezier] */
CubicBezier2D segment;
auto startPoint = CubicHermitePoint2D::fromBezier(
{Vector2{}, Vector2{}, Vector2{}, segment[3]}, segment);
auto endPoint = CubicHermitePoint2D::fromBezier(segment,
{segment[0], Vector2{}, Vector2{}, Vector2{}});
/* [CubicHermitePoint-fromBezier] */
static_cast<void>(startPoint);
static_cast<void>(endPoint);
}

{
/* [Deg-usage] */
using namespace Math::Literals;
Expand Down
18 changes: 18 additions & 0 deletions src/Magnum/Animation/Interpolation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include "Interpolation.h"

#include "Magnum/Math/CubicHermite.h"
#include "Magnum/Math/DualQuaternion.h"

namespace Magnum { namespace Animation {
Expand All @@ -36,6 +37,7 @@ Debug& operator<<(Debug& debug, const Interpolation value) {
#define _c(value) case Interpolation::value: return debug << "Animation::Interpolation::" #value;
_c(Constant)
_c(Linear)
_c(Spline)
_c(Custom)
#undef _c
/* LCOV_EXCL_STOP */
Expand Down Expand Up @@ -66,6 +68,7 @@ template<class T> auto TypeTraits<Math::Quaternion<T>, Math::Quaternion<T>>::int
case Interpolation::Constant: return Math::select;
case Interpolation::Linear: return Math::slerp;

case Interpolation::Spline:
case Interpolation::Custom: ; /* nope */
}

Expand All @@ -77,6 +80,19 @@ template<class T> auto TypeTraits<Math::DualQuaternion<T>, Math::DualQuaternion<
case Interpolation::Constant: return Math::select;
case Interpolation::Linear: return Math::sclerp;

case Interpolation::Spline:
case Interpolation::Custom: ; /* nope */
}

CORRADE_ASSERT(false, "Animation::interpolatorFor(): can't deduce interpolator function for" << interpolation, {});
}

template<UnsignedInt dimensions, class T> auto TypeTraits<Math::CubicHermitePoint<dimensions, T>, Math::Vector<std::size_t(dimensions), T>>::interpolator(Interpolation interpolation) -> Interpolator {
switch(interpolation) {
case Interpolation::Constant: return Math::select;
case Interpolation::Linear: return Math::lerp;
case Interpolation::Spline: return Math::splerp;

case Interpolation::Custom: ; /* nope */
}

Expand All @@ -85,6 +101,8 @@ template<class T> auto TypeTraits<Math::DualQuaternion<T>, Math::DualQuaternion<

template struct MAGNUM_EXPORT TypeTraits<Math::Quaternion<Float>, Math::Quaternion<Float>>;
template struct MAGNUM_EXPORT TypeTraits<Math::DualQuaternion<Float>, Math::DualQuaternion<Float>>;
template struct MAGNUM_EXPORT TypeTraits<Math::CubicHermitePoint<2, Float>, Math::Vector<2, Float>>;
template struct MAGNUM_EXPORT TypeTraits<Math::CubicHermitePoint<3, Float>, Math::Vector<3, Float>>;

}

Expand Down
20 changes: 20 additions & 0 deletions src/Magnum/Animation/Interpolation.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ enum class Interpolation: UnsignedByte {
*/
Linear,

/**
* Spline interpolation.
*
* @see @ref Math::splerp()
*/
Spline,

/**
* Custom interpolation. An user-supplied interpolation function should be
* used.
Expand Down Expand Up @@ -96,12 +103,15 @@ faster but less precise results.
Interpolation type | Value type | Result type | Interpolator
------------------- | ----------------- | ------------- | ------------
@ref Interpolation::Constant | any `V` | `V` | @ref Math::select()
@ref Interpolation::Constant | @ref Math::CubicHermitePoint | @ref Math::Vector | @ref Math::select(const CubicHermitePoint<dimensions, T>&, const CubicHermitePoint<dimensions, T>&, T) "Math::select()"
@ref Interpolation::Linear | @cpp bool @ce <b></b> | @cpp bool @ce <b></b> | @ref Math::select()
@ref Interpolation::Linear | @ref Math::BoolVector | @ref Math::BoolVector | @ref Math::select()
@ref Interpolation::Linear | any scalar `V` | `V` | @ref Math::lerp()
@ref Interpolation::Linear | any vector `V` | `V` | @ref Math::lerp()
@ref Interpolation::Linear | @ref Math::Quaternion | @ref Math::Quaternion | @ref Math::slerp(const Quaternion<T>&, const Quaternion<T>&, T) "Math::slerp()"
@ref Interpolation::Linear | @ref Math::DualQuaternion | @ref Math::DualQuaternion | @ref Math::sclerp(const DualQuaternion<T>&, const DualQuaternion<T>&, T) "Math::sclerp()"
@ref Interpolation::Linear | @ref Math::CubicHermitePoint | @ref Math::Vector | @ref Math::lerp(const CubicHermitePoint<dimensions, T>&, const CubicHermitePoint<dimensions, T>&, T) "Math::lerp()"
@ref Interpolation::Spline | @ref Math::CubicHermitePoint | @ref Math::Vector | @ref Math::splerp(const CubicHermitePoint<dimensions, T>&, const CubicHermitePoint<dimensions, T>&, T) "Math::splerp()"
@see @ref interpolate(), @ref interpolateStrict()
@experimental
Expand Down Expand Up @@ -222,6 +232,7 @@ template<class V> auto TypeTraits<V, V>::interpolator(Interpolation interpolatio
case Interpolation::Constant: return Math::select;
case Interpolation::Linear: return Math::lerp;

case Interpolation::Spline:
case Interpolation::Custom: ; /* nope */
}

Expand All @@ -239,6 +250,7 @@ template<class T> auto TypeTraitsBool<T>::interpolator(Interpolation interpolati
case Interpolation::Constant:
case Interpolation::Linear: return Math::select;

case Interpolation::Spline:
case Interpolation::Custom: ; /* nope */
}

Expand All @@ -259,6 +271,14 @@ template<class T> struct MAGNUM_EXPORT TypeTraits<Math::DualQuaternion<T>, Math:
static Interpolator interpolator(Interpolation interpolation);
};

/* Cubic Hermite spline point has a different result type */
/** @todo get rid of the std::size_t() cast (all math types should have UInt) */
template<UnsignedInt dimensions, class T> struct MAGNUM_EXPORT TypeTraits<Math::CubicHermitePoint<dimensions, T>, Math::Vector<std::size_t(dimensions), T>> {
typedef Math::Vector<std::size_t(dimensions), T>(*Interpolator)(const Math::CubicHermitePoint<dimensions, T>&, const Math::CubicHermitePoint<dimensions, T>&, Float);

static Interpolator interpolator(Interpolation interpolation);
};

}

/* Needs to be defined later so it can pick up the TypeTraits definitions */
Expand Down
4 changes: 4 additions & 0 deletions src/Magnum/Animation/Test/PlayerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,10 @@ void PlayerTest::runFor100YearsFloat() {

CORRADE_COMPARE(player.state(), State::Playing);
{
/* Asm.js uses doubles for all floating-point calculations, so we don't
lose any precision and thus even the "run for 100 years" test passes
there. Unfortunately it's not possible to detect if this is asm.js
so the XFAIL is done like this. */
#ifndef CORRADE_TARGET_EMSCRIPTEN
CORRADE_EXPECT_FAIL_IF(data.failsFuzzyFloat, "Imprecision larger than 2.5e-4f.");
#else
Expand Down
3 changes: 3 additions & 0 deletions src/Magnum/Animation/Track.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,16 @@ are common combinations:
Interpolation type | Value type | Result type | Interpolator
------------------- | ----------------- | ------------- | ------------
Constant | any `V` | `V` | @ref Math::select()
Constant | @ref Math::CubicHermitePoint | @ref Math::Vector | @ref Math::select(const CubicHermitePoint<dimensions, T>&, const CubicHermitePoint<dimensions, T>&, T) "Math::select()"
Linear | @cpp bool @ce <b></b> | @cpp bool @ce <b></b> | @ref Math::select()
Linear | @ref Math::BoolVector | @ref Math::BoolVector | @ref Math::select()
Linear | any scalar `V` | `V` | @ref Math::lerp()
Linear | any vector `V` | `V` | @ref Math::lerp()
Linear | @ref Math::Quaternion | @ref Math::Quaternion | @ref Math::lerp(const Quaternion<T>&, const Quaternion<T>&, T) "Math::lerp()"
Linear | @ref Math::CubicHermitePoint | @ref Math::Vector | @ref Math::lerp(const CubicHermitePoint<dimensions, T>&, const CubicHermitePoint<dimensions, T>&, T) "Math::lerp()"
Spherical linear | @ref Math::Quaternion | @ref Math::Quaternion | @ref Math::slerp(const Quaternion<T>&, const Quaternion<T>&, T) "Math::slerp()"
Screw linear | @ref Math::DualQuaternion | @ref Math::DualQuaternion | @ref Math::sclerp(const DualQuaternion<T>&, const DualQuaternion<T>&, T) "Math::sclerp()"
Spline | @ref Math::CubicHermitePoint | @ref Math::Vector | @ref Math::splerp(const CubicHermitePoint<dimensions, T>&, const CubicHermitePoint<dimensions, T>&, T) "Math::splerp()"
It's also possible to supply a generic interpolation behavior by passing the
@ref Interpolation enum to the constructor. In case the interpolator function
Expand Down
12 changes: 12 additions & 0 deletions src/Magnum/Magnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,12 @@ typedef Math::CubicBezier2D<Float> CubicBezier2D;
/** @brief Float three-dimensional cubic Bézier curve */
typedef Math::CubicBezier3D<Float> CubicBezier3D;

/** @brief Float two-dimensional cubic Hermite spline point */
typedef Math::CubicHermitePoint2D<Float> CubicHermitePoint2D;

/** @brief Float three-dimensional cubic Hermite spline point */
typedef Math::CubicHermitePoint3D<Float> CubicHermitePoint3D;

/** @brief Float complex number */
typedef Math::Complex<Float> Complex;

Expand Down Expand Up @@ -641,6 +647,12 @@ typedef Math::CubicBezier2D<Float> CubicBezier2Dd;
/** @brief Double three-dimensional cubic Bézier curve */
typedef Math::CubicBezier3D<Float> CubicBezier3Dd;

/** @brief Double two-dimensional cubic Hermite spline point */
typedef Math::CubicHermitePoint2D<Double> CubicHermitePoint2Dd;

/** @brief Double three-dimensional cubic Hermite spline point */
typedef Math::CubicHermitePoint3D<Double> CubicHermitePoint3Dd;

/** @brief Double complex number */
typedef Math::Complex<Double> Complexd;

Expand Down
1 change: 1 addition & 0 deletions src/Magnum/Math/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ set(MagnumMath_HEADERS
Color.h
Complex.h
Constants.h
CubicHermite.h
Distance.h
Dual.h
DualComplex.h
Expand Down
Loading

0 comments on commit 63d3684

Please sign in to comment.