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

[Bullet] Convex Collision Sibling wrong margin with Bullet #27427

Open
Tracked by #45022
rogeriodec opened this issue Mar 26, 2019 · 9 comments
Open
Tracked by #45022

[Bullet] Convex Collision Sibling wrong margin with Bullet #27427

rogeriodec opened this issue Mar 26, 2019 · 9 comments

Comments

@rogeriodec
Copy link

Godot version:
3.1

OS/device including version:
Windows 10 x64 / NVIDIA GeForce GTX 1060 6GB / Intel Core i7 4790K

Issue description:
When a CollisionShape is created from a mesh using "Create Convex Collision Sibling", it's being it is getting away from the bottom cube by the "collision margin" distance (0.04):

image

This only happens with ConvexPolygonShape.

With ConcavePolygonShape or even a BoxShape or other native collision shapes, this does not occur.

image

Steps to reproduce:

  1. Run the attached project. It's with a CollisionShape as ConvexPolygonShape and you'll see the margin.
  2. Change the red cube CollisionShape to BoxShape or generate a ConcavePolygonShape and the margin is not there.

Minimal reproduction project:
testes.zip

@akien-mga
Copy link
Member

This is still reproducible in 3.2.2 RC 2 with the above project.

It only affects the Bullet backend, GodotPhysics doesn't have this margin.

CC @AndreaCatania @madmiraal

@akien-mga akien-mga changed the title Convex Collision Sibling wrong margin Convex Collision Sibling wrong margin with Bullet Jun 22, 2020
@AndreaCatania
Copy link
Contributor

It's how bullet handles the margin. Depending the shape type, it may add or remove the specified amount of margin; this because each algorithm perform better with positive or negative margin.

Try to lower the 0.04 margin to something smaller or increase the mesh size.

Make the engine to automatically mask this margin is not a good idea IMO.

@akien-mga
Copy link
Member

Maybe this should be documented in the ConvexPolygonShape class reference?

And/or it might be worth having a doc page about differences between GodotPhysics and Bullet, like we have for GLES2 vs GLES3.

@AndreaCatania
Copy link
Contributor

AndreaCatania commented Jun 22, 2020

Yes, I think that would be useful have the list of the various differences.
Document this behaviour would be really useful too, but I would add somewhere globally, because it's true for all the shapes.

@madmiraal
Copy link
Contributor

I would still consider this a bug, because the type of Shape used shouldn't change it's behaviour.

It brings up the debate on why collision masks are required and how they are used. As @AndreaCatania points out, the margin makes the GJK distance algorithm an efficient way of determining collisions by terminating if the distance is known to be less than the margin.

In Bullet physics Spheres and Capsules are all margin around a point or a line respectively, whereas Boxes become rounded as shown beautifully here. To make sure a BoxShape is not bigger than expected, the size can be adjusted proportionally. However, this is not happening with the ConvexPolygonShape; hence the gap presented in this issue.

Godot uses collision margins differently. I've described this in detail here, but the short, over-simplified version is: it uses the margin to push objects apart and then allows them to come back together again.

@akien-mga akien-mga added the bug label Jun 23, 2020
@AndreaCatania
Copy link
Contributor

The reason why I would not mark this as bug is because try to mask this issue by making the shape bigger or smaller than the mesh, when generating the collision shape is not a good option: Each physics engine has its own way to handle the margins and just mask this issue will just invert the problem, that will be then present with Godot Physics.

However, this is not all; because someone may add another physics engine (even if not supported by the Godot community, or just privately for their game).

In any case, the differences between physics engines exists (otherwise would not even make sense integrate a new one), and all the features of the Game Engine should just do the "right" thing. So is better document instead of mask the various differences between physics engines.

Of course, this is not always true, but for this case I think that is better document the difference and allow the developer choose how to deal with it:

  • Use Godot Physics.
  • Generate a bigger mesh or a smaller shape.
  • Change the margin value.

@madmiraal
Copy link
Contributor

I don't know what the solution is. I haven't looked into it. I'm definitely not suggesting the issue is masked; for all the reasons stated and more. But not knowing what the solution is doesn't stop it from being a bug. Whether the issue lies within Bullet or within Godot's implementation of Bullet doesn't stop it from being a bug. In the meantime, I agree that, as long as there isn't a solution, the known issue should be documented.

@jitspoe
Copy link
Contributor

jitspoe commented Jul 15, 2020

I think the best solution at the moment is to make the margin very small and use double precision in bullet. The 4cm margin (8cm total between 2 objects) is pretty massive, and not only does it create gaps, but it creates potentially undesired behavior along edges (unexpected normals).

@hoontee
Copy link
Contributor

hoontee commented Jul 27, 2020

The issue isn't easily fixable for CollisionPolygons due to the lack of a margin property. You'd have to create new ConvexPolygonShapes with the mesh data and corrected margins:

if parent is PhysicsBody and child is CollisionPolygon:
	var body = parent.get_rid()
	for i in PhysicsServer.body_get_shape_count(body):
		var shape = PhysicsServer.body_get_shape(body, i)
		if PhysicsServer.shape_get_type(shape) == PhysicsServer.SHAPE_CONVEX_POLYGON:
			var new_convex_polygon_shape = ConvexPolygonShape.new()
			new_convex_polygon_shape.margin = 0
			new_convex_polygon_shape.set_points(PhysicsServer.shape_get_data(shape))
			var new_collision_shape = CollisionShape.new()
			new_collision_shape.shape = new_convex_polygon_shape
			new_collision_shape.transform = child.transform
			parent.add_child(new_collision_shape)
	child.free()

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

7 participants