Page 1 of 1

External ballistic sim

Posted: Tue Oct 09, 2012 5:18 pm
by sergiusz308
So far, from what I have red here, best way to simulate external ballistic would be:

1) simulation running at fixed step (i.e. default 1/60)
2) establish how far bullet travel for a particular timeframe - in this case 0,016sec
3) once per update do a raycast test with ray length set based on 2) and position set to ray "endpoint" position from the last update
4) after each step in 3) check how far you got to not exceed max travel distance you established for particular bullet type

Now if this is correct - to find collisions I'd need to check hits returned from raycast.

Taking it little bit further, if I want to ignore collisions with some type of objects (i.e. invisible script trigger entities) should I ask broadphase first for bounding box collisions, list thru them and then do space.Raycast against only qualified objects or may be there is a way to do this with some kind of collision filtering in a single step?

Thanks,
S.

Re: External ballistic sim

Posted: Tue Oct 09, 2012 6:23 pm
by Norbo
Now if this is correct - to find collisions I'd need to check hits returned from raycast.
Yup.

Technically, you could just shoot an actual dynamic entity with its PositionUpdateMode changed to PositionUpdateMode.Continuous, though it will be a little more expensive than a ray cast alone.
Taking it little bit further, if I want to ignore collisions with some type of objects (i.e. invisible script trigger entities) should I ask broadphase first for bounding box collisions, list thru them and then do space.Raycast against only qualified objects or may be there is a way to do this with some kind of collision filtering in a single step?
Space.RayCast is a convenience method which queries the BroadPhase for you. There are overloads of the Space.RayCast method which accept a filter delegate; you can use this to prune out unwanted objects with arbitrary logic.

The BroadPhaseEntry type (instances of which are passed into the filter delegate) is the superclass of everything that can live in the broad phase, including collidable objects. It has a Tag property which could be useful in handling game logic. Note that an Entity is not itself a BroadPhaseEntry; it has a collision proxy EntityCollidable which can be grabbed through the Entity.CollisionInformation property. The EntityCollidable is a BroadPhaseEntry.

Re: External ballistic sim

Posted: Tue Oct 09, 2012 8:29 pm
by sergiusz308
Great.

Is there any piece of demo code I could look at to see how to best implement variable step? Basicaly what I want to do is to have GPU drawing at full speed, but physics run in fixed step, so that drawing code "synchronizes" with physics fixed number of times, thru a BufferedState I believe?

Re: External ballistic sim

Posted: Tue Oct 09, 2012 8:49 pm
by Norbo
There are two common approaches to fixed time step simulation:

A) Using IsFixedTimeStep = true.
1) In XNA, just set the game's IsFixedTimeStep to true.
2) Initialize the Space.TimeStepSettings.TimeStepDuration to the game's update rate. (This only needs to be done once. Note that TimeStepDuration defaults to 1/60f which is the same as the XNA Game update rate default.)
3) Call Space.Update() without a parameter. When used without a parameter, Space.Update() performs a single time step of length Space.TimeStepSettings.TimeStepDuration.

This approach works decently. The entire game update progresses together as many times as necessary to keep up with the draw rate. Since the drawing rate may be indivisible by the update rate, there will be a little remainder left over each frame. This can cause a subtle 'jittery' effect sometimes. It's usually not very noticeable when the entire game is marching forward together using IsFixedTimeStep = true.

B) Using internal time stepping.
1) In XNA, set IsFixedTimeStep to false.
2) Initialize the Space.TimeStepSettings.TimeStepDuration up front to the desired simulation resolution. Defaults to 1/60f.
3) Call Space.Update(dt) with a parameter. The parameter represents the amount of time to try to simulate. It can execute multiple time steps of length Space.TimeStepSettings.TimeStepDuration in an effort to simulate the accumulated time (remainder from previous frames + passed in 'dt').

Using this approach requires more care than A. The game update moves at an arbitrary rate while the physics move at a fixed update rate. That difference can introduce complexity when trying to manage the physics externally. For example, if you want to perform an action on every single time step, you would have to hook an event on some Space update stage so that your logic executes in a time step rather than simply between frames (which could include multiple time steps).

