Jump to content

Gravity without fancy physics engine


joshcamas
 Share

Recommended Posts

Thanks @adam, I forgot that Nockawa post existed. 

@fenomas, that beast has been talked-about in various places.  Here's one place... https://en.wikipedia.org/wiki/Observer_pattern

Be sure to visit that " Implicit invocation " link, too, for maximum brain tumor growth.  heh

If it can fix onLongMiddleMouseButtonPointerUp and other ridiculous event names... I'm all for it.  But it probably can't improve that, and touch events don't have a middle mouse button, nor any mouse at all, so we're all screwed.  :o

User asks:  "Will this work on mobile devices?"

Wingy answers:  "Yes, if your mobile device has a middle mouse button."  :D

http://alistapart.com/d/432/1.9-tablet-zones-2x.jpg

On mobile 2-thumb touch devices, there's only ONE body appendage remaining... that can press that middle area, and it's a men-only operation.  :o  A bit off-topic, though. 

onOcculusMercurySwitchTiltNorthEast?  OnFootRockerboardMercurySwitchTiltSouthWest?  :o 

And joysticks?  We haven't even STARTED addressing those, yet it is still one of the best controller methods to date.  See ANY onJoystick events honored in JS/BJS?  Nope, not even a little.  It is as if the Gods decided "There is no longer such a thing as joysticks".

Oh, the gravity of it all.  (Did I get back on-topic?) 

Link to comment
Share on other sites

thank you for the flowers :D

here's a fixed version : http://www.babylonjs-playground.com/#25OQ8V#13

the parameter CAP was added just after the old PG link, so I just added its value (0 or null) before the parameter scene in all calls to CreateTube().

Yep, as @fenomas said, everything that manages the behaviour of the objects in a scene according to external forces (gravity) or internal values (mass, elasticity, initial velocity, etc) could be called a physics engine. Whether it's minimalist and dedicated to a very single scene or all-purpose like cannonjs or oimojs can be, "physics engines", one and all.

If you want to implement some minimalist simple fast physics engine like this (linear equation), just apply the forces at the moment t only to the wanted meshes :

acc(t) = sum(force(t))        ... well, just remember that acceleration * mass is homogeneous with a force, so if the mass is constant, you can simplify acc = force * someFactor

vel(t) += acc(t);

pos(t) += vel(t);

for instance, each frame :

acc = gravity; 
// or, imagine some other force depending on the distance from the mesh to some other mesh : 
// gravitational force, electromagnetic force, etc
acc = gravity.add(otherForceVector(distance));
vel += acc;
pos += vel;

You can also compute the collisions of your moving meshes only on specific objects on the scene.

If these objects are axis aligned and you know their shapes and where your mesh can collide (platforms, ground, walls), just test for instance the mesh position against the obstacle coordinates : if mesh.position.y < ground.position.y  {...} .

if the mesh must collide and bounce, just invert its velocity accordingly and reduce it for some restitution (loss of energy) value that you can set with the amount of friction you want to apply : vel.y = -vel.y; vel.scaleInPlace(restitution);

If the obstacles aren't so simple, you can rely on the BJS mesh.intersectMesh(otherMesh) method instead of making your own intersection tests and just implement then your own behaviour (collision, bounce). In this case, if you want your mesh to bounce against the obstacle, just get the normal of the obstacle at the mesh/obstacle intersection point (or simply at the current mesh position when it intersects the obstacle to simplify the computation), compute the dot product between the mesh velocity and this normalized normal and just modify the velocity vector according to this formula :

// tmpNormal is a temporary Vector3 in what we store the current obstacle normal at the mesh position
tmpNormal.normalize();                                              // normalize it
var tmpDot = BABYLON.Vector3.Dot(mesh.velocity, tmpNormal);     // dot product (velocity, normal)
// bounce result computation
mesh.velocity.x = -mesh.velocity.x + 2.0 * tmpDot * tmpNormal.x;
mesh.velocity.y = -mesh.velocity.y + 2.0 * tmpDot * tmpNormal.y;
mesh.velocity.z = -mesh.velocity.z + 2.0 * tmpDot * tmpNormal.z;
mesh.velocity.scaleInPlace(restitution);  

