Particle impostors colliding strangely with ground

Recommended Posts

Hi All,

Disclaimer: I'm very new to Babylon.

I was playing around with this cloth tutorial, and I wanted to make the cloth land on some sort of ground object.

So far, I haven't been able to find one that works.  You can see in this playground how the cloth reacts to a box impostor, side-by-side with a sphere behaving normally.

I have the restitution of everything set to 0.  The sphere stops nicely but the cloth shoots off into the distance.  I've also tried this with a ground impostor (sphere works fine, cloth doesn't interact with the ground), 

and a plane impostor (cloth collides correctly, but sphere shoots up into the stratosphere).

I have also tried adjusting the initial linear velocity of the cloth particles.  More velocity = flies away faster, less velocity = falls right through the ground.  My ultimate goal involves the cloth having an initial z velocity, so I'd like to be able to make that work.


Can someone help me figure out what I'm missing here?  Does it have something to do with the distance joints connecting the particles in the cloth? Should I try using sphere impostors instead of particles?




(side note: is there a better way to translate the cloth's position than the translatePositions function I made? The built-in ground.rotation.axis method rotates the cloth, but not the actual particles themselves)

Share this post

Link to post
Share on other sites

Hiya vrent, welcome to the forum.


Let's see... your translate func had a "fencepost error" (off-by-one).  Line 7 needed to be "length+1".  Minor issue.

Um... line 27... enabling physics.  You have not specified WHICH physics engine you want to use... CannonJS or OimoJS.  Sooo... it automatically chooses CannonJS.  This USED TO BE... OimoJS by default.

AND.... this playground was likely intended for OimoJS, but I'm not sure.  I'm speculating.

Anyway, I'm not sure which physics engine(s) allow a "particleImposter" and which don't.  ParticleImpostors are sort of rare.  SO, in line 89, I changed ParticleImpostor... to SphereImpostor.

When I did that, things started acting better.  At least the cloth-ground is colliding with the realGround, now.  Yay!

I also disabled line 52, temporarily (turned off cloth texture so I could see "the spheres" and imagine the many joints that bind them together).  :)

Oh heck, let's go a bit further.


In line 90, I changed BACK-TO ParticleImpostor, and in line 26, I "forced" the use of OimoJS physics engine.  And look, it works!  Yay.

So, what we have deduced... is that ParticleImpostors for CannonJS... are grumpy or somehow not working.  hmm.

Let's ping @RaananW... see if he wants to know about this.  He's done lots of work on our physics engine interfaces.  He is real-life busy, though... so perhaps you and I will go "diving" into the CannonJS plugin and see if we can figure out why it dislikes ParticleImpostors (over a few days).  Perhaps other forum users will help/go-along.  But, perhaps physics God RaananW... will know why CannonJS is being grumpy.

Meantime, you have some working demos... you know a bit more, and you can drop some cloth.  :) 

I once made a cloth demo, based upon Raanan's cloth:  https://www.babylonjs-playground.com/#1M67K8#18

Notice something else?  It's a CannonJS physics demo... with working ParticleImpostors!  hmm.  Wingnut's hypothesis about Cannon disliking ParticleImpostors... is ALL WRONG!  OH NO!  :/

Can we deduce anything new?  Just possibly... CannonJS dislikes your "translatePositions".  Mr. Cannon doesn't want his cloth tipped-sideways.  hmm.  But then again, I have a reputation for being wrong, often.  heh

I'll leave the mystery hanging...  right there.  We have an investigation/case, my dear Watson!  :)  Be well, talk soon.... hope I have been helpful.

PS:  Need a little more speed from your physics engine?  scene.getPhysicsEngine().getPhysicsPlugin().setTimeStep(.07);   (I think default speed is about .0166)


Share this post

Link to post
Share on other sites

Hi Wingnut,

First off, thanks so much for diving into the code and coming up with such an in-depth response!

