How to create explosions

Hi everyone,

I am studying how to implement explosion that typically consists of 3 parts:

  1. Visualization: fire, flashes, lights, particles or anything else that makes explosion visible. I assume that in most cases it might be just artwork without any physics model under it. I am not good at art, so searching for some existing examples.

  2. Splash damage. Damage to objects reduces while distance from explosion center grows. Sounds easy, but might be not so in real. First, we need to calculate which objects in scene will be affected and calculate distance to them to apply corresponding damage. Second, and the hardest part, splash damage should not work through solid walls. Any examples, alorithm here?

  3. Shockwave. Explosion force should push objects from explosion center. And again, force should not work through solid indestructible walls. The hardest part I think.

There is a playground from docs, but it doesn’t work anymore (looks like something is broken): https://playground.babylonjs.com/index.html#0LM7CJ#6

Any way, I need more understanding of how explosion might be simulated. Will appreciate good examples on Babylon and theory references. Please share if there is anything.

Thank you for attention to my question!

1 Like

Well this code should work. I sent an email to https://github.com/bobalazek who is the author :slight_smile:

Pinging @trevordev if he can help as well

Hey! Sorry, I’ll update the documentation ASAP!
Temporarily, here you can see & check out all the effects:
https://playground.babylonjs.com/index.html#UZHINX

  1. Correct, you can do this part without any physics stuff. You could maybe even use babylon’s own particle effects for that: Use the Particle Helper - Babylon.js Documentation
  2. This part is not (yet) implemented into the physics helper, but that was also kind of the idea when I started working on it. Currently it does not deal any damage, but if you check the code, you’ll see the PhysicsRadialImpulseFalloff enum (Babylon.js/physicsHelper.ts at master · BabylonJS/Babylon.js · GitHub), that does exactly that, but it’s used only for internal force calculations.
  3. That’s what the PhysicsHelper is for. To actually do the physics computation. Yes, solid objects/walls, that’s quite a tricky part. Will need to think about that one

Now, I guess the best way to go from there would probably be, that I’ll create a callback function, in which you’d get the distance from impact (centre of explosion) for all physics bodies, and then you do with it whatever you like? As we don’t really have a concept of “health” on a physics body, to which it would be applied automatically.

3 Likes

thanks a lot!!!

Ok, I prepared the affectedImpostors functionality. You can see the the PR here:

So after the PR is merged, you should be able to get the affectedImpostors the following way:

            var event = physicsHelper.applyRadialExplosionImpulse( // or .applyRadialExplosionForce
            origin,
            {
                radius: radius,
                strength: strength,
                falloff: BABYLON.PhysicsRadialImpulseFalloff.Linear, // or BABYLON.PhysicsRadialImpulseFalloff.Constant

                // ONLY THIS PART IS RELEVANT REALLY
                affectedImpostorsCallback: (affectedImpostorsWithData) => {
                    console.log(affectedImpostorsWithData);
                    // Array<{ 
                    //      impostor: PhysicsImpostor,
                    //      hitData: { force: Vector3, contactPoint: Vector3, distanceFromOrigin: number }
                    // }>
                },
            }
        );

After that, you should be able to do with the hit data whatever you like

  1. Thank you for the link to documentation. Actually I am looking for something like grenade explosion, not nuclear bomb. :grin: I will try to remake existing example, but if you already have one or know where to get it, please share.

  2. Looks like basic splash damage might be done even without any physics: Babylon.js Playground
    But the problem is that intersectsMesh method doesn’t work correctly with spheres. You can see that It also affects the destructible object outside the explosion sphere.

Regarding blocking by walls. We can also detect intersections with walls. If wall is met we can use it’s coordinates to turn our explosion sphere into spherical cap (Spherical cap - Wikipedia).
But BABYLON.MeshBuilder.CreateSphere has a slice option that applies only to bottom of sphere. Of course, we can rotate sphere after it, but what about multiple slices? Explosion might intersect several walls in any direction. Can Babylon create multiple sliced mesh?

Probably at this point will be better to rely on Impostor’s hit data.

  1. Probably sliced sphere might be used to create ‘limited’ shockwave. If applyRadialExplosionImpulse could accept random shape as parameter, it could create explosion force field inside given volume. Yes, it will be hard to calculate, for random shapes we can’t apply easy math formula, triple integrals should be used instead I think (I am not so strong in Math, to be honest). But it would be great. Is it possible?

One more little question. How to download last nighty using npm? What should I write in package.json in dependencies section instead of "babylonjs": "^3.2.0",?

click on the torus knot : Babylon.js Playground

2 Likes
  1. Sadly no. I guess you could maybe find a shader from the Shadertoy website and use that in this case
  2. Oh yeah, absolutely. The physics helpers on its own use the exact same feature (native collisions) to get the intersecting meshes. Strange, your PG example works fine for me. The most inner sphere is red, the second one inside it yellow, and the outermost 2 are green
  3. Honestly, I’m not that good in math either. If you check the physicsHelper that I wrote, it’s for the most part just very simple stuff in there. And yeah, as you’ll see there, for each effect I added only simple shapes (sphere & cylinder), as it was primarily meant to do those simple stuff and also for the sake of performance.

