Trouble with fast bullets

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
ecosky
Posts: 69
Joined: Fri Nov 04, 2011 7:13 am
Contact:

Trouble with fast bullets

Post by ecosky »

Hi Norbo,

I've recently added shooting very fast sphere bullets to my game. They have CCD turned on, and hit the static map level reliably.

The problem I am having is with hitting dynamic objects - collisions are sometimes not being detected. In this case, the bullet sphere and a convex hull. As I debugged through the situation I verified that CCD was turned on, and that the code was reaching GeneralConvexPairTexter.GenerateContactCandidate. The CollisionState is Separated, and GJKToolbox.AreShapesIntersecting is returning false. The sphere is moving fast enough that it is often on one side of the convex on the first frame, and the other side of the convex on the second frame. If I move the shooting source forward and backward from the convex object, it will periodically hit the convex as I happen to hit the right distance so that the sphere lands within the convex during one frame. Since there are (as far as I can tell) no swept shapes being used here, GJKToolbox.AreShapesIntersecting is often not producing a hit. While I expect to just switch over to a raycast for anything moving very quickly in order to avoid this problem, I am wondering if there is perhaps something I have overlooked with Bepu here. Is it possible to get an accurate collision in this scenario? Not all projectile types are suited for ray casting, and it would be useful to be able to have reliable collision detection in situations where things larger than a bullet have to move very quickly - for instance high speed missiles. I wouldn't be surprised if I just have to limit speeds but I'm curious if there is something else I can do here.

Thanks for any thoughts or insights on this,
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Trouble with fast bullets

Post by Norbo »

Setting the projectile's PositionUpdateMode to Continuous should catch the collision, even with other moving dynamic objects. CCD performs sweep tests.

Here's a couple of things that could could interfere:

1) The default PositionUpdateMode is Discrete. If the other object is moving quickly, the projectile might pass between the t=0 and t=1 states of the other object.

If two high speed dynamic objects are involved, having the other object be set to Passive or Continuous would be a good idea. That ensures the other object's swept motion is taken into account.

2) CCD allows glancing collisions to proceed unimpeded. This will never knowingly permit through-the-wall type tunneling, but if only the edge of the projectile and the edge of the obstacle would come into contact, the projectile will go through. This tends to improve behavior quality since motion clamping needs to be used sparingly.


If neither of the above are related, it's likely a bug. In that case, a reproduction in the latest BEPUphysicsDemos would be handy.
ecosky
Posts: 69
Joined: Fri Nov 04, 2011 7:13 am
Contact:

Re: Trouble with fast bullets

Post by ecosky »

Hi, thanks for the response.

I'm definitely setting the PositionUpdateMode to Continuous. Prior to switching this from the default, bullets were missing static world/map geometry and now they hit it reliably. The problem I'm having seems to be related to the sphere hitting a convex shape.

