Jump to content

Using physics but keep z position constant

Tom Krueger

Recommended Posts

I have an asteroid field dropping from top to bottom of screen.  I decided to use oimo physics engine so that as asteroids collide they bounce and rotate.  However, I want them to say on the same z position.  Currently I have a star field image as the background and if the z position gets greater than zero the asteroids go behind the starfield image.


I have tried to use updatePhysicsBodyPosition() so that I could set the z position on each frame but this method seems to update x and y as well which is not what I want.  



How do I keep the z position constant when using oimo physics after two items collide?


(I could be going about this completely wrong.  Any thoughts on better design is appreciated as well.)




Link to comment
Share on other sites

Hi Tom!

And welcome to the forum!

So, that's quite a task!

Let's start from a playground and see how we continue! What I have is this - http://www.babylonjs-playground.com/#RKI78 - use a wonderful javascript hack to store the original Z and update it and the body position only when the z is not the same. this keeps the ball very much "sorted", is this what you wanted to achieve? 

Link to comment
Share on other sites

Hi Tom and Raanan!  Hey R, your z-freeze has frozen the x and y, too, right?  The spheres should keep falling, and keep spreading-out along +/- X, I would guess.


I think line 59 needs to be something like b.updatePhysicsBodyPosition(z); and thus not affect X and Y.  I doubt there is a command like that.


Line 34 is a cool line, too.  That looks like a "Darn, I need to answer the door" code-line.  :D


Tom, you could always put your balls in a glass box.  :o   http://www.babylonjs-playground.com/#1MJ09V#2  (I kept a slight amount of visibility on front and back "glass").  The side borders are fully visible, as you can tell.   Ant farm!   heh.  (Place the camera straight-on and somewhat close-to the front panel... for the Asteroids effect.)


Notice that the borders are made from scaled boxes and NO ROTATION is used to get them into proper orientation.  This is because when you setPhysicsState on rotated mesh, it removes the Euler rotation.  (it de-rotates it).  There are ways around it, but it's just as easy to start with 1-unit boxes and scale them in any directions you chose.  Then your borders are always physics-ready.


There is NO friction on the glass front/back panels, and there is very little "free space" for the spheres to move on the z axis.  Anyway, it's something else to play-with.


I'm not sure why there is a specular glow on the glass panels.  gmat has its specularColor = black.  *scratch scratch*  I seem to have forgotten how to create BJS scenes.

Link to comment
Share on other sites

Thank you Raanan and Wignut for your responses.




That was about what I thought would work.  When I had done it in my app using updatePhysicsBodyPosition the objects didn't drop.  However, in your sample they are dropping. However, in your sample they drop and get stuck in a stack.  I still want them to collide and bounce left and right (- x , + x).  I played around a bit with your sample but couldn't get them to do that.




You understand the problem.  Thanks for rewriting the question a bit.  I played with your example and it seems that it will work to put a boundary box around my asteroid field.  My asteroids will be different sizes so the boundary box will need to be deeper than the smallest asteroid to fit the biggest one.  My only concern is that it will be noticeable the asteroids are bouncing forward and backward.  I'll have to try it out to find out.


If either or you or anyone else have any other ideas, I certainly would appreciate them


I'll report back if the boundary box works.




Link to comment
Share on other sites

Hi again, Tom!  I think you will not like the result of widening the gap between the front/back glass panels.  The smaller spheres will sometimes enter a condition where they bounce back and forth along z... between the two glass planes.  It looks ridiculous.  :/


There's another way.  Both of our physics engine plugins... Cannon and Oimo... have the applyImpulse() commands.  I believe... that you can stop the energy of a moving physics object... by simply setPhysicsState AGAIN.  So, what you are looking-at... is creating some off-screen asteroid (sphere) launchers... that launch spheres into the active screen area... but with absolutely NO Z thrust.  The spheres always start at z=0 and you never thrust (applyImpulse) any z-force.  Only apply x and y force... to send it from off-screen to in-view.  Since you are using sphere imposters, there should be no Z-force implied on any collision... in theory.  The collisions are happening z-symmetrically... both/all objects at z = 0.  There should be no z-deflection upon collision.


The difficult part might be knowing WHEN one of the asteroids has drifted off-screen.  That is when you need to stop its energy, then somehow move the asteroid to one of your off-screen launch points, and then re-launch it with an applyImpulse thrusting.  (It might be best to .dispose the mesh and then simply launch a new asteroid from one of your off-screen launch points.)


There would be no borders, this way.  You would need SOME in-render-loop monitoring... checking for when asteroids drift off-screen.  This is probably not easy because physics-active mesh might not have any usable .position numbers.  Only the imposter has any position...  the mesh is a slave to it... I THINK.  :)


There is also one other problem.  None of your asteroids will spin around their x or y axes.  Because of the way you will be launching (applying impulse)  and because of the perfectly aligned z for all collisions... there will only be spin around z.  BUT... there is a solve.  When you launch a sphere from an off-screen position... toward on-screen... you apply THREE impulses.  One impulse sends the sphere moving toward on-screen, and two impulses... happen on two opposing edges of the sphere at the same time... causing a spin.  Because you fire ONE sphere-edge impulse +z, and the other opposite sphere-edge impulse -z, you induced no z-energy (no position energy).  Maybe this diagram for another project... will help you imagine it.




