Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cubic Hermite splines #267

Merged
merged 26 commits into from
Sep 3, 2018
Merged

Cubic Hermite splines #267

merged 26 commits into from
Sep 3, 2018

Conversation

mosra
Copy link
Owner

@mosra mosra commented Aug 5, 2018

Important for animations, among other things, postponed from #191 to unblock progress, but still hopefully on track for 2018.08. Cubic Hermite splines were chosen because they are a superset of all other commonly used splines and thus having support for these will also mean support for Catmull-Rom, Bezier, TCB and others.

A "point" representation was chosen over a "segment" representation in order to better support the use in animations. Math::Bezier, OTOH, has a segment representation.

TODO:

  • Basic Hermite point class
    • Docs explaining what it is, why it was chosen and why it is a point and not a segment
    • Tests for the surface API
    • Split into multiple commits
  • Helper constructors to create the curve from
  • Bezier::fromCubicHermite() (just because I have the class)
  • Cubic Hermite quaternions (needed by glTF), complex numbers, dual quaternions, ... -- or rather have a CubicHermite where T is the underlying type?
  • Hermite curve interpolation and tests
    • Math::select()
    • Math::lerp()
    • Math::splerp()
    • Math::lerp() for quaternions
    • Math::splerp() for quaternions
  • Animation::Interpolation::Spline and support in related APIs
  • Support in Trade::AnimationDataType APIs
  • Implement these in the glTF importer to verify the API is sane to populate
  • Implement these in the magnum-player to verify the API is sane to use
  • Test translation to verify the implementation is sane
  • Add "shortest path" variants for lerp(), slerp() and sclerp()
    • Use them by interpolatorFor()
    • Benchmark
  • Extend the transformation documentation and mention all the interpolation stuff we have
  • Create at least a dummy page for animations
  • Test rotation to verify the implementation is sane

@mosra mosra added this to the 2018.0c milestone Aug 5, 2018
@mosra mosra self-assigned this Aug 5, 2018
@mosra mosra changed the title Cubic Hermite splines [WIP] Cubic Hermite splines Aug 5, 2018
@mosra mosra mentioned this pull request Aug 5, 2018
45 tasks
@Squareys
Copy link
Contributor

AbstractImporter Documentation subtitle lists what it is able to import and missing "animations" there :)

(as requested to put here via gitter)

@mosra mosra mentioned this pull request Aug 29, 2018
56 tasks
The totally random places after were not exactly useful. This file was
sitting here for a while, not sure why I didn't commit that earlier.
Not sure why that wasn't done before.
It's a straight copy of the code for quaternions -- it could probably be
simplified a bit, but I don't have the necessary brain cells at the
moment. I tried the following but failed:

    retun Complex::rotation(acos(cosAngle)*t)*normalizedA;
Not sure why these were omitted. Everything else has them.
Since there's now lerp() and slerp() for it.
For spline interpolation.
@mosra mosra changed the title [WIP] Cubic Hermite splines Cubic Hermite splines Aug 31, 2018
@mosra
Copy link
Owner Author

mosra commented Sep 1, 2018

While this is all green and happy, there are blockers in depending projects:

  • sample glTF models have non-normalized rotation quaternions (the AnimatedTriangle, for example, has the length of 0.999849) .. what do to about these? normalize on import (might affect how the animation looks) or normalize in the interpolator (slow!)? ... this is not really related to splines, but needs to be handled for these as well
  • with the current implementation, the AnimatedTriangle rotation is not doing a full circle (apart from the default scene not being defined, normals missing etc., which is being fixed elsewhere). Needs investigating (fix in the (s)lerp implementation?), apparently I'm not the only one: AnimatedTriangle shouldn't rotate around a complete circle? KhronosGroup/glTF-Sample-Models#185
  • there is nothing in glTF sample models that would allow me to verify spline-interpolated rotation, so I have no idea if the thing I implemented is any good

@codecov-io
Copy link

codecov-io commented Sep 1, 2018

Codecov Report

Merging #267 into master will increase coverage by 0.34%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #267      +/-   ##
==========================================
+ Coverage   50.92%   51.26%   +0.34%     
==========================================
  Files         365      367       +2     
  Lines       16586    16703     +117     
==========================================
+ Hits         8446     8563     +117     
  Misses       8140     8140
Impacted Files Coverage Δ
src/Magnum/DebugTools/ForceRenderer.h 0% <ø> (ø) ⬆️
src/Magnum/Magnum.h 100% <ø> (ø) ⬆️
src/Magnum/Math/Functions.h 100% <ø> (ø) ⬆️
src/Magnum/Math/Half.h 100% <ø> (ø) ⬆️
src/Magnum/Math/Vector.h 100% <ø> (ø) ⬆️
src/Magnum/DebugTools/ResourceManager.h 0% <ø> (ø) ⬆️
src/Magnum/Math/DualComplex.h 100% <ø> (ø) ⬆️
src/Magnum/Animation/Track.h 100% <ø> (ø) ⬆️
src/Magnum/DebugTools/ObjectRenderer.h 0% <ø> (ø) ⬆️
src/Magnum/Trade/AnimationData.cpp 100% <ø> (ø) ⬆️
... and 17 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 943d74d...13a6ba8. Read the comment docs.

No need to have the precision so crazy.
And causes an assertion message. Obviously the test doesn't pass anymore
after this fix.
The fix done with #122
(0e05c72) was not tested properly (see
previous commit) and thus this code path never worked. This properly
lerps the translation part and recombines it with the rotation instead
of interpolating just a part of it.

Also I'm no longer having any "dotResult" that's done only on the
vector part of the rotation, but instead using the full
rotation quaternion dot product. I have no idea why it was done this
way. This branch was also never properly tested -- it'll be with the
introduction of "shortest path" variants in the next commit.
…p().

Before neither of the lerp(), slerp() had the shortest path check, while
sclerp() had it. Now, to be consistent, none of them has it and there
are lerpShortestPath(), slerpShortestPath() and sclerpShortestPath()
functions that have the shortest path check.

This is different from other engines, where there's usually only the
shortest path interpolation by default and either an optional
"non-shortest-path" interpolation or no alternative at all. I like to
give the users a choice, so there's both versions and the
non-shortest-path version is the default, because -- at least in case of
lerp() -- this results in a quite significant perf difference (15%
faster), so why not have it. Preprocess your data instead ;)
@mosra mosra merged commit 13a6ba8 into master Sep 3, 2018
@mosra mosra deleted the splines branch September 3, 2018 23:04
@mosra
Copy link
Owner Author

mosra commented Sep 3, 2018

Merged into master. Shortest path interpolation is part of this PR as well, the remaining issues are glTF-specific, so handling them in the glTF importer itself instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging this pull request may close these issues.

3 participants