Hi,
long time no see. I've got a question regarding the conversion of static meshes to meshes with rigidbodies.
Imagine a small town where one house has a fence. For performance reasons the whole town (including the fence) is baked into one static mesh. Is it possible or even feasible (in your engine or in general) to "unbake" the fence as soon as something is colliding with it, i.e. a car, and to replace it with identical looking fence pieces that have rigidbodies on them to make them move around realistically by the forces of the impact?
I once tried something similar in the Unity engine. I had to store the velocity of a car in previous frames because an impact with static geometry would immediately stop the car. Applying the previously stored velocity to the car - as soon as the impact happened - helped to still make everything look somewhat right. It had some issues, though, and was war from perfect.
Cheers
BrightBit
Convert static mesh to dynamic mesh at an impact
Re: Convert static mesh to dynamic mesh at an impact
In bepuphysics v1 and engines which handle things similarly, removing something from a static mesh is a topological change that will tend to imply a heavy acceleration structure update. So, it is possible, but it comes with pretty significant overhead- especially when talking about a single giant level mesh. In those engines, it's probably worth keeping the environment mesh at least somewhat subdivided to avoid the massive frame spikes that would otherwise occur with those changes, even though the broad phase will become a bit slower in the average case.
In bepuphysics v2 and similar, the need to bake everything into a single mesh pretty much goes out the window. The broad phase handles statics separately so that overhead is pretty miniscule. Having 10000 statics in the world is already pretty negligible, and by the time I'm done it will be even less of a concern.
Notably, v2 handles statics and sleeping bodies in the same way. They have extremely low overhead. So, a game that needs to have a fence that can be knocked over might be able to get away with just having kinematic bodies or constrained dynamic bodies that go to sleep. Upon impact, the kinematic could be forced dynamic or the constraint holding the dynamic could be removed. That would be a little less annoying to deal with than modifying a static mesh.
As for dealing with collision response rigidity, another option would be to check the accumulated impulse of the contact constraints that caused the breakage. You could then choose to undo those impulses partially or in full by applying scaled negative impulses at the contact points along the contact normal. This still wouldn't be perfect, but it can avoid some of the corner cases of fully preserving previous velocity.
A "correct" solution would be to make the solver aware of the breaking force limit. If a fencepost is actually a dynamic body constrained to the ground, you could do this by giving the constraint a maximum force. The impacting object would still lose momentum, but only as much as was required to overpower the constraint. (The constraint would need to be removed after the impact frame.)
In bepuphysics v2 and similar, the need to bake everything into a single mesh pretty much goes out the window. The broad phase handles statics separately so that overhead is pretty miniscule. Having 10000 statics in the world is already pretty negligible, and by the time I'm done it will be even less of a concern.
Notably, v2 handles statics and sleeping bodies in the same way. They have extremely low overhead. So, a game that needs to have a fence that can be knocked over might be able to get away with just having kinematic bodies or constrained dynamic bodies that go to sleep. Upon impact, the kinematic could be forced dynamic or the constraint holding the dynamic could be removed. That would be a little less annoying to deal with than modifying a static mesh.
As for dealing with collision response rigidity, another option would be to check the accumulated impulse of the contact constraints that caused the breakage. You could then choose to undo those impulses partially or in full by applying scaled negative impulses at the contact points along the contact normal. This still wouldn't be perfect, but it can avoid some of the corner cases of fully preserving previous velocity.
A "correct" solution would be to make the solver aware of the breaking force limit. If a fencepost is actually a dynamic body constrained to the ground, you could do this by giving the constraint a maximum force. The impacting object would still lose momentum, but only as much as was required to overpower the constraint. (The constraint would need to be removed after the impact frame.)
Re: Convert static mesh to dynamic mesh at an impact
Thank you for your fast and detailed answer. Now I've got even more reasons to look forward to version 2 of your engine.
Re: Convert static mesh to dynamic mesh at an impact
in V2 you can just do this, by turning you dynamic body to kinematic
Code: Select all
internal static readonly BodyInertia _kinematicInertia = new BodyInertia();
internal void SetKinematic()
{
if (bodyRef.Exists)
{
if (_isKinematic)// setMass to 0 kinematic object
bodyRef.LocalInertia = _kinematicInertia;
else // restore original inverseMass for dynamic object
bodyRef.LocalInertia = _bodyInertia;
}
}
Re: Convert static mesh to dynamic mesh at an impact
While that covers the inertia, there is some other state that should be updated too- the Simulation.Bodies.SetLocalInertia handles the necessary transitions. (Simulation.Bodies.ApplyDescription will too, if necessary.)
Re: Convert static mesh to dynamic mesh at an impact
something like this?
Code: Select all
if (_isKinematic)// set kinematic object
bodyRef.BecomeKinematic();
else // restore original for dynamic object
bodyRef.SetLocalInertia(_bodyInertia);
Re: Convert static mesh to dynamic mesh at an impact
Yup, that'll work.