Vehicle damage of my vehicle

Smart programming, definitely not somebody “enabling car damage” in a premade generic physics library… I’d suggest simulating a very basic model of connected beams for the general structure (chassis, frame) and a mesh deforming based on that. Then another simulation for the slight deformations of the sheet metal surrounding the car. Top that off with a shader for the scratches etc. and you should get somewhere.

See Physics section on BeamNG Wiki here BeamNG.drive. Sure programmers are not stupid but they do search for shortcut first. :wink:

Great… I am not good enough in C++ and C but I also started looking in to bullet APIs. I would be helping hand if you need.

If you don’t need something realistic you could achieve it with only rigidbodies and glsl, this is how i did:

Every vehicle part

  • is a separate geometry that is a child of the vehicle body.
  • has its own rigidbody with cinematic set to true
  • has an userData that keeps track of its integrity

When a collision happens between the part and something

  • It calculates the damage according with the impact force
  • The integrity is decreased by the damage
  • If the integrity is equal or below 0 cinematic will be set to false so the part will fall from the vehicle
  • The impact force and the local collision point are sent to the vertexshader
  • The vertex shader deforms the geometry

It looks fake but still quite enjoyable and it is really fast. (the car here is just one geometry, if you divide it properly in different parts it will look much better)

4 Likes

Nice example. I also tried bit similar but not as good as yours. I used FloatBuffer and modified it on collision at impact point (I guess its bad way). can you explain how to use vertexshader to deform geometry. it will be great if you can share some code snippet to understand it.

I’ll try to explain it.
In my code I can store a fixed number of collisions let’s say 30.(you can’t use dynamics array in glsl)

For storing them I have 3 arrays in both glsl and java.
An array stores the position of the collision, the other one stores the force and the last one the radius, so that RADIUS[0] POSITION[0] and FORCE[0] refers to the same collision and RADIUS[1] POSITION[1] FORCE[1] to another one.

When a collision happens if there is a free space in these arrays I store the force in FORCE, the position in POSITION and an arbitrary value in RADIUS (I use 2 but it depends on the scale of your scene and on your preferences).
If the arrays are full, I get the first nearest stored collision and I replace it with the average between the old and the new one (in truth in the newer version I use a different algorithm instead of the average but I forgot to comment the code and I don’t remember any more how it works :sweat_smile: but the visual result is quite the same) and i increase the radius in order to get it cover the distance between the old and the new collision.

Then I send these 3 arrays to the vertexshader then in the shader I iterate over each collision, i get the distance between POSITION[i] and the current vertex, and I calculate the force of the deformation for the current vertex using FORCE[i] the distance and the radius in order to get gradually less force the more I move away from the collision point then I add the force to the current vertex position (it is called modelSpacePos in the Lighting.vert if i’m not wrong).

The actual code has few more variables like a rigidity factor that I use to get different behaviours on different materials but at this point it’s just a matter of tweaking the resultant force before apply it to the modelSpacePos.

I hope this could help you.

4 Likes

Thanks for your time. I do understand your use of POSITION, FORCE and RADIUS but I’ll have to play with vertexshader first and GLSL scripts. may be than I can understand how it works completely :grinning:. BTW have you used PhysicsCollisionListener. it gives AppliedImpulse may be you can use it for FORCE?

Yes.
From the PhysicsCollisionEvent you can get the two rigidbodies that collides, let’s say that ObjectA is the one which deforms, then I get the linear velocity (a_vel, b_vel) of both (you can do this with getLinearVelocity() if the object is a PhysicsRigidBody or getWalkDirection() if it is a charactercontrol).

Then I sum a_vel.negate() with b_vel and I normalize the result, in this way i get the direction then I multiply for the applied impulse and i get the force.