Jump to content

Gravity without fancy physics engine


joshcamas
 Share

Recommended Posts

Hia guys!
In my very basic game, I have gravity and collision and stuff enabled on my little camera guy. Awesome!
But then when I try enabling gravity on another mesh, it seems to not do anything at all!
Why is this? I seem to remember this being a problem months ago but assumed it got fixed...

If babylon doesn't have this feature, I guess I'll need to implement it myself. I have absolutely no need for a fancy physics engine of any kinda, just need super simple gravity :) 

Alas, imo the greatest weakness of Babylon is it's mix mash of features... we have some absolutely stunning beautiful effects, but then do not support gravity on meshes, if it's true that it's not there.
I think I understand why... different people have developed different things (aka someone else developed free camera and added gravity as a feature), which causes this. I guess it's inevitable.

Regardless, let's figure out how to do this!

EDIT: Btw, I'm working with CreatePlane function, so maybe gravity isn't available in that? I'm looking into it rn

EDIT2: Ok, so I think (?) gravity isn't supported in meshes. However, it looks like implementing it shouldn't be hard at all! Basically, all the free camera does is add the gravity velocity to the velocity. Now, I'm not sure when this happens - I would venture to guess every tick, however in the code it seems to be attached to collision. Hmmmmm :)

Link to comment
Share on other sites

Gravity is a physics thing, I wouldn't think Babylon would have any features related to it when there's no physics engine being used.

That said, if all you want is gravity then:

mesh.velocity = 0
scene.beforeRender = function () {
	mesh.velocity -= 1
	mesh.position.y += mesh.velocity
}

 

Link to comment
Share on other sites

@fenomas: Well, the camera comes with built in gravity, so I don't see why it isn't a bad feature idea on meshes as well :D

@adam: Ahh yeah! Here it be!

http://www.babylonjs-playground.com/#23ICEC#1

(One little "bug" is you have to move to start gravity on the camera. This has to do with it being paired with the function moveWithCollisions, I believe.)
As you can see, free camera has a gravity system. This was built directly into the camera, to make it easy to make fps's and such :D
However, it has not been built into the meshes or nothin :o
So my goal is to do this, so others can easily enable gravity if they wish, or not if they don't. :D Cause sometimes you just want a simple enemy that doesn't float, but don't want a super expensive physics engine with bodies and such

I'll keep ya'll posted as I look into this deeper. One thing I've noticed is Babylon is very good at making super sexy demos, however it often falls short when making a real game, like for example a very simple fps. :3 

Link to comment
Share on other sites

Oh yeah, there's some minimal physics-like stuff built into the camera. Personally I find it a little misleading - it works but only for very specific kinds of contents, and not otherwise. I think it's meant for quick demos and playgrounds, not for real content.

 

53 minutes ago, joshcamas said:

So my goal is to do this, so others can easily enable gravity if they wish, or not if they don't. :D Cause sometimes you just want a simple enemy that doesn't float, but don't want a super expensive physics engine with bodies and such

I strongly suspect you'd be better off just using physics. If "all" you do is enable gravity, everything will just fall forever. So you need some ground, which means you need collisions, which means you need collision impostors, and some rigging to update mesh positions. Then if bodies can collide with anything other than the ground you need constraints, and if performance matters you need broadphase, etc. Once all that's done, you write a release announcement for your new physics engine. ;)

Link to comment
Share on other sites

30 minutes ago, fenomas said:

Oh yeah, there's some minimal physics-like stuff built into the camera. Personally I find it a little misleading - it works but only for very specific kinds of contents, and not otherwise. I think it's meant for quick demos and playgrounds, not for real content.

 

I strongly suspect you'd be better off just using physics. If "all" you do is enable gravity, everything will just fall forever. So you need some ground, which means you need collisions, which means you need collision impostors, and some rigging to update mesh positions. Then if bodies can collide with anything other than the ground you need constraints, and if performance matters you need broadphase, etc. Once all that's done, you write a release announcement for your new physics engine. ;)

I disagree ;) 

Imagine a game like Mario. Is there a physics engine? No. However, it has velocity and acceleration, as well as collision between tiles.
Well, I'm making a game like Mario. Well, more like DOOM... but you get the picture. A grid like environment.

To make ground, I simply do not enable gravity on that object. Collision is already a feature, so this works great! No constraints needed! 

