I am studying how to implement explosion that typically consists of 3 parts:
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.
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?
Shockwave. Explosion force should push objects from explosion center. And again, force should not work through solid indestructible walls. The hardest part I think.
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.
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.
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.
Thank you for the link to documentation. Actually I am looking for something like grenade explosion, not nuclear bomb. I will try to remake existing example, but if you already have one or know where to get it, please share.
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.
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",?
Sadly no. I guess you could maybe find a shader from the Shadertoy website and use that in this case
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
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
If you try this? npm install git://github.com/BabylonJS/Babylon.js.git#master --save
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.
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
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:
Physics is created (using this.physicsHelper.applyRadialExplosionImpulse(...)).
Casting the ray to every destructible object that were received as argument.
Getting picked objects with ray (this.scene.multiPickWithRay(ray)).
An array of picked objects should be cleaned from âexplosion transparentâ objects and sorted by distance (_cleanHitsArray method is for it).
Getting the closest object hit by ray (_getClosestHit method is for it)
Calculating damage to the object that we picked. We are using linear falloff to calculate splash damage.
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?
If all checks are true, then we put picked object in explosion stack with corresponding damage that will be applied later.
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