2929/* *************************************************************************/
3030
3131#include " soft_body_3d.h"
32+ #include " soft_body_3d.compat.inc"
3233
3334#include " scene/3d/physics/physics_body_3d.h"
3435
@@ -200,12 +201,18 @@ bool SoftBody3D::_set_property_pinned_points_indices(const Array &p_indices) {
200201 int point_index;
201202 for (int i = 0 ; i < p_indices_size; ++i) {
202203 point_index = p_indices.get (i);
203- if (w[i].point_index != point_index) {
204- if (-1 != w[i].point_index ) {
204+ if (w[i].point_index != point_index || pinned_points.size () < p_indices_size) {
205+ bool insert = false ;
206+ if (w[i].point_index != -1 && p_indices.find (w[i].point_index ) == -1 ) {
205207 pin_point (w[i].point_index , false );
208+ insert = true ;
206209 }
207210 w[i].point_index = point_index;
208- pin_point (w[i].point_index , true );
211+ if (insert) {
212+ pin_point (w[i].point_index , true , NodePath (), i);
213+ } else {
214+ pin_point (w[i].point_index , true );
215+ }
209216 }
210217 }
211218 return true ;
@@ -356,7 +363,7 @@ void SoftBody3D::_bind_methods() {
356363
357364 ClassDB::bind_method (D_METHOD (" get_point_transform" , " point_index" ), &SoftBody3D::get_point_transform);
358365
359- ClassDB::bind_method (D_METHOD (" set_point_pinned" , " point_index" , " pinned" , " attachment_path" ), &SoftBody3D::pin_point, DEFVAL (NodePath ()));
366+ ClassDB::bind_method (D_METHOD (" set_point_pinned" , " point_index" , " pinned" , " attachment_path" , " insert_at " ), &SoftBody3D::pin_point, DEFVAL (NodePath ()), DEFVAL (- 1 ));
360367 ClassDB::bind_method (D_METHOD (" is_point_pinned" , " point_index" ), &SoftBody3D::is_point_pinned);
361368
362369 ClassDB::bind_method (D_METHOD (" set_ray_pickable" , " ray_pickable" ), &SoftBody3D::set_ray_pickable);
@@ -668,10 +675,11 @@ void SoftBody3D::pin_point_toggle(int p_point_index) {
668675 pin_point (p_point_index, !(-1 != _has_pinned_point (p_point_index)));
669676}
670677
671- void SoftBody3D::pin_point (int p_point_index, bool pin, const NodePath &p_spatial_attachment_path) {
678+ void SoftBody3D::pin_point (int p_point_index, bool pin, const NodePath &p_spatial_attachment_path, int p_insert_at) {
679+ ERR_FAIL_COND_MSG (p_insert_at < -1 || p_insert_at >= pinned_points.size (), " Invalid index for pin point insertion position." );
672680 _pin_point_on_physics_server (p_point_index, pin);
673681 if (pin) {
674- _add_pinned_point (p_point_index, p_spatial_attachment_path);
682+ _add_pinned_point (p_point_index, p_spatial_attachment_path, p_insert_at );
675683 } else {
676684 _remove_pinned_point (p_point_index);
677685 }
@@ -730,7 +738,7 @@ void SoftBody3D::_pin_point_on_physics_server(int p_point_index, bool pin) {
730738 PhysicsServer3D::get_singleton ()->soft_body_pin_point (physics_rid, p_point_index, pin);
731739}
732740
733- void SoftBody3D::_add_pinned_point (int p_point_index, const NodePath &p_spatial_attachment_path) {
741+ void SoftBody3D::_add_pinned_point (int p_point_index, const NodePath &p_spatial_attachment_path, int p_insert_at ) {
734742 SoftBody3D::PinnedPoint *pinned_point;
735743 if (-1 == _get_pinned_point (p_point_index, pinned_point)) {
736744 // Create new
@@ -743,7 +751,11 @@ void SoftBody3D::_add_pinned_point(int p_point_index, const NodePath &p_spatial_
743751 pp.offset = (pp.spatial_attachment ->get_global_transform ().affine_inverse () * get_global_transform ()).xform (PhysicsServer3D::get_singleton ()->soft_body_get_point_global_position (physics_rid, pp.point_index ));
744752 }
745753
746- pinned_points.push_back (pp);
754+ if (p_insert_at != -1 ) {
755+ pinned_points.insert (p_insert_at, pp);
756+ } else {
757+ pinned_points.push_back (pp);
758+ }
747759
748760 } else {
749761 pinned_point->point_index = p_point_index;
0 commit comments