@@ -104,6 +104,12 @@ void AnimationNodeBlendSpace1D::_bind_methods() {
104104 ClassDB::bind_method (D_METHOD (" set_use_sync" , " enable" ), &AnimationNodeBlendSpace1D::set_use_sync);
105105 ClassDB::bind_method (D_METHOD (" is_using_sync" ), &AnimationNodeBlendSpace1D::is_using_sync);
106106
107+ ClassDB::bind_method (D_METHOD (" set_smooth_speed" , " speed" ), &AnimationNodeBlendSpace1D::set_smooth_speed);
108+ ClassDB::bind_method (D_METHOD (" get_smooth_speed" ), &AnimationNodeBlendSpace1D::get_smooth_speed);
109+
110+ ClassDB::bind_method (D_METHOD (" set_use_smooth" , " enable" ), &AnimationNodeBlendSpace1D::set_use_smooth);
111+ ClassDB::bind_method (D_METHOD (" is_using_smooth" ), &AnimationNodeBlendSpace1D::is_using_smooth);
112+
107113 ClassDB::bind_method (D_METHOD (" _add_blend_point" , " index" , " node" ), &AnimationNodeBlendSpace1D::_add_blend_point);
108114
109115 for (int i = 0 ; i < MAX_BLEND_POINTS; i++) {
@@ -117,6 +123,8 @@ void AnimationNodeBlendSpace1D::_bind_methods() {
117123 ADD_PROPERTY (PropertyInfo (Variant::STRING, " value_label" , PROPERTY_HINT_NONE, " " , PROPERTY_USAGE_NO_EDITOR), " set_value_label" , " get_value_label" );
118124 ADD_PROPERTY (PropertyInfo (Variant::INT, " blend_mode" , PROPERTY_HINT_ENUM, " Interpolated,Discrete,Carry" , PROPERTY_USAGE_NO_EDITOR), " set_blend_mode" , " get_blend_mode" );
119125 ADD_PROPERTY (PropertyInfo (Variant::BOOL, " sync" , PROPERTY_HINT_NONE, " " , PROPERTY_USAGE_NO_EDITOR), " set_use_sync" , " is_using_sync" );
126+ ADD_PROPERTY (PropertyInfo (Variant::BOOL, " smooth" , PROPERTY_HINT_NONE, " " , PROPERTY_USAGE_NO_EDITOR), " set_use_smooth" , " is_using_smooth" );
127+ ADD_PROPERTY (PropertyInfo (Variant::FLOAT, " smooth_speed" , PROPERTY_HINT_NONE, " " , PROPERTY_USAGE_NO_EDITOR), " set_smooth_speed" , " get_smooth_speed" );
120128
121129 BIND_ENUM_CONSTANT (BLEND_MODE_INTERPOLATED);
122130 BIND_ENUM_CONSTANT (BLEND_MODE_DISCRETE);
@@ -269,6 +277,21 @@ bool AnimationNodeBlendSpace1D::is_using_sync() const {
269277 return sync;
270278}
271279
280+ void AnimationNodeBlendSpace1D::set_smooth_speed (const float &p_speed) {
281+ smooth_speed = p_speed;
282+ }
283+
284+ float AnimationNodeBlendSpace1D::get_smooth_speed () const {
285+ return smooth_speed;
286+ }
287+ void AnimationNodeBlendSpace1D::set_use_smooth (const bool &p_smooth) {
288+ smooth = p_smooth;
289+ }
290+
291+ bool AnimationNodeBlendSpace1D::is_using_smooth () const {
292+ return smooth;
293+ }
294+
272295void AnimationNodeBlendSpace1D::_add_blend_point (int p_index, const Ref<AnimationRootNode> &p_node) {
273296 if (p_index == blend_points_used) {
274297 add_blend_point (p_node, 0 );
@@ -281,7 +304,6 @@ AnimationNode::NodeTimeInfo AnimationNodeBlendSpace1D::_process(const AnimationM
281304 if (!blend_points_used) {
282305 return NodeTimeInfo ();
283306 }
284-
285307 AnimationMixer::PlaybackInfo pi = p_playback_info;
286308
287309 if (blend_points_used == 1 ) {
@@ -347,18 +369,48 @@ AnimationNode::NodeTimeInfo AnimationNodeBlendSpace1D::_process(const AnimationM
347369 // actually blend the animations now
348370 bool first = true ;
349371 double max_weight = 0.0 ;
372+
373+ int mind_idx = 0 ;
374+ Engine *eng = Engine::get_singleton ();
375+ double delta = eng->get_process_step () * eng->get_time_scale ();
376+ // calculate the true weights before hand
350377 for (int i = 0 ; i < blend_points_used; i++) {
378+ bool found = false ;
351379 if (i == point_lower || i == point_higher) {
352- pi.weight = weights[i];
353- NodeTimeInfo t = blend_node (blend_points[i].node , blend_points[i].name , pi, FILTER_IGNORE, true , p_test_only);
354- if (first || pi.weight > max_weight) {
380+ blend_points[i].weight = (smooth && sync) ? Math::move_toward (blend_points[i].weight , weights[i], static_cast <float >(delta * smooth_speed)) : weights[i];
381+ if (first || blend_points[i].weight > max_weight) {
355382 max_weight = pi.weight ;
356- mind = t;
357383 first = false ;
358384 }
359- } else if (sync) {
360- pi.weight = 0 ;
361- blend_node (blend_points[i].node , blend_points[i].name , pi, FILTER_IGNORE, true , p_test_only);
385+ found = true ;
386+ }
387+ if (!found) {
388+ if (sync) {
389+ blend_points[i].weight = (smooth) ? MAX (Math::move_toward (blend_points[i].weight , 0 .0f , static_cast <float >(delta * smooth_speed)), 0.0 ) : 0.0 ;
390+ } else {
391+ blend_points[i].weight = -1.0 ;
392+ }
393+ }
394+ }
395+ float sum_of_weight = 0.0 ;
396+ if (smooth && sync) {
397+ for (int i = 0 ; i < blend_points_used; i++) {
398+ sum_of_weight += blend_points[i].weight ;
399+ }
400+ if (sum_of_weight <= 0.0 ) {
401+ sum_of_weight = 1.0 ;
402+ }
403+ }
404+ // now we apply them
405+ for (int i = 0 ; i < blend_points_used; i++) {
406+ blend_points[i].weight = (smooth && sync) ? blend_points[i].weight / sum_of_weight : blend_points[i].weight ;
407+ if (blend_points[i].weight == -1.0 ) {
408+ continue ;
409+ }
410+ pi.weight = blend_points[i].weight ;
411+ NodeTimeInfo t = blend_node (blend_points[i].node , blend_points[i].name , pi, FILTER_IGNORE, true , p_test_only);
412+ if (mind_idx == i) {
413+ mind = t;
362414 }
363415 }
364416 } else {
0 commit comments