Path: blob/master/scene/animation/easing_equations.h
10277 views
/**************************************************************************/1/* easing_equations.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#include "core/math/math_funcs.h"3334/*35* Derived from Robert Penner's easing equations: http://robertpenner.com/easing/36*37* Copyright (c) 2001 Robert Penner38*39* Permission is hereby granted, free of charge, to any person obtaining a copy40* of this software and associated documentation files (the "Software"), to deal41* in the Software without restriction, including without limitation the rights42* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell43* copies of the Software, and to permit persons to whom the Software is44* furnished to do so, subject to the following conditions:45*46* The above copyright notice and this permission notice shall be included in all47* copies or substantial portions of the Software.48*49* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR50* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,51* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE52* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER53* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,54* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE55* SOFTWARE.56*/5758namespace Linear {59static real_t in(real_t t, real_t b, real_t c, real_t d) {60return c * t / d + b;61}62}; // namespace Linear6364namespace Sine {65static real_t in(real_t t, real_t b, real_t c, real_t d) {66return -c * std::cos(t / d * (Math::PI / 2)) + c + b;67}6869static real_t out(real_t t, real_t b, real_t c, real_t d) {70return c * std::sin(t / d * (Math::PI / 2)) + b;71}7273static real_t in_out(real_t t, real_t b, real_t c, real_t d) {74return -c / 2 * (std::cos(Math::PI * t / d) - 1) + b;75}7677static real_t out_in(real_t t, real_t b, real_t c, real_t d) {78if (t < d / 2) {79return out(t * 2, b, c / 2, d);80}81real_t h = c / 2;82return in(t * 2 - d, b + h, h, d);83}84}; // namespace Sine8586namespace Quint {87static real_t in(real_t t, real_t b, real_t c, real_t d) {88return c * std::pow(t / d, 5) + b;89}9091static real_t out(real_t t, real_t b, real_t c, real_t d) {92return c * (std::pow(t / d - 1, 5) + 1) + b;93}9495static real_t in_out(real_t t, real_t b, real_t c, real_t d) {96t = t / d * 2;9798if (t < 1) {99return c / 2 * std::pow(t, 5) + b;100}101return c / 2 * (std::pow(t - 2, 5) + 2) + b;102}103104static real_t out_in(real_t t, real_t b, real_t c, real_t d) {105if (t < d / 2) {106return out(t * 2, b, c / 2, d);107}108real_t h = c / 2;109return in(t * 2 - d, b + h, h, d);110}111}; // namespace Quint112113namespace Quart {114static real_t in(real_t t, real_t b, real_t c, real_t d) {115return c * std::pow(t / d, 4) + b;116}117118static real_t out(real_t t, real_t b, real_t c, real_t d) {119return -c * (std::pow(t / d - 1, 4) - 1) + b;120}121122static real_t in_out(real_t t, real_t b, real_t c, real_t d) {123t = t / d * 2;124125if (t < 1) {126return c / 2 * std::pow(t, 4) + b;127}128return -c / 2 * (std::pow(t - 2, 4) - 2) + b;129}130131static real_t out_in(real_t t, real_t b, real_t c, real_t d) {132if (t < d / 2) {133return out(t * 2, b, c / 2, d);134}135real_t h = c / 2;136return in(t * 2 - d, b + h, h, d);137}138}; // namespace Quart139140namespace Quad {141static real_t in(real_t t, real_t b, real_t c, real_t d) {142return c * std::pow(t / d, 2) + b;143}144145static real_t out(real_t t, real_t b, real_t c, real_t d) {146t /= d;147return -c * t * (t - 2) + b;148}149150static real_t in_out(real_t t, real_t b, real_t c, real_t d) {151t = t / d * 2;152153if (t < 1) {154return c / 2 * std::pow(t, 2) + b;155}156return -c / 2 * ((t - 1) * (t - 3) - 1) + b;157}158159static real_t out_in(real_t t, real_t b, real_t c, real_t d) {160if (t < d / 2) {161return out(t * 2, b, c / 2, d);162}163real_t h = c / 2;164return in(t * 2 - d, b + h, h, d);165}166}; // namespace Quad167168namespace Expo {169static real_t in(real_t t, real_t b, real_t c, real_t d) {170if (t == 0) {171return b;172}173return c * std::pow(2, 10 * (t / d - 1)) + b - c * 0.001;174}175176static real_t out(real_t t, real_t b, real_t c, real_t d) {177if (t == d) {178return b + c;179}180return c * 1.001 * (-std::pow(2, -10 * t / d) + 1) + b;181}182183static real_t in_out(real_t t, real_t b, real_t c, real_t d) {184if (t == 0) {185return b;186}187188if (t == d) {189return b + c;190}191192t = t / d * 2;193194if (t < 1) {195return c / 2 * std::pow(2, 10 * (t - 1)) + b - c * 0.0005;196}197return c / 2 * 1.0005 * (-std::pow(2, -10 * (t - 1)) + 2) + b;198}199200static real_t out_in(real_t t, real_t b, real_t c, real_t d) {201if (t < d / 2) {202return out(t * 2, b, c / 2, d);203}204real_t h = c / 2;205return in(t * 2 - d, b + h, h, d);206}207}; // namespace Expo208209namespace Elastic {210static real_t in(real_t t, real_t b, real_t c, real_t d) {211if (t == 0) {212return b;213}214215t /= d;216if (t == 1) {217return b + c;218}219220t -= 1;221float p = d * 0.3f;222float a = c * std::pow(2, 10 * t);223float s = p / 4;224225return -(a * std::sin((t * d - s) * (2 * Math::PI) / p)) + b;226}227228static real_t out(real_t t, real_t b, real_t c, real_t d) {229if (t == 0) {230return b;231}232233t /= d;234if (t == 1) {235return b + c;236}237238float p = d * 0.3f;239float s = p / 4;240241return (c * std::pow(2, -10 * t) * std::sin((t * d - s) * (2 * Math::PI) / p) + c + b);242}243244static real_t in_out(real_t t, real_t b, real_t c, real_t d) {245if (t == 0) {246return b;247}248249if ((t /= d / 2) == 2) {250return b + c;251}252253float p = d * (0.3f * 1.5f);254float a = c;255float s = p / 4;256257if (t < 1) {258t -= 1;259a *= std::pow(2, 10 * t);260return -0.5f * (a * std::sin((t * d - s) * (2 * Math::PI) / p)) + b;261}262263t -= 1;264a *= std::pow(2, -10 * t);265return a * std::sin((t * d - s) * (2 * Math::PI) / p) * 0.5f + c + b;266}267268static real_t out_in(real_t t, real_t b, real_t c, real_t d) {269if (t < d / 2) {270return out(t * 2, b, c / 2, d);271}272real_t h = c / 2;273return in(t * 2 - d, b + h, h, d);274}275}; // namespace Elastic276277namespace Cubic {278static real_t in(real_t t, real_t b, real_t c, real_t d) {279t /= d;280return c * t * t * t + b;281}282283static real_t out(real_t t, real_t b, real_t c, real_t d) {284t = t / d - 1;285return c * (t * t * t + 1) + b;286}287288static real_t in_out(real_t t, real_t b, real_t c, real_t d) {289t /= d / 2;290if (t < 1) {291return c / 2 * t * t * t + b;292}293294t -= 2;295return c / 2 * (t * t * t + 2) + b;296}297298static real_t out_in(real_t t, real_t b, real_t c, real_t d) {299if (t < d / 2) {300return out(t * 2, b, c / 2, d);301}302real_t h = c / 2;303return in(t * 2 - d, b + h, h, d);304}305}; // namespace Cubic306307namespace Circ {308static real_t in(real_t t, real_t b, real_t c, real_t d) {309t /= d;310return -c * (std::sqrt(1 - t * t) - 1) + b;311}312313static real_t out(real_t t, real_t b, real_t c, real_t d) {314t = t / d - 1;315return c * std::sqrt(1 - t * t) + b;316}317318static real_t in_out(real_t t, real_t b, real_t c, real_t d) {319t /= d / 2;320if (t < 1) {321return -c / 2 * (std::sqrt(1 - t * t) - 1) + b;322}323324t -= 2;325return c / 2 * (std::sqrt(1 - t * t) + 1) + b;326}327328static real_t out_in(real_t t, real_t b, real_t c, real_t d) {329if (t < d / 2) {330return out(t * 2, b, c / 2, d);331}332real_t h = c / 2;333return in(t * 2 - d, b + h, h, d);334}335}; // namespace Circ336337namespace Bounce {338static real_t out(real_t t, real_t b, real_t c, real_t d) {339t /= d;340341if (t < (1 / 2.75f)) {342return c * (7.5625f * t * t) + b;343}344345if (t < (2 / 2.75f)) {346t -= 1.5f / 2.75f;347return c * (7.5625f * t * t + 0.75f) + b;348}349350if (t < (2.5 / 2.75)) {351t -= 2.25f / 2.75f;352return c * (7.5625f * t * t + 0.9375f) + b;353}354355t -= 2.625f / 2.75f;356return c * (7.5625f * t * t + 0.984375f) + b;357}358359static real_t in(real_t t, real_t b, real_t c, real_t d) {360return c - out(d - t, 0, c, d) + b;361}362363static real_t in_out(real_t t, real_t b, real_t c, real_t d) {364if (t < d / 2) {365return in(t * 2, b, c / 2, d);366}367real_t h = c / 2;368return out(t * 2 - d, b + h, h, d);369}370371static real_t out_in(real_t t, real_t b, real_t c, real_t d) {372if (t < d / 2) {373return out(t * 2, b, c / 2, d);374}375real_t h = c / 2;376return in(t * 2 - d, b + h, h, d);377}378}; // namespace Bounce379380namespace Back {381static real_t in(real_t t, real_t b, real_t c, real_t d) {382float s = 1.70158f;383t /= d;384385return c * t * t * ((s + 1) * t - s) + b;386}387388static real_t out(real_t t, real_t b, real_t c, real_t d) {389float s = 1.70158f;390t = t / d - 1;391392return c * (t * t * ((s + 1) * t + s) + 1) + b;393}394395static real_t in_out(real_t t, real_t b, real_t c, real_t d) {396float s = 1.70158f * 1.525f;397t /= d / 2;398399if (t < 1) {400return c / 2 * (t * t * ((s + 1) * t - s)) + b;401}402403t -= 2;404return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b;405}406407static real_t out_in(real_t t, real_t b, real_t c, real_t d) {408if (t < d / 2) {409return out(t * 2, b, c / 2, d);410}411real_t h = c / 2;412return in(t * 2 - d, b + h, h, d);413}414}; // namespace Back415416namespace Spring {417static real_t out(real_t t, real_t b, real_t c, real_t d) {418t /= d;419real_t s = 1.0 - t;420t = (std::sin(t * Math::PI * (0.2 + 2.5 * t * t * t)) * std::pow(s, 2.2) + t) * (1.0 + (1.2 * s));421return c * t + b;422}423424static real_t in(real_t t, real_t b, real_t c, real_t d) {425return c - out(d - t, 0, c, d) + b;426}427428static real_t in_out(real_t t, real_t b, real_t c, real_t d) {429if (t < d / 2) {430return in(t * 2, b, c / 2, d);431}432real_t h = c / 2;433return out(t * 2 - d, b + h, h, d);434}435436static real_t out_in(real_t t, real_t b, real_t c, real_t d) {437if (t < d / 2) {438return out(t * 2, b, c / 2, d);439}440real_t h = c / 2;441return in(t * 2 - d, b + h, h, d);442}443}; // namespace Spring444445446