diff --git a/bin/data/johnWhitneyShader01/exampleCode.cpp b/bin/data/johnWhitneyShader01/exampleCode.cpp index e5546bb..49ec7d5 100644 --- a/bin/data/johnWhitneyShader01/exampleCode.cpp +++ b/bin/data/johnWhitneyShader01/exampleCode.cpp @@ -4,15 +4,15 @@ void main() vec3 color = vec3(0.); float redVal = [[time]] * (uv.x * HORIZ_SCALE + RED_SCALE); - float redY = sin(redVal) * VERT_SCALE; + float redY = sin(redVal) * [[vertScale]]; color.r = drawLine(uv, redY); float greenVal = [[time]] * (uv.x * HORIZ_SCALE + GREEN_SCALE); - float greenY = sin(greenVal) * VERT_SCALE; + float greenY = sin(greenVal) * [[vertScale]]; color.g = drawLine(uv, greenY); float blueVal = [[time]] * (uv.x * HORIZ_SCALE + BLUE_SCALE); - float blueY = sin(blueVal) * VERT_SCALE; + float blueY = sin(blueVal) * [[vertScale]]; color.b = drawLine(uv, blueY); gl_FragColor = vec4(color, 1.0); diff --git a/bin/data/johnWhitneyShader01/shader.frag b/bin/data/johnWhitneyShader01/shader.frag index 9014728..9f570ec 100644 --- a/bin/data/johnWhitneyShader01/shader.frag +++ b/bin/data/johnWhitneyShader01/shader.frag @@ -19,6 +19,8 @@ precision mediump float; uniform float time; uniform vec2 resolution; +uniform float vertScale; + float drawLine(vec2 uv, float y) { float dist = abs(uv.y - y); return smoothstep(STEP_MAX, STEP_MIN, dist); @@ -30,15 +32,15 @@ void main() vec3 color = vec3(0.); float redVal = time * (uv.x * HORIZ_SCALE + RED_SCALE); - float redY = sin(redVal) * VERT_SCALE; + float redY = sin(redVal) * vertScale; color.r = drawLine(uv, redY); float greenVal = time * (uv.x * HORIZ_SCALE + GREEN_SCALE); - float greenY = sin(greenVal) * VERT_SCALE; + float greenY = sin(greenVal) * vertScale; color.g = drawLine(uv, greenY); float blueVal = time * (uv.x * HORIZ_SCALE + BLUE_SCALE); - float blueY = sin(blueVal) * VERT_SCALE; + float blueY = sin(blueVal) * vertScale; color.b = drawLine(uv, blueY); gl_FragColor = vec4(color, 1.0); diff --git a/d4nSFPCRunner.xcodeproj/project.pbxproj b/d4nSFPCRunner.xcodeproj/project.pbxproj index ab0dc04..3f49f15 100644 --- a/d4nSFPCRunner.xcodeproj/project.pbxproj +++ b/d4nSFPCRunner.xcodeproj/project.pbxproj @@ -14,6 +14,8 @@ 5CBB2AB3A60F65431D7B555D /* ofxButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C88333E71C9457E441C33474 /* ofxButton.cpp */; }; 63B57AC5BF4EF088491E0317 /* ofxXmlSettings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50DF87D612C5AAE17AAFA6C0 /* ofxXmlSettings.cpp */; }; 7118B75E1C0519830092084A /* johnWhitneyShader01.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7118B75C1C0519830092084A /* johnWhitneyShader01.cpp */; }; + 716EF7821C063048005FA544 /* animatedParameter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 716EF7801C063048005FA544 /* animatedParameter.cpp */; }; + 716EF78B1C063E7A005FA544 /* easing.c in Sources */ = {isa = PBXBuildFile; fileRef = 716EF7891C063E7A005FA544 /* easing.c */; }; 837220E80EB56CD44AD27F2A /* ofxSlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15F2C6477A769C03A56D1401 /* ofxSlider.cpp */; }; 856AA354D08AB4B323081444 /* ofxBaseGui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9604B925D32EE39065747725 /* ofxBaseGui.cpp */; }; 85BCD90A1BF7E398004188EE /* yeseulScene.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85BCD9081BF7E398004188EE /* yeseulScene.cpp */; }; @@ -77,6 +79,10 @@ 52AFA1F08C420992CAAAE648 /* ofxSlider.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 30; name = ofxSlider.h; path = ../../../addons/ofxGui/src/ofxSlider.h; sourceTree = SOURCE_ROOT; }; 7118B75C1C0519830092084A /* johnWhitneyShader01.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = johnWhitneyShader01.cpp; sourceTree = ""; }; 7118B75D1C0519830092084A /* johnWhitneyShader01.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = johnWhitneyShader01.h; sourceTree = ""; }; + 716EF7801C063048005FA544 /* animatedParameter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = animatedParameter.cpp; sourceTree = ""; }; + 716EF7811C063048005FA544 /* animatedParameter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = animatedParameter.h; sourceTree = ""; }; + 716EF7891C063E7A005FA544 /* easing.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = easing.c; sourceTree = ""; }; + 716EF78A1C063E7A005FA544 /* easing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = easing.h; sourceTree = ""; }; 78D67A00EB899FAC09430597 /* ofxLabel.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 30; name = ofxLabel.cpp; path = ../../../addons/ofxGui/src/ofxLabel.cpp; sourceTree = SOURCE_ROOT; }; 802251BAF1B35B1D67B32FD0 /* ofxSliderGroup.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 30; name = ofxSliderGroup.cpp; path = ../../../addons/ofxGui/src/ofxSliderGroup.cpp; sourceTree = SOURCE_ROOT; }; 832BDC407620CDBA568B713D /* tinyxmlerror.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 30; name = tinyxmlerror.cpp; path = ../../../addons/ofxXmlSettings/libs/tinyxmlerror.cpp; sourceTree = SOURCE_ROOT; }; @@ -194,6 +200,15 @@ path = johnWhitneyShader01; sourceTree = ""; }; + 716EF7881C063E7A005FA544 /* vendor */ = { + isa = PBXGroup; + children = ( + 716EF7891C063E7A005FA544 /* easing.c */, + 716EF78A1C063E7A005FA544 /* easing.h */, + ); + path = vendor; + sourceTree = ""; + }; 85BCD9071BF7E398004188EE /* yeseulScene */ = { isa = PBXGroup; children = ( @@ -218,6 +233,8 @@ 9238719F1BF7993A00171456 /* baseScene.h */, 923871A21BF7993A00171456 /* sceneManager.cpp */, 923871A31BF7993A00171456 /* sceneManager.h */, + 716EF7801C063048005FA544 /* animatedParameter.cpp */, + 716EF7811C063048005FA544 /* animatedParameter.h */, ); path = scenes; sourceTree = ""; @@ -326,8 +343,9 @@ E4B69E1C0A3A1BDC003C02F2 /* src */ = { isa = PBXGroup; children = ( - 923871B81BF7D2C400171456 /* appConstants.h */, 9238719D1BF7993A00171456 /* scenes */, + 716EF7881C063E7A005FA544 /* vendor */, + 923871B81BF7D2C400171456 /* appConstants.h */, E4B69E1D0A3A1BDC003C02F2 /* main.cpp */, E4B69E1E0A3A1BDC003C02F2 /* ofApp.cpp */, E4B69E1F0A3A1BDC003C02F2 /* ofApp.h */, @@ -433,6 +451,7 @@ files = ( E4B69E200A3A1BDC003C02F2 /* main.cpp in Sources */, E4B69E210A3A1BDC003C02F2 /* ofApp.cpp in Sources */, + 716EF78B1C063E7A005FA544 /* easing.c in Sources */, 856AA354D08AB4B323081444 /* ofxBaseGui.cpp in Sources */, 5CBB2AB3A60F65431D7B555D /* ofxButton.cpp in Sources */, D5F490EB1BF7E69B00F92C20 /* robbyRileyScene.cpp in Sources */, @@ -452,6 +471,7 @@ 923871B51BF7CCC900171456 /* emptyScene.cpp in Sources */, 923871A41BF7993A00171456 /* baseScene.cpp in Sources */, 5A4349E9754D6FA14C0F2A3A /* tinyxmlparser.cpp in Sources */, + 716EF7821C063048005FA544 /* animatedParameter.cpp in Sources */, D5F490E61BF7DE2D00F92C20 /* robbyMolnarScene.cpp in Sources */, 923871A61BF7993A00171456 /* sceneManager.cpp in Sources */, 7118B75E1C0519830092084A /* johnWhitneyShader01.cpp in Sources */, diff --git a/src/scenes/animatedParameter.cpp b/src/scenes/animatedParameter.cpp new file mode 100644 index 0000000..92a16ce --- /dev/null +++ b/src/scenes/animatedParameter.cpp @@ -0,0 +1,57 @@ +// +// animationTiming.cpp +// d4nSFPCRunner +// +// Created by Christopher Anderson on 11/25/15. +// +// + +#include "animatedParameter.h" + +animatedParameter::animatedParameter() : maxTime(0), loop(true) +{ +} + +void animatedParameter::addAnimation(float startTime, float endTime, float startVal, float endVal, AHEasingFunction f) { + animationTiming timing; + + timing.startTime = startTime; + timing.endTime = endTime; + timing.startValue = startVal; + timing.endValue = endVal; + timing.easingFunction = f; + + if (endTime > maxTime) { + maxTime = endTime; + } + + timings.push_back(timing); +} + +void animatedParameter::updateTime(float time) { + if (timings.size() == 0) { + return; + } + + if (loop && time > maxTime) { + time = fmod(time, maxTime); + } + + // Find the animation we're in right now + animationTiming *t = &timings[0]; + for (auto &animationTiming : timings) { + if (time > animationTiming.startTime) + t = &animationTiming; + } + + if (time < t->startTime) { + return t->startValue; + } else if (time > t->endTime) { + return t->endValue; + } + + float p = (time - t->startTime) / (t->endTime - t->startTime); + float val = t->easingFunction(p) * (t->endValue - t->startValue) + t->startValue; + + set(val); +} diff --git a/src/scenes/animatedParameter.h b/src/scenes/animatedParameter.h new file mode 100644 index 0000000..84df6c3 --- /dev/null +++ b/src/scenes/animatedParameter.h @@ -0,0 +1,32 @@ +// +// animationTiming.hpp +// d4nSFPCRunner +// +// Created by Christopher Anderson on 11/25/15. +// +// + +#pragma once + +#include "ofMain.h" +#include "easing.h" + +struct animationTiming { + float startTime, endTime; + float startValue, endValue; + + AHEasingFunction easingFunction; +}; + +class animatedParameter : public ofParameter { + +public: + animatedParameter(); + + vector< animationTiming > timings; + float maxTime; + bool loop; + + void addAnimation(float startTime, float endTime, float startVal, float endVal, AHEasingFunction f); + void updateTime(float time); +}; diff --git a/src/scenes/baseScene.cpp b/src/scenes/baseScene.cpp index 67ab7a7..6276e5b 100644 --- a/src/scenes/baseScene.cpp +++ b/src/scenes/baseScene.cpp @@ -49,3 +49,10 @@ string baseScene::getCodeWithParamsReplaced(){ return codeWithParams; } + +void baseScene::updateAnimatedParameters() { + float time = ofGetElapsedTimef(); + for (auto animParam : animatedParameters) { + animParam->updateTime(time); + } +} diff --git a/src/scenes/baseScene.h b/src/scenes/baseScene.h index ee8ad62..7c52c0a 100644 --- a/src/scenes/baseScene.h +++ b/src/scenes/baseScene.h @@ -2,6 +2,8 @@ #pragma once #include "ofMain.h" +#include "ofxXmlSettings.h" +#include "animatedParameter.h" class baseScene { @@ -26,5 +28,7 @@ class baseScene { ofRectangle dimensions; // this is the dimensions of // the surface you are drawing into. + void updateAnimatedParameters(); + vector< animatedParameter* > animatedParameters; }; \ No newline at end of file diff --git a/src/scenes/johnWhitneyShader01/johnWhitneyShader01.cpp b/src/scenes/johnWhitneyShader01/johnWhitneyShader01.cpp index bc68ce4..0a7c51e 100644 --- a/src/scenes/johnWhitneyShader01/johnWhitneyShader01.cpp +++ b/src/scenes/johnWhitneyShader01/johnWhitneyShader01.cpp @@ -4,16 +4,25 @@ void johnWhitneyShader01::setup(){ // setup pramaters - time.set("time", 0, 0, 3); + time.set("time", 0, 0, PI); + time.addAnimation(0, 4, 0, PI, QuadraticEaseInOut); + time.addAnimation(4, 8, PI, 0, QuadraticEaseInOut); parameters.add(time); + animatedParameters.push_back(&time); + + vertScale.set("vertScale", 0.15, 0, 1); + vertScale.addAnimation(8, 12, 0.15, 0.5, LinearInterpolation); + vertScale.addAnimation(12, 16, 0.5, 0.15, LinearInterpolation); + parameters.add(vertScale); + animatedParameters.push_back(&vertScale); loadCode("johnWhitneyShader01/exampleCode.cpp"); - + shader.load("johnWhitneyShader01/shader"); } void johnWhitneyShader01::update() { - time.set(ofMap(sin(ofGetElapsedTimef()), -1, 1, 0, PI)); + } void johnWhitneyShader01::draw() { @@ -23,6 +32,8 @@ void johnWhitneyShader01::draw() { shader.begin(); shader.setUniform1f("time", time.get()); shader.setUniform2fv("resolution", resolution); + shader.setUniform1f("vertScale", vertScale.get()); + ofRect(0, 0, dimensions.width, dimensions.height); shader.end(); } \ No newline at end of file diff --git a/src/scenes/johnWhitneyShader01/johnWhitneyShader01.h b/src/scenes/johnWhitneyShader01/johnWhitneyShader01.h index 874bd66..b23fb53 100644 --- a/src/scenes/johnWhitneyShader01/johnWhitneyShader01.h +++ b/src/scenes/johnWhitneyShader01/johnWhitneyShader01.h @@ -14,5 +14,5 @@ class johnWhitneyShader01 : public baseScene { ofShader shader; ofFbo fbo; - ofParameter time; + animatedParameter time, vertScale; }; \ No newline at end of file diff --git a/src/scenes/sceneManager.cpp b/src/scenes/sceneManager.cpp index 863b8ac..594ee76 100644 --- a/src/scenes/sceneManager.cpp +++ b/src/scenes/sceneManager.cpp @@ -18,13 +18,17 @@ void sceneManager::setup(){ + // Has animated parameters + scenes.push_back(new johnWhitneyShader01()); + + // Old-style parameters scenes.push_back(new robbyMolnarScene() ); scenes.push_back(new veraAnimatedScene() ); scenes.push_back(new exampleScene() ); scenes.push_back(new triangleScene() ); scenes.push_back(new robbyRileyScene() ); scenes.push_back(new yeseulScene() ); - scenes.push_back(new johnWhitneyShader01()); + sceneFbo.allocate(VISUALS_WIDTH, VISUALS_HEIGHT, GL_RGBA, 4); codeFbo.allocate(VISUALS_WIDTH, VISUALS_HEIGHT, GL_RGBA, 4); @@ -59,6 +63,7 @@ void sceneManager::setup(){ void sceneManager::update(){ scenes[currentScene]->update(); + scenes[currentScene]->updateAnimatedParameters(); } void sceneManager::draw(){ diff --git a/src/vendor/easing.c b/src/vendor/easing.c new file mode 100644 index 0000000..4138113 --- /dev/null +++ b/src/vendor/easing.c @@ -0,0 +1,302 @@ +// +// easing.c +// +// Copyright (c) 2011, Auerhaus Development, LLC +// +// This program is free software. It comes without any warranty, to +// the extent permitted by applicable law. You can redistribute it +// and/or modify it under the terms of the Do What The Fuck You Want +// To Public License, Version 2, as published by Sam Hocevar. See +// http://sam.zoy.org/wtfpl/COPYING for more details. +// + +#include +#include "easing.h" + +// Modeled after the line y = x +AHFloat LinearInterpolation(AHFloat p) +{ + return p; +} + +// Modeled after the parabola y = x^2 +AHFloat QuadraticEaseIn(AHFloat p) +{ + return p * p; +} + +// Modeled after the parabola y = -x^2 + 2x +AHFloat QuadraticEaseOut(AHFloat p) +{ + return -(p * (p - 2)); +} + +// Modeled after the piecewise quadratic +// y = (1/2)((2x)^2) ; [0, 0.5) +// y = -(1/2)((2x-1)*(2x-3) - 1) ; [0.5, 1] +AHFloat QuadraticEaseInOut(AHFloat p) +{ + if(p < 0.5) + { + return 2 * p * p; + } + else + { + return (-2 * p * p) + (4 * p) - 1; + } +} + +// Modeled after the cubic y = x^3 +AHFloat CubicEaseIn(AHFloat p) +{ + return p * p * p; +} + +// Modeled after the cubic y = (x - 1)^3 + 1 +AHFloat CubicEaseOut(AHFloat p) +{ + AHFloat f = (p - 1); + return f * f * f + 1; +} + +// Modeled after the piecewise cubic +// y = (1/2)((2x)^3) ; [0, 0.5) +// y = (1/2)((2x-2)^3 + 2) ; [0.5, 1] +AHFloat CubicEaseInOut(AHFloat p) +{ + if(p < 0.5) + { + return 4 * p * p * p; + } + else + { + AHFloat f = ((2 * p) - 2); + return 0.5 * f * f * f + 1; + } +} + +// Modeled after the quartic x^4 +AHFloat QuarticEaseIn(AHFloat p) +{ + return p * p * p * p; +} + +// Modeled after the quartic y = 1 - (x - 1)^4 +AHFloat QuarticEaseOut(AHFloat p) +{ + AHFloat f = (p - 1); + return f * f * f * (1 - p) + 1; +} + +// Modeled after the piecewise quartic +// y = (1/2)((2x)^4) ; [0, 0.5) +// y = -(1/2)((2x-2)^4 - 2) ; [0.5, 1] +AHFloat QuarticEaseInOut(AHFloat p) +{ + if(p < 0.5) + { + return 8 * p * p * p * p; + } + else + { + AHFloat f = (p - 1); + return -8 * f * f * f * f + 1; + } +} + +// Modeled after the quintic y = x^5 +AHFloat QuinticEaseIn(AHFloat p) +{ + return p * p * p * p * p; +} + +// Modeled after the quintic y = (x - 1)^5 + 1 +AHFloat QuinticEaseOut(AHFloat p) +{ + AHFloat f = (p - 1); + return f * f * f * f * f + 1; +} + +// Modeled after the piecewise quintic +// y = (1/2)((2x)^5) ; [0, 0.5) +// y = (1/2)((2x-2)^5 + 2) ; [0.5, 1] +AHFloat QuinticEaseInOut(AHFloat p) +{ + if(p < 0.5) + { + return 16 * p * p * p * p * p; + } + else + { + AHFloat f = ((2 * p) - 2); + return 0.5 * f * f * f * f * f + 1; + } +} + +// Modeled after quarter-cycle of sine wave +AHFloat SineEaseIn(AHFloat p) +{ + return sin((p - 1) * M_PI_2) + 1; +} + +// Modeled after quarter-cycle of sine wave (different phase) +AHFloat SineEaseOut(AHFloat p) +{ + return sin(p * M_PI_2); +} + +// Modeled after half sine wave +AHFloat SineEaseInOut(AHFloat p) +{ + return 0.5 * (1 - cos(p * M_PI)); +} + +// Modeled after shifted quadrant IV of unit circle +AHFloat CircularEaseIn(AHFloat p) +{ + return 1 - sqrt(1 - (p * p)); +} + +// Modeled after shifted quadrant II of unit circle +AHFloat CircularEaseOut(AHFloat p) +{ + return sqrt((2 - p) * p); +} + +// Modeled after the piecewise circular function +// y = (1/2)(1 - sqrt(1 - 4x^2)) ; [0, 0.5) +// y = (1/2)(sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1] +AHFloat CircularEaseInOut(AHFloat p) +{ + if(p < 0.5) + { + return 0.5 * (1 - sqrt(1 - 4 * (p * p))); + } + else + { + return 0.5 * (sqrt(-((2 * p) - 3) * ((2 * p) - 1)) + 1); + } +} + +// Modeled after the exponential function y = 2^(10(x - 1)) +AHFloat ExponentialEaseIn(AHFloat p) +{ + return (p == 0.0) ? p : pow(2, 10 * (p - 1)); +} + +// Modeled after the exponential function y = -2^(-10x) + 1 +AHFloat ExponentialEaseOut(AHFloat p) +{ + return (p == 1.0) ? p : 1 - pow(2, -10 * p); +} + +// Modeled after the piecewise exponential +// y = (1/2)2^(10(2x - 1)) ; [0,0.5) +// y = -(1/2)*2^(-10(2x - 1))) + 1 ; [0.5,1] +AHFloat ExponentialEaseInOut(AHFloat p) +{ + if(p == 0.0 || p == 1.0) return p; + + if(p < 0.5) + { + return 0.5 * pow(2, (20 * p) - 10); + } + else + { + return -0.5 * pow(2, (-20 * p) + 10) + 1; + } +} + +// Modeled after the damped sine wave y = sin(13pi/2*x)*pow(2, 10 * (x - 1)) +AHFloat ElasticEaseIn(AHFloat p) +{ + return sin(13 * M_PI_2 * p) * pow(2, 10 * (p - 1)); +} + +// Modeled after the damped sine wave y = sin(-13pi/2*(x + 1))*pow(2, -10x) + 1 +AHFloat ElasticEaseOut(AHFloat p) +{ + return sin(-13 * M_PI_2 * (p + 1)) * pow(2, -10 * p) + 1; +} + +// Modeled after the piecewise exponentially-damped sine wave: +// y = (1/2)*sin(13pi/2*(2*x))*pow(2, 10 * ((2*x) - 1)) ; [0,0.5) +// y = (1/2)*(sin(-13pi/2*((2x-1)+1))*pow(2,-10(2*x-1)) + 2) ; [0.5, 1] +AHFloat ElasticEaseInOut(AHFloat p) +{ + if(p < 0.5) + { + return 0.5 * sin(13 * M_PI_2 * (2 * p)) * pow(2, 10 * ((2 * p) - 1)); + } + else + { + return 0.5 * (sin(-13 * M_PI_2 * ((2 * p - 1) + 1)) * pow(2, -10 * (2 * p - 1)) + 2); + } +} + +// Modeled after the overshooting cubic y = x^3-x*sin(x*pi) +AHFloat BackEaseIn(AHFloat p) +{ + return p * p * p - p * sin(p * M_PI); +} + +// Modeled after overshooting cubic y = 1-((1-x)^3-(1-x)*sin((1-x)*pi)) +AHFloat BackEaseOut(AHFloat p) +{ + AHFloat f = (1 - p); + return 1 - (f * f * f - f * sin(f * M_PI)); +} + +// Modeled after the piecewise overshooting cubic function: +// y = (1/2)*((2x)^3-(2x)*sin(2*x*pi)) ; [0, 0.5) +// y = (1/2)*(1-((1-x)^3-(1-x)*sin((1-x)*pi))+1) ; [0.5, 1] +AHFloat BackEaseInOut(AHFloat p) +{ + if(p < 0.5) + { + AHFloat f = 2 * p; + return 0.5 * (f * f * f - f * sin(f * M_PI)); + } + else + { + AHFloat f = (1 - (2*p - 1)); + return 0.5 * (1 - (f * f * f - f * sin(f * M_PI))) + 0.5; + } +} + +AHFloat BounceEaseIn(AHFloat p) +{ + return 1 - BounceEaseOut(1 - p); +} + +AHFloat BounceEaseOut(AHFloat p) +{ + if(p < 4/11.0) + { + return (121 * p * p)/16.0; + } + else if(p < 8/11.0) + { + return (363/40.0 * p * p) - (99/10.0 * p) + 17/5.0; + } + else if(p < 9/10.0) + { + return (4356/361.0 * p * p) - (35442/1805.0 * p) + 16061/1805.0; + } + else + { + return (54/5.0 * p * p) - (513/25.0 * p) + 268/25.0; + } +} + +AHFloat BounceEaseInOut(AHFloat p) +{ + if(p < 0.5) + { + return 0.5 * BounceEaseIn(p*2); + } + else + { + return 0.5 * BounceEaseOut(p * 2 - 1) + 0.5; + } +} diff --git a/src/vendor/easing.h b/src/vendor/easing.h new file mode 100644 index 0000000..e462ff0 --- /dev/null +++ b/src/vendor/easing.h @@ -0,0 +1,89 @@ +// +// easing.h +// +// Copyright (c) 2011, Auerhaus Development, LLC +// +// This program is free software. It comes without any warranty, to +// the extent permitted by applicable law. You can redistribute it +// and/or modify it under the terms of the Do What The Fuck You Want +// To Public License, Version 2, as published by Sam Hocevar. See +// http://sam.zoy.org/wtfpl/COPYING for more details. +// + +#ifndef AH_EASING_H +#define AH_EASING_H + +#if defined(__LP64__) && !defined(AH_EASING_USE_DBL_PRECIS) +#define AH_EASING_USE_DBL_PRECIS +#endif + +#ifdef AH_EASING_USE_DBL_PRECIS +#define AHFloat double +#else +#define AHFloat float +#endif + +#if defined __cplusplus +extern "C" { +#endif + +typedef AHFloat (*AHEasingFunction)(AHFloat); + +// Linear interpolation (no easing) +AHFloat LinearInterpolation(AHFloat p); + +// Quadratic easing; p^2 +AHFloat QuadraticEaseIn(AHFloat p); +AHFloat QuadraticEaseOut(AHFloat p); +AHFloat QuadraticEaseInOut(AHFloat p); + +// Cubic easing; p^3 +AHFloat CubicEaseIn(AHFloat p); +AHFloat CubicEaseOut(AHFloat p); +AHFloat CubicEaseInOut(AHFloat p); + +// Quartic easing; p^4 +AHFloat QuarticEaseIn(AHFloat p); +AHFloat QuarticEaseOut(AHFloat p); +AHFloat QuarticEaseInOut(AHFloat p); + +// Quintic easing; p^5 +AHFloat QuinticEaseIn(AHFloat p); +AHFloat QuinticEaseOut(AHFloat p); +AHFloat QuinticEaseInOut(AHFloat p); + +// Sine wave easing; sin(p * PI/2) +AHFloat SineEaseIn(AHFloat p); +AHFloat SineEaseOut(AHFloat p); +AHFloat SineEaseInOut(AHFloat p); + +// Circular easing; sqrt(1 - p^2) +AHFloat CircularEaseIn(AHFloat p); +AHFloat CircularEaseOut(AHFloat p); +AHFloat CircularEaseInOut(AHFloat p); + +// Exponential easing, base 2 +AHFloat ExponentialEaseIn(AHFloat p); +AHFloat ExponentialEaseOut(AHFloat p); +AHFloat ExponentialEaseInOut(AHFloat p); + +// Exponentially-damped sine wave easing +AHFloat ElasticEaseIn(AHFloat p); +AHFloat ElasticEaseOut(AHFloat p); +AHFloat ElasticEaseInOut(AHFloat p); + +// Overshooting cubic easing; +AHFloat BackEaseIn(AHFloat p); +AHFloat BackEaseOut(AHFloat p); +AHFloat BackEaseInOut(AHFloat p); + +// Exponentially-decaying bounce easing +AHFloat BounceEaseIn(AHFloat p); +AHFloat BounceEaseOut(AHFloat p); +AHFloat BounceEaseInOut(AHFloat p); + +#ifdef __cplusplus +} +#endif + +#endif