The original tutorial (Raanan's actually) had a playground for both Cannon and Oimo.  I started using the Cannon one, for no particular reason.

If you don't mind, could you elaborate on why ParticleImpostors aren't used very often?

In that vein, I fixed the off-by-one error (whoops), and converted the cloth to use SphereImpostors with Cannon like you did and it behaves much better!


RE: rotating the "cloth ground" and my translatePositions function,

it's strange that rotating the cloth moved the ground itself but not its vertices. The vertices remain unchanged after a rotation:



console.log(ground.getVerticesData(BABYLON.VertexBuffer.PositionKind)); // same result

ground.rotate(BABYLON.Axis.X, Math.PI / 2);

console.log(ground.getVerticesData(BABYLON.VertexBuffer.PositionKind)); // same result



and I end up with a weird shadow cloth disembodied from the SphereImpostors.  Using your playgrounds as examples, it's more like this than that.  

translatePositions ended up doing the trick, but there is some strange behavior here that I don't quite get.


Last point: I think you were on the money with there being something funky about Cannon.js's ParticleImpostors, at least when they interact with certain other impostors (like the box).  

Here's a playground with the translatePositions method and a static sphere, that works fine.

Here are some other  playgrounds without using translatePositions, where the cloth behaves strangely when interacting with a BoxImpostor. (the second one is a pretty sweet magic carpet).

I'd love to help hunt down further issues as best I can, but I'm not sure how useful I'll be at breaking down the inner workings of Cannon.

Thanks again!

Share this post

Link to post
Share on other sites

Hey, nice work!  By doing those playground experiments, you have already helped the investigation MUCH.

I'm no expert, but... rotating the cloth-ground... rotates the mesh, but not the pattern/layout of the "array of physics-active spheres" (this you have said already, and it is the reason your coded the translatePositions func).  I think you need a mesh.bakeCurrentTransformIntoVertices()... after a standard .rotation, but before the spheres-array building.  Then you will no longer need translatePositions() function.  (my theory)  More below.

Your "this" playground shows it perfectly.  The cloth's mesh has been inverted, but not the array-of-spheres.  Lines 54-78 builds the array-of-spheres, of course.

I don't understand "transforms" real well, so, you'll have to play with that area to learn more.  If Raanan visits (author of the cloth demo)... perhaps he will explain more.

Raanan also has this demo pretty well documented... here:  https://blog.raananweber.com/2016/04/03/cloth-physics-simulation-for-babylon-js/


There is command...  mesh.bakeCurrentTransformIntoVertices() that might be handy for you.  I don't know if ANY BJS .rotation or .rotate... actually re-positions any vertices (inn localSpace).  I think they both "apply a transformation"... but to actually "permanentize" (naturalize?) that transformation... we use the bake command as shown above. 

So, your sequence of events might be... rotate the cloth-ground, bake its transforms into the vertices, and THEN do the sphere-array building.  The array-builder will now have a MUCH different mesh to use... as it's array-building template.  You can likely say goodbye to your translatePositions function.

Also, if you are headed-for "magic carpet", then there will need to be OTHER changes in the array-builder.  Primarily... this line... var mass = idx < width ? 0 : 1;  That line... causes the top row of mass-less particleImpostors.  These are the anchor impostors that the cloth hangs-from (I sometimes call them "steads" - short for "steady" and derived from "homestead"). 

When you rotate into flying carpet... you will need to "hold-up" the carpet using some other methods.  You will AT LEAST need a mass-free particleImpostor on each of 4 corners... to keep the carpet from falling from the sky.  OR, you need to turn-off scene gravity or physics engine gravity.

There is another way - near-constantly doing tiny .applyImpulse in upward directions... on all the particleImpostors.  Some fancy things can be done... to "overload" the particleImpostors... making them "smart".  Each impostor might have a .checkMyAltitude() function.  This function would be called on each particleImpostor... constantly, via a for/next loop inside the renderLoop (registerBeforeRender).  In that function... pseudo-code:

if (carpet.wantedAltitude.y - this.position.y > 1.0) { this.applyImpulse(new BABYLON.Vector3(0, .35, 0), this.position }  // thrust this impostor upward a bit.

No promises.  Just an idea, and not a very good one.  Also, this might cause a strange low-altitude wave pattern... to constantly pass-across the carpet.  It might look cool.  Not sure.  Nobody has tried this kind of thing before, as far as I know.  You're the first.  Just some thoughts.


Lastly, do you know about Quaternions, or more specifically, mesh.rotationQuaternion?   I don't either... but I'll tell you what little I know.  Normally, a BJS mesh has no .rotationQuaternion property, and instead uses the Euler-based .rotation property to store it's rotation (transformation).  You can see the affects of a bake... this way.  Try rotating the ground-cloth or ANY mesh (before adding any physics) with a mesh.rotation = whatever.  Dump your .rotation property to JS console, so you can see it.  Now do the mesh.bakeCurrentTransformIntoVertices()... and view the .rotation property again.  It will show 0,0,0.  That's why I call bake...a "permanentizer".  :)  It makes the rotation you added... permanent.  It does this by "moving" (transforming?) all the positionKind data of the mesh (same as your translatePositions func). 

Mesh SHOULD need to be set "updatable" = true... in order to do this.  BUT... I think bakes ignore the updatable flag on mesh.  Fun stuff to try.

As far as I know... ALL mesh need to use .rotationQuaternion for their rotation storage... when they are physics-active.  Physics engines LOVE Quaternions, and in most cases... the Euler .rotation property will be completely ignored by physics engines.  So, to "see" the rotation of a physics-active mesh, you might do console.log(mesh.rotationQuaternion) or console.log(mesh.rotationQuaternion.toEulerAngles()).

SO much crap to deal-with, eh?  Physics engines are somewhat complicated.  An adventuresome spirit and a big jug of enthusiasm juice... is often necessary.  :)


