Futuristic Racing Game

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
willlwill100
Posts: 2
Joined: Tue Feb 01, 2011 4:47 pm

Futuristic Racing Game

Post by willlwill100 »

Hey guys, im currently making a wipeout style game but am having a hard time trying to make a stable physics system for the ship. Does anyone have any suggestions about how we can use the vehicle class to accurately model a ship? Currently it is unbelievably buggy. Is there a better way to use BEPU to do this?

Many thanks in advance, will promise some sick screenshots in the future!!
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Futuristic Racing Game

Post by Norbo »

It would depend on what kind of poor behavior you're seeing. My initial guess would be that it's somehow related to extreme speed for which the default demos vehicle isn't configured for. Going around corners would cause the suspension to squish to nothing and the body of the vehicle would start hitting bumps between triangles. At high speeds, this would probably send the entire thing flying. If the speeds are really high, the suspension wouldn't even matter- going around a very slightly curved corner might cause the car to go from a noncolliding state to a deeply intersecting state in a single frame. Once again, it would go flying :)

So, ignoring the Vehicle class specifically for a moment, these problems can be brute-forced somewhat by decreasing the timestep. By default, the engine runs at 60 hz. For a high speed racing game, going up to 120 hz or more may be recommended (so long as you are within the simulation frametime budget). Space.SimulationSettings.TimeStep.TimeStepDuration is the time step length (1/60f default). When changing that, it may also be helpful to change UseInternalTimeStepping to true so that the physics automatically update enough to keep up with the game.

The other problem of the body hitting triangle bumps is going to be assisted by v0.15.0's internal edge pruning systems, but the situation can be avoided entirely with some care and sufficient update rate. If the vehicles involved actually have wheels (as opposed to being hovercraft), you might try stiffening the suspension and making sure there's sufficient ground clearance while still maintaining a stable, wide wheelbase (or a very low center of gravity).

If the vehicles do not have wheels, then there are a lot of other options. A hovercraft-style vehicle may be best implemented as something like an object floating on a raycast stick. Since it's floating, there's a lot of ground clearance guaranteed and it's possible to fancy tricks to predict the upcoming sections of the track. Instead of blindly integrating forward to the next location, you could raycast forward and down a bit to find the spot that will be under the vehicle one frame into future. You can take that information and normal and compute a better velocity heading to prevent the object from diving into the road surface in the next frame. It's likely that you could create a custom system that is performance-wise faster than the Vehicle class, since a lot of the 'vehicle' dynamics can (and should) be faked for highspeed hovercraft. That extra headroom could be used to increase the update rate, or make other fancy things.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Futuristic Racing Game

Post by Norbo »

Also, another type of issue you may see is related to floating point precision. If triangles are massive or nearly degenerate (high ratio between length and width, or any dimension being an order of magnitude different than around 1-10 units), various systems will start to struggle. The way to address this problem is to ensure that the objects involved in the simulation are of reasonable size. 1-10 units for a dimension is a very safe range and the engine can almost always easily handle values outside of that (especially in v0.15.0), but staying within it provides more guarantees.
willlwill100
Posts: 2
Joined: Tue Feb 01, 2011 4:47 pm

Re: Futuristic Racing Game

Post by willlwill100 »

Thank you very much, that was really helpful. I'm currently working on using the racasted stick model which is fine; what is problematic is thinking about how to model turning with a hovercraft so that it "appears" to turn like a vehicle with resistance on each wheel. How could I stop the vehicle spinning and make it look realistic, the vehicle class was a reasonable solution I thought but there must be some way of doing this better.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Futuristic Racing Game

Post by Norbo »

How could I stop the vehicle spinning and make it look realistic
That would depend on what is considered realistic for the hovercraft in question. There's a couple of core approaches you can take.

First, the hovercraft can be very directly controlled, and its orientation could be considered almost completely a byproduct of direct control as opposed to physical forces over time. In this scheme, when the ship is flying across a surface, it would have an orientation defined by a combination of the support normal (possibly multiple supports) and by user input controlling the yaw around the normal. Then, with a scheme similar to the BEPUphysicsDemos open-source SimpleCharacterController's HandleHorizontalMotion, you can control the sideways sliding and other deceleration. The character controller is designed to work for permanently upright characters, but it can be adapted to arbitrary rotation without too much work- instead of using Vector.Up as an up vector, the support normal would be used.