The target object (the thing I'm shooting at) has been either stationary or slowly moving object during my tests, with size ranging from 0.2 to 3 units across, roughly. The bullet has been various sizes as I've tested, generally from 0.05 to 0.5 across. I also tried a quick switch to a capsule of various lengths aligned with the direction of travel to try to catch the missed collisions (this helped, but ultimately behaved the same as the sphere, for reasons I am sure are obvious to you). The impacts were often direct hits, and the misses were just as often misses through the center of the convex object as I moved slowly towards or away from the target object.

I was hoping (and expecting, really) that the CCD would behave as you describe, so I'll look into this some more and if necessary modify in the BEPUphysicsDemos. From what I could tell, it applied the swept motion while discovering pairs but after that the velocities & swept motion just didn't seem to be considered at least in the portions I stepped through. If I force the game time to slow down dramatically, hits along the same vector with stationary target will get detected simply by changing the scene dT. I am noticing when the hits are detected, it is always in GeneralConvexContactManifold.Update's call to pairTester.GenerateContactCandidate. A position that causes bullets to miss at standard game time will start getting contact candidates here as soon as I slow down game time. Drilling into that method and dependent code I don't see any swept motion going on, so presumably the swept motion tests is done somewhere else? Or maybe I just overlooked it?

If you can point out where the CCD does the swept motion for a sphere to convex hull, I'd appreciate that so I can step through and verify that CCD is in fact occurring where it should - my branch is a little stale and in the off chance I can figure out what is going on it might save us both some time. (I'm pretty sure I've integrated all relevant bug fixes, but I will check again).

Thanks,
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Trouble with fast bullets

Post by Norbo »

If you can point out where the CCD does the swept motion for a sphere to convex hull, I'd appreciate that so I can step through and verify that CCD is in fact occurring where it should
The ConvexPairHandler.UpdateTimeOfImpact should have the sweep tests for the sphere-convex case.

A little more general background:
The most restrictive time of impact is used to 'clamp' the motion of the related entities. That way, during the next frame, the objects that would have otherwise missed will be in touching contact and the regular discrete tests can take over from there. That's why you didn't see any sweep tests in the contact manifold stuff.

The CollidablePairHandler.UpdateTimeOfImpact should be called by the ContinuousPositionUpdater for any pair involving an entity with PositionUpdateMode set to Continuous, subject to one restriction:

A pair will only undergo CCD testing if it passes the MotionSettings.CCDFilter. The default filter stops any CCD from being used on pairs which have a collision rule of NoSolver or more restrictive. If the projectile is being shot at a 'trigger' entity with no collision response, this filter would prevent CCD from running.
ecosky
Posts: 69
Joined: Fri Nov 04, 2011 7:13 am
Contact:

Re: Trouble with fast bullets

Post by ecosky »

A pair will only undergo CCD testing if it passes the MotionSettings.CCDFilter.
That is definitely the case for me. I have an elaborate set of collision group rules set up to optimize interactions across a variety of types of objects, and one of them is a CollisionGroupPair for projectiles and their valid targets which is set to NoSolver. I just wanted a trigger here, and I didn't realize NoSolver would disable CCD. This goes against my interpretation of the definition of the NoSolver mode.. I expected it to find the contacts but not do anything with them. Perhaps I misinterpreted it though.

Can you please elaborate why CCD is disabled for NoSolver types - is there some specific scenario this helps with? I'm struggling to come up with a situation where objects marked as Continuous wouldn't want to use CCD for trigger situations like this. Thanks to your pointer here, I see in MotionSettings that it would be pretty straightforward to use my own CCDFilter delegate that enabled CCD for NoSolver, but I do wonder what the side effects might be.

Thanks again,
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Trouble with fast bullets

Post by Norbo »

This goes against my interpretation of the definition of the NoSolver mode.. I expected it to find the contacts but not do anything with them. ... Can you please elaborate why CCD is disabled for NoSolver types - is there some specific scenario this helps with?
CCD is implemented with motion clamping. It never finds any contacts, and the solver isn't involved. Instead, a time of impact is computed and the object is only allowed to proceed that far under the assumption that discrete collision detection and response (which obey collision rules) will handle it from there during the next frame.

In the case where CCD is used but no collision response takes place, the continuous object will halt on the border of the obstacle. A time of impact is computed that shows the projectile can't advance further without skipping the object, but the next frame's lack of collision response doesn't change the objects' velocities. So the process repeats. After a few frames, some thresholds kick in and CCD gives up, allowing the continuous object to pass through.

The momentary juddering and freezing is extremely jarring. In fact, it's one of my most disliked behaviors in the whole engine. A projectile that immediately gets removed on contact creation won't show the effect since it doesn't stick around, but a fast character running into a trigger region would produce pretty nasty results.

[Side note: speculative contacts, which are supported by the solver and used in some contact manifolds but not used for full-blown CCD, would solve this issue and a couple of others elegantly. Unfortunately, direct implementations of speculative contacts break bounciness and can introduce other artifacts like ghost collisions or missed collisions depending on the details. A full solution that doesn't compromise has been on my long term to-do list for a while, but it's going to be difficult.]
ecosky
Posts: 69
Joined: Fri Nov 04, 2011 7:13 am
Contact:

Re: Trouble with fast bullets

Post by ecosky »

Thanks for clearing this up for me.

I think for my situation, I'll convert from NoSolver to Normal. I need the impact/contact data anyway, so this seems like the way to go even though I immediately destroy the projectile after the impact occurs. For some reason I was thinking the NoSolver would still give me contact data but now that you've explained why it doesn't (and I really should have realized why myself) this all makes a lot more sense.

Thanks again for the great explanations!
Post Reply