Backported from Godot4: Make blend animation to use ResetTrack as default value - TokageItLab

860fac4e6f
This commit is contained in:
Relintai 2022-08-12 17:16:52 +02:00
parent d1fe0ae433
commit ec9eb18aaf
4 changed files with 158 additions and 4 deletions

View File

@ -386,6 +386,7 @@ public:
Variant duplicate(bool deep = false) 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);
struct CallError {
enum Error {

View File

@ -4530,6 +4530,110 @@ Variant Variant::duplicate(bool deep) 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 REAL: {
real_t ra = a._data._real;
real_t rb = b._data._real;
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 QUAT: {
Quat empty_rot;
const Quat *qa = reinterpret_cast<const Quat *>(a._data._mem);
const Quat *qb = reinterpret_cast<const Quat *>(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()) {

View File

@ -538,6 +538,12 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
List<StringName> sname;
player->get_animation_list(&sname);
Ref<Animation> reset_anim;
bool has_reset_anim = player->has_animation("RESET");
if (has_reset_anim) {
reset_anim = player->get_animation("RESET");
}
for (List<StringName>::Element *E = sname.front(); E; E = E->next()) {
Ref<Animation> anim = player->get_animation(E->get());
for (int i = 0; i < anim->get_track_count(); i++) {
@ -591,6 +597,13 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
track = track_value;
if (has_reset_anim) {
int rt = reset_anim->find_track(path, track_type);
if (rt >= 0 && reset_anim->track_get_key_count(rt) > 0) {
track_value->init_value = reset_anim->track_get_key_value(rt, 0);
}
}
} break;
case Animation::TYPE_POSITION_3D:
case Animation::TYPE_ROTATION_3D:
@ -645,6 +658,26 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
default: {
}
}
if (has_reset_anim) {
int rt = reset_anim->find_track(path, track_type);
if (rt >= 0 && reset_anim->track_get_key_count(rt) > 0) {
switch (track_type) {
case Animation::TYPE_POSITION_3D: {
track_xform->init_loc = reset_anim->track_get_key_value(rt, 0);
} break;
case Animation::TYPE_ROTATION_3D: {
track_xform->ref_rot = reset_anim->track_get_key_value(rt, 0);
track_xform->init_rot = track_xform->ref_rot.log();
} break;
case Animation::TYPE_SCALE_3D: {
track_xform->init_scale = reset_anim->track_get_key_value(rt, 0);
} break;
default: {
}
}
}
}
#endif
} break;
case Animation::TYPE_METHOD: {
@ -674,6 +707,13 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
track_bezier->object_id = track_bezier->object->get_instance_id();
track = track_bezier;
if (has_reset_anim) {
int rt = reset_anim->find_track(path, track_type);
if (rt >= 0 && reset_anim->track_get_key_count(rt) > 0) {
track_bezier->init_value = reset_anim->track_get_key_value(rt, 0);
}
}
} break;
case Animation::TYPE_AUDIO: {
TrackCacheAudio *track_audio = memnew(TrackCacheAudio);
@ -1116,10 +1156,16 @@ void AnimationTree::_process_graph(float p_delta) {
if (t->process_pass != process_pass) {
t->process_pass = process_pass;
t->value = value;
t->value.zero();
if (!t->init_value) {
t->init_value = value;
t->init_value.zero();
} else {
t->value = t->init_value;
}
}
Variant::sub(value, t->init_value, value);
Variant::blend(t->value, value, blend, t->value);
} else {
@ -1180,10 +1226,10 @@ void AnimationTree::_process_graph(float p_delta) {
if (t->process_pass != process_pass) {
t->process_pass = process_pass;
t->value = 0;
t->value = t->init_value;
}
t->value += bezier * blend;
t->value += (bezier - t->init_value) * blend;
} break;
case Animation::TYPE_AUDIO: {

View File

@ -215,6 +215,7 @@ private:
};
struct TrackCacheValue : public TrackCache {
Variant init_value;
Variant value;
Vector<StringName> subpath;
TrackCacheValue() { type = Animation::TYPE_VALUE; }
@ -225,11 +226,13 @@ private:
};
struct TrackCacheBezier : public TrackCache {
real_t init_value;
float value;
Vector<StringName> subpath;
TrackCacheBezier() {
type = Animation::TYPE_BEZIER;
value = 0;
init_value = 0.0;
}
};