We already have collision impostors, as in we have a simple collision system. Tbh we need to make meshes be allowed to have a custom collision impostor, I'll add that to my list hehe. For my project, it's a lot like DOOM, so simple walls will do perfectly!

Rigging is only needed for skeletons, something I am not doing.


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

And most video games do not require fancy physics on players and enemies. For example, Skyrim characters - from dragons to the player do not have a physics engine attached. (Also known as the havoc engine) They have gravity though, as well as other nice stuff. However, Skyrim uses a physics engine for objects - notice how these objects require a fancy engine because they roll around in the environment, and can be thrown, and bounced and such! The physics engine is also used for skirts and fluttering clothing. This is what a physics engine is used for!

In UE4, physics engines are used in the same way. Enable it if you want super fancy stuff, but never use it on a player, unless it needs it, like if your a bouncy ball that runs into stuff.

2D Engines do the same thing - in mario, no physics engine is attached to him. However, in some fancier 2D games, there may be objects around that bounce, or as I said above, special cases may arise where even the player has physics enabled. But rarely is this the case.

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

I am personally use BabylonJS to make a game that runs efficiently. Will it break the standard of what webGL will do? Nope. But it will be a fun little game :D 

Soooooo I'll be working on this, should get some sort of demo out within a week or so. What it will do is simply let you type "josh.applyGravity = true", and it will simply automatically lower the character down by the scene's gravity. (moveWithCollision) It's that easy, and it's rad!!!

Your example code is pretty much what I'm looking for, except for some little changes and of course implementation :D
Ooooh and let's Get @Wingnut's thoughts! :D

Link to comment
Share on other sites

hehe.  Hey, don't drag ME into your little stomp'n'snort.  :D  I'm just here for the free beer.

12 hours ago, joshcamas said:

One little "bug" is you have to move to start gravity on the camera

camera._needMoveForGravity = true;    ...  starts camera falling right away.

http://www.babylonjs-playground.com/#1FOXSC#3

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

Would moveWithCollisions also work for adding gravity-movement to a mesh?  I guess we'd need to continuously adjust things... to sim acceleration.  *shrug*

Now, no more sugary soft drinks for you, tonight, okay Josh?  hehe. 

(Just jokin' around, attempting to keep the mood light, and wondering if you have a spur in your saddle)  ;)

Link to comment
Share on other sites

Josh, I think we're talking at cross purposes. Skyrim most certainly uses a physics engine for players (specifically it uses Havok). When you run, behind the scenes the game is applying an impulse to your character's physics body. When you drop a cabbage on the ground and walk over it, it gets knocked out of the way because the character and the cabbage are both bodies in the same physics simulation. Just because the character's individual parts (hair, clothes, etc.) aren't independently simulated doesn't mean there's no engine involved. Most 2D and 3D games work the same way - characters might be represented by a simple impostor (box, capsule, etc), but each impostor's movement in the world is modeled by a physics engine. (Even a game like Mario has a physics engine, in the sense that it has a subsystem that integrates the position of each entity according to physical properties. It's not a general-purpose engine of course, it's an ad-hoc system built into the game - whether that counts as a "physics engine" or not is down to how one defines the term.)

Anyway nomenclature aside, the important point is that there's nothing inherently expensive about using a physics engine. If you set up a scene with some boxes and spheres, moving them around with cannon.js isn't hugely more expensive than moving them with moveWithCollisions - behind the scenes, pretty much the same work is being done. The main difference is that the built-in camera stuff is inflexible and made only for a certain kind of demo, and physics engines are robust and general-purpose. For example, when last I checked the ad-hoc system did all its physics in the camera's move function. Presumably that's because whoever made the feature was envisioning a simple demo where the camera is the only thing that moves, and it starts out sitting on the ground, and it can't jump. And if you're making specifically that demo, the ad-hoc stuff works. If not - well, naturally each of those limitations could be removed, but after them there would be others. If somebody removed all the major limitations in the ad-hoc system, the result would be another physics engine.

Link to comment
Share on other sites

@fenomas

Ya I guess I have a different definition of a physics engine. But yea u sound about right :D

Hmmm I do wonder if cannon is really just equally expensive compared to collisions. I should make a test comparison to see which is better :o Cause maybe since cannon is designed to be a physics engine Itll be better optimized, or maybe it won't depending on what features we want or don't :D

 

@aWeirdo ooo that's a good start, I like it! Maybe we should do it your way and build a super duper simple Gravity manager or something. This works great for any simple needs for 3D Mario-like games ;) Oh, and would it be better to use requestAnimationFrame or setinterval? I forget the pros and cons of each

@Wingnut

Man you are magic at Babylon! How do you find all these magically variables loll

Link to comment
Share on other sites

@joshcamas Anything that moves objects around with velocity and acceleration is effectively a physics engine, some are just more general than others. I mean, what you're talking about making here would be a physics engine, albeit a simplified one.

Whether your simplified engine would be faster than cannon/oimo depends entirely on what you need. Unless you have a clear idea of what work cannon/oimo do that you're sure you won't need, and you're confident that that work would be costly enough to make your game run slow, I think it would be better to build first and tune performance later.

Remember that premature optimization is the root of all evil (97% of the time)!

Link to comment
Share on other sites

@aWeirdo If I can offer some advice :D 

  • Gravity is acceleration, not velocity. "pos += gravity" should be "vel += gravity; pos += vel"
  • Generally processing like this should always be done with render events (beforeRender) etc, rather than setInterval. This is for a bunch of reasons - e.g. so that pausing babylon pauses the physics, and so that you get consistent numbers of renders between each physics update, or vice-versa.
  • Realistically it's necessary to update mesh positions every render. If the camera is moving it winds up looking weird if the scene is rendering at 60fps but objects only move at 30fps. (If the camera is attached to a physics object, as it would be for an FPS, this gets really really noticeable)

For the physics you're doing, performance is completely negligible so there's no downside to just updating the physics every frame, using beforeRender. (In real content it's much better to decouple physics and rendering, but that's probably beyond your scope here.)

Link to comment
Share on other sites

Yeah I think decoupling our mini physics engine (Guess that's what we're building eh) should be done at some point but not now, as you say :D
However, is collision detection optimized in Babylon? Do we make use of quadtrees and such? Related question but also not xD 

Link to comment
Share on other sites

3 hours ago, fenomas said:

@aWeirdo If I can offer some advice :D 

  • Gravity is acceleration, not velocity. "pos += gravity" should be "vel += gravity; pos += vel"
  • Generally processing like this should always be done with render events (beforeRender) etc, rather than setInterval. This is for a bunch of reasons - e.g. so that pausing babylon pauses the physics, and so that you get consistent numbers of renders between each physics update, or vice-versa.
  • Realistically it's necessary to update mesh positions every render. If the camera is moving it winds up looking weird if the scene is rendering at 60fps but objects only move at 30fps. (If the camera is attached to a physics object, as it would be for an FPS, this gets really really noticeable)

For the physics you're doing, performance is completely negligible so there's no downside to just updating the physics every frame, using beforeRender. (In real content it's much better to decouple physics and rendering, but that's probably beyond your scope here.)

@fenomas 

1, i would challenge that and say that Gravity can be define as both; acceleration is what increases the velocity over time, at which the object is falling.
But seening as this is just a very basic and simple simulation of it, (x mesh falls downwards until it hits the ground), i didn't care to add or even think about stuff like mass, drag and acceleration to slowly increase the falling speed.

2. i went for the setInterval with the following in mind; so one could define the frames, if you have some 1000+ objects, running it 60 times / sec seems unnecessarily heavy on the cpu, especially when half is enough, aswell as being able to pause it without having to pause babylon :).(e.g. being able to pause everything with a click, and still move the camera around the scene,
Ofc, looking in hindsight, this could also be done with a boolean value inside a registerBeforeRender, e.g. (!cGravActive) return; or w/e :P 

3. But there's no need in this case, if you can get away with running the calculations 30 frames / second, why not? the render(at 60 fps) is simply rendering it twice in the same position, before it then renders it very slightly lower than that on the third & fourth frames, etc.
Keep in mind that it moves very slowly per frame, so it's hardly notiseable.

With all that being said, it's pretty much just a piece of example code, and what anyone prefers or ends up doing is their own choice ^^.
 
 

Link to comment
Share on other sites

Hi guys!  :)

Back in the old Commodore 64 days, we would "wedge" into the IRQ (interrupt request) loop... which probably doesn't apply here at all.  But, where I'm going with this... is that we could put a function on Node... something like a .runEachFrame() method.  If it is empty (or just a return), nothing happens to that Node (mesh, light, camera) each frame.  If it is set to a function, then that function is run once per frame.