this "inverts" (and scales) the mesh velocity vector around the obstacle normal... so it makes the mesh collide and bounce against the obstacle.

As you can see :

- it's really a simple and fast computation, because it's dedicated to your moving mesh only. Lighter and faster than a full physics engine, but less versatile because specific.

- the need for keeping the acceleration, velocity and position apart is really pertinent in both former examples.

 

Link to comment
Share on other sites

@Wingnut Thanks for the links! I'm more or less familiar with the concept, I was just wondering why BJS put in new observable objects rather than just using the traditional addEventListener model found in the DOM and Node. Six of one, half dozen of the other I guess, but seeing stuff like Observable makes me think of Java :o

@jerome Yeah.. if I could formalize that a little, I'd suggest there is a hierarchy of complexity to physics engines. The simplest case is where every object is modeled as a non-rotating AABB. If that's true, then the math is simple (like what's being done in this thread) and you have enough of a physics engine for a Mario-style platformer. 

However, once you have collision shapes that aren't just AABBs, you inevitably start encountering cases where resolving one constraint breaks another. This is why I think trying to make a "super simple" physics engine with "moveWithCollision" sort of heads down a weird path. (I'm assuming that function uses actual meshes, it doesn't just collide bounding shapes, right?)

Link to comment
Share on other sites

What I was talking about was to :

- use, for instance, the provided methods intersectsMesh(), only on some given meshes in the scene for simplicity and performance reasons, in the case of a dedicated simple physics engine. This method can compute things the AABB way or the OBB way,

- then to implement my own simple physical behaviour (gravity, forces, bouncing, etc) with simple equations : update the force/acceleration, check intersection/collision, update the velocity, update the position.

As you said, this way is somewhere in the physics engine complexity hierarchy : one step little higher than the full AABB Mario-style platformer. and many steps beneath something like oimojs or cannonjs.

What this need ? In order to make things a bit more complex than just platformers and that would be harder to achieve, performance-wise, with a full engine if we don't really care about realism or computing the physics for every moving object in the scene (not sure I'm very clear).

examples : http://www.babylonjs.com/Demos/SPSCollisions/ or http://www.babylonjs.com/Demos/Boom/    no oimojs, nor cannonjs here, just my simple pseudo-physics

I didn't even imagine using moveWithCollision ...

Link to comment
Share on other sites

@jerome Woah this stuff looks really amazing! How is this done without moveWithCollision? I looked at the code and didn't see anything about collision at all! :o How does it collide without this?

EDIT: Ahhh I see now! From my perspective, the reason this stuff works without moveWithCollision is that your hard coding the stuff each object is colliding with! Tell me if i'm wrong, but this is how I see it when skimming the code. The problem with this is obviously when you want a more complex example, such as even a game like mario. While obviously the most optimized way of doing things would be doing super fancy calculations hard coded specifically for a tilemap game, however I think that is not the goal of this little project. I originally intended this to be SUPER simple, with using the built in collision system, coupled with velocity, acceleration, and gravity (which of course is just acceleration) implemented. Maybe with the option to make a mesh have a body object, which would just be mesh data that the corridor would need. (This would allow complex meshes to have simple collision boxes, or any shapes wanted). Does this idea make sense, or is it too focused, or not focused enough? I'm just spewing ideas right now!

Here's my raw design concept, take it or dump it, ya'll choice xD I'm a simple college student that doesn't know much

physicsManager: This is the system that controls everything.

physicsManager.gravity: This is the global gravity for all meshes in the system. Alternatively, we could just use scene.gravity since it's already a thing.

physicsManager.addMesh(mesh,body): This adds the mesh to the system, which means it will update it's physical properties every frame. Body is an optional variable that lets you set the collision mesh/vertices. By default the body is identical to the mesh.

physicsManager.update(): This is run every tick, and simply updates every mesh's physics

