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

Continuous CD not working #9071

Closed
Tracked by #45334
ghost opened this issue Jun 6, 2017 · 55 comments · Fixed by #69934
Closed
Tracked by #45334

Continuous CD not working #9071

ghost opened this issue Jun 6, 2017 · 55 comments · Fixed by #69934

Comments

@ghost
Copy link

ghost commented Jun 6, 2017

Operating system or device - Godot version:
2.1.3 Stable (64-bit)

Issue description:
The Rigidbody2D node does not appear to have correctly functioning Continuous Collision Detection (even thought the option is present). "Tunneling" occurs with both "Cast Ray" and "Cast Shape" options.

Steps to reproduce:

  1. Create a Rigidbody2D node and enable Continuous CD in it's properties (Cast Ray or Cast Shape).
  2. Create an Area2D node as a child of the Rigidbody2D node (so it has mass).
  3. Place the Rigidbody2D node overtop of a ColliderObject2D node (make it static because it should never move anyway).
  4. Set gravity scale to something large, like ... I dunno... 300 or something.
  5. Run the game, watch your Rigidbody2D either pass through the static collider or tunnel into it slightly.

I have tried both options (Cast Ray and Cast Shape) and neither of them seem to work. Looking back on previous issues posted here (and elsewhere), it appears Continuous CD was broken since version 2 of Godot was released and never got fixed. Is there any chance this can be corrected soon? It impacts a lot of my testing currently.

@Zylann
Copy link
Contributor

Zylann commented Jun 6, 2017

Related to #6926 and #6664

@ghost
Copy link
Author

ghost commented Jun 6, 2017

I'd just like to add that comments in those related issues suggest it's only "Cast Ray" that's not working but I've tried this with both "Cast Ray" and "Cast Shape" and neither are working.

@bojidar-bg
Copy link
Contributor

Potentially a result of d7d65fa

@kubecz3k
Copy link
Contributor

kubecz3k commented Apr 4, 2018

First of all thank you for your report and sorry for the delay.

We released Godot 3.0 in January 2018 after 18 months of work, fixing many old issues either directly, or by obsoleting/replacing the features they were referring to.

We still have hundreds of issues whose relevance/reproducibility needs to be checked against the current stable version, and that's where you can help us.
Could you check if the issue that you described initially is still relevant/reproducible in Godot 3.0 or any newer version, and comment about its current status here?

For bug reports, please also make sure that the issue contains detailed steps to reproduce the bug and, if possible, a zipped project that can be used to reproduce it right away. This greatly speeds up debugging and bugfixing tasks for our contributors.

Our Bugsquad will review this issue more in-depth in 15 days, and potentially close it if its relevance could not be confirmed.

Thanks in advance.

Note: This message is being copy-pasted to many "stale" issues (90+ days without activity). It might happen that it is not meaningful for this specific issue or appears oblivious of the issue's context, if so please comment to notify the Bugsquad about it.

@BeayemX
Copy link
Contributor

BeayemX commented Apr 11, 2018

The bug still occurs for both Cast shape and Cast ray.
Version tested: d87307d

@bojidar-bg
Copy link
Contributor

Can someone retest after d403b40?

@akien-mga akien-mga added this to the 3.1 milestone Nov 22, 2018
@BeayemX
Copy link
Contributor

BeayemX commented Nov 22, 2018

Tested with current master (11d7738)

Cast ray does not tunnel through objects any more, but at high speeds, objects will not stop at the collision but instead will be set back quite far.

With Cast shape tunneling still appears

Both behaviours can be seen in this test project

CCDTest.zip

@Zireael07
Copy link
Contributor

Seemingly still an issue on 3.1?

@BeayemX
Copy link
Contributor

BeayemX commented Apr 5, 2019

Yes, still occurring on the latest master e16fc72

@mitchcurtis
Copy link
Contributor

Oh thank god this is an issue and not just me doing it wrong. I have a 3-pixel wide (pixel art game, zoomed in) shield and a projectile that flies kinda quickly, and if I position the character's shield juuuuust right, the projectile gets past the shield. I tried both CCD options and neither of them helped. I really suck at physics, so I really hope this gets fixed.

@Calinou
Copy link
Member

Calinou commented Sep 8, 2019

@mitchcurtis As a workaround for your particular case, you could make the shield's collision shape thicker. It should work well if its collision layers/masks are adjusted not to collide with the player or other parts of the world.

@Zylann
Copy link
Contributor

Zylann commented Sep 8, 2019

Another workaround specifically for projectiles that mostly move in a straight line, is to use raycasts, or an elongated collision shape matching the motion of the projectile for 1 frame. It's a bit of code to write but it should work pretty well. (actually maybe doesnt need code at all, just different setup)

image

@ZingBlue
Copy link

I need this fixed in order to continue working on my game's mechanics, I am not a great programmer, I am (for now) pretty much a web dev(HTML, CSS, JS) and a year of Python. With my skill set, could I fix this bug? If not, can someone else fix it please?

@ZingBlue
Copy link

Someone please, before 3.2 releases, do something.

@Calinou
Copy link
Member

Calinou commented Jan 29, 2020

@ZingBlue Sorry, 3.2 was too close to release, we couldn't afford doing something that potentially introduces a regression somewhere else. I advise you look at the workaround given above: #9071 (comment)

@ZingBlue
Copy link

@Calinou No problem. I'll look into the workaround mentioned above.

@Xrayez
Copy link
Contributor

Xrayez commented Jan 21, 2021

Partially related to #34215, I've also stumbled upon this physics parameter:

# Set this somewhere in `_ready()`.
Physics2DServer.space_set_param(get_world_2d().space, Physics2DServer.SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION, 0)

The default penetration is 0.3 as reported by equivalent space_get_param(...), perhaps it may improve the situation in some cases, but I'm just guessing and those might be yet again unimplemented parameters which are never used by the default physics backend.


Regarding the discussion whether physics work is prioritized... No, I think rendering is more important to the core developers (and investors), otherwise it would've been fixed already. Hopefully physics work is going to be prioritized in 4.1... But yeah I agree that that's something which could've been fixed long time ago, we'd probably have more interesting physics-based games made with Godot by now, but that's just me. 😛

But then again, Godot was probably not designed to handle heavy physics simulations in the first place, so we've got what we have now...

@Calinou
Copy link
Member

Calinou commented Jan 21, 2021

Regarding the discussion whether physics work is prioritized... No, I think rendering is more important to the core developers (and investors), otherwise it would've been fixed already. Hopefully physics work is going to be prioritized in 4.1... But yeah I agree that that's something which could've been fixed long time ago, we'd probably have more interesting physics-based games made with Godot by now, but that's just me. 😛

Physics are already being prioritized for 4.0.

@e344fde6bf
Copy link
Contributor

e344fde6bf commented Apr 4, 2021

EDIT: Wait, no, that's not right. There is something weird going on here.
Let me amend "Bullet CCD works" to "Bullet CCD mostly works"
@Exxion

I had a look and it seems Bullet only supports continuous collision detection for convex collision shapes. Compound collision shapes (btCompound) are not supported. In Godot any collision shape that has a Transform() != identity needs to be wrapped in a btCompound (to set custom centre of mass). So CCD for RigidBody only works for (box, sphere, capsule, cylinder, convex hull) shapes when they have no translation or rotation relative to their parent. Note this only matters for the moving shape, so it'll still detect a collision if the other shape in the collision is concave/compound.

Another issue seems to be if you use collision layers and mask. Bullet's default handling for this seems to require (A.layer & B.mask) && (B.layer & A.mask) to be true for it to detect a collision when it performs the CCD sphere sweep.

I don't think Bullet's CCD handles cases where two fast moving objects cross paths at all.

Kinematic bodies in Godot actually perform a sweep test for each shape, so continuous collision detection seems to work for them, even for compound shapes.

However, Bullet's continuous collision detection for rigid bodies never seemed to prevent tunneling. So even if you use one of the currently supported configurations, it only prevents missed collisions by performing a sweep test with a sphere. There seems to be a way you can manual prevent tunnel in Bullet discussed in this post.

While not a complete fix, you can get much less tunneling for basic shapes by choosing the CCD sphere sweep radius as the largest sphere that fits entirely inside the shape. Currently, Godot set's this to 0.2 * bounding_sphere_raidus, so even if the shape is a sphere it can tunnel 80% of the way to the centre. I think a better default would be something like sweep_radius = min(aabb.x, aabb.y, aabb.z)/2 (edit: for convex hull you probably need to do min(p1, p2, ..., pn) and need the convex hull to contain the origin). However, I think you still need allow some penetration to guarantee that Bullet actually generates contact points after performing the sphere sweep.

