How to create explosions

Now your link is working for me, maybe I just commented something wrong last time. Thank you! However I still don’t understand, how explosion debug sphere that uses only explosion data may be connected with disposing of the mesh that was used only to set position of explosion? And why this happens only in playground?

Please help me with graph theory while implementing explosion chain.

To understand my examples, please open console and take a look at these strings: ‘applyDamage {current_detonating_barrel} {damage_amount} EN:{previous_barrel_in_chain}’. In both cases detonation starts from _5 barrel. Press spacebar to launch chain reaction.

Explosion chains work good for binary trees: https://www.babylonjs-playground.com/#3GBTN9#5
It goes consistently through right branch and after that through left branch. All branches start from _5 root node and damage for closest neighbours (_6 and _4) is calculating from _5 barrel also.

For N-dimensional tree it works much worse: https://www.babylonjs-playground.com/#3GBTN9#6
It goes consistently for _t branch (the bottom one) and then barrels from _t branch trigger barrels from left and right branches. See the red arrows on the figure below.

But I want it to go consistently through all branches one-by-one like it shown by black arrows. I don’t want that ‘red arrows’ intersections. It causes wrong damage calculations.

Possible (but not really good solutions):

  1. Using current barrels positions, build actual N-dimensional tree instead of explosion stack. Then calculate detonation order using in-depth traversing of the tree and then detonate barrels according this order. But such a priori approach doesn’t assume that all current barrels positions might be completely messed up after first explosion. This will be especially notable if we will decide to detonate barrels after delay (fire it up first and then explode like it was in Half-Life). We need onflight recursive solution.
  2. Reduce radius and arrange barrels so the one barrel could trigger only the closest barrels. Ad Hoc solution that doesn’t fix algorhitm itself. Also other barrels can be moved closer after previous explosions.

Please help to understand how to fix this algorhitm.

1 Like

I would interpolate random linear vector for debris position. But beyond that…nvm 12345.

Hi there @splash27

The Double Buffer may be an option to fix your problem with interdependent iteration over collections (like exploding barrels). Scroll to the ‘slapstick comedy’ section, which is an example like exploding barrels igniting each other but then with players slapping each other.

http://gameprogrammingpatterns.com/double-buffer.html

You can read the coding technique online for free (and buy the book if you like it…)

1 Like

I
DID
THIS!

https://www.babylonjs-playground.com/#3GBTN9#7

I wasn’t able to use double buffer directly, but this inspired me for some ideas.

I converted my linear damage stack into this:

/**
 * this.damageStack[0] - readStack
 * this.damageStack[1] - currentStack
 * this.damageStack[2] - nextStack
 * */
 this.damageStack = [];

Read stack keeps only DestructibleObject instances, current and next stacks keep DestructibleObject and args array with damage and other data that might be transfered to applyDamage method (debug data in our case).

Important! We are not creating such structure initially. The current number of existing inner stacks is also important flag that allows us to determine on which stage we are.

The basic idea is:

  1. If there is no inner stacks we can write all affected barrels directly to read and current stacks to save one iteration (Line 322).
  2. If current stack is not empty then affected barrels will be placed into next stack (Line 330). But this will happend only if there is no such destructibe object in read stack. There is no need to add to next stack a barrel that will be exploded in current stack or already has been exploded earlier.
  3. If affected barrel is already in current stack we are updating future damage for this barrel in current stack (Line 317). This is it! This is how damage transition goes through chain. The barrel will receive damage from the nearest barrel in the chain, not from the barrel that firstly affected current barrel.
  4. After all reachable barrels were placed in the next stack, this._processDamageStack() call occurs. This method does shift() from current stack and applies saved damage this may cause new explosion.
  5. If damage wasn’t enough to make new explosion we have a special checking (Line 247) that will force going through current stack if nothing has been exploded.
  6. After all barrels from current stack will be handled, the this._squashDamageStack(); call occurs. This method remove duplicates from next stack saving the biggest damage and puts it as new read and current stack.
  7. If nothing has come to new read/current stack, then all chains are finished (Line 258).

If you will open console, you will see that all barrels will be exploded with the damage from the closest barrel ignoring the barrel that put current barrel to the stack.

Possible performance boosts:

  1. Args array. Since our algorithm ignores the order of adding to stack now we can remove the adding of sourceExplosion to args array (Line 311) which was used for debugging purposes. This allows us to remove one layer of array. This will be good for performance.
    Again, we are not tracking chains we are only delivering damage through it.
  2. ES-6 slow methods. I used reduce method and Map object in squashDamageStack() for readability, but these approaches are relatively slow. Direct array traversing might work faster, despite it will require writing more code.
  3. Turn off debugMode flag in ExplosionManager and DestructibleObject classes.

What’s left:

  1. Visualitation of explosion. Nothing is done here.
  2. Walls should block shockwave. Splash damage through walls already will be blocked in my algorithm. But there is nothing I can do with physical shockwave (that pushes object). I thing this could be fixed only inside Babylon.
  3. The checking on line 247 works for barrel chains but it is not universal. What if something will be destroyed without explosion on it’s death. Will do more investigations here. Stay tuned.

So what do you think about my solution?

EDIT:
I decided that in my gaming world the higher damage in chain will override the lower one. But you can accumulate it instead. This will require pretty obvious changes on lines 215 and 318.

2 Likes

Nice one! As for the physics shockwave - if you want, you can just easily take the relevant bits out of the physicsHelper, and integrate only the stuff you need for your ExplosionManager. For the most part, it’s just simple stuff in there. I will probably be far more efficient, as it now needs to calculate some stuff twice (intersections & raycasting for the same objects).

1 Like

I found a good point to start for explosion visualization.
It is in Babylon demos: https://www.babylonjs-playground.com/#VS5XS7#0

But I have several questions:
a) Why this doesn’t work with GPU? When I launch it like this: var fireBlast = BABYLON.ParticleHelper.CreateDefault(impact, 100, scene, true); I see only white squares. Is it possible to fix this example to work with GPU?

b) I need to use same particle configuration in several places simultaneously. Particularly I need to explode my barrel chain. Is it possibe to configure particle system once and then use it instances in different positions in order to reduce CPU/GPU payload?

c) How to dispose GPUParticleSystem on animation end if it doesn’t support disposeOnStop and doesn’t emit any events on playback end?

1 Like

Add cool translucent dynamic texture to blast radius spheres.
Then inside sphere, at origin, queue boom.
Try not to animate explosions that cannot be seen.

There are a ton of great docs …
https://doc.babylonjs.com/search/?bjsq=particles
https://doc.babylonjs.com/how_to/dynamictexture

: )

Thank you for information, but this doesn’t give answers to my questions. Especially, why given example doesn’t work on GPU?

1 Like