Yes, using a custom shape/mesh was also on my TODO list, but didn’t yet have time to implement it. So if you’re up to it, you can create a PR :slight_smile:

If you try this?
npm install git://github.com/BabylonJS/Babylon.js.git#master --save

2 Likes

Maybe something like this? https://palmer-jc.github.io/scenes/blow_me_baby/index.html

1 Like
  1. The most left sphere should not be green, it should be white because it’s not even intersected. But damageSphere.intersectsMesh() thinks that it is intersected.

Seems like a bug, but not really sure yet on which part. I’m using the same method (intersectsMesh()) in the physicsHelper and it works fine there.

I would do something like this;
uncomment line 60 to see the magic
https://playground.babylonjs.com/#HTV1TD#2

Simple distance check if within explosion range, then cast a ray to the target and look for any explosion blocking meshes, note of course, that a single ray is not very accurate, even if the “explosion blocker” doesn’t cover the entire mesh, but just the small path of the ray, it will still return as blocked, for more accuracy, you can add multiple rays where target vector3 is calculated based on target mesh’s position, size, etc, e.g. position.y + half size.y = head location,

side-note, intersectsMesh() was not working properly because it was running before scene was rendered, same issue here: Odd Ray behavior

2 Likes

Wow! Great idea! Thank you!

So, only shockwave blocking is left.

I continue to work with explosion. Now I am in a process of creation of so called chain explosions.

I created an algorithm: https://www.babylonjs-playground.com/#3GBTN9#1 (press ‘spacebar’ to launch the chain).

I want to discuss this algorithm, but unfortunately I am faced with a bug that could be reproduced only in playground. There is no such bug on my local machine with the same algorithm.

I am receiving ‘Uncaught TypeError: Cannot read property ‘dispose’ of undefined at babylon.js:16’. It’s trying to dispose eventData.sphere that doesn’t exist anymore. I believe it might be connected with some sort of garbage collection issues.

Key points of the algorithm (very briefly, will explain more when bug will be fixed):
class DestructibleObject:
An instance of this class should be assigned as property ‘destructibleObject’ to an object that we want to mark as destructible. But it’s necessary to make it properly.
Wrong: myObject.destructibleObject = new DestructibleObject(...args)
Correct: use createFromObject method from DestructibleObjectsManager class.

class DestructibleObjectsManager:
Tracks all destructible objects in scene. Removes object when destroyed.

class ExplosionManager: executes and debugs explosions. The main thing here is createExplosion method that receives the collection of destructible objects on the scene as one of arguments. What’s going on inside:

  1. Physics is created (using this.physicsHelper.applyRadialExplosionImpulse(...)).
  2. Casting the ray to every destructible object that were received as argument.
  3. Getting picked objects with ray (this.scene.multiPickWithRay(ray)).
  4. An array of picked objects should be cleaned from ‘explosion transparent’ objects and sorted by distance (_cleanHitsArray method is for it).
  5. Getting the closest object hit by ray (_getClosestHit method is for it)
  6. Calculating damage to the object that we picked. We are using linear falloff to calculate splash damage.
  7. Here are 3 important checks for the picked object:
  • Is it destructible object?
  • Is picked object is an object the ray was cast to. Here we are checking that we hit the target object on the ray, not any other destructible object on the way.
  • Is it not in explosion stack already?
  1. If all checks are true, then we put picked object in explosion stack with corresponding damage that will be applied later.
  2. Process the explosion stack.

I don’t like how I organized and execute explosion stack. It has some issues. But I need to find a way how to avoid the bug in playground that I mentioned above before I continue. Please help with a bug.

I haven’t fully checked the code yet, but I think the issue is you disposing the impostor & shape/mesh before the actual explosion event? Inside the redBarrelDieHandler, if comment out the disposes there it works. Or maybe just move the disposing after the event?
The thing is, that the shape (explosion sphere) will be auto disposed with a delay (it’s inside a setTimeout()), in case you still want to use the sphere for your own stuff in the current tick, so you don’t need to manually dispose it.

I don’t think that this is the reason, because:
a) Explosion doesn’t need mesh or impostor, it requires only position vector. I intentionally delete mesh and impostor of the barrel before creation of explosion on it’s spot. It’s necessary to exclude that barrel from destructibleObjects in order to reduce the cycle and eliminate some glitches like self-intersection.
b) If I comment out the disposes nothing changes for me. I am still getting the same error in console.
c) My algorithm doesn’t cause same error on my local machine. I am receiving this error only in playground.

FYI @Deltakosh The playground https://playground.babylonjs.com/index.html#0LM7CJ#6 doesn’t work any more because the data.rays from showExplosionDebug don’t exist any more in the newer BabylonJS release. (I had the same error in my own code, and updated my code to not process rays field.) Loved the ray-functionality though for physics debugging…

Yeah, I know. I removed the rays there as I wasn’t really sure that it would be really used and had a performance cost with some events (such as the updraft & vortex). That’s the new PG with all the effects now: Babylon.js Playground

So this one doesn’t work for you?
https://www.babylonjs-playground.com/#3GBTN9#3

It does fix the error for me

Did you find it in the doc?

1 Like