Steffen

createCompoundImpostor as a cannon slide-constraint?

Recommended Posts

Hello guys,

at first: Wow, what a helpful community, I have learned a lot by reading here and using your samples on the playground - thanks!

Now, here is my problem:

I want to show the oscillations of a stacker crane with the cannon-plugin, because I need the spring-constraints to simulate the stiffness of the crane. Because there is no slider-constraint, I am using a workaround with the createCompoundImpostor to "bind" the load handling device to the crane. But I don't really know how to use this function correctly. I've only found one example, which works, yes, but the declaration of the function is another... (vsCode with typescript tells me: Supplied Parameters do not match ...). In addition, the createCompoundImpostor is deprecated, but what is the alternative? I can't get the impostor.parent to work.

 

I made a simple playground example for you: http://www.babylonjs-playground.com/#1Z17G7#12

You can click on the green box to move the crane and click on the crane to move down the load handling device. Because there is no slider-constraint, I have to move the geometric objects down and then add all the joints again, because I'm calling impostor.forceupdate(). If it's important: I'm using imported 3D-Models from Blender in my current version, but for physics I'm using the boximpostors with visibility = 0.

Actually my question is: How to use the createCompoundImpostor correctly or better what is the alternative?

Thank you!

Share this post


Link to post
Share on other sites

Hi @Steffen, welcome to the forum!  Nice, tasty playground and project, too!  I don't have much to add, other than reminding of Cannon's meshImposter.  If your crane has articulating joints, then using meshImposter on it... will not work.

CompoundImposter is (was) a bit of a kludge, I think.  I think it simply summed the bounding boxes of all involved mesh, and then force-sized a box or sphere impostor to approximate the summed area.  In other words, you won't be rolling a BB around in the cracks of a complex compound.  It's impostor was not precise enough for that, as far as I know.

Thus, meshImposter.  There's been some talk and use of Cannon's MeshImpostor.  Do some forum and playground searches, if you please.  Less than 3 months ago, @RaananW did a grueling refactor of the BJS physics objects.  I haven't had the pleasure of playing with them, yet.  Others have, though.  Sorry I couldn't be of more service.  Maybe others will comment.

Somebody once suggested to me... that you attach multiple primitives together... with joints/links (no parenting).  The joints need to be pulled tight... ZERO flex/spring at the attachment point.  This would be akin to a weld on a crane.  A joint SO TIGHT that it has little/no flex.  Not sure if my thinking is correct on that, but maybe.  I wouldn't count-on parenting having much affect for physics.  No mention of such things... in the physics docs.

In the few tests I've done (mostly with Oimo)... I was never able to get joints/hinges to be that tight.  Constraints seemed to be weak, and allowed unwanted flex and wobble. YMMV.  Good luck, keep us posted if you can.  Lots of us want to learn the physics engines, and your playground(s) helps a lot!  thx!

Share this post


Link to post
Share on other sites