mesh.updatePhysics(): This is what the physicsManager will run every tick. By default, it should just calculate the new position (using move with collisions) depending on the velocity and acceleration variables, as well as gravity depending on the meshes's mass variable. This can also be overridden to do whatever you want with it!

Basically, this single object simply uses what's already available (moveWithCollisions) and calculates stuff depending on some nifty variables (velocity, gravity, acceleration,mass). Think of Phaser's physics system, and you got it :) 

Does this sound plausible? I ain't got a PhD in Physics that's my Dad xD

Link to comment
Share on other sites

1 hour ago, fenomas said:

@joshcamas What you've described is basically how all physics engines work, including cannon and oimo.

 

Did I? Well then, that's good I think! I made sure not to talk about rotation, cause I don't think that's a thing with our simple system, other than rotating the body for collision stuff.

Link to comment
Share on other sites

yep, you just described the way any physics engine works.

If you want something really simple, I could make a quick PG next week, with cubic obstacles, axis aligned and no rotation, and minimalist (but fast) collision computation. It should be enough for a Mario-style platformer.

Link to comment
Share on other sites

On 2/11/2016 at 9:38 PM, joshcamas said:

 

@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

@joshcamas @fenomas 
it wasn't ment to start any drama at all, i simply answered why i did as i did,
While i generally agree with what fenomas wrote,
my example simply made an object fall until it hit the ground, it was never intended to be more complex than that, let alone simulate real world gravity :)
 

Have a nice day.

Link to comment
Share on other sites

http://www.babylonjs-playground.com/#PBVEM#11

in this simple example, you've got :

- a finite world defined by the big box

- some random platforms inside it, built with instances

- a Mario player, the tiny red box

Mario is given an initial random velocity and applied a constant gravity. You can tweak the energy loss against the box walls with the variable restitution (here : 100% = 1.0)