ApplyImpulse() has two parameters (or more).  One is the force direction, and the other is WHERE on the mesh/imposter... to apply that force.  Notice the offsets shown in that diagram.  By moving the contact points (the WHERE)... to a location that is offset from center (in opposite directions)... and firing both impulses (in opposing force directions)... you can induce a zero-translation spin.  You'll spin the object, and it won't drift location whatsoever.  Cool, huh?


BUT... keep in mind that you MUST turn off all friction on these randomly-spinning spheres, or else they will possibly induce z-energy upon themselves and upon other spheres... upon collision.  Reworded, if you spin a friction-active sphere around Y... and then it collides with another sphere... it will likely send that other sphere moving in a z-drift... something you don't want to happen.  By completely removing the friction from your balls (something we ALL seek)... (ahem hehe)... um... none of the spin energy will be transformed into z-translation... during a collision.


Wow, huh?  Friction off, build your asteroid launcher (impulse junk into screen area)... and build your spinner (dual impulses on opposite edges of the sphere, in opposing directions... at the same time.  Fun, eh?! 


The Krueger 3-Impulse Asteroid Launcher... available in stores soon!   :D  Be well.  Keep us posted if you want.  thx.

Link to comment
Share on other sites


That was about what I thought would work.  When I had done it in my app using updatePhysicsBodyPosition the objects didn't drop.  However, in your sample they are dropping. However, in your sample they drop and get stuck in a stack.  I still want them to collide and bounce left and right (- x , + x).  I played around a bit with your sample but couldn't get them to do that.


Hi Tom, Hi Wingnut,


if you leave the playground I created and wait for a minute or five (yes, i know... I hate waiting!) you will notice it does eventually changes. All balls will be aligned on the floor. Notice the "eventually"...

The problem with changing the body position is that the physics engine needs to recalculate the entire path and collisions of all objects once it triggered. This is a rather expensive operation which has a few serious downsides, one of them being the fact that it completely discards of current movement and impulses and has to recalculate them. So no more bouncing, only gravity.


IMHO - it would be very hard getting this to work with the physics engine. It would be simpler to implement it on your own, not using the physics engine...

Link to comment
Share on other sites

Hi again guys! - http://playground.babylonjs.com/#1FR0VN#4  It's a little demo where you can play with applyImpulse.

I have a sphere launcher in line 98.  There is no spin induced by me, on the green "mallet" sphere.  And there is no friction set on it OR on the ground, so I don't know why the mallet is "x - rolling".   I would have thought that friction = 0 on the green wireframe mallet... would prevent rolling.  Oh well.  I'll figure that out some other day.

All that crap aside... look at lines 96 and 97.  Activate those two lines, and de-activate line 98, then press run.

That shows the no-translation spin that I spoke-of... using dual impulsers along the edges of the sphere... thrusting in opposite directions.  The mallet is 5 units wide, but I only offset the contact points -1 and +1 x.  (A bit left and a bit right... enough to get spin).  If you offset (add)  +2 and -2 at the end of lines 96 and 97, then the sphere will spin much faster.  It has something to do with leveraging and fulcrums and all that goofy stuff.

BUT, now activate all three code lines... 96-98.  Now we are simulating your 3-impulse asteroid launcher... inducing a no-translation spin, AND using a basic -z thrust at mallet.position contact point (dead center)... to launch it out into the scene.  See what happens?  The red sphere is STILL deflecting to the left when the mallet hits it.  Why?  I have no idea.  We have NO friction set on either item.  hmm.  I even re-arranged the three lines... trying to impulse the position first, and THEN fire the spin-twins.  No change... still getting left-deflection.

Again, de-activate the spin-twins and leave the position-pulser active (fire the mallet without spin).  No red sphere deflecting seen.  It is the spin... that is causing the deflection. This is the rotation energy that can be transferred to position energy... that I was speaking-of in my previous post.  Put the wrong launch-spin on your launched asteroids... and they will deflect z-ward after collisions.  (an undesired thing)

It's not right.  We have zero friction.  *scratch scratch*  Some kind of bug, probably in Wingnut's brain.   :)

Thoughts, anyone?  Party on! 

Link to comment
Share on other sites

  • 2 weeks later...

Hi Tom and others.  A little update on this thread.

http://playground.babylonjs.com/#1FR0VN#6  Here we have the green mallet spinning, but no deflection of the red sphere due to friction.  Yay!

Wanna know why?  http://www.html5gamedevs.com/topic/10353-collision-check-with-oimo/  A little note from Temechon...


Don't set restitution (or friction) to 0, they won't be taken into account (Oimo issue here)

hmmm.  Thanks Temechon! 

So, I set the friction values for lines 27 and 33 to 0.0001, and suddenly the green mallet's spin (caused by lines 96-97) does not deflect the red sphere to the side.  Mission accomplished.  Tom can now use his off-screen, 3-impulse spinning asteroid launcher... with asteroid spin on ANY axes at any speeds, and the asteroid won't transfer that spin-energy into unwanted z-motion on collided asteroids.  Like billiard balls, we have made them too low-friction... to transfer any cue ball "English" onto any impacted balls.  :o

So, as Temechon states, don't set your Oimo stuff to zero.  :)  Set it to 0.0001 to turn-off those setPhysicsState values.   Interesting.  (almost)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...