Merge pull request #65325 from TokageItLab/refactor-variant-for-anim
Move some static methods to `Animation` from `Variant` for refactoring `Animation` and `Tween`
This commit is contained in:
commit
a981a8061f
@ -251,27 +251,6 @@ static GDNativeBool gdnative_variant_booleanize(const GDNativeVariantPtr p_self)
|
|||||||
return self->booleanize();
|
return self->booleanize();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gdnative_variant_sub(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, GDNativeVariantPtr r_dst) {
|
|
||||||
const Variant *a = (const Variant *)p_a;
|
|
||||||
const Variant *b = (const Variant *)p_b;
|
|
||||||
memnew_placement(r_dst, Variant);
|
|
||||||
Variant::sub(*a, *b, *(Variant *)r_dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gdnative_variant_blend(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, float p_c, GDNativeVariantPtr r_dst) {
|
|
||||||
const Variant *a = (const Variant *)p_a;
|
|
||||||
const Variant *b = (const Variant *)p_b;
|
|
||||||
memnew_placement(r_dst, Variant);
|
|
||||||
Variant::blend(*a, *b, p_c, *(Variant *)r_dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gdnative_variant_interpolate(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, float p_c, GDNativeVariantPtr r_dst) {
|
|
||||||
const Variant *a = (const Variant *)p_a;
|
|
||||||
const Variant *b = (const Variant *)p_b;
|
|
||||||
memnew_placement(r_dst, Variant);
|
|
||||||
Variant::interpolate(*a, *b, p_c, *(Variant *)r_dst);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gdnative_variant_duplicate(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_ret, GDNativeBool p_deep) {
|
static void gdnative_variant_duplicate(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_ret, GDNativeBool p_deep) {
|
||||||
const Variant *self = (const Variant *)p_self;
|
const Variant *self = (const Variant *)p_self;
|
||||||
memnew_placement(r_ret, Variant(self->duplicate(p_deep)));
|
memnew_placement(r_ret, Variant(self->duplicate(p_deep)));
|
||||||
@ -970,9 +949,6 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
|
|||||||
gdni.variant_recursive_hash = gdnative_variant_recursive_hash;
|
gdni.variant_recursive_hash = gdnative_variant_recursive_hash;
|
||||||
gdni.variant_hash_compare = gdnative_variant_hash_compare;
|
gdni.variant_hash_compare = gdnative_variant_hash_compare;
|
||||||
gdni.variant_booleanize = gdnative_variant_booleanize;
|
gdni.variant_booleanize = gdnative_variant_booleanize;
|
||||||
gdni.variant_sub = gdnative_variant_sub;
|
|
||||||
gdni.variant_blend = gdnative_variant_blend;
|
|
||||||
gdni.variant_interpolate = gdnative_variant_interpolate;
|
|
||||||
gdni.variant_duplicate = gdnative_variant_duplicate;
|
gdni.variant_duplicate = gdnative_variant_duplicate;
|
||||||
gdni.variant_stringify = gdnative_variant_stringify;
|
gdni.variant_stringify = gdnative_variant_stringify;
|
||||||
|
|
||||||
|
@ -427,9 +427,6 @@ typedef struct {
|
|||||||
GDNativeInt (*variant_recursive_hash)(const GDNativeVariantPtr p_self, GDNativeInt p_recursion_count);
|
GDNativeInt (*variant_recursive_hash)(const GDNativeVariantPtr p_self, GDNativeInt p_recursion_count);
|
||||||
GDNativeBool (*variant_hash_compare)(const GDNativeVariantPtr p_self, const GDNativeVariantPtr p_other);
|
GDNativeBool (*variant_hash_compare)(const GDNativeVariantPtr p_self, const GDNativeVariantPtr p_other);
|
||||||
GDNativeBool (*variant_booleanize)(const GDNativeVariantPtr p_self);
|
GDNativeBool (*variant_booleanize)(const GDNativeVariantPtr p_self);
|
||||||
void (*variant_sub)(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, GDNativeVariantPtr r_dst);
|
|
||||||
void (*variant_blend)(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, float p_c, GDNativeVariantPtr r_dst);
|
|
||||||
void (*variant_interpolate)(const GDNativeVariantPtr p_a, const GDNativeVariantPtr p_b, float p_c, GDNativeVariantPtr r_dst);
|
|
||||||
void (*variant_duplicate)(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_ret, GDNativeBool p_deep);
|
void (*variant_duplicate)(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_ret, GDNativeBool p_deep);
|
||||||
void (*variant_stringify)(const GDNativeVariantPtr p_self, GDNativeStringPtr r_ret);
|
void (*variant_stringify)(const GDNativeVariantPtr p_self, GDNativeStringPtr r_ret);
|
||||||
|
|
||||||
|
@ -552,9 +552,6 @@ public:
|
|||||||
void zero();
|
void zero();
|
||||||
Variant duplicate(bool p_deep = false) const;
|
Variant duplicate(bool p_deep = false) const;
|
||||||
Variant recursive_duplicate(bool p_deep, int recursion_count) const;
|
Variant recursive_duplicate(bool p_deep, int recursion_count) const;
|
||||||
static void blend(const Variant &a, const Variant &b, float c, Variant &r_dst);
|
|
||||||
static void interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst);
|
|
||||||
static void sub(const Variant &a, const Variant &b, Variant &r_dst);
|
|
||||||
|
|
||||||
/* Built-In Methods */
|
/* Built-In Methods */
|
||||||
|
|
||||||
|
@ -1911,572 +1911,6 @@ Variant Variant::recursive_duplicate(bool p_deep, int recursion_count) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Variant::sub(const Variant &a, const Variant &b, Variant &r_dst) {
|
|
||||||
if (a.type != b.type) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (a.type) {
|
|
||||||
case NIL: {
|
|
||||||
r_dst = Variant();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case INT: {
|
|
||||||
int64_t va = a._data._int;
|
|
||||||
int64_t vb = b._data._int;
|
|
||||||
r_dst = int(va - vb);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case FLOAT: {
|
|
||||||
double ra = a._data._float;
|
|
||||||
double rb = b._data._float;
|
|
||||||
r_dst = ra - rb;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case VECTOR2: {
|
|
||||||
r_dst = *reinterpret_cast<const Vector2 *>(a._data._mem) - *reinterpret_cast<const Vector2 *>(b._data._mem);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case VECTOR2I: {
|
|
||||||
int32_t vax = reinterpret_cast<const Vector2i *>(a._data._mem)->x;
|
|
||||||
int32_t vbx = reinterpret_cast<const Vector2i *>(b._data._mem)->x;
|
|
||||||
int32_t vay = reinterpret_cast<const Vector2i *>(a._data._mem)->y;
|
|
||||||
int32_t vby = reinterpret_cast<const Vector2i *>(b._data._mem)->y;
|
|
||||||
r_dst = Vector2i(int32_t(vax - vbx), int32_t(vay - vby));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case RECT2: {
|
|
||||||
const Rect2 *ra = reinterpret_cast<const Rect2 *>(a._data._mem);
|
|
||||||
const Rect2 *rb = reinterpret_cast<const Rect2 *>(b._data._mem);
|
|
||||||
r_dst = Rect2(ra->position - rb->position, ra->size - rb->size);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case RECT2I: {
|
|
||||||
const Rect2i *ra = reinterpret_cast<const Rect2i *>(a._data._mem);
|
|
||||||
const Rect2i *rb = reinterpret_cast<const Rect2i *>(b._data._mem);
|
|
||||||
|
|
||||||
int32_t vax = ra->position.x;
|
|
||||||
int32_t vay = ra->position.y;
|
|
||||||
int32_t vbx = ra->size.x;
|
|
||||||
int32_t vby = ra->size.y;
|
|
||||||
int32_t vcx = rb->position.x;
|
|
||||||
int32_t vcy = rb->position.y;
|
|
||||||
int32_t vdx = rb->size.x;
|
|
||||||
int32_t vdy = rb->size.y;
|
|
||||||
|
|
||||||
r_dst = Rect2i(int32_t(vax - vbx), int32_t(vay - vby), int32_t(vcx - vdx), int32_t(vcy - vdy));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case VECTOR3: {
|
|
||||||
r_dst = *reinterpret_cast<const Vector3 *>(a._data._mem) - *reinterpret_cast<const Vector3 *>(b._data._mem);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case VECTOR3I: {
|
|
||||||
int32_t vax = reinterpret_cast<const Vector3i *>(a._data._mem)->x;
|
|
||||||
int32_t vbx = reinterpret_cast<const Vector3i *>(b._data._mem)->x;
|
|
||||||
int32_t vay = reinterpret_cast<const Vector3i *>(a._data._mem)->y;
|
|
||||||
int32_t vby = reinterpret_cast<const Vector3i *>(b._data._mem)->y;
|
|
||||||
int32_t vaz = reinterpret_cast<const Vector3i *>(a._data._mem)->z;
|
|
||||||
int32_t vbz = reinterpret_cast<const Vector3i *>(b._data._mem)->z;
|
|
||||||
r_dst = Vector3i(int32_t(vax - vbx), int32_t(vay - vby), int32_t(vaz - vbz));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case AABB: {
|
|
||||||
const ::AABB *ra = reinterpret_cast<const ::AABB *>(a._data._mem);
|
|
||||||
const ::AABB *rb = reinterpret_cast<const ::AABB *>(b._data._mem);
|
|
||||||
r_dst = ::AABB(ra->position - rb->position, ra->size - rb->size);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case QUATERNION: {
|
|
||||||
Quaternion empty_rot;
|
|
||||||
const Quaternion *qa = reinterpret_cast<const Quaternion *>(a._data._mem);
|
|
||||||
const Quaternion *qb = reinterpret_cast<const Quaternion *>(b._data._mem);
|
|
||||||
r_dst = (*qb).inverse() * *qa;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case COLOR: {
|
|
||||||
const Color *ca = reinterpret_cast<const Color *>(a._data._mem);
|
|
||||||
const Color *cb = reinterpret_cast<const Color *>(b._data._mem);
|
|
||||||
float new_r = ca->r - cb->r;
|
|
||||||
float new_g = ca->g - cb->g;
|
|
||||||
float new_b = ca->b - cb->b;
|
|
||||||
float new_a = ca->a - cb->a;
|
|
||||||
new_r = new_r > 1.0 ? 1.0 : new_r;
|
|
||||||
new_g = new_g > 1.0 ? 1.0 : new_g;
|
|
||||||
new_b = new_b > 1.0 ? 1.0 : new_b;
|
|
||||||
new_a = new_a > 1.0 ? 1.0 : new_a;
|
|
||||||
r_dst = Color(new_r, new_g, new_b, new_a);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
default: {
|
|
||||||
r_dst = a;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) {
|
|
||||||
if (a.type != b.type) {
|
|
||||||
if (a.is_num() && b.is_num()) {
|
|
||||||
real_t va = a;
|
|
||||||
real_t vb = b;
|
|
||||||
r_dst = va + vb * c;
|
|
||||||
} else {
|
|
||||||
r_dst = a;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (a.type) {
|
|
||||||
case NIL: {
|
|
||||||
r_dst = Variant();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case INT: {
|
|
||||||
int64_t va = a._data._int;
|
|
||||||
int64_t vb = b._data._int;
|
|
||||||
r_dst = int(va + vb * c + 0.5);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case FLOAT: {
|
|
||||||
double ra = a._data._float;
|
|
||||||
double rb = b._data._float;
|
|
||||||
r_dst = ra + rb * c;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case VECTOR2: {
|
|
||||||
r_dst = *reinterpret_cast<const Vector2 *>(a._data._mem) + *reinterpret_cast<const Vector2 *>(b._data._mem) * c;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case VECTOR2I: {
|
|
||||||
int32_t vax = reinterpret_cast<const Vector2i *>(a._data._mem)->x;
|
|
||||||
int32_t vbx = reinterpret_cast<const Vector2i *>(b._data._mem)->x;
|
|
||||||
int32_t vay = reinterpret_cast<const Vector2i *>(a._data._mem)->y;
|
|
||||||
int32_t vby = reinterpret_cast<const Vector2i *>(b._data._mem)->y;
|
|
||||||
r_dst = Vector2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case RECT2: {
|
|
||||||
const Rect2 *ra = reinterpret_cast<const Rect2 *>(a._data._mem);
|
|
||||||
const Rect2 *rb = reinterpret_cast<const Rect2 *>(b._data._mem);
|
|
||||||
r_dst = Rect2(ra->position + rb->position * c, ra->size + rb->size * c);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case RECT2I: {
|
|
||||||
const Rect2i *ra = reinterpret_cast<const Rect2i *>(a._data._mem);
|
|
||||||
const Rect2i *rb = reinterpret_cast<const Rect2i *>(b._data._mem);
|
|
||||||
|
|
||||||
int32_t vax = ra->position.x;
|
|
||||||
int32_t vay = ra->position.y;
|
|
||||||
int32_t vbx = ra->size.x;
|
|
||||||
int32_t vby = ra->size.y;
|
|
||||||
int32_t vcx = rb->position.x;
|
|
||||||
int32_t vcy = rb->position.y;
|
|
||||||
int32_t vdx = rb->size.x;
|
|
||||||
int32_t vdy = rb->size.y;
|
|
||||||
|
|
||||||
r_dst = Rect2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vcx + vdx * c + 0.5), int32_t(vcy + vdy * c + 0.5));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case VECTOR3: {
|
|
||||||
r_dst = *reinterpret_cast<const Vector3 *>(a._data._mem) + *reinterpret_cast<const Vector3 *>(b._data._mem) * c;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case VECTOR3I: {
|
|
||||||
int32_t vax = reinterpret_cast<const Vector3i *>(a._data._mem)->x;
|
|
||||||
int32_t vbx = reinterpret_cast<const Vector3i *>(b._data._mem)->x;
|
|
||||||
int32_t vay = reinterpret_cast<const Vector3i *>(a._data._mem)->y;
|
|
||||||
int32_t vby = reinterpret_cast<const Vector3i *>(b._data._mem)->y;
|
|
||||||
int32_t vaz = reinterpret_cast<const Vector3i *>(a._data._mem)->z;
|
|
||||||
int32_t vbz = reinterpret_cast<const Vector3i *>(b._data._mem)->z;
|
|
||||||
r_dst = Vector3i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vaz + vbz * c + 0.5));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case AABB: {
|
|
||||||
const ::AABB *ra = reinterpret_cast<const ::AABB *>(a._data._mem);
|
|
||||||
const ::AABB *rb = reinterpret_cast<const ::AABB *>(b._data._mem);
|
|
||||||
r_dst = ::AABB(ra->position + rb->position * c, ra->size + rb->size * c);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case QUATERNION: {
|
|
||||||
Quaternion empty_rot;
|
|
||||||
const Quaternion *qa = reinterpret_cast<const Quaternion *>(a._data._mem);
|
|
||||||
const Quaternion *qb = reinterpret_cast<const Quaternion *>(b._data._mem);
|
|
||||||
r_dst = *qa * empty_rot.slerp(*qb, c);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case COLOR: {
|
|
||||||
const Color *ca = reinterpret_cast<const Color *>(a._data._mem);
|
|
||||||
const Color *cb = reinterpret_cast<const Color *>(b._data._mem);
|
|
||||||
float new_r = ca->r + cb->r * c;
|
|
||||||
float new_g = ca->g + cb->g * c;
|
|
||||||
float new_b = ca->b + cb->b * c;
|
|
||||||
float new_a = ca->a + cb->a * c;
|
|
||||||
new_r = new_r > 1.0 ? 1.0 : new_r;
|
|
||||||
new_g = new_g > 1.0 ? 1.0 : new_g;
|
|
||||||
new_b = new_b > 1.0 ? 1.0 : new_b;
|
|
||||||
new_a = new_a > 1.0 ? 1.0 : new_a;
|
|
||||||
r_dst = Color(new_r, new_g, new_b, new_a);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
default: {
|
|
||||||
r_dst = c < 0.5 ? a : b;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst) {
|
|
||||||
if (a.type != b.type) {
|
|
||||||
if (a.is_num() && b.is_num()) {
|
|
||||||
//not as efficient but..
|
|
||||||
real_t va = a;
|
|
||||||
real_t vb = b;
|
|
||||||
r_dst = va + (vb - va) * c;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
r_dst = a;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (a.type) {
|
|
||||||
case NIL: {
|
|
||||||
r_dst = Variant();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case BOOL: {
|
|
||||||
r_dst = a;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case INT: {
|
|
||||||
int64_t va = a._data._int;
|
|
||||||
int64_t vb = b._data._int;
|
|
||||||
r_dst = int(va + (vb - va) * c);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case FLOAT: {
|
|
||||||
real_t va = a._data._float;
|
|
||||||
real_t vb = b._data._float;
|
|
||||||
r_dst = va + (vb - va) * c;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case STRING: {
|
|
||||||
//this is pretty funny and bizarre, but artists like to use it for typewriter effects
|
|
||||||
String sa = *reinterpret_cast<const String *>(a._data._mem);
|
|
||||||
String sb = *reinterpret_cast<const String *>(b._data._mem);
|
|
||||||
String dst;
|
|
||||||
int sa_len = sa.length();
|
|
||||||
int sb_len = sb.length();
|
|
||||||
int csize = sa_len + (sb_len - sa_len) * c;
|
|
||||||
if (csize == 0) {
|
|
||||||
r_dst = "";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dst.resize(csize + 1);
|
|
||||||
dst[csize] = 0;
|
|
||||||
int split = csize / 2;
|
|
||||||
|
|
||||||
for (int i = 0; i < csize; i++) {
|
|
||||||
char32_t chr = ' ';
|
|
||||||
|
|
||||||
if (i < split) {
|
|
||||||
if (i < sa.length()) {
|
|
||||||
chr = sa[i];
|
|
||||||
} else if (i < sb.length()) {
|
|
||||||
chr = sb[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (i < sb.length()) {
|
|
||||||
chr = sb[i];
|
|
||||||
} else if (i < sa.length()) {
|
|
||||||
chr = sa[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dst[i] = chr;
|
|
||||||
}
|
|
||||||
|
|
||||||
r_dst = dst;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case VECTOR2: {
|
|
||||||
r_dst = reinterpret_cast<const Vector2 *>(a._data._mem)->lerp(*reinterpret_cast<const Vector2 *>(b._data._mem), c);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case VECTOR2I: {
|
|
||||||
int32_t vax = reinterpret_cast<const Vector2i *>(a._data._mem)->x;
|
|
||||||
int32_t vbx = reinterpret_cast<const Vector2i *>(b._data._mem)->x;
|
|
||||||
int32_t vay = reinterpret_cast<const Vector2i *>(a._data._mem)->y;
|
|
||||||
int32_t vby = reinterpret_cast<const Vector2i *>(b._data._mem)->y;
|
|
||||||
r_dst = Vector2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
case RECT2: {
|
|
||||||
r_dst = Rect2(reinterpret_cast<const Rect2 *>(a._data._mem)->position.lerp(reinterpret_cast<const Rect2 *>(b._data._mem)->position, c), reinterpret_cast<const Rect2 *>(a._data._mem)->size.lerp(reinterpret_cast<const Rect2 *>(b._data._mem)->size, c));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case RECT2I: {
|
|
||||||
const Rect2i *ra = reinterpret_cast<const Rect2i *>(a._data._mem);
|
|
||||||
const Rect2i *rb = reinterpret_cast<const Rect2i *>(b._data._mem);
|
|
||||||
|
|
||||||
int32_t vax = ra->position.x;
|
|
||||||
int32_t vay = ra->position.y;
|
|
||||||
int32_t vbx = ra->size.x;
|
|
||||||
int32_t vby = ra->size.y;
|
|
||||||
int32_t vcx = rb->position.x;
|
|
||||||
int32_t vcy = rb->position.y;
|
|
||||||
int32_t vdx = rb->size.x;
|
|
||||||
int32_t vdy = rb->size.y;
|
|
||||||
|
|
||||||
r_dst = Rect2i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vcx + vdx * c + 0.5), int32_t(vcy + vdy * c + 0.5));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
case VECTOR3: {
|
|
||||||
r_dst = reinterpret_cast<const Vector3 *>(a._data._mem)->lerp(*reinterpret_cast<const Vector3 *>(b._data._mem), c);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case VECTOR3I: {
|
|
||||||
int32_t vax = reinterpret_cast<const Vector3i *>(a._data._mem)->x;
|
|
||||||
int32_t vbx = reinterpret_cast<const Vector3i *>(b._data._mem)->x;
|
|
||||||
int32_t vay = reinterpret_cast<const Vector3i *>(a._data._mem)->y;
|
|
||||||
int32_t vby = reinterpret_cast<const Vector3i *>(b._data._mem)->y;
|
|
||||||
int32_t vaz = reinterpret_cast<const Vector3i *>(a._data._mem)->z;
|
|
||||||
int32_t vbz = reinterpret_cast<const Vector3i *>(b._data._mem)->z;
|
|
||||||
r_dst = Vector3i(int32_t(vax + vbx * c + 0.5), int32_t(vay + vby * c + 0.5), int32_t(vaz + vbz * c + 0.5));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
case TRANSFORM2D: {
|
|
||||||
r_dst = a._data._transform2d->interpolate_with(*b._data._transform2d, c);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case PLANE: {
|
|
||||||
r_dst = a;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case QUATERNION: {
|
|
||||||
r_dst = reinterpret_cast<const Quaternion *>(a._data._mem)->slerp(*reinterpret_cast<const Quaternion *>(b._data._mem), c);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case AABB: {
|
|
||||||
r_dst = ::AABB(a._data._aabb->position.lerp(b._data._aabb->position, c), a._data._aabb->size.lerp(b._data._aabb->size, c));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case BASIS: {
|
|
||||||
r_dst = a._data._basis->lerp(*b._data._basis, c);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case TRANSFORM3D: {
|
|
||||||
r_dst = a._data._transform3d->interpolate_with(*b._data._transform3d, c);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case COLOR: {
|
|
||||||
r_dst = reinterpret_cast<const Color *>(a._data._mem)->lerp(*reinterpret_cast<const Color *>(b._data._mem), c);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case STRING_NAME: {
|
|
||||||
r_dst = a;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case NODE_PATH: {
|
|
||||||
r_dst = a;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case RID: {
|
|
||||||
r_dst = a;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case OBJECT: {
|
|
||||||
r_dst = a;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case DICTIONARY: {
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case ARRAY: {
|
|
||||||
r_dst = a;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case PACKED_BYTE_ARRAY: {
|
|
||||||
r_dst = a;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case PACKED_INT32_ARRAY: {
|
|
||||||
const Vector<int32_t> *arr_a = &PackedArrayRef<int32_t>::get_array(a._data.packed_array);
|
|
||||||
const Vector<int32_t> *arr_b = &PackedArrayRef<int32_t>::get_array(b._data.packed_array);
|
|
||||||
int32_t sz = arr_a->size();
|
|
||||||
if (sz == 0 || arr_b->size() != sz) {
|
|
||||||
r_dst = a;
|
|
||||||
} else {
|
|
||||||
Vector<int32_t> v;
|
|
||||||
v.resize(sz);
|
|
||||||
{
|
|
||||||
int32_t *vw = v.ptrw();
|
|
||||||
const int32_t *ar = arr_a->ptr();
|
|
||||||
const int32_t *br = arr_b->ptr();
|
|
||||||
|
|
||||||
Variant va;
|
|
||||||
for (int32_t i = 0; i < sz; i++) {
|
|
||||||
Variant::interpolate(ar[i], br[i], c, va);
|
|
||||||
vw[i] = va;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r_dst = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case PACKED_INT64_ARRAY: {
|
|
||||||
const Vector<int64_t> *arr_a = &PackedArrayRef<int64_t>::get_array(a._data.packed_array);
|
|
||||||
const Vector<int64_t> *arr_b = &PackedArrayRef<int64_t>::get_array(b._data.packed_array);
|
|
||||||
int64_t sz = arr_a->size();
|
|
||||||
if (sz == 0 || arr_b->size() != sz) {
|
|
||||||
r_dst = a;
|
|
||||||
} else {
|
|
||||||
Vector<int64_t> v;
|
|
||||||
v.resize(sz);
|
|
||||||
{
|
|
||||||
int64_t *vw = v.ptrw();
|
|
||||||
const int64_t *ar = arr_a->ptr();
|
|
||||||
const int64_t *br = arr_b->ptr();
|
|
||||||
|
|
||||||
Variant va;
|
|
||||||
for (int64_t i = 0; i < sz; i++) {
|
|
||||||
Variant::interpolate(ar[i], br[i], c, va);
|
|
||||||
vw[i] = va;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r_dst = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case PACKED_FLOAT32_ARRAY: {
|
|
||||||
const Vector<float> *arr_a = &PackedArrayRef<float>::get_array(a._data.packed_array);
|
|
||||||
const Vector<float> *arr_b = &PackedArrayRef<float>::get_array(b._data.packed_array);
|
|
||||||
int sz = arr_a->size();
|
|
||||||
if (sz == 0 || arr_b->size() != sz) {
|
|
||||||
r_dst = a;
|
|
||||||
} else {
|
|
||||||
Vector<float> v;
|
|
||||||
v.resize(sz);
|
|
||||||
{
|
|
||||||
float *vw = v.ptrw();
|
|
||||||
const float *ar = arr_a->ptr();
|
|
||||||
const float *br = arr_b->ptr();
|
|
||||||
|
|
||||||
Variant va;
|
|
||||||
for (int i = 0; i < sz; i++) {
|
|
||||||
Variant::interpolate(ar[i], br[i], c, va);
|
|
||||||
vw[i] = va;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r_dst = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case PACKED_FLOAT64_ARRAY: {
|
|
||||||
const Vector<double> *arr_a = &PackedArrayRef<double>::get_array(a._data.packed_array);
|
|
||||||
const Vector<double> *arr_b = &PackedArrayRef<double>::get_array(b._data.packed_array);
|
|
||||||
int sz = arr_a->size();
|
|
||||||
if (sz == 0 || arr_b->size() != sz) {
|
|
||||||
r_dst = a;
|
|
||||||
} else {
|
|
||||||
Vector<double> v;
|
|
||||||
v.resize(sz);
|
|
||||||
{
|
|
||||||
double *vw = v.ptrw();
|
|
||||||
const double *ar = arr_a->ptr();
|
|
||||||
const double *br = arr_b->ptr();
|
|
||||||
|
|
||||||
Variant va;
|
|
||||||
for (int i = 0; i < sz; i++) {
|
|
||||||
Variant::interpolate(ar[i], br[i], c, va);
|
|
||||||
vw[i] = va;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r_dst = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case PACKED_STRING_ARRAY: {
|
|
||||||
r_dst = a;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case PACKED_VECTOR2_ARRAY: {
|
|
||||||
const Vector<Vector2> *arr_a = &PackedArrayRef<Vector2>::get_array(a._data.packed_array);
|
|
||||||
const Vector<Vector2> *arr_b = &PackedArrayRef<Vector2>::get_array(b._data.packed_array);
|
|
||||||
int sz = arr_a->size();
|
|
||||||
if (sz == 0 || arr_b->size() != sz) {
|
|
||||||
r_dst = a;
|
|
||||||
} else {
|
|
||||||
Vector<Vector2> v;
|
|
||||||
v.resize(sz);
|
|
||||||
{
|
|
||||||
Vector2 *vw = v.ptrw();
|
|
||||||
const Vector2 *ar = arr_a->ptr();
|
|
||||||
const Vector2 *br = arr_b->ptr();
|
|
||||||
|
|
||||||
for (int i = 0; i < sz; i++) {
|
|
||||||
vw[i] = ar[i].lerp(br[i], c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r_dst = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case PACKED_VECTOR3_ARRAY: {
|
|
||||||
const Vector<Vector3> *arr_a = &PackedArrayRef<Vector3>::get_array(a._data.packed_array);
|
|
||||||
const Vector<Vector3> *arr_b = &PackedArrayRef<Vector3>::get_array(b._data.packed_array);
|
|
||||||
int sz = arr_a->size();
|
|
||||||
if (sz == 0 || arr_b->size() != sz) {
|
|
||||||
r_dst = a;
|
|
||||||
} else {
|
|
||||||
Vector<Vector3> v;
|
|
||||||
v.resize(sz);
|
|
||||||
{
|
|
||||||
Vector3 *vw = v.ptrw();
|
|
||||||
const Vector3 *ar = arr_a->ptr();
|
|
||||||
const Vector3 *br = arr_b->ptr();
|
|
||||||
|
|
||||||
for (int i = 0; i < sz; i++) {
|
|
||||||
vw[i] = ar[i].lerp(br[i], c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r_dst = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case PACKED_COLOR_ARRAY: {
|
|
||||||
const Vector<Color> *arr_a = &PackedArrayRef<Color>::get_array(a._data.packed_array);
|
|
||||||
const Vector<Color> *arr_b = &PackedArrayRef<Color>::get_array(b._data.packed_array);
|
|
||||||
int sz = arr_a->size();
|
|
||||||
if (sz == 0 || arr_b->size() != sz) {
|
|
||||||
r_dst = a;
|
|
||||||
} else {
|
|
||||||
Vector<Color> v;
|
|
||||||
v.resize(sz);
|
|
||||||
{
|
|
||||||
Color *vw = v.ptrw();
|
|
||||||
const Color *ar = arr_a->ptr();
|
|
||||||
const Color *br = arr_b->ptr();
|
|
||||||
|
|
||||||
for (int i = 0; i < sz; i++) {
|
|
||||||
vw[i] = ar[i].lerp(br[i], c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r_dst = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
default: {
|
|
||||||
r_dst = a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Variant::_register_variant_setters_getters() {
|
void Variant::_register_variant_setters_getters() {
|
||||||
register_named_setters_getters();
|
register_named_setters_getters();
|
||||||
register_indexed_setters_getters();
|
register_indexed_setters_getters();
|
||||||
|
@ -6050,10 +6050,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
|
|||||||
real_t to_diff = fmod(b - a, Math_TAU);
|
real_t to_diff = fmod(b - a, Math_TAU);
|
||||||
to_v = a + fmod(2.0 * to_diff, Math_TAU) - to_diff;
|
to_v = a + fmod(2.0 * to_diff, Math_TAU) - to_diff;
|
||||||
}
|
}
|
||||||
Variant delta_v;
|
Variant delta_v = Animation::subtract_variant(to_v, from_v);
|
||||||
Variant::sub(to_v, from_v, delta_v);
|
|
||||||
double duration = to_t - from_t;
|
double duration = to_t - from_t;
|
||||||
double fixed_duration = duration - 0.01; // Prevent to overwrap keys...
|
double fixed_duration = duration - UNIT_EPSILON; // Prevent to overwrap keys...
|
||||||
for (double delta_t = dur_step; delta_t < fixed_duration; delta_t += dur_step) {
|
for (double delta_t = dur_step; delta_t < fixed_duration; delta_t += dur_step) {
|
||||||
Pair<real_t, Variant> keydata;
|
Pair<real_t, Variant> keydata;
|
||||||
keydata.first = from_t + delta_t;
|
keydata.first = from_t + delta_t;
|
||||||
|
@ -650,15 +650,14 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
|
|||||||
double c = Math::ease(p_time / first_key_time, transition);
|
double c = Math::ease(p_time / first_key_time, transition);
|
||||||
Variant first_value = a->track_get_key_value(i, first_key);
|
Variant first_value = a->track_get_key_value(i, first_key);
|
||||||
first_value = _post_process_key_value(a, i, first_value, nc->node);
|
first_value = _post_process_key_value(a, i, first_value, nc->node);
|
||||||
Variant interp_value;
|
Variant interp_value = Animation::interpolate_variant(pa->capture, first_value, c);
|
||||||
Variant::interpolate(pa->capture, first_value, c, interp_value);
|
|
||||||
if (pa->accum_pass != accum_pass) {
|
if (pa->accum_pass != accum_pass) {
|
||||||
ERR_CONTINUE(cache_update_prop_size >= NODE_CACHE_UPDATE_MAX);
|
ERR_CONTINUE(cache_update_prop_size >= NODE_CACHE_UPDATE_MAX);
|
||||||
cache_update_prop[cache_update_prop_size++] = pa;
|
cache_update_prop[cache_update_prop_size++] = pa;
|
||||||
pa->value_accum = interp_value;
|
pa->value_accum = interp_value;
|
||||||
pa->accum_pass = accum_pass;
|
pa->accum_pass = accum_pass;
|
||||||
} else {
|
} else {
|
||||||
Variant::interpolate(pa->value_accum, interp_value, p_interp, pa->value_accum);
|
pa->value_accum = Animation::interpolate_variant(pa->value_accum, interp_value, p_interp);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue; //handled
|
continue; //handled
|
||||||
@ -679,7 +678,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
|
|||||||
pa->value_accum = value;
|
pa->value_accum = value;
|
||||||
pa->accum_pass = accum_pass;
|
pa->accum_pass = accum_pass;
|
||||||
} else {
|
} else {
|
||||||
Variant::interpolate(pa->value_accum, value, p_interp, pa->value_accum);
|
pa->value_accum = Animation::interpolate_variant(pa->value_accum, value, p_interp);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (p_is_current && p_delta != 0) {
|
} else if (p_is_current && p_delta != 0) {
|
||||||
|
@ -1383,8 +1383,13 @@ void AnimationTree::_process_graph(double p_delta) {
|
|||||||
}
|
}
|
||||||
t->value = Math::fposmod(rot_a + (rot_b - rot_init) * (float)blend, (float)Math_TAU);
|
t->value = Math::fposmod(rot_a + (rot_b - rot_init) * (float)blend, (float)Math_TAU);
|
||||||
} else {
|
} else {
|
||||||
Variant::sub(value, t->init_value, value);
|
if (t->init_value.get_type() == Variant::BOOL) {
|
||||||
Variant::blend(t->value, value, blend, t->value);
|
value = Animation::subtract_variant(value.operator real_t(), t->init_value.operator real_t());
|
||||||
|
t->value = Animation::blend_variant(t->value.operator real_t(), value.operator real_t(), blend);
|
||||||
|
} else {
|
||||||
|
value = Animation::subtract_variant(value, t->init_value);
|
||||||
|
t->value = Animation::blend_variant(t->value, value, blend);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (blend < CMP_EPSILON) {
|
if (blend < CMP_EPSILON) {
|
||||||
@ -1703,7 +1708,11 @@ void AnimationTree::_process_graph(double p_delta) {
|
|||||||
case Animation::TYPE_VALUE: {
|
case Animation::TYPE_VALUE: {
|
||||||
TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
|
TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
|
||||||
|
|
||||||
t->object->set_indexed(t->subpath, t->value);
|
if (t->init_value.get_type() == Variant::BOOL) {
|
||||||
|
t->object->set_indexed(t->subpath, t->value.operator real_t() >= 0.5);
|
||||||
|
} else {
|
||||||
|
t->object->set_indexed(t->subpath, t->value);
|
||||||
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case Animation::TYPE_BEZIER: {
|
case Animation::TYPE_BEZIER: {
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include "scene/animation/easing_equations.h"
|
#include "scene/animation/easing_equations.h"
|
||||||
#include "scene/main/node.h"
|
#include "scene/main/node.h"
|
||||||
|
#include "scene/resources/animation.h"
|
||||||
|
|
||||||
Tween::interpolater Tween::interpolaters[Tween::TRANS_MAX][Tween::EASE_MAX] = {
|
Tween::interpolater Tween::interpolaters[Tween::TRANS_MAX][Tween::EASE_MAX] = {
|
||||||
{ &linear::in, &linear::in, &linear::in, &linear::in }, // Linear is the same for each easing.
|
{ &linear::in, &linear::in, &linear::in, &linear::in }, // Linear is the same for each easing.
|
||||||
@ -375,264 +376,14 @@ Variant Tween::interpolate_variant(Variant p_initial_val, Variant p_delta_val, f
|
|||||||
ERR_FAIL_INDEX_V(p_trans, TransitionType::TRANS_MAX, Variant());
|
ERR_FAIL_INDEX_V(p_trans, TransitionType::TRANS_MAX, Variant());
|
||||||
ERR_FAIL_INDEX_V(p_ease, EaseType::EASE_MAX, Variant());
|
ERR_FAIL_INDEX_V(p_ease, EaseType::EASE_MAX, Variant());
|
||||||
|
|
||||||
// Helper macro to run equation on sub-elements of the value (e.g. x and y of Vector2).
|
// Special case for bool.
|
||||||
#define APPLY_EQUATION(element) \
|
if (p_initial_val.get_type() == Variant::BOOL) {
|
||||||
r.element = run_equation(p_trans, p_ease, p_time, i.element, d.element, p_duration);
|
return run_equation(p_trans, p_ease, p_time, p_initial_val, p_delta_val, p_duration) >= 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
switch (p_initial_val.get_type()) {
|
Variant ret = Animation::add_variant(p_initial_val, p_delta_val);
|
||||||
case Variant::BOOL: {
|
ret = Animation::interpolate_variant(p_initial_val, ret, run_equation(p_trans, p_ease, p_time, 0.0, 1.0, p_duration));
|
||||||
return (run_equation(p_trans, p_ease, p_time, p_initial_val, p_delta_val, p_duration)) >= 0.5;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::INT: {
|
|
||||||
return (int)run_equation(p_trans, p_ease, p_time, (int)p_initial_val, (int)p_delta_val, p_duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::FLOAT: {
|
|
||||||
return run_equation(p_trans, p_ease, p_time, (real_t)p_initial_val, (real_t)p_delta_val, p_duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::VECTOR2: {
|
|
||||||
Vector2 i = p_initial_val;
|
|
||||||
Vector2 d = p_delta_val;
|
|
||||||
Vector2 r;
|
|
||||||
|
|
||||||
APPLY_EQUATION(x);
|
|
||||||
APPLY_EQUATION(y);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::VECTOR2I: {
|
|
||||||
Vector2i i = p_initial_val;
|
|
||||||
Vector2i d = p_delta_val;
|
|
||||||
Vector2i r;
|
|
||||||
|
|
||||||
APPLY_EQUATION(x);
|
|
||||||
APPLY_EQUATION(y);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::RECT2: {
|
|
||||||
Rect2 i = p_initial_val;
|
|
||||||
Rect2 d = p_delta_val;
|
|
||||||
Rect2 r;
|
|
||||||
|
|
||||||
APPLY_EQUATION(position.x);
|
|
||||||
APPLY_EQUATION(position.y);
|
|
||||||
APPLY_EQUATION(size.x);
|
|
||||||
APPLY_EQUATION(size.y);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::RECT2I: {
|
|
||||||
Rect2i i = p_initial_val;
|
|
||||||
Rect2i d = p_delta_val;
|
|
||||||
Rect2i r;
|
|
||||||
|
|
||||||
APPLY_EQUATION(position.x);
|
|
||||||
APPLY_EQUATION(position.y);
|
|
||||||
APPLY_EQUATION(size.x);
|
|
||||||
APPLY_EQUATION(size.y);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::VECTOR3: {
|
|
||||||
Vector3 i = p_initial_val;
|
|
||||||
Vector3 d = p_delta_val;
|
|
||||||
Vector3 r;
|
|
||||||
|
|
||||||
APPLY_EQUATION(x);
|
|
||||||
APPLY_EQUATION(y);
|
|
||||||
APPLY_EQUATION(z);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::VECTOR3I: {
|
|
||||||
Vector3i i = p_initial_val;
|
|
||||||
Vector3i d = p_delta_val;
|
|
||||||
Vector3i r;
|
|
||||||
|
|
||||||
APPLY_EQUATION(x);
|
|
||||||
APPLY_EQUATION(y);
|
|
||||||
APPLY_EQUATION(z);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::TRANSFORM2D: {
|
|
||||||
Transform2D i = p_initial_val;
|
|
||||||
Transform2D d = p_delta_val;
|
|
||||||
Transform2D r;
|
|
||||||
|
|
||||||
APPLY_EQUATION(columns[0][0]);
|
|
||||||
APPLY_EQUATION(columns[0][1]);
|
|
||||||
APPLY_EQUATION(columns[1][0]);
|
|
||||||
APPLY_EQUATION(columns[1][1]);
|
|
||||||
APPLY_EQUATION(columns[2][0]);
|
|
||||||
APPLY_EQUATION(columns[2][1]);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
case Variant::VECTOR4: {
|
|
||||||
Vector4 i = p_initial_val;
|
|
||||||
Vector4 d = p_delta_val;
|
|
||||||
Vector4 r;
|
|
||||||
|
|
||||||
APPLY_EQUATION(x);
|
|
||||||
APPLY_EQUATION(y);
|
|
||||||
APPLY_EQUATION(z);
|
|
||||||
APPLY_EQUATION(w);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::QUATERNION: {
|
|
||||||
Quaternion i = p_initial_val;
|
|
||||||
Quaternion d = p_delta_val;
|
|
||||||
Quaternion r = i * d;
|
|
||||||
r = i.slerp(r, run_equation(p_trans, p_ease, p_time, 0.0, 1.0, p_duration));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::AABB: {
|
|
||||||
AABB i = p_initial_val;
|
|
||||||
AABB d = p_delta_val;
|
|
||||||
AABB r;
|
|
||||||
|
|
||||||
APPLY_EQUATION(position.x);
|
|
||||||
APPLY_EQUATION(position.y);
|
|
||||||
APPLY_EQUATION(position.z);
|
|
||||||
APPLY_EQUATION(size.x);
|
|
||||||
APPLY_EQUATION(size.y);
|
|
||||||
APPLY_EQUATION(size.z);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::BASIS: {
|
|
||||||
Basis i = p_initial_val;
|
|
||||||
Basis d = p_delta_val;
|
|
||||||
Basis r;
|
|
||||||
|
|
||||||
APPLY_EQUATION(rows[0][0]);
|
|
||||||
APPLY_EQUATION(rows[0][1]);
|
|
||||||
APPLY_EQUATION(rows[0][2]);
|
|
||||||
APPLY_EQUATION(rows[1][0]);
|
|
||||||
APPLY_EQUATION(rows[1][1]);
|
|
||||||
APPLY_EQUATION(rows[1][2]);
|
|
||||||
APPLY_EQUATION(rows[2][0]);
|
|
||||||
APPLY_EQUATION(rows[2][1]);
|
|
||||||
APPLY_EQUATION(rows[2][2]);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::TRANSFORM3D: {
|
|
||||||
Transform3D i = p_initial_val;
|
|
||||||
Transform3D d = p_delta_val;
|
|
||||||
Transform3D r;
|
|
||||||
|
|
||||||
APPLY_EQUATION(basis.rows[0][0]);
|
|
||||||
APPLY_EQUATION(basis.rows[0][1]);
|
|
||||||
APPLY_EQUATION(basis.rows[0][2]);
|
|
||||||
APPLY_EQUATION(basis.rows[1][0]);
|
|
||||||
APPLY_EQUATION(basis.rows[1][1]);
|
|
||||||
APPLY_EQUATION(basis.rows[1][2]);
|
|
||||||
APPLY_EQUATION(basis.rows[2][0]);
|
|
||||||
APPLY_EQUATION(basis.rows[2][1]);
|
|
||||||
APPLY_EQUATION(basis.rows[2][2]);
|
|
||||||
APPLY_EQUATION(origin.x);
|
|
||||||
APPLY_EQUATION(origin.y);
|
|
||||||
APPLY_EQUATION(origin.z);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::COLOR: {
|
|
||||||
Color i = p_initial_val;
|
|
||||||
Color d = p_delta_val;
|
|
||||||
Color r;
|
|
||||||
|
|
||||||
APPLY_EQUATION(r);
|
|
||||||
APPLY_EQUATION(g);
|
|
||||||
APPLY_EQUATION(b);
|
|
||||||
APPLY_EQUATION(a);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
return p_initial_val;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#undef APPLY_EQUATION
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant Tween::calculate_delta_value(Variant p_intial_val, Variant p_final_val) {
|
|
||||||
ERR_FAIL_COND_V_MSG(p_intial_val.get_type() != p_final_val.get_type(), p_intial_val, "Type mismatch between initial and final value: " + Variant::get_type_name(p_intial_val.get_type()) + " and " + Variant::get_type_name(p_final_val.get_type()));
|
|
||||||
|
|
||||||
switch (p_intial_val.get_type()) {
|
|
||||||
case Variant::BOOL: {
|
|
||||||
return (int)p_final_val - (int)p_intial_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::RECT2: {
|
|
||||||
Rect2 i = p_intial_val;
|
|
||||||
Rect2 f = p_final_val;
|
|
||||||
return Rect2(f.position - i.position, f.size - i.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::RECT2I: {
|
|
||||||
Rect2i i = p_intial_val;
|
|
||||||
Rect2i f = p_final_val;
|
|
||||||
return Rect2i(f.position - i.position, f.size - i.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::TRANSFORM2D: {
|
|
||||||
Transform2D i = p_intial_val;
|
|
||||||
Transform2D f = p_final_val;
|
|
||||||
return Transform2D(f.columns[0][0] - i.columns[0][0],
|
|
||||||
f.columns[0][1] - i.columns[0][1],
|
|
||||||
f.columns[1][0] - i.columns[1][0],
|
|
||||||
f.columns[1][1] - i.columns[1][1],
|
|
||||||
f.columns[2][0] - i.columns[2][0],
|
|
||||||
f.columns[2][1] - i.columns[2][1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::AABB: {
|
|
||||||
AABB i = p_intial_val;
|
|
||||||
AABB f = p_final_val;
|
|
||||||
return AABB(f.position - i.position, f.size - i.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::BASIS: {
|
|
||||||
Basis i = p_intial_val;
|
|
||||||
Basis f = p_final_val;
|
|
||||||
return Basis(f.rows[0][0] - i.rows[0][0],
|
|
||||||
f.rows[0][1] - i.rows[0][1],
|
|
||||||
f.rows[0][2] - i.rows[0][2],
|
|
||||||
f.rows[1][0] - i.rows[1][0],
|
|
||||||
f.rows[1][1] - i.rows[1][1],
|
|
||||||
f.rows[1][2] - i.rows[1][2],
|
|
||||||
f.rows[2][0] - i.rows[2][0],
|
|
||||||
f.rows[2][1] - i.rows[2][1],
|
|
||||||
f.rows[2][2] - i.rows[2][2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
case Variant::TRANSFORM3D: {
|
|
||||||
Transform3D i = p_intial_val;
|
|
||||||
Transform3D f = p_final_val;
|
|
||||||
return Transform3D(f.basis.rows[0][0] - i.basis.rows[0][0],
|
|
||||||
f.basis.rows[0][1] - i.basis.rows[0][1],
|
|
||||||
f.basis.rows[0][2] - i.basis.rows[0][2],
|
|
||||||
f.basis.rows[1][0] - i.basis.rows[1][0],
|
|
||||||
f.basis.rows[1][1] - i.basis.rows[1][1],
|
|
||||||
f.basis.rows[1][2] - i.basis.rows[1][2],
|
|
||||||
f.basis.rows[2][0] - i.basis.rows[2][0],
|
|
||||||
f.basis.rows[2][1] - i.basis.rows[2][1],
|
|
||||||
f.basis.rows[2][2] - i.basis.rows[2][2],
|
|
||||||
f.origin.x - i.origin.x,
|
|
||||||
f.origin.y - i.origin.y,
|
|
||||||
f.origin.z - i.origin.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
return Variant::evaluate(Variant::OP_SUBTRACT, p_final_val, p_intial_val);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tween::_bind_methods() {
|
void Tween::_bind_methods() {
|
||||||
@ -748,10 +499,10 @@ void PropertyTweener::start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (relative) {
|
if (relative) {
|
||||||
final_val = Variant::evaluate(Variant::Operator::OP_ADD, initial_val, base_final_val);
|
final_val = Animation::add_variant(initial_val, base_final_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
delta_val = tween->calculate_delta_value(initial_val, final_val);
|
delta_val = Animation::subtract_variant(final_val, initial_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PropertyTweener::step(float &r_delta) {
|
bool PropertyTweener::step(float &r_delta) {
|
||||||
@ -973,7 +724,7 @@ void MethodTweener::_bind_methods() {
|
|||||||
MethodTweener::MethodTweener(Callable p_callback, Variant p_from, Variant p_to, float p_duration) {
|
MethodTweener::MethodTweener(Callable p_callback, Variant p_from, Variant p_to, float p_duration) {
|
||||||
callback = p_callback;
|
callback = p_callback;
|
||||||
initial_val = p_from;
|
initial_val = p_from;
|
||||||
delta_val = tween->calculate_delta_value(p_from, p_to);
|
delta_val = Animation::subtract_variant(p_to, p_from);
|
||||||
final_val = p_to;
|
final_val = p_to;
|
||||||
duration = p_duration;
|
duration = p_duration;
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,6 @@ public:
|
|||||||
|
|
||||||
static real_t run_equation(TransitionType p_trans_type, EaseType p_ease_type, real_t t, real_t b, real_t c, real_t d);
|
static real_t run_equation(TransitionType p_trans_type, EaseType p_ease_type, real_t t, real_t b, real_t c, real_t d);
|
||||||
static Variant interpolate_variant(Variant p_initial_val, Variant p_delta_val, float p_time, float p_duration, Tween::TransitionType p_trans, Tween::EaseType p_ease);
|
static Variant interpolate_variant(Variant p_initial_val, Variant p_delta_val, float p_time, float p_duration, Tween::TransitionType p_trans, Tween::EaseType p_ease);
|
||||||
Variant calculate_delta_value(Variant p_intial_val, Variant p_final_val);
|
|
||||||
|
|
||||||
bool step(float p_delta);
|
bool step(float p_delta);
|
||||||
bool can_process(bool p_tree_paused) const;
|
bool can_process(bool p_tree_paused) const;
|
||||||
|
@ -2317,9 +2317,7 @@ Quaternion Animation::_interpolate(const Quaternion &p_a, const Quaternion &p_b,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Variant Animation::_interpolate(const Variant &p_a, const Variant &p_b, real_t p_c) const {
|
Variant Animation::_interpolate(const Variant &p_a, const Variant &p_b, real_t p_c) const {
|
||||||
Variant dst;
|
return interpolate_variant(p_a, p_b, p_c);
|
||||||
Variant::interpolate(p_a, p_b, p_c, dst);
|
|
||||||
return dst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
real_t Animation::_interpolate(const real_t &p_a, const real_t &p_b, real_t p_c) const {
|
real_t Animation::_interpolate(const real_t &p_a, const real_t &p_b, real_t p_c) const {
|
||||||
@ -5563,6 +5561,466 @@ bool Animation::_fetch_compressed_by_index(uint32_t p_compressed_track, int p_in
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper math fuctions for Variant.
|
||||||
|
Variant Animation::add_variant(const Variant &a, const Variant &b) {
|
||||||
|
if (a.get_type() != b.get_type()) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (a.get_type()) {
|
||||||
|
case Variant::NIL: {
|
||||||
|
return Variant();
|
||||||
|
}
|
||||||
|
case Variant::BOOL: {
|
||||||
|
return (a.operator real_t()) + (b.operator real_t()); // It is cast for interpolation.
|
||||||
|
}
|
||||||
|
case Variant::RECT2: {
|
||||||
|
const Rect2 ra = a.operator Rect2();
|
||||||
|
const Rect2 rb = b.operator Rect2();
|
||||||
|
return Rect2(ra.position + rb.position, ra.size + rb.size);
|
||||||
|
}
|
||||||
|
case Variant::RECT2I: {
|
||||||
|
const Rect2i ra = a.operator Rect2i();
|
||||||
|
const Rect2i rb = b.operator Rect2i();
|
||||||
|
return Rect2i(ra.position + rb.position, ra.size + rb.size);
|
||||||
|
}
|
||||||
|
case Variant::PLANE: {
|
||||||
|
const Plane pa = a.operator Plane();
|
||||||
|
const Plane pb = b.operator Plane();
|
||||||
|
return Plane(pa.normal + pb.normal, pa.d + pb.d);
|
||||||
|
}
|
||||||
|
case Variant::AABB: {
|
||||||
|
const ::AABB aa = a.operator ::AABB();
|
||||||
|
const ::AABB ab = b.operator ::AABB();
|
||||||
|
return ::AABB(aa.position + ab.position, aa.size + ab.size);
|
||||||
|
}
|
||||||
|
case Variant::QUATERNION: {
|
||||||
|
return (a.operator Quaternion()) * (b.operator Quaternion());
|
||||||
|
}
|
||||||
|
case Variant::TRANSFORM2D: {
|
||||||
|
return (a.operator Transform2D()) * (b.operator Transform2D());
|
||||||
|
}
|
||||||
|
case Variant::TRANSFORM3D: {
|
||||||
|
return (a.operator Transform3D()) * (b.operator Transform3D());
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return Variant::evaluate(Variant::OP_ADD, a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Variant Animation::subtract_variant(const Variant &a, const Variant &b) {
|
||||||
|
if (a.get_type() != b.get_type()) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (a.get_type()) {
|
||||||
|
case Variant::NIL: {
|
||||||
|
return Variant();
|
||||||
|
}
|
||||||
|
case Variant::BOOL: {
|
||||||
|
return (a.operator real_t()) - (b.operator real_t()); // It is cast for interpolation.
|
||||||
|
}
|
||||||
|
case Variant::RECT2: {
|
||||||
|
const Rect2 ra = a.operator Rect2();
|
||||||
|
const Rect2 rb = b.operator Rect2();
|
||||||
|
return Rect2(ra.position - rb.position, ra.size - rb.size);
|
||||||
|
}
|
||||||
|
case Variant::RECT2I: {
|
||||||
|
const Rect2i ra = a.operator Rect2i();
|
||||||
|
const Rect2i rb = b.operator Rect2i();
|
||||||
|
return Rect2i(ra.position - rb.position, ra.size - rb.size);
|
||||||
|
}
|
||||||
|
case Variant::PLANE: {
|
||||||
|
const Plane pa = a.operator Plane();
|
||||||
|
const Plane pb = b.operator Plane();
|
||||||
|
return Plane(pa.normal - pb.normal, pa.d - pb.d);
|
||||||
|
}
|
||||||
|
case Variant::AABB: {
|
||||||
|
const ::AABB aa = a.operator ::AABB();
|
||||||
|
const ::AABB ab = b.operator ::AABB();
|
||||||
|
return ::AABB(aa.position - ab.position, aa.size - ab.size);
|
||||||
|
}
|
||||||
|
case Variant::QUATERNION: {
|
||||||
|
return (b.operator Quaternion()).inverse() * (a.operator Quaternion());
|
||||||
|
}
|
||||||
|
case Variant::TRANSFORM2D: {
|
||||||
|
return (b.operator Transform2D()).inverse() * (a.operator Transform2D());
|
||||||
|
}
|
||||||
|
case Variant::TRANSFORM3D: {
|
||||||
|
return (b.operator Transform3D()).inverse() * (a.operator Transform3D());
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return Variant::evaluate(Variant::OP_SUBTRACT, a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Variant Animation::blend_variant(const Variant &a, const Variant &b, float c) {
|
||||||
|
if (a.get_type() != b.get_type()) {
|
||||||
|
if (a.is_num() && b.is_num()) {
|
||||||
|
real_t va = a;
|
||||||
|
real_t vb = b;
|
||||||
|
return va + vb * c;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (a.get_type()) {
|
||||||
|
case Variant::NIL: {
|
||||||
|
return Variant();
|
||||||
|
}
|
||||||
|
case Variant::INT: {
|
||||||
|
return int((a.operator int64_t()) + (b.operator int64_t()) * c + 0.5);
|
||||||
|
}
|
||||||
|
case Variant::FLOAT: {
|
||||||
|
return (a.operator double()) + (b.operator double()) * c;
|
||||||
|
}
|
||||||
|
case Variant::VECTOR2: {
|
||||||
|
return (a.operator Vector2()) + (b.operator Vector2()) * c;
|
||||||
|
}
|
||||||
|
case Variant::VECTOR2I: {
|
||||||
|
const Vector2i va = a.operator Vector2i();
|
||||||
|
const Vector2i vb = b.operator Vector2i();
|
||||||
|
return Vector2i(int32_t(va.x + vb.x * c + 0.5), int32_t(va.y + vb.y * c + 0.5));
|
||||||
|
}
|
||||||
|
case Variant::RECT2: {
|
||||||
|
const Rect2 ra = a.operator Rect2();
|
||||||
|
const Rect2 rb = b.operator Rect2();
|
||||||
|
return Rect2(ra.position + rb.position * c, ra.size + rb.size * c);
|
||||||
|
}
|
||||||
|
case Variant::RECT2I: {
|
||||||
|
const Rect2i ra = a.operator Rect2i();
|
||||||
|
const Rect2i rb = b.operator Rect2i();
|
||||||
|
return Rect2i(int32_t(ra.position.x + rb.position.x * c + 0.5), int32_t(ra.position.y + rb.position.y * c + 0.5), int32_t(ra.size.x + rb.size.x * c + 0.5), int32_t(ra.size.y + rb.size.y * c + 0.5));
|
||||||
|
}
|
||||||
|
case Variant::VECTOR3: {
|
||||||
|
return (a.operator Vector3()) + (b.operator Vector3()) * c;
|
||||||
|
}
|
||||||
|
case Variant::VECTOR3I: {
|
||||||
|
const Vector3i va = a.operator Vector3i();
|
||||||
|
const Vector3i vb = b.operator Vector3i();
|
||||||
|
return Vector3i(int32_t(va.x + vb.x * c + 0.5), int32_t(va.y + vb.y * c + 0.5), int32_t(va.z + vb.z * c + 0.5));
|
||||||
|
}
|
||||||
|
case Variant::VECTOR4: {
|
||||||
|
return (a.operator Vector4()) + (b.operator Vector4()) * c;
|
||||||
|
}
|
||||||
|
case Variant::VECTOR4I: {
|
||||||
|
const Vector4i va = a.operator Vector4i();
|
||||||
|
const Vector4i vb = b.operator Vector4i();
|
||||||
|
return Vector4i(int32_t(va.x + vb.x * c + 0.5), int32_t(va.y + vb.y * c + 0.5), int32_t(va.z + vb.z * c + 0.5), int32_t(va.w + vb.w * c + 0.5));
|
||||||
|
}
|
||||||
|
case Variant::PLANE: {
|
||||||
|
const Plane pa = a.operator Plane();
|
||||||
|
const Plane pb = b.operator Plane();
|
||||||
|
return Plane(pa.normal + pb.normal * c, pa.d + pb.d * c);
|
||||||
|
}
|
||||||
|
case Variant::COLOR: {
|
||||||
|
return (a.operator Color()) + (b.operator Color()) * c;
|
||||||
|
}
|
||||||
|
case Variant::AABB: {
|
||||||
|
const ::AABB aa = a.operator ::AABB();
|
||||||
|
const ::AABB ab = b.operator ::AABB();
|
||||||
|
return ::AABB(aa.position + ab.position * c, aa.size + ab.size * c);
|
||||||
|
}
|
||||||
|
case Variant::BASIS: {
|
||||||
|
return (a.operator Basis()) + (b.operator Basis()) * c;
|
||||||
|
}
|
||||||
|
case Variant::QUATERNION: {
|
||||||
|
return (a.operator Quaternion()) * Quaternion().slerp((b.operator Quaternion()), c);
|
||||||
|
}
|
||||||
|
case Variant::TRANSFORM2D: {
|
||||||
|
return (a.operator Transform2D()) * Transform2D().interpolate_with((b.operator Transform2D()), c);
|
||||||
|
}
|
||||||
|
case Variant::TRANSFORM3D: {
|
||||||
|
return (a.operator Transform3D()) * Transform3D().interpolate_with((b.operator Transform3D()), c);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return c < 0.5 ? a : b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Variant Animation::interpolate_variant(const Variant &a, const Variant &b, float c) {
|
||||||
|
if (a.get_type() != b.get_type()) {
|
||||||
|
if (a.is_num() && b.is_num()) {
|
||||||
|
real_t va = a;
|
||||||
|
real_t vb = b;
|
||||||
|
return va + (vb - va) * c;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (a.get_type()) {
|
||||||
|
case Variant::NIL: {
|
||||||
|
return Variant();
|
||||||
|
}
|
||||||
|
case Variant::INT: {
|
||||||
|
const int64_t va = a.operator int64_t();
|
||||||
|
return int(va + ((b.operator int64_t()) - va) * c);
|
||||||
|
}
|
||||||
|
case Variant::FLOAT: {
|
||||||
|
const real_t va = a.operator real_t();
|
||||||
|
return va + ((b.operator real_t()) - va) * c;
|
||||||
|
}
|
||||||
|
case Variant::VECTOR2: {
|
||||||
|
return (a.operator Vector2()).lerp(b.operator Vector2(), c);
|
||||||
|
}
|
||||||
|
case Variant::VECTOR2I: {
|
||||||
|
const Vector2i va = a.operator Vector2i();
|
||||||
|
const Vector2i vb = b.operator Vector2i();
|
||||||
|
return Vector2i(int32_t(va.x + (vb.x - va.x) * c), int32_t(va.y + (vb.y - va.y) * c));
|
||||||
|
}
|
||||||
|
case Variant::RECT2: {
|
||||||
|
const Rect2 ra = a.operator Rect2();
|
||||||
|
const Rect2 rb = b.operator Rect2();
|
||||||
|
return Rect2(ra.position.lerp(rb.position, c), ra.size.lerp(rb.size, c));
|
||||||
|
}
|
||||||
|
case Variant::RECT2I: {
|
||||||
|
const Rect2i ra = a.operator Rect2i();
|
||||||
|
const Rect2i rb = b.operator Rect2i();
|
||||||
|
return Rect2i(int32_t(ra.position.x + (rb.position.x - ra.position.x) * c), int32_t(ra.position.y + (rb.position.y - ra.position.y) * c), int32_t(ra.size.x + (rb.size.x - ra.size.x) * c), int32_t(ra.size.y + (rb.size.y - ra.size.y) * c));
|
||||||
|
}
|
||||||
|
case Variant::VECTOR3: {
|
||||||
|
return (a.operator Vector3()).lerp(b.operator Vector3(), c);
|
||||||
|
}
|
||||||
|
case Variant::VECTOR3I: {
|
||||||
|
const Vector3i va = a.operator Vector3i();
|
||||||
|
const Vector3i vb = b.operator Vector3i();
|
||||||
|
return Vector3i(int32_t(va.x + (vb.x - va.x) * c), int32_t(va.y + (vb.y - va.y) * c), int32_t(va.z + (vb.z - va.z) * c));
|
||||||
|
}
|
||||||
|
case Variant::VECTOR4: {
|
||||||
|
return (a.operator Vector4()).lerp(b.operator Vector4(), c);
|
||||||
|
}
|
||||||
|
case Variant::VECTOR4I: {
|
||||||
|
const Vector4i va = a.operator Vector4i();
|
||||||
|
const Vector4i vb = b.operator Vector4i();
|
||||||
|
return Vector4i(int32_t(va.x + (vb.x - va.x) * c), int32_t(va.y + (vb.y - va.y) * c), int32_t(va.z + (vb.z - va.z) * c), int32_t(va.w + (vb.w - va.w) * c));
|
||||||
|
}
|
||||||
|
case Variant::PLANE: {
|
||||||
|
const Plane pa = a.operator Plane();
|
||||||
|
const Plane pb = b.operator Plane();
|
||||||
|
return Plane(pa.normal.lerp(pb.normal, c), pa.d + (pb.d - pa.d) * c);
|
||||||
|
}
|
||||||
|
case Variant::COLOR: {
|
||||||
|
return (a.operator Color()).lerp(b.operator Color(), c);
|
||||||
|
}
|
||||||
|
case Variant::AABB: {
|
||||||
|
const ::AABB aa = a.operator ::AABB();
|
||||||
|
const ::AABB ab = b.operator ::AABB();
|
||||||
|
return ::AABB(aa.position.lerp(ab.position, c), aa.size.lerp(ab.size, c));
|
||||||
|
}
|
||||||
|
case Variant::BASIS: {
|
||||||
|
return (a.operator Basis()).lerp(b.operator Basis(), c);
|
||||||
|
}
|
||||||
|
case Variant::QUATERNION: {
|
||||||
|
return (a.operator Quaternion()).slerp(b.operator Quaternion(), c);
|
||||||
|
}
|
||||||
|
case Variant::TRANSFORM2D: {
|
||||||
|
return (a.operator Transform2D()).interpolate_with(b.operator Transform2D(), c);
|
||||||
|
}
|
||||||
|
case Variant::TRANSFORM3D: {
|
||||||
|
return (a.operator Transform3D()).interpolate_with(b.operator Transform3D(), c);
|
||||||
|
}
|
||||||
|
case Variant::STRING: {
|
||||||
|
// This is pretty funny and bizarre, but artists like to use it for typewriter effects.
|
||||||
|
const String sa = a.operator String();
|
||||||
|
const String sb = b.operator String();
|
||||||
|
String dst;
|
||||||
|
int sa_len = sa.length();
|
||||||
|
int sb_len = sb.length();
|
||||||
|
int csize = sa_len + (sb_len - sa_len) * c;
|
||||||
|
if (csize == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
dst.resize(csize + 1);
|
||||||
|
dst[csize] = 0;
|
||||||
|
int split = csize / 2;
|
||||||
|
|
||||||
|
for (int i = 0; i < csize; i++) {
|
||||||
|
char32_t chr = ' ';
|
||||||
|
|
||||||
|
if (i < split) {
|
||||||
|
if (i < sa.length()) {
|
||||||
|
chr = sa[i];
|
||||||
|
} else if (i < sb.length()) {
|
||||||
|
chr = sb[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (i < sb.length()) {
|
||||||
|
chr = sb[i];
|
||||||
|
} else if (i < sa.length()) {
|
||||||
|
chr = sa[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dst[i] = chr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
case Variant::PACKED_INT32_ARRAY: {
|
||||||
|
const Vector<int32_t> *arr_a = Object::cast_to<Vector<int32_t>>(a);
|
||||||
|
const Vector<int32_t> *arr_b = Object::cast_to<Vector<int32_t>>(b);
|
||||||
|
int32_t sz = arr_a->size();
|
||||||
|
if (sz == 0 || arr_b->size() != sz) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
Vector<int32_t> v;
|
||||||
|
v.resize(sz);
|
||||||
|
{
|
||||||
|
int32_t *vw = v.ptrw();
|
||||||
|
const int32_t *ar = arr_a->ptr();
|
||||||
|
const int32_t *br = arr_b->ptr();
|
||||||
|
|
||||||
|
Variant va;
|
||||||
|
for (int32_t i = 0; i < sz; i++) {
|
||||||
|
va = interpolate_variant(ar[i], br[i], c);
|
||||||
|
vw[i] = va;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Variant::PACKED_INT64_ARRAY: {
|
||||||
|
const Vector<int64_t> *arr_a = Object::cast_to<Vector<int64_t>>(a);
|
||||||
|
const Vector<int64_t> *arr_b = Object::cast_to<Vector<int64_t>>(b);
|
||||||
|
int64_t sz = arr_a->size();
|
||||||
|
if (sz == 0 || arr_b->size() != sz) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
Vector<int64_t> v;
|
||||||
|
v.resize(sz);
|
||||||
|
{
|
||||||
|
int64_t *vw = v.ptrw();
|
||||||
|
const int64_t *ar = arr_a->ptr();
|
||||||
|
const int64_t *br = arr_b->ptr();
|
||||||
|
|
||||||
|
Variant va;
|
||||||
|
for (int64_t i = 0; i < sz; i++) {
|
||||||
|
va = interpolate_variant(ar[i], br[i], c);
|
||||||
|
vw[i] = va;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Variant::PACKED_FLOAT32_ARRAY: {
|
||||||
|
const Vector<float> *arr_a = Object::cast_to<Vector<float>>(a);
|
||||||
|
const Vector<float> *arr_b = Object::cast_to<Vector<float>>(b);
|
||||||
|
int sz = arr_a->size();
|
||||||
|
if (sz == 0 || arr_b->size() != sz) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
Vector<float> v;
|
||||||
|
v.resize(sz);
|
||||||
|
{
|
||||||
|
float *vw = v.ptrw();
|
||||||
|
const float *ar = arr_a->ptr();
|
||||||
|
const float *br = arr_b->ptr();
|
||||||
|
|
||||||
|
Variant va;
|
||||||
|
for (int i = 0; i < sz; i++) {
|
||||||
|
va = interpolate_variant(ar[i], br[i], c);
|
||||||
|
vw[i] = va;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Variant::PACKED_FLOAT64_ARRAY: {
|
||||||
|
const Vector<double> *arr_a = Object::cast_to<Vector<double>>(a);
|
||||||
|
const Vector<double> *arr_b = Object::cast_to<Vector<double>>(b);
|
||||||
|
int sz = arr_a->size();
|
||||||
|
if (sz == 0 || arr_b->size() != sz) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
Vector<double> v;
|
||||||
|
v.resize(sz);
|
||||||
|
{
|
||||||
|
double *vw = v.ptrw();
|
||||||
|
const double *ar = arr_a->ptr();
|
||||||
|
const double *br = arr_b->ptr();
|
||||||
|
|
||||||
|
Variant va;
|
||||||
|
for (int i = 0; i < sz; i++) {
|
||||||
|
va = interpolate_variant(ar[i], br[i], c);
|
||||||
|
vw[i] = va;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Variant::PACKED_VECTOR2_ARRAY: {
|
||||||
|
const Vector<Vector2> *arr_a = Object::cast_to<Vector<Vector2>>(a);
|
||||||
|
const Vector<Vector2> *arr_b = Object::cast_to<Vector<Vector2>>(b);
|
||||||
|
int sz = arr_a->size();
|
||||||
|
if (sz == 0 || arr_b->size() != sz) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
Vector<Vector2> v;
|
||||||
|
v.resize(sz);
|
||||||
|
{
|
||||||
|
Vector2 *vw = v.ptrw();
|
||||||
|
const Vector2 *ar = arr_a->ptr();
|
||||||
|
const Vector2 *br = arr_b->ptr();
|
||||||
|
|
||||||
|
for (int i = 0; i < sz; i++) {
|
||||||
|
vw[i] = ar[i].lerp(br[i], c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Variant::PACKED_VECTOR3_ARRAY: {
|
||||||
|
const Vector<Vector3> *arr_a = Object::cast_to<Vector<Vector3>>(a);
|
||||||
|
const Vector<Vector3> *arr_b = Object::cast_to<Vector<Vector3>>(b);
|
||||||
|
int sz = arr_a->size();
|
||||||
|
if (sz == 0 || arr_b->size() != sz) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
Vector<Vector3> v;
|
||||||
|
v.resize(sz);
|
||||||
|
{
|
||||||
|
Vector3 *vw = v.ptrw();
|
||||||
|
const Vector3 *ar = arr_a->ptr();
|
||||||
|
const Vector3 *br = arr_b->ptr();
|
||||||
|
|
||||||
|
for (int i = 0; i < sz; i++) {
|
||||||
|
vw[i] = ar[i].lerp(br[i], c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Variant::PACKED_COLOR_ARRAY: {
|
||||||
|
const Vector<Color> *arr_a = Object::cast_to<Vector<Color>>(a);
|
||||||
|
const Vector<Color> *arr_b = Object::cast_to<Vector<Color>>(b);
|
||||||
|
int sz = arr_a->size();
|
||||||
|
if (sz == 0 || arr_b->size() != sz) {
|
||||||
|
return a;
|
||||||
|
} else {
|
||||||
|
Vector<Color> v;
|
||||||
|
v.resize(sz);
|
||||||
|
{
|
||||||
|
Color *vw = v.ptrw();
|
||||||
|
const Color *ar = arr_a->ptr();
|
||||||
|
const Color *br = arr_b->ptr();
|
||||||
|
|
||||||
|
for (int i = 0; i < sz; i++) {
|
||||||
|
vw[i] = ar[i].lerp(br[i], c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return c < 0.5 ? a : b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Animation::Animation() {}
|
Animation::Animation() {}
|
||||||
|
|
||||||
Animation::~Animation() {
|
Animation::~Animation() {
|
||||||
|
@ -496,6 +496,12 @@ public:
|
|||||||
void optimize(real_t p_allowed_velocity_err = 0.01, real_t p_allowed_angular_err = 0.01, int p_precision = 3);
|
void optimize(real_t p_allowed_velocity_err = 0.01, real_t p_allowed_angular_err = 0.01, int p_precision = 3);
|
||||||
void compress(uint32_t p_page_size = 8192, uint32_t p_fps = 120, float p_split_tolerance = 4.0); // 4.0 seems to be the split tolerance sweet spot from many tests
|
void compress(uint32_t p_page_size = 8192, uint32_t p_fps = 120, float p_split_tolerance = 4.0); // 4.0 seems to be the split tolerance sweet spot from many tests
|
||||||
|
|
||||||
|
// Helper math fuctions for Variant.
|
||||||
|
static Variant add_variant(const Variant &a, const Variant &b);
|
||||||
|
static Variant subtract_variant(const Variant &a, const Variant &b);
|
||||||
|
static Variant blend_variant(const Variant &a, const Variant &b, float c);
|
||||||
|
static Variant interpolate_variant(const Variant &a, const Variant &b, float c);
|
||||||
|
|
||||||
Animation();
|
Animation();
|
||||||
~Animation();
|
~Animation();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user