Problems with collision and fast objects
-
- Posts: 38
- Joined: Mon Aug 20, 2012 10:33 am
Problems with collision and fast objects
Hi everybody!
I am having some problems with object passing though other objects. This happens mostly with fast objects. I saw some other post on the forum about this subject, and based also on my observations, it does seem that the collision check would take place between two time steps and this is why it is skipped.
Things get more complicated when you consider two scenarios that make you game run slower: running on older machines and capturing video with some program, like with FRAPS.
Collision issues are very rare when your game is capable of maintaining a very steady framerate of above 100. But when running on a machine that only manages 20-40 FPS, fast objects pass though other objects almost as a rule. I managed to solve this partially by making TimeStepSettings.TimeStepDuration = 1 / 120.0f and calling Update(dt) version, with the time delta between frames.
This does work when running while FRAPS is capturing, but it makes everything very floaty, even when the framerate under FRAPS on a strong machine is the same as the framerate without FRAPS on a weaker machine. This situation has been improved by calling Update(dt /2); Update(dt / 2), but calling update twice still does not behave that great. Raising time step duration more makes all physics very slow.
So I was wondering if there is a way to handle varying framerate better and enforce collisions more? Even if this greatly impacts performance. I don't need a lot of objects on the move. I did not manage to get a set of parameters that works well for anything except medium ranges. Throwing an object from close range towards a wall will pass thought the wall in 95% of the cases, and throwing the object very far will cause it to clip though the floor. At medium range it works pretty good.
This could be due to my ForceUpdater.Gravity value, which is almost 1000. The way the world is set up, 1 meter is about 100 units, and this was a good value that did not cause physics to behave floaty.
And another question: for collision meshes created from vertex data, like terrain, I suspect is is better to chunk the terrain into a lot of small pieces that fit perfectly in axis-aligned boxes (for performance). Am I right?
Thank you!
I am having some problems with object passing though other objects. This happens mostly with fast objects. I saw some other post on the forum about this subject, and based also on my observations, it does seem that the collision check would take place between two time steps and this is why it is skipped.
Things get more complicated when you consider two scenarios that make you game run slower: running on older machines and capturing video with some program, like with FRAPS.
Collision issues are very rare when your game is capable of maintaining a very steady framerate of above 100. But when running on a machine that only manages 20-40 FPS, fast objects pass though other objects almost as a rule. I managed to solve this partially by making TimeStepSettings.TimeStepDuration = 1 / 120.0f and calling Update(dt) version, with the time delta between frames.
This does work when running while FRAPS is capturing, but it makes everything very floaty, even when the framerate under FRAPS on a strong machine is the same as the framerate without FRAPS on a weaker machine. This situation has been improved by calling Update(dt /2); Update(dt / 2), but calling update twice still does not behave that great. Raising time step duration more makes all physics very slow.
So I was wondering if there is a way to handle varying framerate better and enforce collisions more? Even if this greatly impacts performance. I don't need a lot of objects on the move. I did not manage to get a set of parameters that works well for anything except medium ranges. Throwing an object from close range towards a wall will pass thought the wall in 95% of the cases, and throwing the object very far will cause it to clip though the floor. At medium range it works pretty good.
This could be due to my ForceUpdater.Gravity value, which is almost 1000. The way the world is set up, 1 meter is about 100 units, and this was a good value that did not cause physics to behave floaty.
And another question: for collision meshes created from vertex data, like terrain, I suspect is is better to chunk the terrain into a lot of small pieces that fit perfectly in axis-aligned boxes (for performance). Am I right?
Thank you!
Re: Problems with collision and fast objects
It sounds like there are a few things going on at once.
1) Space.Update() performs one time step of length Space.TimeStepSettings.TimeStepDuration. Space.Update(dt) takes however many timesteps of length Space.TimeStepSettings.TimeStepDuration are necessary to simulate the accumulated time passed in as a parameter. Changing Space.TimeStepSettings.TimeStepDuration dynamically and continuously will introduce instability even if it's changing between values smaller than 1/60f. Allowing it to vary with FPS entirely will cause huge issues during times of bad framerate. Space.Update(dt) is the correct method to decouple physics update rates from game update rates.
If the Space.TimeStepSettings.TimeStepDuration is 1/60f and Space.Update(dt) is called from a game loop with a 60hz update rate, an average of one physics time step will occur every game frame. If the Space.TimeStepSettings.TimeStepDuration is 1/120f and Space.Update(dt) is called from a game loop with a 60hz update rate, an average of two physics time steps will occur every game frame. This allows you to decouple the physics update rate and the game update rate.
A common problem is grabbing the value to pass into Space.Update(dt) from the number of elapsed milliseconds instead of seconds. This means the values passed into the Space.Update(dt) method are 1000x larger than you expected. The Space.Update(dt) method will try to simulate the requested thousand time steps per frame, but there is a configurable Space.TimeStepSettings.MaximumTimeStepsPerFrame limit that defaults to 3. This maximum prevents the engine from going through all 1000 requested time steps. This recouples the physics update to the game update rate. This is likely why splitting it into two Space.Update(dt) calls seemed to help- each one had its own per-frame maximum.
Passing in the fraction of seconds elapsed rather than milliseconds will fix this issue.
2) Floatiness is generally caused by object sizes being large relative to the gravity and your expectations. If this were the sole cause, then increasing gravity or decreasing object sizes would help.
Sometimes (and in this case), it is caused by an insufficient number of time steps. For example, if the Space.TimeStepSettings.TimeStepDuration is 1/120f and Space.Update() is called once per 1/60f game frame, then only one 1/120f duration time step will occur for every 1/60f game frame. This will make the game appear to advance at half speed, and things will appear floaty. The above '1000x more updates requested than expected' from #1 will also cause this effect. Only 3 updates of the expected 1000 are running, so the physics update rate is coupled to the game update rate. Fix that problem first before attempting to analyze floatiness.
3) The engine is tuned for a size range of around 0.5 to 10 units by default. It's conditionally safe to go out of this range with the default settings, but going all the way out to 100x larger (as implied by your gravity of 1000) is going to introduce instability. Collisions will fail to generate good contacts. Stuff will jiggle and fall through. To address this, check out the ScaleDemo and ConfigurationHelper.ApplyScale method in the BEPUphysicsDemos source. The ConfigurationHelper.ApplyScale method adjusts a set of variables used by the engine to interpret scales so that it can handle different size ranges better. Another option is to just scale down the world so that it is closer to the default scale interpretation. I generally advise sticking to the default scale interpretation if possible.
4) Setting an entity's entity.PositionUpdateMode to PositionUpdateMode.Continuous will enable continuous collision detection for that object. This sweeps core shapes to prevent the most heinous of missed collisions like tunneling straight through a wall. While this may mitigate the problems you're seeing, the rest of the above problems will likely need to be addressed too.
So, to summarize:
1) Fix the time step issues first. For simplicity, leave the Space.TimeStepSettings.TimeStepDuration at the default of 1/60f and either call Space.Update() once per frame if your game has a fixed time step of length 1/60f or use Space.Update(dt) where dt is the elapsed seconds instead of milliseconds.
2) Examine floatiness. If it's still floaty even after fixing time step issues, increase gravity relative to the object sizes or decrease object sizes.
3) Fix scale issues so that you know any tunneling is truly caused by discrete updates and not just contact generation failure.
4) If tunneling is still present, set the relevant entities' PositionUpdateMode to Continuous. This is a very cheap thing to enable; I only left it as the last thing on the list to ensure that all the other problems are addressed first.
Keep as much in one mesh as reasonably possible. If it isn't convenient to keep things in one mesh for some reason (say, some game logic), consider bundling the many StaticMeshes into one StaticGroup. This will be roughly as fast as having all of the triangles in one big StaticMesh, minus a tiny little bit of overhead.
1) Space.Update() performs one time step of length Space.TimeStepSettings.TimeStepDuration. Space.Update(dt) takes however many timesteps of length Space.TimeStepSettings.TimeStepDuration are necessary to simulate the accumulated time passed in as a parameter. Changing Space.TimeStepSettings.TimeStepDuration dynamically and continuously will introduce instability even if it's changing between values smaller than 1/60f. Allowing it to vary with FPS entirely will cause huge issues during times of bad framerate. Space.Update(dt) is the correct method to decouple physics update rates from game update rates.
If the Space.TimeStepSettings.TimeStepDuration is 1/60f and Space.Update(dt) is called from a game loop with a 60hz update rate, an average of one physics time step will occur every game frame. If the Space.TimeStepSettings.TimeStepDuration is 1/120f and Space.Update(dt) is called from a game loop with a 60hz update rate, an average of two physics time steps will occur every game frame. This allows you to decouple the physics update rate and the game update rate.
A common problem is grabbing the value to pass into Space.Update(dt) from the number of elapsed milliseconds instead of seconds. This means the values passed into the Space.Update(dt) method are 1000x larger than you expected. The Space.Update(dt) method will try to simulate the requested thousand time steps per frame, but there is a configurable Space.TimeStepSettings.MaximumTimeStepsPerFrame limit that defaults to 3. This maximum prevents the engine from going through all 1000 requested time steps. This recouples the physics update to the game update rate. This is likely why splitting it into two Space.Update(dt) calls seemed to help- each one had its own per-frame maximum.
Passing in the fraction of seconds elapsed rather than milliseconds will fix this issue.
2) Floatiness is generally caused by object sizes being large relative to the gravity and your expectations. If this were the sole cause, then increasing gravity or decreasing object sizes would help.
Sometimes (and in this case), it is caused by an insufficient number of time steps. For example, if the Space.TimeStepSettings.TimeStepDuration is 1/120f and Space.Update() is called once per 1/60f game frame, then only one 1/120f duration time step will occur for every 1/60f game frame. This will make the game appear to advance at half speed, and things will appear floaty. The above '1000x more updates requested than expected' from #1 will also cause this effect. Only 3 updates of the expected 1000 are running, so the physics update rate is coupled to the game update rate. Fix that problem first before attempting to analyze floatiness.
3) The engine is tuned for a size range of around 0.5 to 10 units by default. It's conditionally safe to go out of this range with the default settings, but going all the way out to 100x larger (as implied by your gravity of 1000) is going to introduce instability. Collisions will fail to generate good contacts. Stuff will jiggle and fall through. To address this, check out the ScaleDemo and ConfigurationHelper.ApplyScale method in the BEPUphysicsDemos source. The ConfigurationHelper.ApplyScale method adjusts a set of variables used by the engine to interpret scales so that it can handle different size ranges better. Another option is to just scale down the world so that it is closer to the default scale interpretation. I generally advise sticking to the default scale interpretation if possible.
4) Setting an entity's entity.PositionUpdateMode to PositionUpdateMode.Continuous will enable continuous collision detection for that object. This sweeps core shapes to prevent the most heinous of missed collisions like tunneling straight through a wall. While this may mitigate the problems you're seeing, the rest of the above problems will likely need to be addressed too.
So, to summarize:
1) Fix the time step issues first. For simplicity, leave the Space.TimeStepSettings.TimeStepDuration at the default of 1/60f and either call Space.Update() once per frame if your game has a fixed time step of length 1/60f or use Space.Update(dt) where dt is the elapsed seconds instead of milliseconds.
2) Examine floatiness. If it's still floaty even after fixing time step issues, increase gravity relative to the object sizes or decrease object sizes.
3) Fix scale issues so that you know any tunneling is truly caused by discrete updates and not just contact generation failure.
4) If tunneling is still present, set the relevant entities' PositionUpdateMode to Continuous. This is a very cheap thing to enable; I only left it as the last thing on the list to ensure that all the other problems are addressed first.
StaticMeshes (and the rest of the meshes) have an internal acceleration structure which has more guarantees than the broad phase does. This makes them more efficient at their job. Splitting up a StaticMesh into a bunch of pieces puts more pressure on the broad phase rather than the more efficient internal acceleration structure, slowing things down.And another question: for collision meshes created from vertex data, like terrain, I suspect is is better to chunk the terrain into a lot of small pieces that fit perfectly in axis-aligned boxes (for performance). Am I right?
Keep as much in one mesh as reasonably possible. If it isn't convenient to keep things in one mesh for some reason (say, some game logic), consider bundling the many StaticMeshes into one StaticGroup. This will be roughly as fast as having all of the triangles in one big StaticMesh, minus a tiny little bit of overhead.
-
- Posts: 38
- Joined: Mon Aug 20, 2012 10:33 am
Re: Problems with collision and fast objects
Hi Norbo!
Thank you for the quick reply.
I should have started by saying that I do not use a fixed time step.
I went through the list and tried the changes you proposed to see what effect they have.
Calling Update(dt) with the elapsed seconds between frames did wonders to make the game run at a more consistent pace. Using a TimeStepDuration of 1/60 is not enough, but using 1/120 and only changing the delta time passed to Update fixed a big number of issues with tunneling.
I tried changing the world scale, but for now I only manged to reduce it 10 times, so my g is around 100 (10 * nomal g). As far as I can tell this had little to no effect on stability. For now I can't lower the scale any more because I encounter issues with my shaders. If I manage to reduce the scale even more, I'll let you know.
Still, even with these two changes tunneling was very common at long range with fast objects, while greatly reduced at short to medium ranges. Setting PositionUpdateMode.Continuous on the other hand fixes these issues. Tunneling is very rare. Ironically, because of how rare and surprising it is, it is even more disturbing then when it happened all the time.
I added PositionUpdateMode.Continuous to all movable objects for now and I'll keep on profiling. Performance was not impacted a lot, but I do get occasional spikes that last a few seconds and I need to find out if this is due to physics or if I did something wrong when I scaled the world down.
The only issues I am still having are with FRAPS. FRAPS halves the framerate. Because of the speed it is fairly hard to tell what is going on, but physics seems to run at half speed too.
While waiting for you reply I did break up the terrain into smaller chunks, and indeed the physics time increased slightly. I am not worried about that for now.
I have one more question for now: how is it better to map smaller immovable or semi immovable (they can't be moved by physics interaction but sometimes I move them through code) objects? I could create the collision mesh from the vertices of the real mesh. Most of my models are low res, but still I suspect this can get quite expensive. So I could use a low resolution approximation mesh for objects. The third variant would be to try and approximate the shape using boxes, cylinders, spheres, etc. Which one do you recommend? I am talking about object like wall sections, larger but not too big furniture pieces like beds, columns, wardrobes, etc.
Thank you for the quick reply.
I should have started by saying that I do not use a fixed time step.
I went through the list and tried the changes you proposed to see what effect they have.
Calling Update(dt) with the elapsed seconds between frames did wonders to make the game run at a more consistent pace. Using a TimeStepDuration of 1/60 is not enough, but using 1/120 and only changing the delta time passed to Update fixed a big number of issues with tunneling.
I tried changing the world scale, but for now I only manged to reduce it 10 times, so my g is around 100 (10 * nomal g). As far as I can tell this had little to no effect on stability. For now I can't lower the scale any more because I encounter issues with my shaders. If I manage to reduce the scale even more, I'll let you know.
Still, even with these two changes tunneling was very common at long range with fast objects, while greatly reduced at short to medium ranges. Setting PositionUpdateMode.Continuous on the other hand fixes these issues. Tunneling is very rare. Ironically, because of how rare and surprising it is, it is even more disturbing then when it happened all the time.
I added PositionUpdateMode.Continuous to all movable objects for now and I'll keep on profiling. Performance was not impacted a lot, but I do get occasional spikes that last a few seconds and I need to find out if this is due to physics or if I did something wrong when I scaled the world down.
The only issues I am still having are with FRAPS. FRAPS halves the framerate. Because of the speed it is fairly hard to tell what is going on, but physics seems to run at half speed too.
While waiting for you reply I did break up the terrain into smaller chunks, and indeed the physics time increased slightly. I am not worried about that for now.
I have one more question for now: how is it better to map smaller immovable or semi immovable (they can't be moved by physics interaction but sometimes I move them through code) objects? I could create the collision mesh from the vertices of the real mesh. Most of my models are low res, but still I suspect this can get quite expensive. So I could use a low resolution approximation mesh for objects. The third variant would be to try and approximate the shape using boxes, cylinders, spheres, etc. Which one do you recommend? I am talking about object like wall sections, larger but not too big furniture pieces like beds, columns, wardrobes, etc.
Re: Problems with collision and fast objects
If the scale cannot be changed any further, then using the ConfigurationHelper.ApplyScale method I mentioned in the previous post would be a good idea. Given that the gravity is still 10 times higher than 'regular,' trying values between 5 and 15 may be a good starting point. The best values depend heavily on what exactly is going on in the simulation. Gravity magnitude alone isn't enough information to pick the best values, unfortunately.I tried changing the world scale, but for now I only manged to reduce it 10 times, so my g is around 100 (10 * nomal g). As far as I can tell this had little to no effect on stability. For now I can't lower the scale any more because I encounter issues with my shaders. If I manage to reduce the scale even more, I'll let you know.
If the tunneling occurs when objects are entirely isolated from other dynamic objects, moving quickly against static geometry, a failure of contact generation due to remaining size issues is possible.Still, even with these two changes tunneling was very common at long range with fast objects, while greatly reduced at short to medium ranges. Setting PositionUpdateMode.Continuous on the other hand fixes these issues. Tunneling is very rare. Ironically, because of how rare and surprising it is, it is even more disturbing then when it happened all the time.
If the tunneling occurs during forceful interactions with other dynamic objects, then the object may be shoved out of the world through immense force applied when the object is already in collision. When a pair of objects are already in collision, motion clamping CCD cannot really do anything useful. At that point, the only thing stopping the object from tunneling is the generated contacts. If the manifold is not yet complete (or is poor due to scaling issues), it may rotate through the obstacle in the space of one time step.
Bounciness, in particular, can cause significant problems when combined with high velocity and heavy interaction. In these situations, setting MotionSettings.UseExtraExpansionForContinuousBoundingBoxes to true can help, though this can be very expensive in the worst case.
The Space.TimeStepSettings.MaximumTimeStepsPerFrame mentioned in the previous post probably explains this. At a physics time step duration of 1/120f, a game update rate of 30hz would require 4 time steps on average. This is already higher than the default maximum of 3. Increasing the maximum would address the issue so long as your computer is capable of running the simulation in the time allotted.The only issues I am still having are with FRAPS. FRAPS halves the framerate. Because of the speed it is fairly hard to tell what is going on, but physics seems to run at half speed too.
It's a good idea to keep the physics representation separate from the actual graphics.I have one more question for now: how is it better to map smaller immovable or semi immovable (they can't be moved by physics interaction but sometimes I move them through code) objects? I could create the collision mesh from the vertices of the real mesh. Most of my models are low res, but still I suspect this can get quite expensive. So I could use a low resolution approximation mesh for objects. The third variant would be to try and approximate the shape using boxes, cylinders, spheres, etc. Which one do you recommend? I am talking about object like wall sections, larger but not too big furniture pieces like beds, columns, wardrobes, etc.
A physics mesh should have the smallest number of triangles possible while approximating the desired shape and avoiding 'bad' triangles. A 'bad' triangle is one that is too large or too small for the current scale interpretation to handle efficiently, or a triangle which is much longer than it is wide.
For example, a very long hallway floor could be represented by two triangles, but the triangles would each be 2x1000 units. While this minimizes the triangle count, the triangles are 'bad' and should be avoided. Adding a few more triangles to prevent near degenerate geometry is worth it.
For objects which map to a primitive like a box or cylinder sufficiently closely, using a box or cylinder instead of a mesh will help performance. However, given the number of separate objects involved, a StaticGroup should be used to bundle them together. Check out the StaticGroupDemo for an example.
(Note: moving objects in a static group requires refitting the acceleration structure of the static group. Adding objects to or removing objects from the static group requires a acceleration structure reconstruction. A reconstruction is slow; if there is a small subset of objects which get added/removed frequently, keeping them outside of the StaticGroup would avoid the reconstruction at the cost of more broad phase pollution.)
I would recommend using meshes for the main world structure, though. Creating floors out of a bunch of boxes will cause the player or physics objects to 'bump' at box intersections sometimes. Properly built meshes avoid bumps by using the connectivity information stored in the index list.
-
- Posts: 38
- Joined: Mon Aug 20, 2012 10:33 am
Re: Problems with collision and fast objects
I finally decided to go for it and reduce the scale of the world. I was running a setup where a person had the eye level at 10 units, a box was about 3, a barrel was 6, etc. In this setup I used a gravity of 30 *g, but probably 20 *g would have been enough for objects not to be floaty.
Under the new setup I scaled things down 10 times, but now things behave weird. I don't know how to describe it, but things are more bouncy and active. Dropping something will result a more energetic contact, inserting something into the volume of something else will cause a more accelerated ejection, and most importantly cylinders no longer behave as "perfect" cylinders rolling down smoothly. Instead they behave like a low poly approximation of a cylinder mesh that has a limited number of sides. This is very apparent at rolling down hills and also the cylinder actually stops a lot faster from rolling.
Any idea what might cause this behavior? With the times 10 scale thing are pretty stable, but I do need continuous position updates to prevent random but rare tunneling. There might be just a bit of jittering and object take some time to settle, but the entire system is stable.
And another question. How could I handle non energetic interactive placement of objects in the game world, like decorating an interior. Currently I am using something like this:
This works pretty good at placing thing only on top of objects, but I am having troubles placing them on even light slopes. Especially cylinders tip over really easy. Is there a way to drop objects only on relatively smooth surfaces but make them behave like they were slowly and very carefully placed down? With minimal impact. I don't want someone putting a box on a table and causing all the silverware to behave like something was dropped on it. This is only for the initial placement. Otherwise objects should react normally to physics.
Under the new setup I scaled things down 10 times, but now things behave weird. I don't know how to describe it, but things are more bouncy and active. Dropping something will result a more energetic contact, inserting something into the volume of something else will cause a more accelerated ejection, and most importantly cylinders no longer behave as "perfect" cylinders rolling down smoothly. Instead they behave like a low poly approximation of a cylinder mesh that has a limited number of sides. This is very apparent at rolling down hills and also the cylinder actually stops a lot faster from rolling.
Any idea what might cause this behavior? With the times 10 scale thing are pretty stable, but I do need continuous position updates to prevent random but rare tunneling. There might be just a bit of jittering and object take some time to settle, but the entire system is stable.
And another question. How could I handle non energetic interactive placement of objects in the game world, like decorating an interior. Currently I am using something like this:
Code: Select all
Ray ray = new Ray();
ray.Position = camera.Position;
ray.Direction = camera.ViewDirection;
RayCastResult res;
int index = 0;
if (space.RayCast(ray, out res)) {
Vector3 v = res.HitData.Normal;
v.Normalize();
if (v.Y > 0.85f/* && v.X < 0.1f && v.Z < 0.1f && v.X > 0.0f && v.Z > 0.0f*/) {
ray.Position = res.HitData.Location + new Vector3(0, 100, 0);
ray.Direction = Vector3.Down;
if (space.RayCast(ray, out res)) {
CreateObjectCube(res.HitData.Location + new Vector3(0, meshes[index].size.Y / 2 + 0.05f, 0), index);
}
}
}
Re: Problems with collision and fast objects
As you scale down more and more, you will run into the default tuning factors. The 'energy' is probably coming from a combination of high relative velocities causing deep penetration and a strong penetration correction force relative to the scale. The speed achieved by penetration correction impulses is capped by CollisionResponseSettings.MaximumPenetrationCorrectionSpeed.Under the new setup I scaled things down 10 times, but now things behave weird. I don't know how to describe it, but things are more bouncy and active. Dropping something will result a more energetic contact, inserting something into the volume of something else will cause a more accelerated ejection, and most importantly cylinders no longer behave as "perfect" cylinders rolling down smoothly. Instead they behave like a low poly approximation of a cylinder mesh that has a limited number of sides. This is very apparent at rolling down hills and also the cylinder actually stops a lot faster from rolling.
It sounds like you're also running into other tuning factors, like contact invalidation. Both of these and more are covered by the BEPUphysicsDemos ConfigurationHelper.ApplyScale method.
Also, if you are not using it already, I would recommend updating to the latest version (v1.2 or the in-development version). They have some scale-related improvements.
Something does not sound right here. If the character is supposed to be approximately human-sized with relation to its environment and 'g' is (0, -9.81f, 0), then the necessary gravity should only be 5g to have realistic gravity, not 30g (which would be more than twice Jupiter's gravity at the gaseous surface).I was running a setup where a person had the eye level at 10 units, a box was about 3, a barrel was 6, etc. In this setup I used a gravity of 30 *g, but probably 20 *g would have been enough for objects not to be floaty.
If 30g is truly required to achieve a perception of earthlike gravity, there is probably some time step issue still present.
For slopes, you'll have to rotate the object so that its bottom surface is in a nice comfortable touching contact. Spawning an object partially inside another or floating above it will cause a forceful interaction.Is there a way to drop objects only on relatively smooth surfaces but make them behave like they were slowly and very carefully placed down? With minimal impact.
Also, be sure to take into account the object's full shape. For example, all convex objects have a collision margin (found in the ConvexShape.CollisionMargin property; defaults to 0.04 for everything but spheres and capsules) for collision detection purposes. Spheres, capsules, boxes, and cylinders use 'internal' collision margins, meaning they are contained within the defined shape of the primitive rather than expanding outward. These are easier to deal with since the dimensions of the shape include the margin. Other shapes, like convex hulls, expand outward.
-
- Posts: 38
- Joined: Mon Aug 20, 2012 10:33 am
Re: Problems with collision and fast objects
I started using ApplyScale(10) and a gravity of 5g and things are still a little bit floaty, but at least 30g is not needed. Finding both a good scale for the world and a value for ApplyScale is pretty time consuming.Norbo wrote: As you scale down more and more, you will run into the default tuning factors. The 'energy' is probably coming from a combination of high relative velocities causing deep penetration and a strong penetration correction force relative to the scale. The speed achieved by penetration correction impulses is capped by CollisionResponseSettings.MaximumPenetrationCorrectionSpeed.
It sounds like you're also running into other tuning factors, like contact invalidation. Both of these and more are covered by the BEPUphysicsDemos ConfigurationHelper.ApplyScale method.
Also, if you are not using it already, I would recommend updating to the latest version (v1.2 or the in-development version). They have some scale-related improvements.
Another question: is it feasible to start using convex hulls and compounds instead of simple physics shapes? On a large scale. I am speaking about hundreds of objects spread out over the surface of the map and generally only a few interacting. Currently I am only using cubes and cylinders, but most meshes could greatly benefit from a more accurate collision mesh.
Re: Problems with collision and fast objects
ApplyScale should not affect the gravity necessary to avoid 'floatiness.' ApplyScale just changes some values related to collision detection and collision response like the minimum allowed distance between contact points.I started using ApplyScale(10) and a gravity of 5g and things are still a little bit floaty, but at least 30g is not needed.
Floatiness is caused by low gravity relative to object size or time step related issues. Since you've already fiddled with gravity, it sounds like there's still time step related issues.
If you scale the world such that it fits within the default scale interpretation, you do not need to use ApplyScale at all. Generally, you should only have to use one or the other. There is rarely any value in doing both at once from a simulation perspective.Finding both a good scale for the world and a value for ApplyScale is pretty time consuming.
A good target scale can be estimated by dividing the size of the world by the default recommended size. If your objects frequently range from 5 to 100 units, then ApplyScale(10) would be appropriate because the default range if 0.5 to 10. For many simulations, this also tends to correlate with the gravity required to produce the desired effect. So, for 5 * -9.81, ApplyScale(5) would probably be a good start.
Yes, it's feasible. Convex hulls and compounds are going to be a little more expensive than simple primitives, but not nearly as much as something like a mobile mesh. If the object can be represented by a simple primitive like a box shape or cylinder shape, I would recommend using it for performance reasons, but if a particular object would really benefit from more detail then it is fine to use a more detailed shape.Another question: is it feasible to start using convex hulls and compounds instead of simple physics shapes? On a large scale. I am speaking about hundreds of objects spread out over the surface of the map and generally only a few interacting. Currently I am only using cubes and cylinders, but most meshes could greatly benefit from a more accurate collision mesh.
The cost of collision detection with convex hulls rises roughly linearly with the number of vertices on the surface of the hull, though. Using the graphical vertices directly is rarely necessary for a tight-fitting appearance; I would recommend using simplified point sets.
-
- Posts: 38
- Joined: Mon Aug 20, 2012 10:33 am
Re: Problems with collision and fast objects
Wow, even an ApplyScale of 5 makes collision of small objects very unstable and adds a lot of tunneling. Did not notice it before because I was testing only medium objects. Placing a barrel or table on a floor is fine, placing a fork on the table is not.
Removing the ApplyScale call. Things are stable, but I'm not sure everything is tuned to work as intended. It is a question of "feel" and these are particularly difficult to resolve without a good frame of reference. The official BEPU demos feel floaty.
Removing the ApplyScale call. Things are stable, but I'm not sure everything is tuned to work as intended. It is a question of "feel" and these are particularly difficult to resolve without a good frame of reference. The official BEPU demos feel floaty.
Re: Problems with collision and fast objects
In the case of very tiny objects, you'll need to pick the ApplyScale such that the tuning variables don't interfere with contact generation. If they're 0.2 units across and ApplyScale(5) is used, contacts won't be able to generate properly.Wow, even an ApplyScale of 5 makes collision of small objects very unstable and adds a lot of tunneling
Very tiny stuff imposes a hard limit on how much you can adjust the scale interpretation; scaling up changes things like minimum contact separation which will confound tiny contact manifolds if pushed too far. The failure case for objects which are too large for the scale interpretation is more subtle and generally not as heinous as it is with very very tiny objects.
The demos feel floaty because the objects are all the size of cars (or sometimes buses) if gravity is assumed to be earthlike. ApplyScale has no effect on this, though- floatiness is related to the size of objects relative to gravity (as in the demos) or potential time stepping issues (as it may be in this case).It is a question of "feel" and these are particularly difficult to resolve without a good frame of reference. The official BEPU demos feel floaty.