summaryrefslogtreecommitdiff
path: root/scene/animation/animation_player.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/animation/animation_player.cpp')
-rw-r--r--scene/animation/animation_player.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 8407e0dd99..1f000d5f39 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -257,6 +257,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov
ERR_CONTINUE_MSG(!child, "On Animation: '" + p_anim->name + "', couldn't resolve track: '" + String(a->track_get_path(i)) + "'."); // couldn't find the child node
ObjectID id = resource.is_valid() ? resource->get_instance_id() : child->get_instance_id();
int bone_idx = -1;
+ int blend_shape_idx = -1;
#ifndef _3D_DISABLED
if (a->track_get_path(i).get_subname_count() == 1 && Object::cast_to<Skeleton3D>(child)) {
@@ -266,6 +267,22 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov
continue;
}
}
+
+ if (a->track_get_type(i) == Animation::TYPE_BLEND_SHAPE) {
+ MeshInstance3D *mi_3d = Object::cast_to<MeshInstance3D>(child);
+ if (!mi_3d) {
+ continue;
+ }
+ if (a->track_get_path(i).get_subname_count() != 1) {
+ continue;
+ }
+
+ blend_shape_idx = mi_3d->find_blend_shape_by_name(a->track_get_path(i).get_subname(0));
+ if (blend_shape_idx == -1) {
+ continue;
+ }
+ }
+
#endif // _3D_DISABLED
{
@@ -277,6 +294,7 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov
TrackNodeCacheKey key;
key.id = id;
key.bone_idx = bone_idx;
+ key.blend_shape_idx = blend_shape_idx;
if (!node_cache_map.has(key)) {
node_cache_map[key] = TrackNodeCache();
@@ -334,6 +352,13 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov
}
}
}
+
+ if (a->track_get_type(i) == Animation::TYPE_BLEND_SHAPE) {
+ // special cases and caches for transform tracks
+ node_cache->node_blend_shape = Object::cast_to<MeshInstance3D>(child);
+ node_cache->blend_shape_idx = blend_shape_idx;
+ }
+
#endif // _3D_DISABLED
if (a->track_get_type(i) == Animation::TYPE_VALUE) {
@@ -481,6 +506,31 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
}
#endif // _3D_DISABLED
} break;
+ case Animation::TYPE_BLEND_SHAPE: {
+#ifndef _3D_DISABLED
+ if (!nc->node_blend_shape) {
+ continue;
+ }
+
+ float blend;
+
+ Error err = a->blend_shape_track_interpolate(i, p_time, &blend);
+ //ERR_CONTINUE(err!=OK); //used for testing, should be removed
+
+ if (err != OK) {
+ continue;
+ }
+
+ if (nc->accum_pass != accum_pass) {
+ ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX);
+ nc->accum_pass = accum_pass;
+ cache_update[cache_update_size++] = nc;
+ nc->blend_shape_accum = blend;
+ } else {
+ nc->blend_shape_accum = Math::lerp(nc->blend_shape_accum, blend, p_interp);
+ }
+#endif // _3D_DISABLED
+ } break;
case Animation::TYPE_VALUE: {
if (!nc->node) {
continue;
@@ -947,6 +997,8 @@ void AnimationPlayer::_animation_update_transforms() {
nc->skeleton->set_bone_pose_scale(nc->bone_idx, nc->scale_accum);
}
+ } else if (nc->node_blend_shape) {
+ nc->node_blend_shape->set_blend_shape_value(nc->blend_shape_idx, nc->blend_shape_accum);
} else if (nc->node_3d) {
if (nc->loc_used) {
nc->node_3d->set_position(nc->loc_accum);