Skip to content

Instantly share code, notes, and snippets.

@m1keall1son
Last active May 24, 2017 22:22
Show Gist options
  • Save m1keall1son/dd87fa85a32a7b41f8f562e7e708981e to your computer and use it in GitHub Desktop.
Save m1keall1son/dd87fa85a32a7b41f8f562e7e708981e to your computer and use it in GitHub Desktop.
Animation Controller firmware
///this code is not tested
////.h
struct Color {
Color(){}
Color( int r, int g, int b ):r( static_cast<float>(r) ),g( static_cast<float>(g) ),b( static_cast<float>(b) ){}
float r{0};
float g{0};
float b{0};
};
using EasingFn = float(*)(float);
enum Easing {
LINEAR,
IN_QUAD, OUT_QUAD, IN_OUT_QUAD, OUT_IN_QUAD,
IN_CUBIC, OUT_CUBIC, IN_OUT_CUBIC, OUT_IN_CUBIC,
IN_QUART, OUT_QUART, IN_OUT_QUART, OUT_IN_QUART,
IN_QUINT, OUT_QUINT, IN_OUT_QUINT, OUT_IN_QUINT,
NUM_EASING = 17
};
//no ease
float linearEase(float t){ return t; }
//! Easing equation for a quadratic (t^2) ease-in, accelerating from zero velocity.
float easeInQuad( float t ){ return t*t; }
//! Easing equation for a quadratic (t^2) ease-out, decelerating to zero velocity.
float easeOutQuad( float t ){ return -t * ( t - 2 ); }
//! Easing equation for a quadratic (t^2) ease-in/out, accelerating until halfway, then decelerating.
float easeInOutQuad( float t ){
t *= 2;
if( t < 1 ) return 0.5f * t * t;
t -= 1;
return -0.5f * ((t)*(t-2) - 1);
}
float easeOutInQuad( float t ){
if( t < 0.5f) return easeOutQuad( t*2 ) * 0.5f;
return easeInQuad( (2*t)-1 ) * 0.5f + 0.5f;
}
//! Easing equation function for a cubic (t^3) ease-in, accelerating from zero velocity.
float easeInCubic( float t ){ return t*t*t; }
//! Easing equation for a cubic (t^3) ease-out, decelerating to zero velocity.
float easeOutCubic( float t ){
t -= 1;
return t*t*t + 1;
}
//! Easing equation for a cubic (t^3) ease-in/out, accelerating until halfway, then decelerating.
float easeInOutCubic( float t ){
t *= 2;
if( t < 1 )
return 0.5f * t*t*t;
t -= 2;
return 0.5f*(t*t*t + 2);
}
//! Easing equation for a cubic (t^3) ease-out/in, decelerating until halfway, then accelerating.
float easeOutInCubic( float t ){
if( t < 0.5f ) return easeOutCubic( 2 * t ) / 2;
return easeInCubic(2*t - 1)/2 + 0.5f;
}
//! Easing equation for a quartic (t^4) ease-in, accelerating from zero velocity.
float easeInQuart( float t ){ return t*t*t*t; }
//! Easing equation for a quartic (t^4) ease-out, decelerating to zero velocity.
inline float easeOutQuart( float t )
{
t -= 1;
return -(t*t*t*t - 1);
}
//! Easing equation for a quartic (t^4) ease-in/out, accelerating until halfway, then decelerating.
float easeInOutQuart( float t ){
t *= 2;
if( t < 1 ) return 0.5f*t*t*t*t;
else {
t -= 2;
return -0.5f * (t*t*t*t - 2);
}
}
//! Easing equation for a quartic (t^4) ease-out/in, decelerating until halfway, then accelerating.
inline float easeOutInQuart( float t )
{
if( t < 0.5f ) return easeOutQuart( 2*t ) / 2;
return easeInQuart(2*t-1)/2 + 0.5f;
}
//! Easing equation function for a quintic (t^5) ease-in, accelerating from zero velocity.
float easeInQuint( float t ){ return t*t*t*t*t; }
//! Easing equation for a quintic (t^5) ease-out, decelerating to zero velocity.
float easeOutQuint( float t ){
t -= 1;
return t*t*t*t*t + 1;
}
//! Easing equation for a quintic (t^5) ease-in/out, accelerating until halfway, then decelerating.
float easeInOutQuint( float t ){
t *= 2;
if( t < 1 ) return 0.5f*t*t*t*t*t;
else {
t -= 2;
return 0.5f*(t*t*t*t*t + 2);
}
}
//! Easing equation for a quintic (t^5) ease-out/in, decelerating until halfway, then accelerating.
inline float easeOutInQuint( float t )
{
if( t < 0.5f ) return easeOutQuint( 2*t ) / 2;
return easeInQuint( 2*t - 1 ) / 2 + 0.5f;
}
const EaseFn easingFns[NUM_EASING] = {
linearEase,
easeInQuad, easeOutQuad, easeInOutQuad, easeOutInQuad,
easeInCubic, easeOutCubic, easeInOutCubic, easeOutInCubic,
easeInQuart, easeOutQuart, easeInOutQuart, easeOutInQuart,
easeInQuint, easeOutQuint, easeInOutQuint, easeOutInQuint
};
float lerp(float start, float target, float duration)
{
return start + duration * (target- start);
}
class Animation {
public:
void set( Color target, float duration, Easing ease ){
m_StartTime = millis();
m_Start = m_Current;
m_Target = target;
m_Easing = ease;
m_Duration = duration;
m_isDone = false;
m_IsComplete = false;
}
void update();
bool isDone(){return m_IsDone;}
bool isComplete(){return m_IsComplete;}
void setComplete(){ m_IsComplete = true; }
private:
bool m_IsDone{false};
bool m_IsComplete{false};
int m_StartTime;
float m_Duration{0};
Color m_Start{0,0,0};
Color m_Target{0,0,0};
Color m_Current{0,0,0};
Easing m_Easing{LINEAR};
}
///.cpp
void Animation::update(){
int currentTime = millis();
float percent_complete = static_cast<float>( currentTime - m_StartTime ) / static_cast<float>( m_Duration );
float t = easingFns[m_Easing](percent_complete);
//or HSV
m_Current.r = constrain( lerp( m_Start.r, m_Target.r, t ), 0, 255 ) );
m_Current.g = constrain( lerp( m_Start.g, m_Target.g, t ), 0, 255 ) );
m_Current.b = constrain( lerp( m_Start.b, m_Target.b, t ), 0, 255 ) );
//SET NEO PIXEL VALUE HERE and static cast to int!
if(percent_complete >= 1.0){
m_IsDone = true;
}
}
//USAGE
//global or private memeber of task
Aniamtion anim;
...
//on interrupt
anim.set( /* data from server */ );
...
//in task once each frame, p5resumes setting and updating Animation are atomic
if(anim.isDone() && !anim.isComplete()){
//send animation complete callback message
anim.setComplete();
}else if(!anim.isDone() && !anim.isComplete()){
anim.update();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment