Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3D rotating/spinning RigidBody bumpy collisions with Trimesh Static Body #50463

Open
Tracked by #45333
Saitodepaula opened this issue Jul 14, 2021 · 22 comments
Open
Tracked by #45333

Comments

@Saitodepaula
Copy link

Saitodepaula commented Jul 14, 2021

Godot version

3.3.2 stable official

System information

Windows 10, GLES 3 NVIDIA GeForce RTX 2060

Issue description

In 3D, when a RigidBody like a sphere or a cyllinder is rotating fast, it bumps and jumps at the triangle edges of a ConcavePolygonShape (generated from a 3D mesh), with Create Trimesh Static Body option. Even on a flat plane this behaviour can be observed.

With Bullet, even with CollisionShape margin set to 0.001, origin at 0,0,0 and Smooth Trimesh Collision activated, it happens.

With Gogot Physics, it also happens, but it's almost imperceptible (look at the ball shadow to see it in the video below).

I know there is #46596 already open, but the author of that issue describes sliding RigidBody.

Also, in #21341, it looks like when Smooth Trimesh Collision was implemented, it targeted sliding bodies.

May be related to #36729?

Steps to reproduce

  1. Import a large plane (example 1 km x 1 km) mesh, from an external 3D modelling software, with subdivisions.
  2. Create Trimesh Static Body from this plane.
  3. Make a RigidBody like a sphere or cyllinder, and make it rotate very fast over the plane.

Minimal reproduction project

The first video show behaviour both on Bullet and Godot Physics (Godot 3.3.2).

The second video is an update (26/01/2022) with Godot 4.0 Alpha 1. In my opinion, this issue got worse in Godot 4 (considering the Godot Physics results in 3.3).

TrimeshCollision.zip

TrimeshCollision.mp4
TrimeshCollision_Godot4.mp4
@Calinou Calinou changed the title 3D rotating/spinning RigidBody bumpy collisions with Trimesh Static Body [Bullet] 3D rotating/spinning RigidBody bumpy collisions with Trimesh Static Body Jul 14, 2021
@pouleyKetchoupp pouleyKetchoupp changed the title [Bullet] 3D rotating/spinning RigidBody bumpy collisions with Trimesh Static Body 3D rotating/spinning RigidBody bumpy collisions with Trimesh Static Body Oct 1, 2021
@Saitodepaula
Copy link
Author

Saitodepaula commented Nov 8, 2021

I've tested the minimal reproduction project on 3.4 using the new method from #50257, setting the COLLISION ITERATIONS to values like 16, 64 and 128, but with no success. The result is a bit different from the original video I've posted, but the problem persists.

And using Godot Physics, just to make sure.

@mustangchavez
Copy link

@pouleyKetchoupp Do you know what causes this to occur? We're using a custom build of the engine to solve a couple other issues and may try to fix this one. Hoping to find a starting point.

@pouleyKetchoupp
Copy link
Contributor

@mustangchavez I haven't investigated, but it looks like rigid bodies are wrongly detecting collision with triangle edges at high speed, maybe because of slight overlaps.

In Bullet, I'm not sure why it fails even when Smooth Trimesh Collision is enabled. Maybe @AndreaCatania knows more about possible limitations.

In Godot Physics, Smooth Trimesh Collision is not implemented at all. So if there's any deeper overlap with the ground you can end up with colliding with triangle edges. I don't know exactly how it works in Bullet, but I imagine it could be implemented by marking triangle edges with a specific normal based on the average between the two neighboring triangles, and take it into account when generating contact points.

Apart from that, when it comes to Godot Physics there's also a general issue with rigid bodies overlapping too much with each other, and I wonder if they also overlap more than they should with static bodies. I'm going to check this issue in the coming weeks, so it would be worth checking again this kind of triangle mesh issue afterwards to see if there's any improvement.

Hope it helps you get a starting point :)
Your help would be very welcome, please share anything you find out!

@AndreaCatania
Copy link
Contributor

Yes, this issue is really annoying and should be fully solved with Smooth Trimesh Collision on Bullet. However, notice that Smooth Trimesh Collision works only if the TrimeshBody shape isn't rotated/transformed/scaled relative to the body and must be the only shape under the object.

@Saitodepaula Is your Trimesh Body respecting that?

@Saitodepaula
Copy link
Author

Saitodepaula commented Nov 22, 2021

@AndreaCatania , the static body and the collision shape are not rotated/transformed/scaled. And Collision Shape margin is at 0.001.

@broag
Copy link

broag commented Jan 19, 2022

@AndreaCatania and @pouleyKetchoupp