When Mario hits a platform coming downward (he's above the platform), he bounces back with some energy loss (variable platformBounceRestitution), when he hits the platform under it, he's just rejected. This is a very simple and naive physics engine because I don't even test if Mario hits the platform borders here. But it is fast.

Note that I also test all the platforms what is not performant at all (well, they aren't very numerous). The use of an octree or any preselection (we know where all the obstacles are in the space before the scene starts !) would be better.

 

[EDIT] http://www.babylonjs-playground.com/#PBVEM#13

another one with many more platforms and a bigger world

 

[EDIT2] http://www.babylonjs-playground.com/#PBVEM#14

1000 plaforms without any octree, so 1000 (AABB) intersection tests each frame and still 60 fps here

Link to comment
Share on other sites

I just found this on the tutorials page on the wiki, I'm not quite sure what it's about:

https://doc.babylonjs.com/tutorials/Adding_Your_Own_Physics_Engine_Plugin_to_Babylon.js

I thought it was just implementing your own physics engine, but then again it talks an awful lot about cannon. 

And wowsers, I did a simple test with characters simply applying collision gravity (moveWithCollisions) every tick, and wowserssss my game started tanking to 40 fps after only 3 characters were spawned, and it went downhill from there. (Hahah get it? Downhill? Gravity?) Soooo looks like either I'm using it wrong, or we need to let that function go for this engine, as jerome is doing. Btw, that's awesome work jerome!
EDIT: Well, unless we use web workers... however, I don't think that works on mobile. :0

And now that I think about it, how will this system work? Do we move the object a short distance in the direction of the velocity, and stop when the object starts intersecting? O_O

Link to comment
Share on other sites

nope, the tests here are really simple (and fast), so no sweepAABB algo ( http://noonat.github.io/intersect/#aabb-vs-swept-aabb ), but this could be easily implemented.

Why do I do such an "engine" ?

Because it fits my needs : light, fast, unrealistic, customizable... and because I know (or at least I can quickly and easily learn from my background skills) some maths and physics to make it by my own. Coding this kind of things is a game or a challenge for me, it's a part of the pleasure.

As long as I don't need to re-create a full physics engine for my little needs, I like to play this way. But if I need something dealing with more complexity or more realism, I would certainly use a full physics engine like oimojs or cannonjs.

If your needs are higher than very simple things or if you feel that it will quickly get to far more maths (and it will !), or simply more maths than you would manage/learn, I would suggest to use directly oimojs or cannonjs... and spend a little time tweaking them to set the behaviour you expect : who can the more, can the less 

Link to comment
Share on other sites

Nice code, Jerome!  I did one, too... with 500 clones with materials.

http://www.babylonjs-playground.com/#PBVEM#15

Heavy.  :)  If a guy wanted to make a town... with 10 planes per house... this demo would give us 50 houses to "blow up" with our cannonball.

BUT... hmm.  Jerome, you did SPS intersecting recently, yes?  And we really don't need materials on all these planes... but instead, vertex colors.  hmm.

Little houses are better-made with triangles, so we can get triangular gables on the roof.  Let's see, 2 triangles (2 faces) for each wall (total 8 triangles), 2 triangles for each side of the peaked roof planes (total 4 triangles), and two triangles for the gable ends.  14 triangles per little house.  That a nice amount of triangles to "explode" when a cannonball hits a house.

I'm talking the top-left house style... seen here.

hmm.  SPS-Based Vertex-Colored Little Explode-able House Generator - v1.0... hmm.  :)  Thinkin'.  Artillery Duel 2.0 - Mowing Down-Town!  heh

Link to comment
Share on other sites

Yep, the SPS would be the way to go imho to deal with many platforms with different colors and textures (all the images inside a single texture, aka atlas), so one draw call, one material, one texture.

I used the instances in the PG demo in purpose. To make it simple and understandable (not that the SPS is complex, but it's another world) and to focus on the physics/intersection/collision stuff.

Link to comment
Share on other sites

19 hours ago, jerome said:

Why do I do such an "engine" ?

Because it fits my needs : light, fast, unrealistic, customizable... and because I know (or at least I can quickly and easily learn from my background skills) some maths and physics to make it by my own. Coding this kind of things is a game or a challenge for me, it's a part of the pleasure.

Yup! Sounds good to me! Do what you need! :D

And thanks for that sweep link, it's super useful, like literally everything I could have asked for!!! <3 
 

 

Link to comment
Share on other sites

So currently I'm simply trying to rebuild the link jerome sent us with BABYLON, and since I am not knowledgeable about bounding boxes, it's painful... but aye we getting somewhere! Currently using simple AABB, and trying to find the point of intersection. Only supports XY, and the y is funky.

http://www.babylonjs-playground.com/#1BVXYE#2

I'll keep working on this and keep ya'll posted ;)

EDIT: Also, with this tutorial it requires the function to be run on the static box, sadly.

Link to comment
Share on other sites

  • 2 months later...

ALRIGHT I'M BACK

Here's something interesting:

http://www.babylonjs-playground.com/#1BVXYE#4

vs

http://www.babylonjs-playground.com/#1BVXYE#2

Notice how in test #1 the Y detection is incorrect. However, in test #2 it shows that the X detection is correct. (The red ball turns white when it detects intersection, and the black ball is the corrected position) 

Why is this? Is the bounding info on the large mesh incorrect?

EDIT: Of course I find the problem RIGHT WHEN I POST THE PROBLEM. It's cause when you rotate a mesh, it looks like the bounding box values I'm reading do not react/change. I'm assuming there are values that do, since that's the point of a bounding box. WOOHOO PROGRESS

EDIT 2: Strangeness... http://www.babylonjs-playground.com/#1BVXYE#6

Link to comment
Share on other sites

How should we handle collision boxes? My current idea is to automatically resort to bounding boxes, unless another bounds (box, sphere) is specified. 

Is anyone else interested in this physics engine? This should allow for dozens of characters running around at once. Is this something people want?

Link to comment
Share on other sites

Am playing around in this area myself. Not quite what you are doing. Have you read this?

Currently I am playing with the intersection of two complex (ie concave) shapes. Will give examples should I ever get it working.

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