Added some transitions.
This commit is contained in:
60
src/display/animation/easing.c
Normal file
60
src/display/animation/easing.c
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "easing.h"
|
||||
|
||||
float easeLinear(float t) {
|
||||
return t;
|
||||
}
|
||||
|
||||
float easeInQuad(float t) {
|
||||
return t * t;
|
||||
}
|
||||
|
||||
float easeOutQuad(float t) {
|
||||
return t * (2 - t);
|
||||
}
|
||||
|
||||
float easeInOutQuad(float t) {
|
||||
return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
||||
}
|
||||
|
||||
float easeInCubic(float t) {
|
||||
return t * t * t;
|
||||
}
|
||||
|
||||
float easeOutCubic(float t) {
|
||||
return (t - 1) * (t - 1) * (t - 1) + 1;
|
||||
}
|
||||
|
||||
float easeInOutCubic(float t) {
|
||||
return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
|
||||
}
|
||||
|
||||
float easeInQuart(float t) {
|
||||
return t * t * t * t;
|
||||
}
|
||||
|
||||
float easeOutQuart(float t) {
|
||||
return 1 - (t-1)*(t-1)*(t-1)*(t-1);
|
||||
}
|
||||
|
||||
float easeInOutQuart(float t) {
|
||||
return t < .5 ? 8*t*t*t*t : 1-8*(t-1)*(t-1)*(t-1)*(t-1);
|
||||
}
|
||||
|
||||
float easeInQuint(float t) {
|
||||
return t*t*t*t*t;
|
||||
}
|
||||
|
||||
float easeOutQuint(float t) {
|
||||
return 1 + (t-1)*(t-1)*(t-1)*(t-1)*(t-1);
|
||||
}
|
||||
|
||||
float easeInOutQuint(float t) {
|
||||
return t<.5 ? 16*t*t*t*t*t : 1+16*(t-1)*(t-1)*(t-1)*(t-1)*(t-1);
|
||||
}
|
@ -6,6 +6,8 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
typedef float easefunction_t(float t);
|
||||
|
||||
/**
|
||||
* Returns the ease time for a given real time duration span.
|
||||
* @param start At what point in time the animation started
|
||||
@ -15,22 +17,16 @@
|
||||
*/
|
||||
#define easeTimeToEase(start, current, duration) ((current-start)/duration)
|
||||
|
||||
|
||||
// Easing Functions, most were sourced from https://gist.github.com/gre/1650294
|
||||
#define easeLinear(t) t
|
||||
|
||||
#define easeInQuad(t) (t*t)
|
||||
#define easeOutQuad(t) (t*(2-t))
|
||||
#define easeInOutQuad(t) (t < .5 ? 2*t*t : -1+(4-2*t)*t)
|
||||
|
||||
#define easeInCubic(t) (t*t*t)
|
||||
#define easeOutCubic(t) ((t-1)*(t-1)*(t-1)+1)
|
||||
#define easeInOutCubic(t) (t < .5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1)
|
||||
|
||||
#define easeInQuart(t) (t*t*t*t)
|
||||
#define easeOutQuart(t) (1 - (t-1)*(t-1)*(t-1)*(t-1))
|
||||
#define easeInOutQuart(t) (t < .5 ? 8*t*t*t*t : 1-8*(t-1)*(t-1)*(t-1)*(t-1))
|
||||
|
||||
#define easeInQuint(t) (t*t*t*t*t)
|
||||
#define easeOutQuint(t) (1 + (t-1)*(t-1)*(t-1)*(t-1)*(t-1))
|
||||
#define easeInOutQuint(t) (t<.5 ? 16*t*t*t*t*t : 1+16*(t-1)*(t-1)*(t-1)*(t-1)*(t-1))
|
||||
float easeLinear(float t);
|
||||
float easeInQuad(float t);
|
||||
float easeOutQuad(float t);
|
||||
float easeInOutQuad(float t);
|
||||
float easeInCubic(float t);
|
||||
float easeOutCubic(float t);
|
||||
float easeInOutCubic(float t);
|
||||
float easeInQuart(float t);
|
||||
float easeOutQuart(float t);
|
||||
float easeInOutQuart(float t);
|
||||
float easeInQuint(float t);
|
||||
float easeOutQuint(float t);
|
||||
float easeInOutQuint(float t);
|
@ -7,6 +7,32 @@
|
||||
|
||||
#include "timeline.h"
|
||||
|
||||
void _timelineActionDeltaUpdateStart(
|
||||
timeline_t *timeline, timelineaction_t *action, uint8_t i
|
||||
) {
|
||||
if(action->data == NULL) return;
|
||||
*((float *)action->data) = timeline->initials[i];
|
||||
}
|
||||
|
||||
void _timelineActionDeltaUpdateDuration(
|
||||
timeline_t *timeline, timelineaction_t *action, uint8_t i
|
||||
) {
|
||||
float n;
|
||||
if(action->data == NULL) return;
|
||||
n = timeline->easings[i](
|
||||
timelineActionGetTimeRaw(timeline, action)
|
||||
);
|
||||
*((float *)action->data) = timeline->initials[i] + (timeline->deltas[i] * n);
|
||||
}
|
||||
|
||||
void _timelineActionDeltaUpdateEnd(
|
||||
timeline_t *timeline, timelineaction_t *action, uint8_t i
|
||||
) {
|
||||
if(action->data == NULL) return;
|
||||
*((float *)action->data) = timeline->initials[i] + timeline->deltas[i];
|
||||
}
|
||||
|
||||
|
||||
void timelineInit(timeline_t *timeline) {
|
||||
timeline->current = 0;
|
||||
timeline->diff = 0;
|
||||
@ -68,10 +94,48 @@ bool timelineIsFinished(timeline_t *timeline) {
|
||||
timelineaction_t * timelineAddAction(timeline_t *timeline, float start,
|
||||
float duration
|
||||
) {
|
||||
if(timeline->actionCount == TIMELINE_ACTION_COUNT_MAX) return NULL;
|
||||
timelineaction_t *action = timeline->actions + (timeline->actionCount++);
|
||||
action->loop = false;
|
||||
action->start = start, action->duration = duration;
|
||||
action->onStart = action->onEnd = action->onDuration = NULL;
|
||||
return action;
|
||||
}
|
||||
|
||||
timelineaction_t * timelineAddDeltaAction(timeline_t *timeline,
|
||||
float start, float duration, float initial, float delta,
|
||||
easefunction_t *easing, float *destination
|
||||
) {
|
||||
timelineaction_t *action;
|
||||
timeline->initials[timeline->actionCount] = initial;
|
||||
timeline->deltas[timeline->actionCount] = delta;
|
||||
timeline->easings[timeline->actionCount] = (
|
||||
easing == NULL ? &easeLinear : easing
|
||||
);
|
||||
action = timelineAddAction(timeline, start, duration);
|
||||
action->data = destination;
|
||||
action->onStart = &_timelineActionDeltaUpdateStart;
|
||||
action->onDuration = &_timelineActionDeltaUpdateDuration;
|
||||
action->onEnd = &_timelineActionDeltaUpdateEnd;
|
||||
return action;
|
||||
}
|
||||
|
||||
timelineaction_t * timelineAddDeltaActionTo(timeline_t *timeline,
|
||||
float start, float duration, float initial, float end,
|
||||
easefunction_t *easing, float *destination
|
||||
) {
|
||||
return timelineAddDeltaAction(
|
||||
timeline, start, duration, initial, end-initial, easing, destination
|
||||
);
|
||||
}
|
||||
|
||||
float timelineActionGetTimeRaw(timeline_t *timeline, timelineaction_t *action) {
|
||||
return (timeline->current - action->start) / action->duration;
|
||||
}
|
||||
|
||||
float timelineActionGetTime(timeline_t *tl, timelineaction_t *at) {
|
||||
return mathClamp(timelineActionGetTimeRaw(tl, at), 0, 1);
|
||||
}
|
||||
|
||||
void timelineClear(timeline_t *timeline) {
|
||||
timeline->actionCount = 0;
|
||||
}
|
@ -5,6 +5,8 @@
|
||||
|
||||
#pragma once
|
||||
#include "../../libs.h"
|
||||
#include "../../util/math.h"
|
||||
#include "easing.h"
|
||||
|
||||
/** Maximum number of actions a timeline can support, smaller than 0xFF */
|
||||
#define TIMELINE_ACTION_COUNT_MAX 128
|
||||
@ -72,6 +74,14 @@ typedef struct _timeline_t {
|
||||
|
||||
/** Actions within the timeline */
|
||||
timelineaction_t actions[TIMELINE_ACTION_COUNT_MAX];
|
||||
|
||||
/** For delta actions, storage of the initial values */
|
||||
float initials[TIMELINE_ACTION_COUNT_MAX];
|
||||
/** For delta actions, storage of their deltas. */
|
||||
float deltas[TIMELINE_ACTION_COUNT_MAX];
|
||||
/** Easing functions to use for delta functions */
|
||||
easefunction_t *easings[TIMELINE_ACTION_COUNT_MAX];
|
||||
|
||||
uint8_t actionCount;
|
||||
} timeline_t;
|
||||
|
||||
@ -110,4 +120,68 @@ bool timelineIsFinished(timeline_t *timeline);
|
||||
*/
|
||||
timelineaction_t * timelineAddAction(timeline_t *timeline, float start,
|
||||
float duration
|
||||
);
|
||||
);
|
||||
|
||||
/**
|
||||
* Add a special action kind that can treat delta style animations. These are
|
||||
* animations that have a start, and an end value, that will be tracked for you
|
||||
* and keep you up to date.
|
||||
*
|
||||
* @param timeline Timeline to add to.
|
||||
* @param start Starting time.
|
||||
* @param duration Animation duration.
|
||||
* @param initial Initial value for the animation.
|
||||
* @param delta Delta value for the animation.
|
||||
* @param easing Pointer to an easing function to use, set to NULL for linear.
|
||||
* @param destination A constant floating point to update.
|
||||
* @return The queued timeline action.
|
||||
*/
|
||||
timelineaction_t * timelineAddDeltaAction(timeline_t *timeline,
|
||||
float start, float duration, float initial, float delta,
|
||||
easefunction_t *easing, float *destination
|
||||
);
|
||||
|
||||
/**
|
||||
* Shorthand for timelineAddDeltaAction that will calculate the delta based on
|
||||
* and end position.
|
||||
*
|
||||
* @param timeline Timeline to add to.
|
||||
* @param start Starting time.
|
||||
* @param duration Animation duration.
|
||||
* @param initial Initial value for the animation.
|
||||
* @param end End value for the animation.
|
||||
* @param easing Pointer to an easing function to use, set to NULL for linear.
|
||||
* @param destination A constant floating point to update.
|
||||
* @return The queued timeline action.
|
||||
*/
|
||||
timelineaction_t * timelineAddDeltaActionTo(timeline_t *timeline,
|
||||
float start, float duration, float initial, float end,
|
||||
easefunction_t *easing, float *destination
|
||||
);
|
||||
|
||||
/**
|
||||
* Gets the timeline action's animation time. This is a representation of
|
||||
* 0 - 1 where 0 means the animation is at the start, and 1 meaning the
|
||||
* animation is at full completion. This is not clamped and may exceed 1.
|
||||
*
|
||||
* @param timeline Timeline the action belongs to.
|
||||
* @param action Action itself.
|
||||
* @return 0 - 1+, where 0 = start, 1 = duration, >1 is time since duration.
|
||||
*/
|
||||
float timelineActionGetTimeRaw(timeline_t *timeline, timelineaction_t *action);
|
||||
|
||||
/**
|
||||
* Gets the timeline action's animation time between 0 - 1, clamped.
|
||||
*
|
||||
* @param tl Timeline to get delta from.
|
||||
* @param at Timeline action.
|
||||
* @return 0 - 1, where 0 = start, 1 = duration.
|
||||
*/
|
||||
float timelineActionGetTime(timeline_t *tl, timelineaction_t *at);
|
||||
|
||||
/**
|
||||
* Removes all actions from the timeline.
|
||||
*
|
||||
* @param timeline Timeline to clear.
|
||||
*/
|
||||
void timelineClear(timeline_t *timeline);
|
@ -15,6 +15,12 @@ void cameraLookAt(camera_t *camera,
|
||||
matrixLookAt(&camera->view, x, y, z, targetX, targetY, targetZ, 0, 1, 0);
|
||||
}
|
||||
|
||||
void cameraLookAtStruct(camera_t *camera, cameralookat_t look) {
|
||||
cameraLookAt(camera,
|
||||
look.x, look.y, look.z, look.lookX, look.lookY, look.lookZ
|
||||
);
|
||||
}
|
||||
|
||||
void cameraLook(camera_t *camera,
|
||||
float x, float y, float z,
|
||||
float pitch, float yaw, float roll
|
||||
|
@ -17,6 +17,10 @@ typedef struct {
|
||||
matrix_t projection;
|
||||
} camera_t;
|
||||
|
||||
typedef struct {
|
||||
float x, y, z, lookX, lookY, lookZ;
|
||||
} cameralookat_t;
|
||||
|
||||
/**
|
||||
* Make a camera look at a position in world space while itself being positioned
|
||||
* within world space.
|
||||
@ -34,6 +38,14 @@ void cameraLookAt(camera_t *camera,
|
||||
float targetX, float targetY, float targetZ
|
||||
);
|
||||
|
||||
/**
|
||||
* Shorthand for look at that uses the look struct.
|
||||
*
|
||||
* @param camera Camera to position.
|
||||
* @param look Look vectors.
|
||||
*/
|
||||
void cameraLookAtStruct(camera_t *camera, cameralookat_t look);
|
||||
|
||||
/**
|
||||
* Make a camera look in a direction based on a rotation direction.
|
||||
*
|
||||
|
Reference in New Issue
Block a user