Hi @Wingnut (don't know how to tag...), I should have bet that you are the first answering my post :D Thank you!

Maybe, the title should actually be "createCompoundImpostor as a slide-constraint for cannon?". No idea why I did'nt found the correct syntax for the createCompoundImpostor the last days. Here it is:

(http://www.babylonjs-playground.com/#1Z17G7#13)

var compound = scene.createCompoundImpostor([
      { mesh: root, impostor: BABYLON.PhysicsEngine.BoxImpostor }, 
      { mesh: part1, impostor: BABYLON.PhysicsEngine.BoxImpostor },
      { mesh: part2, impostor: BABYLON.PhysicsEngine.BoxImpostor },
      { mesh: part3, impostor: BABYLON.PhysicsEngine.BoxImpostor }
    ], { mass: 50, friction: 0.99, restitution: 0 }
);

In my example, the root is the crane and the other parts build the load handling device ("Loadholder"). I think I could merge the parts to one Mesh and then use the MeshImpostor on it. But I still need the compoundImpostor to link it with the crane, because high and mass of the load affects the osszillation.

I also tried to use a DistanceJoint with distance=0 or HingeJoints with an extra backup-construction for the sliding. But you are right when you say constraints seemed to be weak. You can test it by setting the iStackLoad_mass higher: http://www.babylonjs-playground.com/#1Z17G7#14
The crane is linked by a Hingejoint (1dof - rotation around z-axis) to the chassi, but as you can see there is unwanted flex (rotation around x-axis).

I think the compoundImpostor just binds the other impostors to the root impostors. So there is no extra force-sized impostor to approximate the summed area. I've built an example: http://www.babylonjs-playground.com/#1PEY4O
You can click in the scene to apply an impulse to the sphere. The box consists of different parts, "linked" by a compoundImpostor. So I think it's possible to roll a BB around in the cracks of a more complex compound (but have not tried it yet).

 

One further question: In my example, if I only have a base platform as a load handling device (without the left, right and front backups) and my friction is set to 0.99 - why does the load (brown box) slooowly moves and finally fall of the base platform? See it: http://www.babylonjs-playground.com/#1Z17G7#15

Share this post


Link to post
Share on other sites

Nod.  Good points, thanks for the info, and sorry if I misled.  (I do that fairly often).  You are absolutely correct about the compound.  In my feeble test, the load is seen moving within the volume of the 4 part stackLoadHolder compound.  Yep, I stand corrected, thanks for fixing my brain, Steffen!

http://www.babylonjs-playground.com/#1Z17G7#18

There, I did some gravity reduction and lots of de-parenting, disabled crane-to-load joint, created crane-to-holder joint which is saggy.  :) Still thinking.  I don't think I have the experience to be of much help.  But, I dislike parenting, when it comes to physics. 

Notice I made the load bunk (floor of loadholder carriage)... thicker.  I was trying to use the collision: true; in line 147... to keep the holder carriage from sagging.  But, it needs more surface area at crane-holder colliding surface. 

Possibly, a small "support box" under the carriage floor, against the crane mast... would remove carriage sag.  (One more member for the compound).

This under-carriage block could also keep the holder carriage from lowering all the way to floor-level.   Maybe no good.

*scratch scratch*

A slide-constraint... is a "stopper" at the end(s) of a translation movement, right?  (I should go read about it.  What a lazy crap I am).  :) 

Wanna see a nice "slide"?  Remark-out line 178.  (okay, that's not a slide, that's a plain ol' FALL)  :)

An invisible box with a zero-restitution boxImposter... would act like a slide-stopper, yes?  hmm.  I should just shut up and let actual experts comment, eh?  *nod*

Share this post


Link to post
Share on other sites

Hi!

Reading between the lines, it seems like the compound impostor is malfunctioning for some reason?

It should, and is usually the best way of creating a complex mesh that is physics controlled. If you can provide with a link just for a simple compound that is not working properly, it would be great.

About the last question (the brown box "sliding") I will have to understand the scene a bit better, will take some time (I am not sure, for example, what the spring joints' part in the entire thing is). Even without setting the friction to a high value the brown box should stay intact, unless something is pressuring it and ejecting it out. Again, this scene is relatively complex, will take some time to debug. If you want to simplify things a bit it would help a lot :) 

 

Share this post


Link to post
Share on other sites

To be clear, I am talking about two "sliding-versions":

1. The desired sliding of the whole load handling device (at the moment only vertical, but the next step would be to implement a horizontal slide too)
2. The unwanted sliding of the load itself (brown box) up to falling of the handling device

I attached two pictures which hopefully will help you unterstanding the idea of the scene: You can get the idea why I want to slide and you see the (invisible) impostors.

@Wingnut (how can I tag members? I feel so dummy :D) What do you mean with "stopper" in the context of slide-constrain? I need to translate the physical impostors as well as the geometric bodies horizontal and vertical. The high of the load should affect the oscillation of the crane.I had the same idea with the "support boxes", but the compoundImpostor together with manual translation, forceupdate() and adding all the joints again gave a better result.

@RaananW The spring joints should simulate the oscillation/vibration of the crane when accelerating/stopping. So by changing the spring params I can change the oscillation behavior. The HingeJoint should allow an oscillation (a simple rotation) only around one defined axis.

Here is a playground with a simple compound not working properly (unwanted slide of the box): http://www.babylonjs-playground.com/#1Z17G7#22 

Run it, wait some seconds and you will see that not only the box is moving, even the compound is moving too. Play with the variables in the first code-lines.

 

And of course, thank you for this community ;)

StackerCrane_Impostors.PNG

StackerCrane.PNG

Share this post


Link to post
Share on other sites

Hi again,

Name tags:  Type @  followed immediately by nearly any other key, and a selector panel SHOULD open... which lets you select which forum member name.  Sometimes, name tags just refuse to work, and you can type @whatever all day long, and that selector panel will not open.  Go fig.  It has some issues.  :)

[snip - text removed for lack of interest, and for physics sleep issue being discussed in a parallel topic]

http://www.babylonjs-playground.com/#1Z17G7#25

Still testing - no auto-sleep.  Increased load (line 4).  Removed var compound = (in line 89) - no returns from that call.  Un-parented things again  :D

Jittering is far worse now.  Increased mass is causing impostor overlap (sinking into floor, etc).  hmm. 

Watch console until load falls-off holder.  Render-loop monitoring for load and holder to sleep.  Neither ever do.  hmm.

Share this post


Link to post
Share on other sites

@Wingnut (wow it works, did the same the posts before buuuut ok... :D)

I just wanted to relax on my weekend and answer your text on Monday and BAM, you just snipped your post - I'm too slow :D

I tried the example above without the compound, with an additional "ground" (big box with mass = 0) and with calling the sleep-method. But it did not make any difference. The load-holder sinks into the ground.

It seems to be ok if the load-holder mass is a "bit" higher than the load mass itself, but it only seems to be. Even if you increase the holder mass to 10.000 or more, it begins to sink again.

Maybe it would be better to devide all my units by a factor of 10 or 100 or so to make them smaller. Maybe the physics engine can't handle such big values. But I think then it would change the oscillation behavior too much.

Share this post


Link to post
Share on other sites

Hi Steffen,

did some checking about the sliding effect.

This seems to be the way cannon calculates the forces on those boxes. I have simplified the scene a bit more - http://www.babylonjs-playground.com/#1Z17G7#26 just to see if the compound is to blame.

The best way to avoid this would be to force the body (the tray's body will be the best candidate) to sleep while it is waiting on the load holder, and wake it up when needed (when something is moving, when a different impostor collided against it). Another way would be to lower the mass of the load and increase the friction of the tray, but I am not sure this is the correct solution in your case (or in any other case for that matter).

Hope this helps! I will keep on debugging and seeing if I can help further.

Share this post


Link to post
Share on other sites

@Steffen - Hi again!  I have the original post... telling of Brownian jitter and my theories about spongy-ness/density vs. restitution.  I thought I might have gotten too long, too teachy, and too much comedy trying.  (I annoyed MYSELF with my own post).  :D  Sometimes I write tutorials on the forum, and then back-walk and realize I over-explained or tried to make it too la-tee-da  (trying to make a post useful for ALL skill levels).  After reading my post, it made me say "geez, Wingy" to myself.  hehe.  But, as long as you're not annoyed with it, I'm cool to include it here.   Sorry I snipped it away too quick.  I thought maybe I was being annoying.  I'm glad I wasn't.  So, here we go.

------------------

Hi again, S.  I enjoy your personality.  :)

Um, name tags?  Just type @  followed immediately by nearly any other key, and a selector panel SHOULD open... which lets you select which forum member name.  For example, I type @s and the panel opens, showing me 10 names.  But your name isn't in the list yet. So I type further... now @st.  Panel opens, but still no steffen.  Only the top 10 "st" names.  I type further... @ste.  Still not enough, you are not in the top 10 list.  Type more... @stef - list opens... ahh... there is Steffen, coming in at #9 on the charts this week.  ;)

But sometimes, name tags just refuse to work, and you can type @whatever all day long, and that selector panel will not open.  Go fig.  It has some issues.  :)

Ok, now to the physics.  http://www.babylonjs-playground.com/#1Z17G7#23

Solid as a rock.  (Holder is solid.  I didn't sleep() the brown load itself... yet.)

The physics impostor's physicsBody... isn't doing auto-sleep for some reason.  Not sure why.  Line 100, I'm sending the physicsBody to console.  WHEN I DO THAT, I get to click on it in the console, which opens my Firefox object inspector... and then I can see all the "sleep"-related things on that object (and even SET those values - LIVE).  So, that is a nice way to watch both your impostor, and your impostor's impostor.  (huh?)  Note that the .sleep() method is on the impostor, not on the impostor's physicsBody.  Corn-fusing, eh?  *nod*

All in all, you might be able to see some residual inertia via looking at values in the object inspector, and you could manually null them out... for testing.  

Possibly... the loadHolder is too positionally low.  Perhaps the ground's physics impostor body (pib?) is overlapping the loadHolder's "pib".  This might be caused by a fencepost error (off-by-one error) in the relationship of the actual mesh position... to the impostor and its pib position.

In other words, BJS thinks everything is cool... no overlapping ground-to-holder.  Physics engine... which is NOW doing automatic updatePhysicsBodyPosition (after recent refactoring)... is in disagreement about the "everything is cool".  :) It DOES see an overlap, and thus, it refuses to auto-sleep the mesh/pib... due to micro-jiggle.  How's that for tech-talk?  Impressive, eh?  Brownian jiggle.  Good with maple syrup atop.  :)

To make a long story even longer, I have put some pertinent property settings and console log reports in the above playground... and you'll notice that the forced .sleep() call has solved the issue.  But, me thinks we have a fence-post bug in our plugins or in the physics engine.  I think we have overlap.  We definitely have a failed auto-sleep in THIS scene, for SOME reason.

Ok, now on to the slide-stopper.  Imagine an invisible army tank blocking the railroad tracks.  The Train will definitely be constrained from further sliding if it hits that 90000 mass invisible army tank, right?  And with no restitution on either body, there will be no bounce.  Mister train will encounter something known as "a dead stop".  :)

Is that the kind of slide-constraint you need... like an invisible tank at the top of the crane mast... to keep applyImpulse LIFT-force from shooting the holder into outer space?

Yep, should work.  Big invisible physics active box at the top of the crane mast.  All things stop there.  Floor sliding... same thing.  Invisible box, mass 99999, brings all other physics-active things to a stop.  "Thoust shalst not slideth beyond me."  *shrug*  In a way, the invisible stopper boxes... are your indexers, right?  Their vertical and lateral positions... will set your lateral chassis-slide stop points, and your vertical carriage-lift stop points, too.

If you need to index the 3rd shelf from the ground on the 12th column of shelves... place your vertical stopper-mesh at 3, and horizontal at 12.  Fire all impulses!  Pieces flying everywhere, ambulances called!   Err... no... it's all pretty and nice.  Invisible physics-active stoppers (sometimes called "steads") (ie. Home-stead, spring-stead, solid points at the ends of things)... could also be a good place to mount a "ray"... which is quite good at measuring distances to things.  When the ray on the "stead" shoots repeatedly at the load moving towards it, it will KNOW when the distance-to-load == 0.  At that point, it COULD give the command to latch the chassis/holder, and stop all further impulsings.  It's just like a Hall Effect device only completely different.  :) I think it can be done with magnets, too.  A guy needs to fig a way to know when the load has arrived... so it can shut off impulse/force.  Otherwise... we might see more jiggle ahead... impulsing vs. stoppers  :)

I'm a bit child-like, eh?  *nod*  I love hanging-out there, mentally.  Got my "play" on.  :)

------ end of original post ------

@raanan (see, no panel opened there, name tagging failed)... are you sure this is normal?  Does auto-sleep EVER work?  I see there is another thread active that is talking about physics insomnia, too.  Related?

http://www.babylonjs-playground.com/#JXJ2I#17  There is an old Oimo-based sleep-check demo.  It also fails.  Look at versions #10-16... user was testing cubeBody.body.sleeping.  CubeBody.body seems to no longer exist.  Are ANY of the oimo-based demos that used mesh.body.body ... still working?  Maybe not, huh?

Generally, I'm touring playgrounds that have the word "sleep" in them, seeing what I can learn.  Thanks for your attention, @Raanan (name tag fail again).  Raanan, let me know if I can help with some troubleshooting or tests  (it will be a nice break from learning shaders, for me).  And if you get a chance, could you add a section about parenting... to your physics docs?  I did a quick scan of the Cannon plugin yesterday, and I saw some parent checking... on impostors themselves.  Heck, I didn't even know impostors COULD have parents/children.  Any info about that, or pointers to info, would be appreciated.  :)

All in all, I think there's an issue with auto-sleep.  Sleeping is the way physics engines deal with Brownian noise jitter (I suspect)... and if ours doesn't work... then I think we got trouble... right here in River City:)

Share this post


Link to post
Share on other sites

Thanks for checking @RaananW! I played a bit with the sleep methods and I think it won't work in my case. I have to set both the load itself and the tray to sleep-mode for working. And because I can only access the root of the compound, which is the crane, i have to set the crane to sleep mode. So if I want to move the crane and call the wakeup-method, there is the slide effect again. I think my best option here is to force the box (load) to stay there with invisible box impostors.

@Wingnut: Ah, now I got your idea with the slide-stopper. Very figuratively btw ;) . I keep the "base chassi" in the line in a similar way. With enough "stoppers", it would be possible. Thx for the idea.

But there is the problem: I have to fire an impulse on the ray (=load holder), which I cannot do because it is a part of the compound in which I have only access to the root (=crane).

It would be so nice if I could simply attach the ray impostor as a child to the crane impostor, so it would always have the same (relative) position and rotation to the crane and I could easily move the ray with the load.....Yeah that would be nice ^^

My current solution for "linear sliding" of the load is to dispose all impostors, translate load holder & load and adding the impostors again when the new position is arrived. But this isn't working if I want to move chassi and load at the same time WITH the changing oscillation behavior caused by the changing high of the load and the acceleration of the chassi (e.g. chassi is moving to the 12th column, load holder is moving to the 3rd row).

Share this post


Link to post
Share on other sites

@RaananW, @Wingnut

It is not possible to move a part including its impostor inside an compound impostor, is it? After some testing and code reading on github, it seems that childs don't get a physics body.

Does the MeshImpostor automatically recognize changes of the Mesh? Just got the idea that I can export the whole crane as a mesh (including the load holder) and attach the MeshImpostor. Then I can access the load holder as a submesh and move it. 

Share this post


Link to post
Share on other sites

nope, and nope :)

Physics engines are based on rigid bodies, unchanged. If you want to change the mesh's characteristics you will have to create a new impostor.

you can connect many bodies using joints. this is the safest way to be able to move impostors while connected to others. But then they are limited by the joint, so choose the correct joint. I still need to finish the joints documentation (sorry about that). if you have any question here, let me know.

Share this post


Link to post
Share on other sites

Hi Guys.  Sorry for the butt-in again... but @Steffen... I said something ridiculous to you and I wanted to correct.  You will not be able to put a mass 9999 stopper at the top of the crane mast  (as a slide constraint)... cuzzzz... that puppy will instantly fall to the ground and kill everyone.  :) The only way to keep it there... is continuous force from beneath.  So, it was stupid of me to say.  :)

What about a distance joint... between the load holder... and the chassis.  By adjusting the distance of that joint... (amount of slide up/down Y)... that should work for setting your holder to different shelf-heights, I think.  Maybe.  Just a thought.  No impostor-changing, and no need to applyForce/Impulse to bottom of holder.  BUT... as you change that joint distance... the holder might move up/down rather bouncy or strange looking.  Not sure.  Might have to gradually change joint distance.  On the fly joint-distance updating.  hmm.   Just a thought.  :)

Share this post


Link to post
Share on other sites

@Wingnut Yes, I know, but the idea is still nice ;-) I tried with a stopper of mass 0, but the main problem is that the holder have to be linked to the crane. That's the problem with the DistanceJoint (chassi<->holder), too. I tried to link it with both, the crane and the chassi, but this didn't work either. Maybe it would work, but I don't know how.

@RaananW I was afraid of that.... Yes the correct joint...Unfortunately, there is no prismatic constraint implemented in cannon. But I found the LockConstraint method (http://schteppe.github.io/cannon.js/docs/classes/LockConstraint.html), which will remove all degrees of freedom between the given bodies. If I could use this method, then, maybe, I could use the PointToPoint- or DistanceJoint for linking the holder to the crane. Whereas I think that the DistanceJoint would not work, because there are no params for setting the pivot points, are there? Is it possible to use native "Cannon-Methods" within babylon such as the LockConstraint method?

 

Share this post


Link to post
Share on other sites

Hi @Steffen,

Constraints (Joints) are cannon's downside in my opinion. Cannon lacks a lot of joint types that oimo, for example, has.

The Lock Constraint is the one constraint i haven't integrated in the framework, but it should take long for me to add it for you. We are almost ready to deliver 2.4, I will see if I can squeeze in a quick update. If not, I will show you a way to hack a lock constraint.

Maybe give oimo a try? might fit your needs (if you don't need complex mesh types and able to live with boxes, spheres and cylinders only).

 

Share this post


Link to post
Share on other sites

Hi @RaananW,

That would be very nice if you can integrate it or show me a way. Thank you! I thought of oimo, but cannon is the only one having a spring "constraint" - in fact it isn't a real constraint. And I need the springs to simulate the inherent oscillation of the crane. The oimo distance joint (which has some stiff parameters) did not work as aspected. So currently, I'm "constrained" to cannon (what a cheap joke ^^).

Share this post


Link to post
Share on other sites

:)

Yep, Oimo's distance joint can't really replace the spring (none) constraint cannon has (and you are right, I am calling it a constraint, or a joint, but in cannon it isn't really one). 

Let me check if I can still integrate the change, will keep you updated.

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.