Hey guys, I am yet another person who would like to see this issue resolved. I have only a surface level understanding of the Godot BulletPhysics implementation, but I wanted to help however I could. I put together another Godot 3.4 test project that might be useful in diagnosing the issue.

https://github.com/broag/godot-bumpy-sphere

I stuck with Bullet + Smooth Trimesh Collision to test because Godot Physics and just Bullet did not look promising, even though there were circumstances where Godot Physics caused less bumpy behavior. It looks to me like the Smooth Trimesh Collision is only providing stabilization for RigidBodys with physics object primitives that do not rotate or ones that rotate very slowly. Rotating spheres and cylinders don't seem to benefit from the Smooth Trimesh Collision.

Here is a video showing bumpy behavior with some sane defaults I chose (with friction enabled):
https://user-images.githubusercontent.com/6625903/150038528-f5640487-7de2-4e07-8c62-c95e47b282a8.mp4

Here is a video showing no bumpy behavior with the same defaults however friction is 0.0:
https://user-images.githubusercontent.com/6625903/150038572-cc877790-d0e0-47e7-8738-aaa05d233139.mp4

It seems like something about the rotation is causing the problem, could it be a changing contact point thing (I have no clue...)?

I'd love to help solve this issue! I've looked through the commits for the implementation of Smooth Trimesh Collision, but its pretty far beyond my understanding at this point. Any suggestions for a better starting off point or things that can be done to help someone get to a resolution on this?

Thanks!

@Saitodepaula
Copy link
Author

I've just tested this same minimal project on Godot 4.0 Alpha 1, and in the ball script, I've had the error

Invalid call. Nonexistent function 'add_torque' in base 'RigidDynamicBody3D ()'.

The entire script is just this:

extends RigidDynamicBody3D

func _ready():
	pass # Replace with function body.

func _physics_process(delta):
	self.add_torque(Vector3(-1000,0,0))

@broag
Copy link

broag commented Jan 26, 2022

Invalid call. Nonexistent function 'add_torque' in base 'RigidDynamicBody3D ()'.

My first thought is that add_torque got deprecated in Godot 4.0, but I haven't verified. Either way, you can use add_central_force to achieve the same rolling effect if friction is non-zero.

@Saitodepaula
Copy link
Author

Saitodepaula commented Jan 26, 2022

My first thought is that add_torque got deprecated in Godot 4.0, but I haven't verified. Either way, you can use add_central_force to achieve the same rolling effect if friction is non-zero.

It may be. The documentation is being updated. For example, add_central_force is now add_constant_central_force, but in the docs, it's still add_central_force.

For this example, the result is the same, but for a wheel of a vehicle it's not the same. So I hope add_torque has not been removed.

Anyway, I've updated the first post with a video using Godot 4, using add_constant_central_force, and in my opinion the result is now worse (the ball jumps even higher), considering the Godot Physics results in 3.3.

@broag
Copy link

broag commented Jan 26, 2022

I noticed that there were definitely differences between Godot Physics and Bullet Physics as well. The default physics engine switched from Bullet to Godot Physics in Godot 4.0. It would be helpful to verify with physics engine you are using for the videos. Bullet w/ Trimesh? or Godot Physics by default?

@Saitodepaula
Copy link
Author

Saitodepaula commented Jan 26, 2022

I noticed that there were definitely differences between Godot Physics and Bullet Physics as well. The default physics engine switched from Bullet to Godot Physics in Godot 4.0. It would be helpful to verify with physics engine you are using for the videos. Bullet w/ Trimesh? or Godot Physics by default?

Godot 3.3: both engines, in the first video you can see I tested both.
Godot 4.0: there is no option to change it, so, it's Godot Physics.

@broag
Copy link

broag commented Jan 26, 2022

I just read that Bullet Physics will be supported by an official plugin for Godot 4.0 (no idea what the current status is), but honestly I'm happy to use any engine that fixes this problem.

@Calinou
Copy link
Member

Calinou commented Jan 26, 2022

I just read that Bullet Physics will be supported by an official plugin for Godot 4.0 (no idea what the current status is), but honestly I'm happy to use any engine that fixes this problem.

I doubt this will be done in time for 4.0.

@valknor
Copy link

valknor commented Feb 23, 2022

Has anyone found a workaround for this problem? I was starting to make more complicated test models for my map, and ran into the same problem. I've been working on this game for about two months, and feel like I've run into a dead end. The player character is a Rigid Body sphere which uses add_torque for movement. I'm running into this problem with both Bullet and Godot physics.

Edit:

