godot icon indicating copy to clipboard operation
godot copied to clipboard

Generic6DOFJoint3D Motors and Springs not working

Open ellogwen opened this issue 2 years ago • 20 comments

Godot version

4.0 Beta 1

System information

Linux (but it doesn't matter)

Issue description

First I thought it was a bug, since I didn't get the motors and springs of the Generic6DOFJoint3D to work, after I looked up the source code https://github.com/godotengine/godot/blob/bcf754d735249a779469839455d925cf42b48057/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp I saw that it was just not implemented.

Will this be available in the final 4 release or is 3D physics not in scope yet?

Steps to reproduce

Add a Generic6DOFJoint3D, setup motors or springs, see them do nothing

Minimal reproduction project

No response

ellogwen avatar Sep 24 '22 06:09 ellogwen

Will this be available in the final 4 release or is 3D physics not in scope yet?

We don't know if this will be implemented in time for 4.0, as there are few physics contributors.

Calinou avatar Sep 24 '22 15:09 Calinou

@Calinou

If you can't fix it, can you rollback to Bullet physics? Also my issue seems to be the same as this one:

https://github.com/godotengine/godot/issues/68852

ArseniyMirniy avatar Nov 23 '22 22:11 ArseniyMirniy

See #68852 for a MRP for angular motor.

akien-mga avatar Nov 24 '22 11:11 akien-mga

And from #68852 limiters also won't work properly (on Hinge 3D as well), if the motor is enabled and limiters values aren't 0-0.

  • If the motor is enabled, limiters will be passed easily and the connected body will be rotated 360
  • If the motor is enabled and limiters set to 0-0, it will be limited by 0-0
  • If the motor is disabled, but limiter is enabled, any value will work

ArseniyMirniy avatar Nov 24 '22 11:11 ArseniyMirniy

@akien-mga Any plans for 4.1?

ArseniyMirniy avatar Mar 09 '23 22:03 ArseniyMirniy

Nobody is working on this specifically right now, so I can't make any promise. Any interested contributor is welcome to have a go at implementing this joint in GodotPhysics.

akien-mga avatar Mar 09 '23 23:03 akien-mga

I've looked a bit through the code and it looks like the Godot Physics 6dof joint code is based on an early version from Bullet, so it may be possible to update it to a more recent version of that code which has the motor/spring support. I'm willing to take a stab at it, but to set expectations I'm very short on spare time, so no idea how much and how fast I can make progress. If anyone with more time would like to take this on, let me know.

thierryreding avatar Apr 02 '23 18:04 thierryreding

I've looked a bit through the code and it looks like the Godot Physics 6dof joint code is based on an early version from Bullet, so it may be possible to update it to a more recent version of that code which has the motor/spring support. I'm willing to take a stab at it, but to set expectations I'm very short on spare time, so no idea how much and how fast I can make progress. If anyone with more time would like to take this on, let me know.

Hello, mate! Did you manage to advance somehow in resolving this issue?

Tony2371 avatar Apr 15 '23 11:04 Tony2371

Not really. Turns out this isn't as simple as updating the code to a more recent version from Bullet. The Bullet module in Godot 3.5 uses a variant of the 6dof joint that has significantly changed since the version that Godot Physics forked from a long time ago. The existing Godot Physics 6dof joint also has a couple of oddities that make it behave completely differently from the version in 3.5. For example, if you constrain the Y axis to upper and lower limits of 0 (meaning that it shouldn't move at all on the Y axis), I still see it move down a little bit (about 0.2 units over the first half a second or so) under the influence of gravity.

So after a bit of investigation I tried to incrementally improve the existing code, but given the time constraints I made very little progress. I managed to implement a linear motor that seems to work to some degree, though, again, it behaves slightly differently from Godot 3.5. I also experimented a bit with the linear spring component, but haven't managed to get something that behaves in a stable way (i.e. depending on the stiffness/damping, it can oscillate completely out of control).

I tried to read up a bit on motors/springs and physics solvers in general, but the time constraints make this progress really slow. My tentative plan is to look at angular motors/springs next, which is what I originally wanted to have for an idea that I wanted to play around with (I started with linear because I thought it'd be simpler...). There's a lot of commonality between linear and angular motors/springs, at least in the Bullet code, so progress on any of those should impact the other as well.

I also looked around various other physics engines for inspiration, but they all work in slightly different ways and I wanted to keep as close to the behavior of Godot 3.5 as possible, to make migration to Godot 4 more seamless. Which brings me to another thing that I've been pondering: if we want Godot 4 to behave as closely as possible to Godot 3.5, maybe it'd be better to forward-port the Bullet module rather than essentially duplicating Bullet's code in Godot. I understand that there's been a plan for that anyway, so perhaps for the 6dof joint in particular that'd be easier. I've played around with some of the other joints and they seem to work fairly well, as do unconstrained physics.

The code is a bit messy right now, but I'll try to clean things up a bit and upload what I have if anybody wants to give this a go. One thing that would be nice to have is a collection of small demos that use 6dof joints. So far I've been creating use-cases myself, but that's obviously very biased and also time-consuming.

thierryreding avatar Apr 17 '23 08:04 thierryreding

Not really. Turns out this isn't as simple as updating the code to a more recent version from Bullet. The Bullet module in Godot 3.5 uses a variant of the 6dof joint that has significantly changed since the version that Godot Physics forked from a long time ago. The existing Godot Physics 6dof joint also has a couple of oddities that make it behave completely differently from the version in 3.5. For example, if you constrain the Y axis to upper and lower limits of 0 (meaning that it shouldn't move at all on the Y axis), I still see it move down a little bit (about 0.2 units over the first half a second or so) under the influence of gravity.

