2020-01-15 04:07:48 -08:00
|
|
|
#include "Runtime/Character/CCharAnimTime.hpp"
|
|
|
|
|
2020-03-09 09:21:08 -07:00
|
|
|
#include <algorithm>
|
2016-08-21 13:39:18 -07:00
|
|
|
#include <cmath>
|
2016-02-26 22:03:39 -08:00
|
|
|
|
2021-04-10 01:42:06 -07:00
|
|
|
namespace metaforce {
|
2016-02-26 22:03:39 -08:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
bool CCharAnimTime::EqualsZero() const {
|
|
|
|
if (x4_type == EType::ZeroIncreasing || x4_type == EType::ZeroSteady || x4_type == EType::ZeroDecreasing)
|
|
|
|
return true;
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2020-03-09 09:09:54 -07:00
|
|
|
return x0_time == 0.f;
|
2016-04-10 20:59:54 -07:00
|
|
|
}
|
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
bool CCharAnimTime::EpsilonZero() const { return (std::fabs(x0_time) < 0.00001f); }
|
2016-08-21 13:39:18 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
bool CCharAnimTime::GreaterThanZero() const {
|
|
|
|
if (EqualsZero())
|
|
|
|
return false;
|
2020-03-09 09:09:54 -07:00
|
|
|
return x0_time > 0.f;
|
2016-04-10 20:59:54 -07:00
|
|
|
}
|
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
bool CCharAnimTime::operator==(const CCharAnimTime& other) const {
|
|
|
|
if (x4_type == EType::NonZero) {
|
|
|
|
if (other.x4_type == EType::NonZero)
|
|
|
|
return x0_time == other.x0_time;
|
2019-01-19 22:43:11 -08:00
|
|
|
return false;
|
2018-12-07 21:30:43 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (EqualsZero()) {
|
|
|
|
if (other.EqualsZero()) {
|
|
|
|
int type = -1;
|
|
|
|
if (x4_type != EType::ZeroDecreasing) {
|
|
|
|
if (x4_type != EType::ZeroSteady)
|
|
|
|
type = 1;
|
|
|
|
else
|
|
|
|
type = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int otherType = -1;
|
|
|
|
if (other.x4_type != EType::ZeroDecreasing) {
|
|
|
|
if (other.x4_type != EType::ZeroSteady)
|
|
|
|
otherType = 1;
|
|
|
|
else
|
|
|
|
otherType = 0;
|
|
|
|
}
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
return type == otherType;
|
2016-04-10 20:59:54 -07:00
|
|
|
}
|
2018-12-07 21:30:43 -08:00
|
|
|
return false;
|
|
|
|
}
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
if (other.x4_type == EType::Infinity)
|
2020-08-23 23:28:18 -07:00
|
|
|
return x0_time * other.x0_time > 0.f;
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
return false;
|
2016-04-10 20:59:54 -07:00
|
|
|
}
|
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
bool CCharAnimTime::operator!=(const CCharAnimTime& other) const { return !(*this == other); }
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
bool CCharAnimTime::operator>=(const CCharAnimTime& other) const {
|
|
|
|
if (*this == other)
|
|
|
|
return true;
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2020-03-09 09:09:54 -07:00
|
|
|
return *this > other;
|
2016-04-10 20:59:54 -07:00
|
|
|
}
|
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
bool CCharAnimTime::operator<=(const CCharAnimTime& other) const {
|
|
|
|
if (*this == other)
|
|
|
|
return true;
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2020-03-09 09:09:54 -07:00
|
|
|
return *this < other;
|
2016-04-10 20:59:54 -07:00
|
|
|
}
|
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
bool CCharAnimTime::operator>(const CCharAnimTime& other) const { return (!(*this == other) && !(*this < other)); }
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
bool CCharAnimTime::operator<(const CCharAnimTime& other) const {
|
|
|
|
if (x4_type == EType::NonZero) {
|
2020-11-01 15:04:13 -08:00
|
|
|
if (other.x4_type == EType::NonZero) {
|
2018-12-07 21:30:43 -08:00
|
|
|
return x0_time < other.x0_time;
|
2020-11-01 15:04:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return other.EqualsZero() ? x0_time < 0.f : other.x0_time > 0;
|
2018-12-07 21:30:43 -08:00
|
|
|
}
|
|
|
|
|
2020-11-01 15:04:13 -08:00
|
|
|
if (!EqualsZero()) {
|
|
|
|
if (other.x4_type == EType::Infinity) {
|
|
|
|
return x0_time >= 0 || other.x0_time <= 0.f;
|
|
|
|
}
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2020-11-01 15:04:13 -08:00
|
|
|
return x0_time < 0.f;
|
|
|
|
}
|
2018-12-07 21:30:43 -08:00
|
|
|
|
2020-11-01 15:04:13 -08:00
|
|
|
if (!other.EqualsZero()) {
|
|
|
|
if (other.x4_type == EType::NonZero) {
|
|
|
|
return other.x0_time > 0.f;
|
2016-04-10 20:59:54 -07:00
|
|
|
}
|
2018-12-07 21:30:43 -08:00
|
|
|
|
2020-11-01 15:04:13 -08:00
|
|
|
return other.x0_time > 0.f;
|
2018-12-07 21:30:43 -08:00
|
|
|
}
|
2020-08-24 15:42:43 -07:00
|
|
|
|
2020-11-01 15:04:13 -08:00
|
|
|
int type = x4_type == EType::ZeroDecreasing ? -1 : x4_type == EType::ZeroSteady ? 0 : 1;
|
|
|
|
int otherType = other.x4_type == EType::ZeroDecreasing ? -1 : other.x4_type == EType::ZeroSteady ? 0 : 1;
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2020-11-01 15:04:13 -08:00
|
|
|
return type < otherType;
|
2016-04-10 20:59:54 -07:00
|
|
|
}
|
|
|
|
|
2020-11-01 15:04:13 -08:00
|
|
|
CCharAnimTime& CCharAnimTime::operator*=(const CCharAnimTime& other) { return *this = *this * other; }
|
|
|
|
|
|
|
|
CCharAnimTime& CCharAnimTime::operator+=(const CCharAnimTime& other) { return *this = *this + other; }
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
CCharAnimTime CCharAnimTime::operator+(const CCharAnimTime& other) const {
|
|
|
|
if (x4_type == EType::Infinity && other.x4_type == EType::Infinity) {
|
|
|
|
if (other.x0_time != x0_time)
|
2020-03-09 09:09:54 -07:00
|
|
|
return {};
|
2018-12-07 21:30:43 -08:00
|
|
|
return *this;
|
|
|
|
} else if (x4_type == EType::Infinity)
|
|
|
|
return *this;
|
|
|
|
else if (other.x4_type == EType::Infinity)
|
|
|
|
return other;
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
if (!EqualsZero() || !other.EqualsZero())
|
2020-03-09 09:09:54 -07:00
|
|
|
return {x0_time + other.x0_time};
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
int type = -1;
|
|
|
|
if (x4_type != EType::ZeroDecreasing) {
|
2020-03-09 09:09:54 -07:00
|
|
|
type = x4_type == EType::ZeroSteady ? 0 : 1;
|
2018-12-07 21:30:43 -08:00
|
|
|
}
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
int otherType = -1;
|
|
|
|
if (other.x4_type != EType::ZeroDecreasing) {
|
2020-03-09 09:09:54 -07:00
|
|
|
otherType = other.x4_type == EType::ZeroSteady ? 0 : 1;
|
2018-12-07 21:30:43 -08:00
|
|
|
}
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
type += otherType;
|
|
|
|
otherType = std::max(-1, std::min(type, 1));
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
if (otherType == -1)
|
2020-03-09 09:09:54 -07:00
|
|
|
return {EType::ZeroDecreasing, 0.f};
|
2018-12-07 21:30:43 -08:00
|
|
|
else if (otherType == 0)
|
2020-03-09 09:09:54 -07:00
|
|
|
return {EType::ZeroSteady, 0.f};
|
2018-12-07 21:30:43 -08:00
|
|
|
else
|
2020-03-09 09:09:54 -07:00
|
|
|
return {EType::ZeroIncreasing, 0.f};
|
2016-04-10 20:59:54 -07:00
|
|
|
}
|
|
|
|
|
2020-11-01 15:04:13 -08:00
|
|
|
CCharAnimTime& CCharAnimTime::operator-=(const CCharAnimTime& other) { return *this = *this - other; }
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
CCharAnimTime CCharAnimTime::operator-(const CCharAnimTime& other) const {
|
|
|
|
if (x4_type == EType::Infinity && other.x4_type == EType::Infinity) {
|
|
|
|
if (other.x0_time == x0_time)
|
2020-03-09 09:09:54 -07:00
|
|
|
return {};
|
2018-12-07 21:30:43 -08:00
|
|
|
return *this;
|
|
|
|
} else if (x4_type == EType::Infinity)
|
|
|
|
return *this;
|
|
|
|
else if (other.x4_type == EType::Infinity) {
|
2020-03-09 09:09:54 -07:00
|
|
|
return {EType::Infinity, -other.x0_time};
|
2018-12-07 21:30:43 -08:00
|
|
|
}
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
if (!EqualsZero() || !other.EqualsZero())
|
2020-03-09 09:09:54 -07:00
|
|
|
return {x0_time - other.x0_time};
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
int type = -1;
|
|
|
|
if (x4_type != EType::ZeroDecreasing) {
|
|
|
|
if (x4_type != EType::ZeroSteady)
|
|
|
|
type = 1;
|
2016-04-10 20:59:54 -07:00
|
|
|
else
|
2018-12-07 21:30:43 -08:00
|
|
|
type = 0;
|
|
|
|
}
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
int otherType = -1;
|
|
|
|
if (other.x4_type != EType::ZeroDecreasing) {
|
|
|
|
if (other.x4_type != EType::ZeroSteady)
|
|
|
|
otherType = 1;
|
|
|
|
else
|
|
|
|
otherType = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
type -= otherType;
|
|
|
|
if (type == -1)
|
2020-03-09 09:09:54 -07:00
|
|
|
return {EType::ZeroDecreasing, 0.f};
|
2018-12-07 21:30:43 -08:00
|
|
|
else if (type == 0)
|
2020-03-09 09:09:54 -07:00
|
|
|
return {EType::ZeroSteady, 0.f};
|
2018-12-07 21:30:43 -08:00
|
|
|
else
|
2020-03-09 09:09:54 -07:00
|
|
|
return {EType::ZeroIncreasing, 0.f};
|
2016-04-10 20:59:54 -07:00
|
|
|
}
|
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
CCharAnimTime CCharAnimTime::operator*(const CCharAnimTime& other) const {
|
|
|
|
if (x4_type == EType::Infinity && other.x4_type == EType::Infinity) {
|
|
|
|
if (other.x0_time != x0_time)
|
2020-03-09 09:09:54 -07:00
|
|
|
return {};
|
2018-12-07 21:30:43 -08:00
|
|
|
return *this;
|
|
|
|
} else if (x4_type == EType::Infinity)
|
|
|
|
return *this;
|
|
|
|
else if (other.x4_type == EType::Infinity)
|
|
|
|
return other;
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
if (!EqualsZero() || !other.EqualsZero())
|
2020-03-09 09:09:54 -07:00
|
|
|
return {x0_time * other.x0_time};
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
int type = -1;
|
|
|
|
if (x4_type != EType::ZeroDecreasing) {
|
|
|
|
if (x4_type != EType::ZeroSteady)
|
|
|
|
type = 1;
|
|
|
|
else
|
|
|
|
type = 0;
|
|
|
|
}
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
int otherType = -1;
|
|
|
|
if (other.x4_type != EType::ZeroDecreasing) {
|
|
|
|
if (other.x4_type != EType::ZeroSteady)
|
|
|
|
otherType = 1;
|
2016-04-10 20:59:54 -07:00
|
|
|
else
|
2018-12-07 21:30:43 -08:00
|
|
|
otherType = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
type += otherType;
|
|
|
|
otherType = std::max(-1, std::min(type, 1));
|
|
|
|
|
|
|
|
if (otherType == -1)
|
2020-03-09 09:09:54 -07:00
|
|
|
return {EType::ZeroDecreasing, 0.f};
|
2018-12-07 21:30:43 -08:00
|
|
|
else if (otherType == 0)
|
2020-03-09 09:09:54 -07:00
|
|
|
return {EType::ZeroSteady, 0.f};
|
2018-12-07 21:30:43 -08:00
|
|
|
else
|
2020-03-09 09:09:54 -07:00
|
|
|
return {EType::ZeroIncreasing, 0.f};
|
2016-04-10 20:59:54 -07:00
|
|
|
}
|
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
CCharAnimTime CCharAnimTime::operator*(const float& other) const {
|
|
|
|
if (other == 0.f)
|
2020-03-09 09:09:54 -07:00
|
|
|
return {};
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
if (!EqualsZero())
|
2020-03-09 09:09:54 -07:00
|
|
|
return {x0_time * other};
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
if (other > 0.f)
|
|
|
|
return *this;
|
|
|
|
|
2020-03-09 09:09:54 -07:00
|
|
|
if (x4_type == EType::ZeroDecreasing) {
|
|
|
|
return {EType::ZeroIncreasing, 0.f};
|
|
|
|
} else if (x4_type == EType::ZeroSteady) {
|
|
|
|
return {EType::ZeroSteady, 0.f};
|
|
|
|
} else {
|
|
|
|
return {EType::ZeroDecreasing, 0.f};
|
|
|
|
}
|
2016-04-10 20:59:54 -07:00
|
|
|
}
|
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
float CCharAnimTime::operator/(const CCharAnimTime& other) const {
|
|
|
|
if (other.EqualsZero())
|
|
|
|
return 0.f;
|
2016-04-10 20:59:54 -07:00
|
|
|
|
2018-12-07 21:30:43 -08:00
|
|
|
return x0_time / other.x0_time;
|
2016-04-10 20:59:54 -07:00
|
|
|
}
|
|
|
|
|
2021-04-10 01:42:06 -07:00
|
|
|
} // namespace metaforce
|