Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make blend animation to use ResetTrack as default value #60093

Merged
merged 1 commit into from
Apr 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions core/extension/gdnative_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,13 @@ static GDNativeBool gdnative_variant_booleanize(const GDNativeVariantPtr p_self)
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;
Expand Down Expand Up @@ -939,6 +946,7 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
gdni.variant_iter_get = gdnative_variant_iter_get;
gdni.variant_hash_compare = gdnative_variant_hash_compare;
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;
Expand Down
1 change: 1 addition & 0 deletions core/extension/gdnative_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ typedef struct {
void (*variant_iter_get)(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_iter, GDNativeVariantPtr r_ret, GDNativeBool *r_valid);
GDNativeBool (*variant_hash_compare)(const GDNativeVariantPtr p_self, const GDNativeVariantPtr p_other);
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);
Expand Down
1 change: 1 addition & 0 deletions core/variant/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ class Variant {
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 */

Expand Down
104 changes: 104 additions & 0 deletions core/variant/variant_setget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,110 @@ 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()) {
Expand Down
61 changes: 55 additions & 6 deletions scene/animation/animation_tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,11 @@ 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 (const StringName &E : sname) {
Ref<Animation> anim = player->get_animation(E);
for (int i = 0; i < anim->get_track_count(); i++) {
Expand Down Expand Up @@ -593,6 +598,12 @@ 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:
Expand Down Expand Up @@ -645,6 +656,25 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
}
}

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 // _3D_DISABLED
} break;
case Animation::TYPE_BLEND_SHAPE: {
Expand Down Expand Up @@ -675,6 +705,13 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
track_bshape->object = mesh_3d;
track_bshape->object_id = mesh_3d->get_instance_id();
track = track_bshape;

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_bshape->init_value = reset_anim->track_get_key_value(rt, 0);
}
}
#endif
} break;
case Animation::TYPE_METHOD: {
Expand Down Expand Up @@ -704,6 +741,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);
Expand Down Expand Up @@ -1226,7 +1270,7 @@ void AnimationTree::_process_graph(double p_delta) {

if (t->process_pass != process_pass) {
t->process_pass = process_pass;
t->value = 0;
t->value = t->init_value;
}

float value;
Expand All @@ -1238,7 +1282,7 @@ void AnimationTree::_process_graph(double p_delta) {
continue;
}

t->value += value * blend;
t->value += (value - t->init_value) * blend;
#endif // _3D_DISABLED
} break;
case Animation::TYPE_VALUE: {
Expand All @@ -1256,10 +1300,15 @@ void AnimationTree::_process_graph(double 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 {
if (blend < CMP_EPSILON) {
Expand Down Expand Up @@ -1303,10 +1352,10 @@ void AnimationTree::_process_graph(double 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: {
if (blend < CMP_EPSILON) {
Expand Down
3 changes: 3 additions & 0 deletions scene/animation/animation_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,14 @@ class AnimationTree : public Node {

struct TrackCacheBlendShape : public TrackCache {
MeshInstance3D *mesh_3d = nullptr;
float init_value = 0;
float value = 0;
int shape_index = -1;
TrackCacheBlendShape() { type = Animation::TYPE_BLEND_SHAPE; }
};

struct TrackCacheValue : public TrackCache {
Variant init_value;
Variant value;
Vector<StringName> subpath;
TrackCacheValue() { type = Animation::TYPE_VALUE; }
Expand All @@ -228,6 +230,7 @@ class AnimationTree : public Node {
};

struct TrackCacheBezier : public TrackCache {
real_t init_value = 0.0;
real_t value = 0.0;
Vector<StringName> subpath;
TrackCacheBezier() {
Expand Down