@@ -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,46 @@ 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+ // calculate the true weights before hand
350375 for (int i = 0 ; i < blend_points_used; i++) {
376+ bool found = false ;
351377 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) {
378+ blend_points[i].weight = (smooth && sync) ? Math::move_toward (blend_points[i].weight , weights[i], static_cast <float >(pi.delta * smooth_speed)) : weights[i];
379+ if (first || blend_points[i].weight > max_weight) {
355380 max_weight = pi.weight ;
356- mind = t;
357381 first = false ;
358382 }
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);
383+ found = true ;
384+ }
385+ if (!found) {
386+ if (sync) {
387+ blend_points[i].weight = (smooth) ? MAX (Math::move_toward (blend_points[i].weight , 0 .0f , static_cast <float >(pi.delta * smooth_speed)), 0.0 ) : 0.0 ;
388+ } else {
389+ blend_points[i].weight = -1.0 ;
390+ }
391+ }
392+ }
393+ float sum_of_weight = 0.0 ;
394+ if (smooth && sync) {
395+ for (int i = 0 ; i < blend_points_used; i++) {
396+ sum_of_weight += blend_points[i].weight ;
397+ }
398+ if (sum_of_weight <= 0.0 ) {
399+ sum_of_weight = 1.0 ;
400+ }
401+ }
402+ // now we apply them
403+ for (int i = 0 ; i < blend_points_used; i++) {
404+ blend_points[i].weight = (smooth && sync) ? blend_points[i].weight / sum_of_weight : blend_points[i].weight ;
405+ if (blend_points[i].weight == -1.0 ) {
406+ continue ;
407+ }
408+ pi.weight = blend_points[i].weight ;
409+ NodeTimeInfo t = blend_node (blend_points[i].node , blend_points[i].name , pi, FILTER_IGNORE, true , p_test_only);
410+ if (mind_idx == i) {
411+ mind = t;
362412 }
363413 }
364414 } else {
0 commit comments