Second, the hovercraft can be physical. There are a lot of ways of doing this, depending on what exact behavior is desired. The Vehicle is one option. It can very likely be tuned to work for your simulation, though it will behave something like a wheeled vehicle (since that what it is designed to be :)). You could also bypass the vehicle if you wanted to exert more control over specific behaviors, but still implement a form of soft suspension by raycasting from multiple locations and applying forces to the ship so that its orientation stays stable. You could apply forces to turn around the vehicle's up vector.

These options are both on a spectrum of sorts. You can mix and match to have some parts physical, and other parts directly controlled. In either case, I'd recommend working on the impulse or, equivalently, velocity level as opposed to setting the position/orientation directly. This lets things respond properly to the velocity in collisions instead of teleporting through as can happen when setting position/orientation directly.
Jamedjo
Posts: 3
Joined: Tue May 31, 2011 9:30 pm

Re: Futuristic Racing Game

Post by Jamedjo »

Thanks for all the help. Our original problem was partly that we didn't know much about game physics, and have since learnt a lot from your forum posts in various threads.

We implemented our ship using raycasts to find the distance above/below the track from the four corners of our ship. We then applied impulses linearly based on these distances, and rotated using angularImpulses around the up vector. We didn't manage to do any predictive tricks as we had trouble balancing the impulses so the ship wouldn't bounce too high or sink through the floor. In the end we also removed the ship's linear velocity towards the floor upon contact and things worked OK.

Unfortunately this system didn't work very well going uphill or on loop sections of the track, as the ship occasionally goes through the track. I'm currently experimenting using the Vehicle class to perform the suspension while using the previous code to control rotation/movement.This needed the solver to be turned back on for the track which creates a different problem:
- When driving straight up a curved section of track the front of the ship collides with the track in front of it
- Sometimes the response is the front of the ship being suddenly pushed sideways.

Is there any way we can either make the ship respond by tilting upwards with the slope instead of turning sideways? Alternatively have you got any suggestions for stopping the ship going under the track with the solver turned off?

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

Re: Futuristic Racing Game

Post by Norbo »

Is there any way we can either make the ship respond by tilting upwards with the slope instead of turning sideways?
Is this in the latest version? The development version in particular has had a lot of improvements to mesh collision: http://bepuphysics.codeplex.com/SourceC ... evelopment

If collisions are still frequently really bad, it may be related to scale issues. The engine likes 0.5 to 10 units per colliding object (e.g. a triangle in a mesh). It can pretty easily work outside of that range, but the further up it goes, the more likely that numerical issues will creep in (particularly on triangle boundary collisions).

If the collision shape of the ship is rounded, like a box with high collision margin or even a sphere, the collision normals are more likely to point in desired directions as well.

Of course, it would be better if the vehicle's body didn't even hit the surface of the track. It's going to be problematic if the vehicle is going fast enough along a sufficiently sloped surface with long enough timesteps that collisions are unavoidable. Decreasing the time step duration is a good option if possible. Tuning/lengthening/repositioning the suspension could help. Unconventional additional wheel placement, like extending out in front of the vehicle, may help handle the curves. Setting them up such that they wouldn't cause other problems could be tricky.
Alternatively have you got any suggestions for stopping the ship going under the track with the solver turned off?
With no collision response, the core idea is that the ship knows where it is on the track, and it knows the slope of the track at that point. If you still wanted otherwise physical behavior, you'd have to find a way to blend the data into the rest of the system.

There's a variety of ways to collect those position/slope hints.
-The most direct option is the raycasting approach where you collect support locations immediately below the ship, as it sounds like you are doing now.
-That can be improved a bit by casting forward/down a bit (the predictive casting covered earlier) and feeding that into the system somehow.
-Depending on the environment, you may also be able to provide additional hints in the form of metadata curves that follow the geometry or something that ensure that the vehicle is facing in the correct direction. This alone wouldn't stop the ship from flying through the level always, but it could provide valuable information to other systems to avoid it.
Jamedjo
Posts: 3
Joined: Tue May 31, 2011 9:30 pm

Re: Futuristic Racing Game

Post by Jamedjo »

Just moved to development fork, which may have made some improvement. Increasing the suspension length helped reduce the number of bouncy collisions at low speed.

The ship is about 8x4x2 units and the StaticMesh triangles are also a decent size. The collisions are probably realistic as the convex hull is pointy at the font. We could try to round the mesh off using collision margins. The problem is that we want unrealistic collisions so the ship is more likely to drive up the surface it drives into instead of rotating away from it. I was considering adjusting the InertiaTensor, but with the Vehicle class it flips over too much as it is and this would make it worse.