Further, the subtle jittery effect caused by the time remainders at the end of each frame are generally slightly more noticeable since parts of the game might be using the variable time step directly. To address this, use interpolated states. An explanation and example of interpolated states can be found in the asynchronous update documentation and its associated demo. (Note that interpolated states do not require asynchronous updates to be useful; it's just a common use case.)

Re: External ballistic sim

Posted: Tue Oct 09, 2012 9:33 pm
by sergiusz308
Thanks Norbo.

About ballistics, let's say I want to simulate effects like bullet drop and derivation. As for drop it's probably easiest to do with bullet being dynamic entity - it simply will be affected by gravity. What about derivation - setting appropriate angular velocity will do the magic?

In case if I'll do it by ray casting I probably need to calculate additional parameters externaly and construct ray so that position and normal will be affected by those parameters to achieve desired effects?

I'm still little bit confused about units and scales in bepu. Default gravity value seems to say we're dealing with meters and seconds here - I understand that it's all depends on simulation parameters and specific implementations but how should I think about those units to resamble real-life behavior, i.e. if something weighs 100 ton it won't move after collision with 1kg object?

Re: External ballistic sim

Posted: Tue Oct 09, 2012 10:00 pm
by Norbo
What about derivation - setting appropriate angular velocity will do the magic?
I'm not sure what you mean by derivation here. If you're wondering about the effect of a spinning bullet fired from a rifled barrel, there is no built-in aerodynamic simulation which would destabilize a bullet midair so the effect isn't necessary. You can spin the bullet if you want, though :)

If you mean other angular velocity/aerodynamics related effects like the Magnus effect, then those aren't simulated automatically either. By default, everything is simulated as if it were in some sort of strange vacuum that happens to have a configurable per-object damping effect (entity.LinearDamping and entity.AngularDamping).
In case if I'll do it by ray casting I probably need to calculate additional parameters externaly and construct ray so that position and normal will be affected by those parameters to achieve desired effects?
Yup. Doing it with ray casts would be the 'manual' way. If your aim is to simulate a bunch of specific effects which entities don't have by default anyway, it might not be any more work to just do it 'manually' with ray casts.
I'm still little bit confused about units and scales in bepu. Default gravity value seems to say we're dealing with meters and seconds here - I understand that it's all depends on simulation parameters and specific implementations but how should I think about those units to resamble real-life behavior, i.e. if something weighs 100 ton it won't move after collision with 1kg object?
The engine is completely unitless, so you can consider the values to be whatever you want so long as the end result is numbers whose values do not introduce stability issues*A. If you want an object to appear heavy in comparison to another object, give the heavy object 1000x the mass or something along those lines*B. The light object will have a very hard time moving the heavy object.

[*A: For example, using the convention that a unit is a light year but having the play space be 10 meters across would result in numbers around 1e-14; that would be very unwieldy for the simulation. It runs into all sorts of problems with single precision floating point numbers, epsilons, and tuning variables.

Instead, pick nice regular values to keep the simulation happy. The default 'scale interpretation' of the engine likes numbers to be around 0.5 to 10 units. It can handle numbers quite a ways beyond that, but sticking within that range is very stable. If your object dimensions violate that recommended range too much, the scale interpretation will probably have to be changed (using something like the ConfigurationHelper.ApplyScale method in the BEPUphysicsDemos) or the simulation will just need to be resized.

*B: Masses have an additional requirement on top of the above: heavy objects should not depend on light objects. That is, do not try to stack a 1000 unit mass box on top of a 1 unit mass box. It will be highly unstable; the light box will likely shoot out from beneath the heavy box after some shaking. Stacking a 1 unit mass box on a 1000 unit mass box, on the other hand, is extremely stable.

The same sort of 'mass ratio' idea applies to constraints in general. Making a chain of entities connected by ball socket joints which carry some big wrecking ball on the end will be quite difficult to simulate. If acceptable to the design, tuning the constraints to be less rigid will improve stability in such a situation. The other option is to increase the solver iteration count a large amount. Chances are, the time step duration will also have to be made smaller.]