So after a bit of investigation I tried to incrementally improve the existing code, but given the time constraints I made very little progress. I managed to implement a linear motor that seems to work to some degree, though, again, it behaves slightly differently from Godot 3.5. I also experimented a bit with the linear spring component, but haven't managed to get something that behaves in a stable way (i.e. depending on the stiffness/damping, it can oscillate completely out of control).

I tried to read up a bit on motors/springs and physics solvers in general, but the time constraints make this progress really slow. My tentative plan is to look at angular motors/springs next, which is what I originally wanted to have for an idea that I wanted to play around with (I started with linear because I thought it'd be simpler...). There's a lot of commonality between linear and angular motors/springs, at least in the Bullet code, so progress on any of those should impact the other as well.

I also looked around various other physics engines for inspiration, but they all work in slightly different ways and I wanted to keep as close to the behavior of Godot 3.5 as possible, to make migration to Godot 4 more seamless. Which brings me to another thing that I've been pondering: if we want Godot 4 to behave as closely as possible to Godot 3.5, maybe it'd be better to forward-port the Bullet module rather than essentially duplicating Bullet's code in Godot. I understand that there's been a plan for that anyway, so perhaps for the 6dof joint in particular that'd be easier. I've played around with some of the other joints and they seem to work fairly well, as do unconstrained physics.

The code is a bit messy right now, but I'll try to clean things up a bit and upload what I have if anybody wants to give this a go. One thing that would be nice to have is a collection of small demos that use 6dof joints. So far I've been creating use-cases myself, but that's obviously very biased and also time-consuming.

Actually you have already advanced a lot! I hope there will be some kind of solution any time soon

Tony2371 avatar Apr 17 '23 08:04 Tony2371

I've uploaded a branch that has working linear and angular motors implemented (the angular motors are mostly based on the Hinge Joint code):

https://github.com/thierryreding/godot/tree/6dof

The history isn't cleaned up on purpose, for my own reference. I'll clean it up eventually. Next up will be springs, but based on some experiments I've been doing I'm not overly confident that I can make them work. There's also potential to clean up some of the existing code. Feel free to give this a try. I've also uploaded the demo project I use to test these:

https://github.com/thierryreding/godot-physics

thierryreding avatar Apr 24 '23 22:04 thierryreding

Tested your code with non-zero linear limits and motor enabled and it seems to work. I noticed that opposing motor forces lead to body movement although being identical. But maybe that has nothing to do with your specific code. Also, motor velocities behave odd (out of scale, increasing velocity parameters sometimes result in lower velocities).

markusneg avatar May 05 '23 14:05 markusneg

For anyone interested in springs, I've just discovered a good video on YouTube explaining how to make Active Ragdolls in Godot 4.0

The author also has this repo with an example project featuring Active Ragdolls.

It can be helpful for developers who want to implement angular springs in their Godot 4 project themselves as a workaround, or for engine contributors working on adding this feature to the Godot Physics Engine.

alex-karev avatar Aug 28 '23 09:08 alex-karev

Yeah, it is fixed by the Jolt Physics. : )

6dof_test

It is missing a script in the mrp to test this, so:


extends Node3D

func _physics_process(delta: float) -> void:
	$Generic6DOFJoint3D3.set_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, -8)
	$Generic6DOFJoint3D2.set_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, -8)
	$Generic6DOFJoint3D.set_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, -8)
	$Generic6DOFJoint3D4.set_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, -8)

AttackButton avatar Sep 20 '23 18:09 AttackButton

Yeah, it is fixed by the Jolt Physics. : )

6dof_test 6dof_test

It is missing a script in the mrp to test this, so:


extends Node3D

func _physics_process(delta: float) -> void:
	$Generic6DOFJoint3D3.set_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, -8)
	$Generic6DOFJoint3D2.set_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, -8)
	$Generic6DOFJoint3D.set_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, -8)
	$Generic6DOFJoint3D4.set_param_x(Generic6DOFJoint3D.PARAM_ANGULAR_MOTOR_TARGET_VELOCITY, -8)

In my demo, the motion was set in node settings (not script)

But thanks a lot anyway! Jolt should become the default option!

ArseniyMirniy avatar Sep 20 '23 21:09 ArseniyMirniy

But thanks a lot anyway! Jolt should become the default option!

At least it should be included inside the engine, not as external addon. I miss Bullet too much...

GrauBlitz avatar Sep 23 '23 08:09 GrauBlitz

At least it should be included inside the engine, not as external addon. I miss Bullet too much...

See https://github.com/godotengine/godot-proposals/issues/7308.

Calinou avatar Sep 26 '23 21:09 Calinou