Image
Image

Is there an equation for manually solving a collision? That way we might be able to adjust it so that the response is limited to pitch in rotation and up/down in movement so there is never any sideways kick.

We can also get the road direction from the nearest meta data point. We already use this meta data to define suspension direction and simulate gravity with an impulse in this direction.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Futuristic Racing Game

Post by Norbo »

The collisions are probably realistic as the convex hull is pointy at the font. We could try to round the mesh off using collision margins. The problem is that we want unrealistic collisions so the ship is more likely to drive up the surface it drives into instead of rotating away from it.
If you stick with a physical approach, increasing the ConvexHullShape.CollisionMargin will keep the normals as 'good' as they can be without direct intervention.
Is there an equation for manually solving a collision? That way we might be able to adjust it so that the response is limited to pitch in rotation and up/down in movement so there is never any sideways kick.
You can solve it however you'd like and apply arbitrary impulses, but the calculations can get pretty hairy. One alternative may be to use immediate collision events to correct contact normals according to the meta data.

However, when going for such arbitrary control and nonphysical situations, a completely faked approach will probably produce the best result.
We can also get the road direction from the nearest meta data point. We already use this meta data to define suspension direction and simulate gravity with an impulse in this direction.
Instead of using the meta data to control things indirectly, it may be easier to just use the meta data directly. Force the ship into an acceptable location and orientation based on the nearby node. Store a horizontal offset relative to the central node path. When the player moves, he's actually just moving around in a 2d space where one axis is this local horizontal offset, and the other axis is forward/back along the track. All other effects would be faked or simulated secondarily and physics engine would be primarily used for collision detection.
Jamedjo
Posts: 3
Joined: Tue May 31, 2011 9:30 pm

Re: Futuristic Racing Game

Post by Jamedjo »

CollisionMargins increased.

We already 'fake' the reaction to collisions with walls and other ships using ".CollisionInformation.Events.ContactCreated += new ContactCreatedEventHandler<EntityCollidable>..." along with ".CollisionRules.Personal = CollisionRule.NoSolver;" and then apply impulses. We tried using the meta data to interpolate/lerp the ship's orientation to a new orientation, but that broke the impulse based systems.

If we moved to a 2d representation of space it seams we would have to start from scratch, and would have new problems. I can think of a way to fake jumps, but could have trouble mapping 3D velocities into the virtual 2D plane. If the ship is on the inside of a curve it would have to move faster through the virtual 2D space than when on the outside of a curve.

Maybe if instead we faked the collision by rotating the LinearVelocity into an new direction and applying an angular impulse to adjust the orientation, and one impulse to balance out the existing penetration from the collision. In a perfect system, if the track curved 90 degrees upwards like a wall the ship would then start moving up the wall in its new orientation. Is this similar to what you mean by "use immediate collision events to correct contact normals"?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Futuristic Racing Game

Post by Norbo »

If we moved to a 2d representation of space it seams we would have to start from scratch, and would have new problems. I can think of a way to fake jumps, but could have trouble mapping 3D velocities into the virtual 2D plane. If the ship is on the inside of a curve it would have to move faster through the virtual 2D space than when on the outside of a curve.
Correct. It would require various tricky transforms to ensure that the 2d 'gameplay space' represented something that felt good when projected up into 3d. The meta data would inform the tricky transforms by looking at various properties of the curve.
Maybe if instead we faked the collision by rotating the LinearVelocity into an new direction and applying an angular impulse to adjust the orientation, and one impulse to balance out the existing penetration from the collision. In a perfect system, if the track curved 90 degrees upwards like a wall the ship would then start moving up the wall in its new orientation. Is this similar to what you mean by "use immediate collision events to correct contact normals"?
Correcting contact normals means actually changing the normal inside contact objects within collisions. The result is that the contact will resist penetration along that normal. By correcting it, you can guarantee that it won't ever actively push in any direction other than the local up vector. At a 90 degree wall, if the meta data actually switches 90 degrees, the vehicle would slam into the face of the wall and stop.

If you do want a behavior where switching 90 degrees instantly can happen, then a lot of hacks (as you describe) will be necessary. Mixing highly controlled, arbitrary motion with physics gets messy unless the rules of interaction can be unified somehow. At this level, it's probably best to completely ignore physical orientation and just use a sphere with LocalInertiaTensorInverse = new Matrix3X3(). At least then you do not need to worry about managing angular velocity; the orientation would be defined entirely by gameplay factors like metadata or effects.
Post Reply