In other words, a mesh, camera, or light, could be self-controlling.  One scene item could be slowly floating upward, another dropping due to gravity, a light could be doing cosine panning back and forth, or whatever.  I suppose some kind of "state" would need to be maintained ... for SOME .runEachFrame() funcs.  Some added properties, I guess.  I suppose a guy could use a .eachFrameStore property, and coders of .runEachFrame() funcs... could use that as a node-state storage place.... and count on it being available on any node.

These node-wedge funcs would need to complete REAL FAST, or else... trouble.  :)

This could/would cause some scene delay as the engine polls through all nodes on each frame... running every .runEachFrame() function.  But each scene item could have different gravity rates.... or monitor for scene.wind and move appropriately, anything.  It would certainly be versatile and allow for "smart nodes".  It is also programmer-installable on a scene-by-scene basis.  No need to add it to the framework.  Just overload Node, and iterate through all scene nodes once per frame... from the scene's beforeRender loop.

Come to think of it, this would be node.beforeRender, eh? 

Just another goofy Wingnut idea... which usually means...  insane.  :D

Link to comment
Share on other sites

just my two cents, usually doing some dedicated ultra-simple physics engines in my own scenes (moves, simple collisions and bounces) when I don't need the whole power of full engine,  I agree with @fenomas :

- it's always better to update everything before each rendering when it's possible

- it's better to keep each physics dimension (position, velocity, acceleration) apart because you may want to tweak them later to get more realism or more dynamics (realistic moves aren't always the best to make a scene attractive). Ex : change the gravity, give an initial velocity or acceleration.

Just remember that the velocity is the temporal derivation of the position, and the acceleration is the temporal derivation of the velocity what can be easily approximated (for linear equations) by the increase of the velocity by the acceleration amount each frame and then the increase of the position by the velocity.

so : vel += acc; pos += vel; is the right way to go imho.

Remember also that a force is homogeneous with a mass multilplied by an acceleration. So for a given mass (object), just tweaking its acceleration vector along the time is the same than applying forces onto it.

Link to comment
Share on other sites

 

@fenomas and @aWeirdo wowsers didn't mean to make drama! I think both of your ideas are great and both make sense, it's just two different ideas on how something should work :)
However, it'll probably be easier to just throw all of this in the babylon render loop for now, and think about better optimization later :D


@jerome Woah math is mathy

Link to comment
Share on other sites

Hi again.  I am wandering off-topic, sorry, but both examples of observers in the docs... use scene.onBeforeRenderObservable.add(). 

Hey @adam (or anyone)... would you have a moment to show us when/how to use a mesh.onBeforeRenderObservable or mesh.onBeforeDrawObservable?  That would be cool, thx, whomever.  And if you accidentally intersect some mesh, maybe incorporate abstractMesh.onCollideObservable, too?  That would be extra far-out!  Then maybe we will add it to the examples in the observer docs.

Ok, back to gravity, velocity, acceleration, and what IS a "physics engine".

@jerome built a basic cannon for me, once.  He used math to make the cannonball bounce on the ground when it landed.  Was that a physics engine?  Yep.  I cherish the math that made that sphere bounce.  I still send him flowers every Valentine's Day.  His basic sphere-bounce calculations were/are FAST!  Good stuff.  Physics engine... sorta.  :)   Let's see, where did I put that thing?  Ahhh, HERE... but it's a bit broken.  MeshBuilder changes, I suppose.  ("buggle" == cannon "pucker"... a cartoon cannon "puckers-up" before it fires.  That is what I was after... Jerome pulled it off.  He's a God!)

Gotta dot(product) your i's and cross(product) your t's.  (huh?)  :)

I wanna make the mesh itself... smart... autonomous.  Spawn'n'forget.  I guess that's just overloading/hacking the Mesh class.  But... hmm... still seeking autonomous self-monitoring.  Gravity/flight-trajectory on a single mesh of a many-mesh scene.  No scene code needed, except to build the autonomous mesh factory.  Am I weird?  I wish I were a better coder.  :/  Still, it's gotta "wedge" into the renderLoop SOMEWHERE, I suppose.

Even the addition of the observer... should be done by code on the mesh itself.  "Hey engine...  run THIS method on me... as often as you can, please" :)  (Cordiality is important)  heh

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.

Guest
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.

Loading...
 Share

  • Recently Browsing   0 members

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