Last active
May 24, 2017 22:22
-
-
Save m1keall1son/dd87fa85a32a7b41f8f562e7e708981e to your computer and use it in GitHub Desktop.
Animation Controller firmware
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///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