godot
godot copied to clipboard
Generic6DOFJoint3D Motors and Springs not working
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
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
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
See #68852 for a MRP for angular motor.
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
@akien-mga Any plans for 4.1?
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.
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.
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?
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.
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
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
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).
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.
Yeah, it is fixed by the Jolt Physics. : )
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)
Yeah, it is fixed by the Jolt Physics. : )
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!
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...
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.