SolidParticleSystem and rotation

Hi folks,
I’m currently facing a problem regarding SPS and rotation. In my game I’m using as an explosion effect a SPS which has the mesh to eplode digested. The code is based on the PG provided by the SPS Docs “Digest a Mesh”. It works as expected as long as the digested mesh istn’t rotated. For better unterstanding see this PG Babylon.js Playground (copy of the one from the Docs). As you can see, the particles are pulled according to the gravity towards the ground (-y). If the digested mesh is now rotated: (see line 42), the particles are pulled against +x, which is not what I expect. I suspect it has something to do with wordlspace/localspace but I’m out of luck here because my math-skills are pretty low.
So what need to be changed that the particles are always pulled against -y of worldspace regardless of the digested mesh’s rotation? Any help appreciated :slight_smile:

Would rotating the model work for you? Note you need to bake the transformation into the model.

Thanks @JohnK, that’s basically how it should work!
However I’m having problems getting this integrated in the context of my game. I’ll first have to dig deeper and come probably back with some more questions :slight_smile:

The particle positions and rotations are simply always expressed within the SPS local space.

Is this also the case for the ‘normal’ particle system?

@JohnK: Now I had the time to play more with the PG and modified it so it corresponds more to the actual in-game usecase.
As already mentioned the SPS is used as an explosion effect. This means that the mesh to explode can have arbitrary rotation/position at the time of explosion. To overcome the problem with gravitation always pulling to -y mesh.bakeCurrentTransformIntoVertices() is used which works fine so far. The problem I’m facing now is performance. Because most recent rotation/position of the mesh to explode is needed at the time of explosion bakeCurrentTransformIntoVertices/sps.digest/sps.buildMesh must be called at this point too, which is quite CPU intense. This leads to hickups in rendering on low end machines. See the updated PG here which does the expensive calculations at the time the moving/rotating cone is clicked:
Ideally sps.digest/sps.buildMesh should be done upon mesh (cone) creation, when explosion is finally triggered the most recent rotation/position should be calculated directly in the updateParticle() function.
I hope this makes sense, any help appreciated.

I’m still searching a way of having the gravitation calculated towards world -y directly within sps.updateParticle(). As I mentioned earlier the costly digesting/building of the sps.mesh should be done in advance. See this playground which sets sps.mesh.position/sps.mesh.rotation (line 124-125) just before the actual explosion-animation is started. I think there must be a way to use this rotation for transforming the gravity vector which is added to p.velocity (line 97) to actually overcome the problem of local-space which has the rotation as it was at the very beginning whnen digesting the mesh.
It would be great if someone could have a look how such a transformation could actually been done. Maybe @jerome has an idea :slight_smile: Thanks in advance!

yes you’re right : transforming the gravity vector is the simplest way to do.
gravity is (0, -1, 0) in the SPS local space
the SPS is rotated for (a, b, c)

So compute the rotation matrix for this rotation, invert it and apply this inverted rotation matrix to the gravity vector in the local space, you’ll get the gravity from the world space in the local space.

Thanks a lot @jerome that sounds like a plan. So I’m going to activate my non existing math-skills and give it a try :smiley:

I don’t have an already set PG here, but try this :
given vector gravity(0, -1, 0) and the mesh rotation(x, y, z)

get the rotation matrix from these euler angles , there are methods like fromEulerToQuaternion and RotationMatrixFromQuaternion or something close to this
given this rotation matrix RotMatrix built from the mesh rotation, compute the inverted matrix : var inverted = rotMatrix.invert()

then apply this inverted matrix to the gravity vector : TransformNormals(gravity, inverted)
you’ll get then the world gravity vector (0, -1, 0) expressed in the SPS local space as a result

At the time of your writing I manged to come up (or better stolen from different other PGs :slight_smile:) with something that looks exactly as what you’ve suggested: (starting at line 129)
Thank you so much!

1 Like

If you want to optimize then, use now the same methods suffixed with xxxxxxToRef().
So you can use only one matrix, one inverted matrix, one quaternion in your code instead of creating new ones each call. Just create all these objects once outside the render loop and reuse them at will.

Thanks for the sugestions! Here you can see the sps-explosion in action:

1 Like

waoow superb :slightly_smiling_face:

Looks really good!

Thank you guys! Really appreciate your feedback :slight_smile: