Make blend animation to use ResetTrack as default value
This commit is contained in:
parent
bf153b82c7
commit
860fac4e6f
6 changed files with 172 additions and 6 deletions
|
@ -241,6 +241,13 @@ 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) {
|
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 *a = (const Variant *)p_a;
|
||||||
const Variant *b = (const Variant *)p_b;
|
const Variant *b = (const Variant *)p_b;
|
||||||
|
@ -939,6 +946,7 @@ void gdnative_setup_interface(GDNativeInterface *p_interface) {
|
||||||
gdni.variant_iter_get = gdnative_variant_iter_get;
|
gdni.variant_iter_get = gdnative_variant_iter_get;
|
||||||
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_blend = gdnative_variant_blend;
|
||||||
gdni.variant_interpolate = gdnative_variant_interpolate;
|
gdni.variant_interpolate = gdnative_variant_interpolate;
|
||||||
gdni.variant_duplicate = gdnative_variant_duplicate;
|
gdni.variant_duplicate = gdnative_variant_duplicate;
|
||||||
|
|
|
@ -416,6 +416,7 @@ typedef struct {
|
||||||
void (*variant_iter_get)(const GDNativeVariantPtr p_self, GDNativeVariantPtr r_iter, GDNativeVariantPtr r_ret, GDNativeBool *r_valid);
|
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_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_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_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);
|
||||||
|
|
|
@ -511,6 +511,7 @@ public:
|
||||||
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 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 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 */
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) {
|
||||||
if (a.type != b.type) {
|
if (a.type != b.type) {
|
||||||
if (a.is_num() && b.is_num()) {
|
if (a.is_num() && b.is_num()) {
|
||||||
|
|
|
@ -540,6 +540,11 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
|
||||||
List<StringName> sname;
|
List<StringName> sname;
|
||||||
player->get_animation_list(&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) {
|
for (const StringName &E : sname) {
|
||||||
Ref<Animation> anim = player->get_animation(E);
|
Ref<Animation> anim = player->get_animation(E);
|
||||||
for (int i = 0; i < anim->get_track_count(); i++) {
|
for (int i = 0; i < anim->get_track_count(); i++) {
|
||||||
|
@ -593,6 +598,12 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
|
||||||
|
|
||||||
track = track_value;
|
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;
|
} break;
|
||||||
case Animation::TYPE_POSITION_3D:
|
case Animation::TYPE_POSITION_3D:
|
||||||
case Animation::TYPE_ROTATION_3D:
|
case Animation::TYPE_ROTATION_3D:
|
||||||
|
@ -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
|
#endif // _3D_DISABLED
|
||||||
} break;
|
} break;
|
||||||
case Animation::TYPE_BLEND_SHAPE: {
|
case Animation::TYPE_BLEND_SHAPE: {
|
||||||
|
@ -675,6 +705,13 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
|
||||||
track_bshape->object = mesh_3d;
|
track_bshape->object = mesh_3d;
|
||||||
track_bshape->object_id = mesh_3d->get_instance_id();
|
track_bshape->object_id = mesh_3d->get_instance_id();
|
||||||
track = track_bshape;
|
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
|
#endif
|
||||||
} break;
|
} break;
|
||||||
case Animation::TYPE_METHOD: {
|
case Animation::TYPE_METHOD: {
|
||||||
|
@ -704,6 +741,13 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
|
||||||
track_bezier->object_id = track_bezier->object->get_instance_id();
|
track_bezier->object_id = track_bezier->object->get_instance_id();
|
||||||
|
|
||||||
track = track_bezier;
|
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;
|
} break;
|
||||||
case Animation::TYPE_AUDIO: {
|
case Animation::TYPE_AUDIO: {
|
||||||
TrackCacheAudio *track_audio = memnew(TrackCacheAudio);
|
TrackCacheAudio *track_audio = memnew(TrackCacheAudio);
|
||||||
|
@ -1226,7 +1270,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
||||||
|
|
||||||
if (t->process_pass != process_pass) {
|
if (t->process_pass != process_pass) {
|
||||||
t->process_pass = process_pass;
|
t->process_pass = process_pass;
|
||||||
t->value = 0;
|
t->value = t->init_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
float value;
|
float value;
|
||||||
|
@ -1238,7 +1282,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
t->value += value * blend;
|
t->value += (value - t->init_value) * blend;
|
||||||
#endif // _3D_DISABLED
|
#endif // _3D_DISABLED
|
||||||
} break;
|
} break;
|
||||||
case Animation::TYPE_VALUE: {
|
case Animation::TYPE_VALUE: {
|
||||||
|
@ -1256,10 +1300,15 @@ void AnimationTree::_process_graph(double p_delta) {
|
||||||
|
|
||||||
if (t->process_pass != process_pass) {
|
if (t->process_pass != process_pass) {
|
||||||
t->process_pass = process_pass;
|
t->process_pass = process_pass;
|
||||||
t->value = value;
|
if (!t->init_value) {
|
||||||
t->value.zero();
|
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);
|
Variant::blend(t->value, value, blend, t->value);
|
||||||
} else {
|
} else {
|
||||||
if (blend < CMP_EPSILON) {
|
if (blend < CMP_EPSILON) {
|
||||||
|
@ -1303,10 +1352,10 @@ void AnimationTree::_process_graph(double p_delta) {
|
||||||
|
|
||||||
if (t->process_pass != process_pass) {
|
if (t->process_pass != process_pass) {
|
||||||
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;
|
} break;
|
||||||
case Animation::TYPE_AUDIO: {
|
case Animation::TYPE_AUDIO: {
|
||||||
if (blend < CMP_EPSILON) {
|
if (blend < CMP_EPSILON) {
|
||||||
|
|
|
@ -212,12 +212,14 @@ private:
|
||||||
|
|
||||||
struct TrackCacheBlendShape : public TrackCache {
|
struct TrackCacheBlendShape : public TrackCache {
|
||||||
MeshInstance3D *mesh_3d = nullptr;
|
MeshInstance3D *mesh_3d = nullptr;
|
||||||
|
float init_value = 0;
|
||||||
float value = 0;
|
float value = 0;
|
||||||
int shape_index = -1;
|
int shape_index = -1;
|
||||||
TrackCacheBlendShape() { type = Animation::TYPE_BLEND_SHAPE; }
|
TrackCacheBlendShape() { type = Animation::TYPE_BLEND_SHAPE; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TrackCacheValue : public TrackCache {
|
struct TrackCacheValue : public TrackCache {
|
||||||
|
Variant init_value;
|
||||||
Variant value;
|
Variant value;
|
||||||
Vector<StringName> subpath;
|
Vector<StringName> subpath;
|
||||||
TrackCacheValue() { type = Animation::TYPE_VALUE; }
|
TrackCacheValue() { type = Animation::TYPE_VALUE; }
|
||||||
|
@ -228,6 +230,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TrackCacheBezier : public TrackCache {
|
struct TrackCacheBezier : public TrackCache {
|
||||||
|
real_t init_value = 0.0;
|
||||||
real_t value = 0.0;
|
real_t value = 0.0;
|
||||||
Vector<StringName> subpath;
|
Vector<StringName> subpath;
|
||||||
TrackCacheBezier() {
|
TrackCacheBezier() {
|
||||||
|
|
Loading…
Reference in a new issue