If anyone was wondering, I'm trying to make a game similar to this: https://youtu.be/6vtTBc65ZVc

EDIT 2:

I found the smooth_trimesh_collision option inside Godot_v3.4.3-rc2_x11.64 I'm not sure why it wasn't in 3.4.2. Now when I open 3.4.2 the option shows up for this project (which is now bugged in other ways, fortunately I have a backup). It doesn't seem to help in either version of Godot, nor with either version of Godot Physics.

EDIT 3:

So, this problem can be reduced, at least for me by increasing the physics frames from 60 to 240. It's probably not an ideal solution, as this may reduce the number of devices that can play the game, but it seems to make the problem almost unnoticeable in my project. I've had the best luck here with Bullet Physics, as Godot Physics introduces a new problem where the ball will suddenly freeze in place, and I haven't had any success fixing that.

@Noah-Huppert
Copy link

I suspect I might be running into this bug re this q&a post I made: https://godotengine.org/qa/137705/rigidbody-get_contact_local_normal-jumps-passing-collision

@Noah-Huppert
Copy link

Noah-Huppert commented Aug 25, 2022

I enabled "Smooth Trimesh Collision" and switched to "GodotPhysics" for my project. The collision normals seem to be more stable now

Here is a video of the player's camera being rotated based on the player's collision Z axis:

godot-brap-ball-not-jumping.gif0001-0802.mp4

Graph of the normal's Z axis from that video:
image

I also updated to 3.5 from 3.4.4 but I'm not sure if that helped.

@Saitodepaula
Copy link
Author

I suspect I might be running into this bug re this q&a post I made: https://godotengine.org/qa/137705/rigidbody-get_contact_local_normal-jumps-passing-collision

I have opened an issue very similar to your problem (I did test almost the same test you did): #36729.

@Calinou
Copy link
Member

Calinou commented Dec 6, 2022

As mentioned in Shifty's Godot Character Movement Manifesto, the current workaround is to merge the adjacent colliders into a single convex collider shape:

  • Sets of small adjacent colliders (such as a checkered floor) cause the character to collide with their edges and pop into the air
    • Manually combine sets of small adjacent colliders into one larger collider by aggregating their vertices inside a ConvexPolygonShape

@Zireael07
Copy link
Contributor

@Calinou This should be documented in Godot docs themselves, not in 3rd party site

@YuriSizov YuriSizov modified the milestones: 4.0, 4.1 Feb 27, 2023
@YuriSizov YuriSizov modified the milestones: 4.1, 4.2 Jun 22, 2023
@YuriSizov YuriSizov removed this from the 4.2 milestone Nov 14, 2023
@Tr1bute
Copy link

Tr1bute commented Feb 9, 2024

This issue is still occurring on Godot 4.2 using a RigidBody3D with a sphere CollisionShape3D. Merging colliders is not a relevant workaround, because this also occurs on the internal edges of a single convex collision shape.

I'd also like to add that it also happens on 'sliding', with linear velocity.

  • Default Godot Physics Engine
Godot_v4.2_9OwWuGnoGO.mp4

Also occurs in Jolt (spinning):

2024-01-27.04-56-56.mp4

@Tr1bute
Copy link

Tr1bute commented Feb 21, 2024

The latest version of Jolt merged Jan 20, 2024 has mitigated this problem: jrouwe/JoltPhysics#882

This was pulled into GodotJolt on Feb 2. 2024:
godot-jolt/godot-jolt#767

With an internal edge removal setting added on Feb 12. 2024:
godot-jolt/godot-jolt#775

This tweet by jrouwe talks about the fix:
https://twitter.com/jrouwe/status/1748821475623088550?s=20

They link to a source which explains the improved algorithm here, that could potentially be implemented into the Godot physics engine? https://www.codercorner.com/blog/?p=1156

As of the current date, the fix in the Jolt physics engine is not available in the release version of Godot Jolt, so it has to be built from the Godot Jolt source. Instructions can be found here: https://github.com/godot-jolt/godot-jolt/blob/master/docs/building.md

I confirmed this in my own project, and so far I have not experienced ghost collisions on internal edges. I hope this will be helpful to anyone passing by.

@Ughuuu
Copy link
Contributor

Ughuuu commented Aug 8, 2024

I wanna add to this discussion what I ended up doing in the Godot Rapier plugin ghost collisions:

ghost_collisions

The idea is from http://briansemrau.github.io/dealing-with-ghost-collisions/. If the movement direction interacts with something that completely opposes it and the intersection distance is small enough, I disregard that contact point and eliminate it.

Right now this is tested just for 2D, but it's also for 3D, just need to test it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests