|
@@ -273,10 +273,6 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if (!p_seek && p_optimize && !any_valid) { //pointless to go on, all are zero
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
String new_path;
|
|
String new_path;
|
|
AnimationNode *new_parent;
|
|
AnimationNode *new_parent;
|
|
|
|
|
|
@@ -289,6 +285,10 @@ double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Stri
|
|
new_parent = parent;
|
|
new_parent = parent;
|
|
new_path = String(parent->base_path) + String(p_subpath) + "/";
|
|
new_path = String(parent->base_path) + String(p_subpath) + "/";
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (!p_seek && p_optimize && !any_valid) {
|
|
|
|
+ return p_node->_pre_process(new_path, new_parent, state, 0, p_seek, p_connections);
|
|
|
|
+ }
|
|
return p_node->_pre_process(new_path, new_parent, state, p_time, p_seek, p_connections);
|
|
return p_node->_pre_process(new_path, new_parent, state, p_time, p_seek, p_connections);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -618,6 +618,11 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
|
|
int bone_idx = sk->find_bone(path.get_subname(0));
|
|
int bone_idx = sk->find_bone(path.get_subname(0));
|
|
if (bone_idx != -1) {
|
|
if (bone_idx != -1) {
|
|
track_xform->bone_idx = bone_idx;
|
|
track_xform->bone_idx = bone_idx;
|
|
|
|
+ Transform3D rest = sk->get_bone_rest(bone_idx);
|
|
|
|
+ track_xform->init_loc = rest.origin;
|
|
|
|
+ track_xform->ref_rot = rest.basis.get_rotation_quaternion();
|
|
|
|
+ track_xform->init_rot = track_xform->ref_rot.log();
|
|
|
|
+ track_xform->init_scale = rest.basis.get_scale();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -644,7 +649,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
|
|
} break;
|
|
} break;
|
|
case Animation::TYPE_BLEND_SHAPE: {
|
|
case Animation::TYPE_BLEND_SHAPE: {
|
|
#ifndef _3D_DISABLED
|
|
#ifndef _3D_DISABLED
|
|
-
|
|
|
|
if (path.get_subname_count() != 1) {
|
|
if (path.get_subname_count() != 1) {
|
|
ERR_PRINT("AnimationTree: '" + String(E) + "', blend shape track does not contain a blend shape subname: '" + String(path) + "'");
|
|
ERR_PRINT("AnimationTree: '" + String(E) + "', blend shape track does not contain a blend shape subname: '" + String(path) + "'");
|
|
continue;
|
|
continue;
|
|
@@ -942,23 +946,16 @@ void AnimationTree::_process_graph(double p_delta) {
|
|
|
|
|
|
real_t blend = (*as.track_blends)[blend_idx] * weight;
|
|
real_t blend = (*as.track_blends)[blend_idx] * weight;
|
|
|
|
|
|
- if (blend < CMP_EPSILON) {
|
|
|
|
- continue; //nothing to blend
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
switch (ttype) {
|
|
switch (ttype) {
|
|
case Animation::TYPE_POSITION_3D: {
|
|
case Animation::TYPE_POSITION_3D: {
|
|
#ifndef _3D_DISABLED
|
|
#ifndef _3D_DISABLED
|
|
TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
|
|
TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
|
|
-
|
|
|
|
if (t->process_pass != process_pass) {
|
|
if (t->process_pass != process_pass) {
|
|
t->process_pass = process_pass;
|
|
t->process_pass = process_pass;
|
|
- t->loc = Vector3();
|
|
|
|
- t->rot = Quaternion();
|
|
|
|
- t->rot_blend_accum = 0;
|
|
|
|
- t->scale = Vector3(1, 1, 1);
|
|
|
|
|
|
+ t->loc = t->init_loc;
|
|
|
|
+ t->rot = t->init_rot;
|
|
|
|
+ t->scale = t->init_scale;
|
|
}
|
|
}
|
|
-
|
|
|
|
if (track->root_motion) {
|
|
if (track->root_motion) {
|
|
double prev_time = time - delta;
|
|
double prev_time = time - delta;
|
|
if (!backward) {
|
|
if (!backward) {
|
|
@@ -1036,22 +1033,19 @@ void AnimationTree::_process_graph(double p_delta) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- t->loc = t->loc.lerp(loc, blend);
|
|
|
|
|
|
+ t->loc += (loc - t->init_loc) * blend;
|
|
}
|
|
}
|
|
#endif // _3D_DISABLED
|
|
#endif // _3D_DISABLED
|
|
} break;
|
|
} break;
|
|
case Animation::TYPE_ROTATION_3D: {
|
|
case Animation::TYPE_ROTATION_3D: {
|
|
#ifndef _3D_DISABLED
|
|
#ifndef _3D_DISABLED
|
|
TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
|
|
TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
|
|
-
|
|
|
|
if (t->process_pass != process_pass) {
|
|
if (t->process_pass != process_pass) {
|
|
t->process_pass = process_pass;
|
|
t->process_pass = process_pass;
|
|
- t->loc = Vector3();
|
|
|
|
- t->rot = Quaternion();
|
|
|
|
- t->rot_blend_accum = 0;
|
|
|
|
- t->scale = Vector3(1, 1, 1);
|
|
|
|
|
|
+ t->loc = t->init_loc;
|
|
|
|
+ t->rot = t->init_rot;
|
|
|
|
+ t->scale = t->init_scale;
|
|
}
|
|
}
|
|
-
|
|
|
|
if (track->root_motion) {
|
|
if (track->root_motion) {
|
|
double prev_time = time - delta;
|
|
double prev_time = time - delta;
|
|
if (!backward) {
|
|
if (!backward) {
|
|
@@ -1097,8 +1091,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
a->rotation_track_interpolate(i, (double)a->get_length(), &rot[1]);
|
|
a->rotation_track_interpolate(i, (double)a->get_length(), &rot[1]);
|
|
- Quaternion q = Quaternion().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized();
|
|
|
|
- t->rot = (t->rot * q).normalized();
|
|
|
|
|
|
+ t->rot += (rot[1].log() - rot[0].log()) * blend;
|
|
prev_time = 0;
|
|
prev_time = 0;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
@@ -1108,8 +1101,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
a->rotation_track_interpolate(i, 0, &rot[1]);
|
|
a->rotation_track_interpolate(i, 0, &rot[1]);
|
|
- Quaternion q = Quaternion().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized();
|
|
|
|
- t->rot = (t->rot * q).normalized();
|
|
|
|
|
|
+ t->rot += (rot[1].log() - rot[0].log()) * blend;
|
|
prev_time = 0;
|
|
prev_time = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1120,8 +1112,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
|
}
|
|
}
|
|
|
|
|
|
a->rotation_track_interpolate(i, time, &rot[1]);
|
|
a->rotation_track_interpolate(i, time, &rot[1]);
|
|
- Quaternion q = Quaternion().slerp(rot[0].normalized().inverse() * rot[1].normalized(), blend).normalized();
|
|
|
|
- t->rot = (t->rot * q).normalized();
|
|
|
|
|
|
+ t->rot += (rot[1].log() - rot[0].log()) * blend;
|
|
prev_time = !backward ? 0 : (double)a->get_length();
|
|
prev_time = !backward ? 0 : (double)a->get_length();
|
|
|
|
|
|
} else {
|
|
} else {
|
|
@@ -1132,29 +1123,22 @@ void AnimationTree::_process_graph(double p_delta) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- if (t->rot_blend_accum == 0) {
|
|
|
|
- t->rot = rot;
|
|
|
|
- t->rot_blend_accum = blend;
|
|
|
|
- } else {
|
|
|
|
- real_t rot_total = t->rot_blend_accum + blend;
|
|
|
|
- t->rot = rot.slerp(t->rot, t->rot_blend_accum / rot_total).normalized();
|
|
|
|
- t->rot_blend_accum = rot_total;
|
|
|
|
|
|
+ if (signbit(rot.dot(t->ref_rot))) {
|
|
|
|
+ rot = -rot;
|
|
}
|
|
}
|
|
|
|
+ t->rot += (rot.log() - t->init_rot) * blend;
|
|
}
|
|
}
|
|
#endif // _3D_DISABLED
|
|
#endif // _3D_DISABLED
|
|
} break;
|
|
} break;
|
|
case Animation::TYPE_SCALE_3D: {
|
|
case Animation::TYPE_SCALE_3D: {
|
|
#ifndef _3D_DISABLED
|
|
#ifndef _3D_DISABLED
|
|
TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
|
|
TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
|
|
-
|
|
|
|
if (t->process_pass != process_pass) {
|
|
if (t->process_pass != process_pass) {
|
|
t->process_pass = process_pass;
|
|
t->process_pass = process_pass;
|
|
- t->loc = Vector3();
|
|
|
|
- t->rot = Quaternion();
|
|
|
|
- t->rot_blend_accum = 0;
|
|
|
|
- t->scale = Vector3(1, 1, 1);
|
|
|
|
|
|
+ t->loc = t->init_loc;
|
|
|
|
+ t->rot = t->init_rot;
|
|
|
|
+ t->scale = t->init_scale;
|
|
}
|
|
}
|
|
-
|
|
|
|
if (track->root_motion) {
|
|
if (track->root_motion) {
|
|
double prev_time = time - delta;
|
|
double prev_time = time - delta;
|
|
if (!backward) {
|
|
if (!backward) {
|
|
@@ -1232,7 +1216,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- t->scale = t->scale.lerp(scale, blend);
|
|
|
|
|
|
+ t->scale += (scale - t->init_scale) * blend;
|
|
}
|
|
}
|
|
#endif // _3D_DISABLED
|
|
#endif // _3D_DISABLED
|
|
} break;
|
|
} break;
|
|
@@ -1254,7 +1238,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- t->value = Math::lerp(t->value, value, (float)blend);
|
|
|
|
|
|
+ t->value += value * blend;
|
|
#endif // _3D_DISABLED
|
|
#endif // _3D_DISABLED
|
|
} break;
|
|
} break;
|
|
case Animation::TYPE_VALUE: {
|
|
case Animation::TYPE_VALUE: {
|
|
@@ -1271,13 +1255,16 @@ void AnimationTree::_process_graph(double p_delta) {
|
|
}
|
|
}
|
|
|
|
|
|
if (t->process_pass != process_pass) {
|
|
if (t->process_pass != process_pass) {
|
|
- t->value = value;
|
|
|
|
t->process_pass = process_pass;
|
|
t->process_pass = process_pass;
|
|
|
|
+ t->value = value;
|
|
|
|
+ t->value.zero();
|
|
}
|
|
}
|
|
|
|
|
|
- Variant::interpolate(t->value, value, blend, t->value);
|
|
|
|
-
|
|
|
|
|
|
+ Variant::blend(t->value, value, blend, t->value);
|
|
} else {
|
|
} else {
|
|
|
|
+ if (blend < CMP_EPSILON) {
|
|
|
|
+ continue; //nothing to blend
|
|
|
|
+ }
|
|
List<int> indices;
|
|
List<int> indices;
|
|
a->value_track_get_key_indices(i, time, delta, &indices, pingponged);
|
|
a->value_track_get_key_indices(i, time, delta, &indices, pingponged);
|
|
|
|
|
|
@@ -1289,7 +1276,10 @@ void AnimationTree::_process_graph(double p_delta) {
|
|
|
|
|
|
} break;
|
|
} break;
|
|
case Animation::TYPE_METHOD: {
|
|
case Animation::TYPE_METHOD: {
|
|
- if (delta == 0) {
|
|
|
|
|
|
+ if (blend < CMP_EPSILON) {
|
|
|
|
+ continue; //nothing to blend
|
|
|
|
+ }
|
|
|
|
+ if (!seeked && Math::is_zero_approx(delta)) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
TrackCacheMethod *t = static_cast<TrackCacheMethod *>(track);
|
|
TrackCacheMethod *t = static_cast<TrackCacheMethod *>(track);
|
|
@@ -1312,14 +1302,16 @@ void AnimationTree::_process_graph(double p_delta) {
|
|
real_t bezier = a->bezier_track_interpolate(i, time);
|
|
real_t bezier = a->bezier_track_interpolate(i, time);
|
|
|
|
|
|
if (t->process_pass != process_pass) {
|
|
if (t->process_pass != process_pass) {
|
|
- t->value = bezier;
|
|
|
|
t->process_pass = process_pass;
|
|
t->process_pass = process_pass;
|
|
|
|
+ t->value = 0;
|
|
}
|
|
}
|
|
|
|
|
|
- t->value = Math::lerp(t->value, bezier, blend);
|
|
|
|
-
|
|
|
|
|
|
+ t->value += bezier * blend;
|
|
} break;
|
|
} break;
|
|
case Animation::TYPE_AUDIO: {
|
|
case Animation::TYPE_AUDIO: {
|
|
|
|
+ if (blend < CMP_EPSILON) {
|
|
|
|
+ continue; //nothing to blend
|
|
|
|
+ }
|
|
TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track);
|
|
TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track);
|
|
|
|
|
|
if (seeked) {
|
|
if (seeked) {
|
|
@@ -1431,6 +1423,9 @@ void AnimationTree::_process_graph(double p_delta) {
|
|
}
|
|
}
|
|
} break;
|
|
} break;
|
|
case Animation::TYPE_ANIMATION: {
|
|
case Animation::TYPE_ANIMATION: {
|
|
|
|
+ if (blend < CMP_EPSILON) {
|
|
|
|
+ continue; //nothing to blend
|
|
|
|
+ }
|
|
TrackCacheAnimation *t = static_cast<TrackCacheAnimation *>(track);
|
|
TrackCacheAnimation *t = static_cast<TrackCacheAnimation *>(track);
|
|
|
|
|
|
AnimationPlayer *player2 = Object::cast_to<AnimationPlayer>(t->object);
|
|
AnimationPlayer *player2 = Object::cast_to<AnimationPlayer>(t->object);
|
|
@@ -1521,6 +1516,7 @@ void AnimationTree::_process_graph(double p_delta) {
|
|
case Animation::TYPE_POSITION_3D: {
|
|
case Animation::TYPE_POSITION_3D: {
|
|
#ifndef _3D_DISABLED
|
|
#ifndef _3D_DISABLED
|
|
TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
|
|
TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
|
|
|
|
+ t->rot = t->rot.exp();
|
|
|
|
|
|
if (t->root_motion) {
|
|
if (t->root_motion) {
|
|
Transform3D xform;
|
|
Transform3D xform;
|