How can I change PinJoint2d's rest position of either node (A or B) dynamically in code, without creating a new joint?

By "Rest position" I mean relative position between nodes, that the joint tries to achieve by applying force to them.
It's set up when you first join them all up, but I can't seem to find a way to change it later (neither by code or the editor).

Is there a way to do it without reattaching everything?

in Engine
edited

What do you mean by "rest position"?

Relative position between nodes that the pinJoint tries to achieve.
You know, position of nodes in which pinJoint doesn't apply any force to them anymore.
It's set up when you attach joint to both nodes, but I can't find a way to change it after that....
(Sorry for confusion...)

Oh okay now I understand. :)

As far as I know there is no possibility in changing the distance between the two nodes which the PinJoint2d wants to reach. This would be an interesting feature so you could propose it in the github issues!

I'm not comfortable with Godots codebase, but if I'm not mistaken the resting distance is calculated with the help of the relative vectors `rA` and `rB` which are constructed by `anchor_A` and `anchor_B`:

``````rA = A->get_transform().basis_xform(anchor_A);
rB = B ? B->get_transform().basis_xform(anchor_B) : anchor_B;
``````

(Can be found here)

The problem is that the initial positions of node A (`p_body_a`) and node B (`p_body_b`) are used to define these vectors when the PinJoint is created (in the constructor):

``````anchor_A = p_body_a->get_inv_transform().xform(p_pos);
anchor_B = p_body_b ? p_body_b->get_inv_transform().xform(p_pos) : p_pos;
``````

(Found here)

So as long as `anchor_A` and `anchor_B` can't be recalculated there is no way of changing this "resting distance".

by (1,032 points)
edited

That's too bad :(
I'll definietly propose it as I think it should be possible...

You can link to the issue here so when people are curious if that changed somewhen in the future they can get more information on github.

I took a peek at the source code, assuming you are using Godot 3.

You want `_configure_joint` to be called, because it recreates the joint object in the physics server, which will use the current position of both bodies to determine the rest position.

`_configure_point` is called from `_update_joint`.

`_update_joint` gets called in several cases:

The latter is probably the most robust way of doing this. Note that the value must actually change for it to work. So you can use this workaround:

``````pin_joint.disable_collision = !pin_joint.disable_collision
pin_joint.disable_collision = !pin_joint.disable_collision
``````

Removing the node from the tree (`remove_child`) and adding it again (`add_child`) should also work, but it can mess with the ordering of nodes so it's not entirely free of side effects.

by (18 points)