Just a big pile of bad news from Wingnut, eh?  Sorry.  There are some "Gods" around here that know transformations like they are best friends... but not Mister Wingnut.  You have taken-on a pretty serious project here... but it IS do-able... and the result will be very cool, I think.  Physics engines are pretty strict.  Often, the impostor wants to have full control of the mesh, and YOU, as a programmer... sort of need to "ask" the physics engine to perform movements that you want (floating in one place, even while gravity is ON and masses are set).  The engine doesn't really care what you want, and if it thinks it is time for the carpet to drift-away... it will drift it away.  You will need to use .rotate()'s sister function... .translate(), OR use applyImpulse() [puffs of thrust/wind]... to keep the carpet from drifting away.  :)

It's not really that bad... but p-engines tend to surprise us.  They seem to act very strange at times, but, both our engines are pretty well tested.


Oh yeah, I forgot to answer WHY particleImpostors are rare.  It's simply because not many people have experimented/tested with them.  Most people want to tumble a box. or roll a sphere, or drive a vehicle across a heightMap impostor... which might also use particleImpostors... I haven't investigated the code in our physicsPlugins to see how heightmapImpostors do their stuff.

You... are being very brave and adventuresome.  Cool.  We just need to make sure that you don't get a brain tumor, or go insane.  If your project has a "deadline", then... you might want to make sure that is plenty flexible. :D  We have a shortage of physics experts around here, because there aren't any wonderful docs for these 3rd-party-authored engines.  AND... because learning the physics engines well... is a large time-consuming task.  SO... learning physics engines often comes down-to... experimenting - see what happens... see what works.

Also, some of us are thinking... that the next generation of computers will have hardware/firmware physics engines that might be accessible from JS/webGL.  RaananW and others did a GREAT JOB at TRYING to make our physics interfaces to the 3rd party physics engines... as easy as possible.  But, it's still not wonderful... not without having a basic understanding of how ALL physics engines work.  This forum is actually STARVING for more physics experts... because lots of people LOVE physics sims.  They are very difficult to "teach".

I dunno if you have been following my insane joint experiments in The Wingnut Chronicles thread... but it doesn't take long to notice that I have talked 100,000 words in 20 posts... ONLY about an OimoJS hinge joint... and I'm still only half-way to being an expert.  JUST learning a basic hinge joint (although I took some breaks to experiment with Babylon GUI system).  There are about 8 different kinds of joints... and they each have math formulas that can scare a professor.  :)  I estimate that... to learn ONE physics engine REAL NICELY... it would take about 3 years of dedicated study/experimenting.  erf!  But I foresee it as a "hot commodity" for the future.  I foresee ALL 3D game/sim companies... having "a physics person" on-staff, all the time.  Hot hot hot.  High demand... even if the engines move to hardware-level in next-gen computers.  Folks will STILL need to know how to drive those physics engines, no matter where they reside.

Sorry... Wingnut rattling-on, aimlessly... and surely from an odd and possibly discouraging perspective.  I don't have great learning abilities, myself.  I'm quite weak in math, and projective geometry, and matrix transformations.  I need to SEE IT HAPPEN, and cannot see it happen by studying a math formula.  Others CAN do that, though.  They can code math... while a 3D scene is happening in their head.  I envy those people. 

We have a few of those around here, but they are SO SO busy in real life... because of those same "think math in 3d" -skills. 

I'll be here to help/talk/mess-with your playgrounds.  My suggestion: turn OFF the gravity... and play with the code that builds the array of spheres.  Use a simple groundcloth.rotation.x = -Math.PI/2, then do the bake  (without using your translate func).  Then see what "orientation" the array-builder... creates.  By turning off gravity, there will be no "falling" of any kind, so you can easily see the natural orientation of the spheres-array/sheet.  You can see if your bake... worked.  :)  Party on, talk again soon.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.