Physics dont work sometimes (bullets can fly through wall)

I’m testing physical collisions. However I was surprised to find that the physics collision in the 'examples\physics\physics_3d_shooter ’ bullet sometimes fails. Sometimes it goes right through the wall and sometimes it gets stuck in the wall.

How can i fix it?

Unfortunately, it is indeed a problem.

We have investigated it with Andrzej Kilijański in the past, trying to “defeat” it, but without a resolution. So far, it does seem it is just a problem of the underlying physics engine (Kraft) and we cannot really avoid/workaround it at CGE level 100% reliably.

In the long run, we plan to add (and maybe make default) other physics engines. Our current best candidate is PhysX, and second best candidate Bullet (see Roadmap | Manual | Castle Game Engine ). Comment of course welcome. Both are well-known, popular, feature-rich, open-source, cross-platform → so we’re confident they will serve CGE well. They will likely provide a reliable solution to this.

For now, for Kraft:

  1. One practical solution is just to not use such fast flying objects. I know, it sucks. But if possible, this is the simplest working solution – when the objects do not move very fast, the problem disappears, or at least is rare enough to not matter.

  2. A solution that should work, but actually doesn’t, is using “continuous” collision detection. This is the mode that should fix such issues. However, we tried with Andrzej enabling it, and no tweaking of options achieved 100% reliable solution to this problem. But you are welcome to try it yourself:

    • Set TCastleRigidBody.CollisionDetection to cdContinuous (default is dtDiscrete) for all relevant rigid bodies (so be sure, on both bullets and walls).

    • Make sure MyViewport.Items.PhysicsProperties.ContinuousCollisionDetection is true. It is already true by default.

    • If you want to experiment more yourself – see comments in TCastleAbstractRootTransform.InitializePhysicsEngine, castle-engine/src/transform/castletransform_physics.inc at master · castle-engine/castle-engine · GitHub . You will find there various comments about tests done.

    As I said, we did try this approach with Andrzej – but we were not able to find the combination of options that reliably solves this issue. Maybe you will find it? If you have resources and want to experiment with this, feedback will be most welcome.

Sorry, no better answer yet. Aside from 1 and 2, the “ultimate” solution will likely come from just using a different physics engine, like PhysX, in CGE.

  1. One other solution, which also a “crazy workaround” (in the sense: it means just resigning from using physics for one use-case):

    If your bullets fly really fast, then move them yourself, not depending on physics engine moving rigid bodies. Check collisions along the way yourself, e.g. check Viewport.Items.PhysicsRayCast(...) (so you can still check wrt to physics colliders) and if bullet can move, move it yourself by adjusting TCastleTransform.Translation.

I tried method 2. but unfortunately it doesn’t work. But when I reduced the bullet velocity the problem did rarely happen. Also, I’ve noticed that the problem seems to be more likely to occur when the FPS is very low. Is this an illusion?

Well, maybe I should try lowering the bullet velocity until there is a better solution to replace it. Thanks for the work. :grinning:

It’s not an illusion, lower FPS can indeed provoke the problem more.

The underlying issue is that when physics uses “discrete” checks, then it only checks each position of the bullet (and not the geometry “stretched” between previous and new position). When the bullet is fast and/or when FPS is low, then there’s more distance between every previous and new position, and so there’s more chance that both previous position will be valid (completely before the wall) and new position will be valid (completely after the wall) and the physics engine will “miss” the fact that in-between there was invalid state (since the bullet traveled through the wall).

The solution AD 2 is in theory the right one – using “continuous” checks means physics engine should check rays between previous and new positions. But it seems it doesn’t work reliably in Kraft for us.

You can read about it more (as the concept applies to all physics engines) e.g. on https://nphysics.org/continuous_collision_detection/ (nice images illustrating where’s the problem).

  1. Oh, I also though of another workaround. Increase physics engine frequency. Set MyViewport.PhysicsProperties.Frequency to something larger than default (60). For example, try 120 or even more. It may also be necessary to similarly increase MyViewport.PhysicsProperties.MaxPhysicsTicksPerUpdate, default 5, to e.g. 10.

    Doing this effectively makes the physics checks more often, so the problem will occur more rarely.