Larger sweep radius
void RigidBodyBullet::set_continuous_collision_detection(bool p_enable) {
  if (p_enable) {
  	btBody->setCcdMotionThreshold(1e-7);

  	const btCollisionShape* shape = btBody->getCollisionShape();
  	if (!shape) {
  		btBody->setCcdSweptSphereRadius(1.0);
  		return;
  	}

      /// CCD works on an embedded sphere with fixed radius, make sure this
      /// radius is embedded inside the convex objects, preferably smaller.
  	btVector3 aabb_min;
  	btVector3 aabb_max;
  	shape->getAabb(btTransform::getIdentity(), aabb_min, aabb_max);

  	btVector3 bounds = aabb_max - aabb_min;
  	btScalar min_bound = MIN(bounds.x(), bounds.y());
  	min_bound = MIN(min_bound, bounds.z());

  	btBody->setCcdSweptSphereRadius(MAX(0.04, (min_bound / 2.0) - 0.04));
  } else {
  	btBody->setCcdMotionThreshold(0.);
  	btBody->setCcdSweptSphereRadius(0.);
  }
}

In summary, it seems Bullet doesn't have great support for CCD internally, so you'll have to do a fair bit of work to get it working correctly in all cases for rigid bodies.

@skaiware
Copy link

skaiware commented Apr 4, 2021

Thanks for the analysis @e344fde6bf
Camille: aka @pouleyKetchoupp : would CCD work better with your retouches/enhancements of the Godot PhysicsEngine ?

@pouleyKetchoupp
Copy link
Contributor

@skaiware I haven't looked into ccd yet, but given there are multiple reported issues, it's an area me or other contributors are going to check. And given @e344fde6bf's findings it seems there's some room for improvements.

@unfa
Copy link

unfa commented Sep 21, 2021

Still an issue in Godot 4 pre-alpha.
I have shell casings in my game (small objects) and they keep phasing through other objects even when Continuous Collision Detection is on.

@lexum0
Copy link

lexum0 commented Dec 9, 2021

CCD is completely broken in Godot 3.4, but seems to be working in Godot 2.1.4. What can we do to help fix it? It's an important feature when dealing with physics.

A workaround would be to detect the collision in GDScript using raycast and apply an impulse or change the velocity to simulate the collision, does anyone have more details on the implementation?

@starry-abyss
Copy link
Contributor

I don't know if it's the proper way to deal with CCD, but HaxeFlixel engine stores previous positions of objects. This allows to detect overlaps not only for objects themselves, but also for the paths they moved along during the frame.

@LowBudgetHomebrew

This comment has been minimized.

@Calinou
Copy link
Member

Calinou commented Dec 18, 2021

@LowBudgetHomebrew Please don't bump issues without contributing significant new information. Use the 👍 reaction button on the first post instead.

@loicmorvan
Copy link

FYI I'm trying to make a little Pinball game with Godot v3.5.stable.official [991bb6a].
The only dynamic body is the ball (a single CircleShape2D, not thin), everything else so far is static or kinematic with CollisionPolygon2D.
Whatever the CCD mode I choose the ball interpenetrates the other bodies (while it should never enter inside these bodies), or if its speed is too high (but not exaggerated) traverse static bodies.

I'm new to Godot, but I have a bit of knowledge on physics and physics engine implementations, so I would be pleased to try to help you fixing that, if I can ;)

@Calinou
Copy link
Member

Calinou commented Aug 20, 2022

Whatever the CCD mode I choose the ball interpenetrates the other bodies (while it should never enter inside these bodies), or if its speed is too high (but not exaggerated) traverse static bodies.

Increasing physics FPS in the project settings will probably resolve this in your particular project (try 120, 180 or 240).

I'm new to Godot, but I have a bit of knowledge on physics and physics engine implementations, so I would be pleased to try to help you fixing that, if I can ;)

Thanks for your interest in contributing 🙂

See Pull request workflow for guidelines. In particular, pull requests should target the master branch first (which means porting your project, or a minimal version of it to 4.0.alpha so you can test your changes).

GodotPhysics should also be fixed first, as that's what is used in 4.0 and is the only physics engine available for 2D in 3.x too. Bullet could be fixed later, as it's only used for 3D in 3.x (and people can switch to GodotPhysics there too).

@Zireael07
Copy link
Contributor

Woohoo, closing a 5 year old issue!

@djrain
Copy link

djrain commented Apr 11, 2023

If this is the "definitive" issue for CCD not working, then maybe it should be reopened - 2D CCD is certainly still broken in Godot 4.0.2. But the simple steps described here are really not adequate for testing it thoroughly.

@YuriSizov
Copy link
Contributor

@djrain There is no definitive issue. Please open a new bug report with a reproduction project for the issues that you encounter. (There are some other reports too, btw).

@Regrad
Copy link

Regrad commented Jul 11, 2023

Continuous CD still bugged. Object stops despite bounce 1:
https://youtu.be/bsOe_VxWv2M

@YuriSizov
Copy link
Contributor

@Regrad Please open a bug report with a reproduction project that demonstrates the issue.

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

Successfully merging a pull request may close this issue.