Switching SceneItems to smarts
This commit is contained in:
17
archive/animation/Animation.cpp
Normal file
17
archive/animation/Animation.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Animation.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void Animation::restart() {
|
||||
this->time = 0;
|
||||
this->finished = false;
|
||||
}
|
||||
|
||||
void Animation::clear() {
|
||||
this->duration = 0;
|
||||
}
|
38
archive/animation/Animation.hpp
Normal file
38
archive/animation/Animation.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "state/StateEvent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct Animation {
|
||||
public:
|
||||
bool_t loop = false;
|
||||
bool_t finished = false;
|
||||
float_t time = 0;
|
||||
float_t duration = 0;
|
||||
StateEvent<> eventAnimationEnd;
|
||||
|
||||
/**
|
||||
* Ticks the animation along. Delta is whatever you want to update the
|
||||
* animation by (in seconds). Animations can overshoot if necessary and
|
||||
* will not be clamped (by default). Subclasses may interpret ticks in
|
||||
* different ways.
|
||||
*
|
||||
* @param delta Time delta (in seconds) to tick the animaiton by.
|
||||
*/
|
||||
virtual void tick(const float_t delta) = 0;
|
||||
|
||||
/**
|
||||
* Restart a running animation.
|
||||
*/
|
||||
virtual void restart();
|
||||
|
||||
/**
|
||||
* Clears an animaton of all its animation items and keyframes.
|
||||
*/
|
||||
virtual void clear();
|
||||
};
|
||||
}
|
12
archive/animation/CMakeLists.txt
Normal file
12
archive/animation/CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2022 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
Animation.cpp
|
||||
TiledSpriteAnimation.cpp
|
||||
easing.cpp
|
||||
)
|
207
archive/animation/SimpleAnimation.hpp
Normal file
207
archive/animation/SimpleAnimation.hpp
Normal file
@ -0,0 +1,207 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "Animation.hpp"
|
||||
#include "easing.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
template<typename T>
|
||||
struct SimpleKeyframe {
|
||||
float_t time;
|
||||
T value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct SimpleAnimation : public Animation {
|
||||
protected:
|
||||
/**
|
||||
* Function for subclasses to be "notified" when the value has been
|
||||
* modified.
|
||||
*/
|
||||
virtual void onValueModified() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts internal keyframes by their time to make them conform correctly.
|
||||
*/
|
||||
void sortKeyframes() {
|
||||
std::sort(
|
||||
this->keyframes.begin(),
|
||||
this->keyframes.end(),
|
||||
[](struct SimpleKeyframe<T> &a, struct SimpleKeyframe<T> &b) {
|
||||
return a.time < b.time;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public:
|
||||
std::function<float_t(const float_t)> easing = easeLinear;
|
||||
T *modifies;
|
||||
std::vector<struct SimpleKeyframe<T>> keyframes;
|
||||
|
||||
/**
|
||||
* Constructs a new Simple Animation instance.
|
||||
*
|
||||
* @param modifies Pointer to the value that will be modified.
|
||||
*/
|
||||
SimpleAnimation(T *modifies) {
|
||||
assertNotNull(modifies, "Modifies cannot be null");
|
||||
this->modifies = modifies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a keyframe that will be slerped to at a given time.
|
||||
*
|
||||
* @param time Time the keyframe occurs.
|
||||
* @param value Value at this given time.
|
||||
*/
|
||||
void addKeyframe(float_t time, T value) {
|
||||
assertTrue(time >= 0, "Time must be >= 0");
|
||||
|
||||
struct SimpleKeyframe<T> keyframe;
|
||||
keyframe.time = time;
|
||||
keyframe.value = value;
|
||||
this->duration = mathMax<float_t>(this->duration, time);
|
||||
this->finished = false;
|
||||
this->keyframes.push_back(keyframe);
|
||||
|
||||
if(time < this->duration) this->sortKeyframes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Quickly add a series of keyframes. For example, if you want to have a
|
||||
* keyframe series of;
|
||||
* [ 1, 3, 5, 7, 9 ]
|
||||
*
|
||||
* And occur at times
|
||||
* [ 0, 2, 4, 6, 8 ]
|
||||
*
|
||||
* You would pass frameTime as 2, and step as 2.
|
||||
*
|
||||
* @param startTime When the first keyframe occurs.
|
||||
* @param frameTime At what rate do keyframes occur.
|
||||
* @param start Initial value (the value at startTime).
|
||||
* @param end The end value (for the last keyframe).
|
||||
* @param step How to step the value.
|
||||
*/
|
||||
void addSequentialKeyframes(
|
||||
float_t startTime,
|
||||
float_t frameTime,
|
||||
T start,
|
||||
T end,
|
||||
T step
|
||||
) {
|
||||
T v = start;
|
||||
float_t n = startTime;
|
||||
while(v != end) {
|
||||
this->addKeyframe(n, v);
|
||||
n += frameTime;
|
||||
v += step;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand addSequentialKeyframes, assumes a step of 1 and a startTime
|
||||
* of 0.
|
||||
*
|
||||
* @param frameTime Time between frames.
|
||||
* @param start Initial value.
|
||||
* @param end End value.
|
||||
*/
|
||||
void addSequentialKeyframes(float_t frameTime, T start, T end) {
|
||||
this->addSequentialKeyframes(0, frameTime, start, end, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Immediately sets the value, bypassing keyframes and ticks. Useful for
|
||||
* setting an initial value.
|
||||
*
|
||||
* @param value Value to set.
|
||||
*/
|
||||
void setValue(T value) {
|
||||
*modifies = value;
|
||||
this->onValueModified();
|
||||
}
|
||||
|
||||
void tick(float_t delta) override {
|
||||
if(this->finished) return;
|
||||
|
||||
float_t newTime = this->time + delta;
|
||||
|
||||
struct SimpleKeyframe<T> *keyframeNext = nullptr;
|
||||
struct SimpleKeyframe<T> *keyframeCurrent = nullptr;
|
||||
|
||||
// Find current and next keyframe(s)
|
||||
auto itKey = this->keyframes.begin();
|
||||
while(itKey != this->keyframes.end()) {
|
||||
if(itKey->time > newTime) {
|
||||
keyframeNext = &(*itKey);
|
||||
break;
|
||||
}
|
||||
keyframeCurrent = &(*itKey);
|
||||
++itKey;
|
||||
}
|
||||
|
||||
// Update values
|
||||
if(keyframeCurrent != nullptr && keyframeNext == nullptr) {
|
||||
// "End of animation"
|
||||
*this->modifies = keyframeCurrent->value;
|
||||
this->onValueModified();
|
||||
} else if(keyframeNext != nullptr) {
|
||||
T oldValue;
|
||||
float_t oldTime;
|
||||
|
||||
if(keyframeCurrent == nullptr) {
|
||||
// "Start of animation"
|
||||
oldValue = keyframeCurrent->value;
|
||||
oldTime = keyframeCurrent->time;
|
||||
} else {
|
||||
// "Mid animation"
|
||||
oldTime = this->time;
|
||||
oldValue = *this->modifies;
|
||||
}
|
||||
|
||||
// Slerp between keyframes
|
||||
float_t keyframeDelta = this->easing(
|
||||
(newTime - oldTime) / (keyframeNext->time - oldTime)
|
||||
);
|
||||
*this->modifies = oldValue + (
|
||||
(keyframeNext->value - oldValue) * keyframeDelta
|
||||
);
|
||||
this->onValueModified();
|
||||
}
|
||||
|
||||
// First possible frame? I think this can be done cleaner
|
||||
if(this->time == 0 && keyframeCurrent->time == 0) {
|
||||
*this->modifies = keyframeCurrent->value;
|
||||
this->onValueModified();
|
||||
}
|
||||
|
||||
// Update time.
|
||||
this->time = newTime;
|
||||
|
||||
// Has the animation finished?
|
||||
if(newTime < this->duration) return;
|
||||
|
||||
// Do we need to loop?
|
||||
if(this->loop) {
|
||||
this->time = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Animation end.
|
||||
this->finished = true;
|
||||
this->eventAnimationEnd.invoke();
|
||||
}
|
||||
|
||||
void clear() override {
|
||||
Animation::clear();
|
||||
this->keyframes.clear();
|
||||
}
|
||||
};
|
||||
}
|
51
archive/animation/SimpleCallbackAnimation.hpp
Normal file
51
archive/animation/SimpleCallbackAnimation.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "SimpleAnimation.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
template<typename T, class I>
|
||||
struct SimpleCallbackAnimation : public SimpleAnimation<T> {
|
||||
protected:
|
||||
I *instance;
|
||||
void (I::*callback)(T arg);
|
||||
T value;
|
||||
|
||||
/**
|
||||
* Internally invoke the function that this animation is owning.
|
||||
*/
|
||||
void invoke() {
|
||||
assertNotNull(this->instance);
|
||||
((*this->instance).*(this->callback))(this->value);
|
||||
}
|
||||
|
||||
void onValueModified() override {
|
||||
SimpleAnimation<T>::onValueModified();
|
||||
this->invoke();
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct a new Simple Function Animation object
|
||||
*/
|
||||
SimpleCallbackAnimation() :
|
||||
SimpleAnimation<T>(&value)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the callback for the animation to use.
|
||||
*
|
||||
* @param instance Instance of the object that has the callback.
|
||||
* @param callback Callback method to be invoked.
|
||||
*/
|
||||
void setCallback(I *instance, void (I::*callback)(T arg)) {
|
||||
assertNotNull(instance);
|
||||
this->instance = instance;
|
||||
this->callback = callback;
|
||||
}
|
||||
};
|
||||
}
|
31
archive/animation/SimplerCallbackAnimation.hpp
Normal file
31
archive/animation/SimplerCallbackAnimation.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "SimpleAnimation.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
template<typename T>
|
||||
struct SimplerCallbackAnimation : public SimpleAnimation<T> {
|
||||
protected:
|
||||
T value;
|
||||
|
||||
void onValueModified() override {
|
||||
SimpleAnimation<T>::onValueModified();
|
||||
this->callback(this->value);
|
||||
}
|
||||
|
||||
public:
|
||||
std::function<void(T)> callback = std::function<void(T)>();
|
||||
|
||||
/**
|
||||
* Construct a new Simple Function Animation object
|
||||
*/
|
||||
SimplerCallbackAnimation() :
|
||||
SimpleAnimation<T>(&value)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
19
archive/animation/TiledSpriteAnimation.cpp
Normal file
19
archive/animation/TiledSpriteAnimation.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "TiledSpriteAnimation.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
TiledSpriteAnimation::TiledSpriteAnimation(TiledSprite *sprite) :
|
||||
SimpleAnimation(&frame),
|
||||
sprite(sprite)
|
||||
{
|
||||
}
|
||||
|
||||
void TiledSpriteAnimation::tick(const float_t delta) {
|
||||
SimpleAnimation::tick(delta);
|
||||
this->sprite->tile = frame;
|
||||
}
|
25
archive/animation/TiledSpriteAnimation.hpp
Normal file
25
archive/animation/TiledSpriteAnimation.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "SimpleAnimation.hpp"
|
||||
#include "scene/components/display/TiledSprite.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct TiledSpriteAnimation : public SimpleAnimation<int32_t> {
|
||||
public:
|
||||
int32_t frame = 0;
|
||||
TiledSprite *sprite = nullptr;
|
||||
|
||||
/**
|
||||
* Construct a new Tiled Sprite Animation.
|
||||
*
|
||||
* @param sprite Sprite that this animation will control.
|
||||
*/
|
||||
TiledSpriteAnimation(TiledSprite *sprite);
|
||||
|
||||
void tick(const float_t delta) override;
|
||||
};
|
||||
}
|
66
archive/animation/easing.cpp
Normal file
66
archive/animation/easing.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "easing.hpp"
|
||||
|
||||
float_t easeTimeToEase(
|
||||
const float_t start,
|
||||
const float_t current,
|
||||
const float_t duration
|
||||
) {
|
||||
return (current - start) / duration;
|
||||
}
|
||||
|
||||
float_t easeLinear(const float_t t) {
|
||||
return t;
|
||||
}
|
||||
|
||||
float_t easeInQuad(const float_t t) {
|
||||
return t * t;
|
||||
}
|
||||
|
||||
float_t easeOutQuad(const float_t t) {
|
||||
return t * (2 - t);
|
||||
}
|
||||
|
||||
float_t easeOutCubic(const float_t t) {
|
||||
return 1 - powf(1 - t, 3);
|
||||
}
|
||||
|
||||
float_t easeInOutQuad(const float_t t) {
|
||||
return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
||||
}
|
||||
|
||||
float_t easeInCubic(const float_t t) {
|
||||
return t * t * t;
|
||||
}
|
||||
|
||||
float_t easeInOutCubic(const float_t t) {
|
||||
return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
|
||||
}
|
||||
|
||||
float_t easeInQuart(const float_t t) {
|
||||
return t * t * t * t;
|
||||
}
|
||||
|
||||
float_t easeOutQuart(const float_t t) {
|
||||
return 1 - (t-1)*(t-1)*(t-1)*(t-1);
|
||||
}
|
||||
|
||||
float_t easeInOutQuart(const float_t t) {
|
||||
return t < .5 ? 8*t*t*t*t : 1-8*(t-1)*(t-1)*(t-1)*(t-1);
|
||||
}
|
||||
|
||||
float_t easeInQuint(const float_t t) {
|
||||
return t*t*t*t*t;
|
||||
}
|
||||
|
||||
float_t easeOutQuint(const float_t t) {
|
||||
return 1 + (t-1)*(t-1)*(t-1)*(t-1)*(t-1);
|
||||
}
|
||||
|
||||
float_t easeInOutQuint(const float_t t) {
|
||||
return t<.5 ? 16*t*t*t*t*t : 1+16*(t-1)*(t-1)*(t-1)*(t-1)*(t-1);
|
||||
}
|
37
archive/animation/easing.hpp
Normal file
37
archive/animation/easing.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
|
||||
typedef float_t easefunction_t(const float_t t);
|
||||
|
||||
/**
|
||||
* Returns the ease time for a given real time duration span.
|
||||
* @param start At what point in time the animation started
|
||||
* @param current The current point in time the animation is at.
|
||||
* @param duration The total duration on the animation.
|
||||
* @returns The easing time (0-1 time) that the animation is at.
|
||||
*/
|
||||
float_t easeTimeToEase(
|
||||
const float_t start,
|
||||
const float_t current,
|
||||
const float_t duration
|
||||
);
|
||||
|
||||
float_t easeLinear(const float_t t);
|
||||
float_t easeInQuad(const float_t t);
|
||||
float_t easeOutQuad(const float_t t);
|
||||
float_t easeOutCubic(const float_t t);
|
||||
float_t easeInOutQuad(const float_t t);
|
||||
float_t easeInCubic(const float_t t);
|
||||
float_t easeInOutCubic(const float_t t);
|
||||
float_t easeInQuart(const float_t t);
|
||||
float_t easeOutQuart(const float_t t);
|
||||
float_t easeInOutQuart(const float_t t);
|
||||
float_t easeInQuint(const float_t t);
|
||||
float_t easeOutQuint(const float_t t);
|
||||
float_t easeInOutQuint(const float_t t);
|
Reference in New Issue
Block a user