Operators for Conversions between ci::Anim<T> and T

Hi All,

My team has been using the timeline class quite a lot across many of our projects and one thing folks often still stumble over is conversion between `ci::Anim<T>` and `T`.

One solution we’ve landed on for convenience recently has been to write a big old list of templated operators that take various combinations of `ci::Anim<T>`, `T` or `U` (`U` for operations between types like `ci::Anim<vec2>` and `float`).

Here’s a snapshot of what we currently have: https://gist.github.com/benjaminbojko/72a24102400cc09c812024ad443f9740

With that, for…

``````ci::Anim<vec2> size;
ci::Anim<vec2> pos;
vec2 otherPos;
``````

… we can write…

``````vec2 scaledSize = size * 0.5f;
vec2 stretchedSize = size * vec2(2.f, 1.f);
vec2 normalizedSize = size / vec2(1920.f, 1080.f);
vec2 bottomRight = pos + size;
otherPos += size;
``````

``````vec2 scaledSize = size.value() * 0.5f;
vec2 stretchedSize = size.value() * vec2(2.f, 1.f);
vec2 normalizedSize = size.value() / vec2(1920.f, 1080.f);
vec2 bottomRight = pos.value() + size.value();
otherPos += size.value();
``````

Two caveats are that accessing properties of the value still requires calling `value()` or `()`

``````float width = size().value().x;
float height = size()().y;
``````

…and assignments only work one way (maybe there’s a way around this?)

``````// works
vec2 bottomRight = pos;
bottomRight += size;

// breaks
size += vec2(100.f);
``````

Honestly, it still doesn’t really feel quite kosher to me personally, but it does make dealing with animations much more convenient. What do folks here think? Is this risky because it might lead to unexpected implicit conversions? Is it just plain old messy? Is it helpful?

Happy to turn this gist into something more formal/reusable like a PR, but would love to hear some of your thoughts first.

You could always eschew `Anim<T>` altogether and just call `timeline().applyPtr ( &T, ... )` rather than `timeline().apply ( &Anim<T>, ... )`

Also, be wary of `Anim<T>` and glm. I ran into this doozy a while ago that caused a major performance problem because of my carelessness with when to use or omit the call operator on `Anim<T>` types being passed to templated glm constructors.

Oof that’s a great issue to flag and the kind of stuff I’m concerned about too. Thanks for raising it.

We mostly use `ci::Anim` in scene graphs where performance isn’t the top priority and I’m a little weary of using `applyPtr()` because of the risks it poses when removing objects with animated properties on the fly. As far as I understand it you’d also lose the convenience of `myAnim.stop()`, right?

In more mission critical pieces of code issues like the one you illustrated might be amplified by the implicit conversion, though.