Jump to content

We need a new collision system


joshcamas
 Share

Recommended Posts

Hey guys!

 

I've been using Babylon for about 5 or months now. My goal has been somewhat obvious - make a game.

 

And today I realized something pretty insane - we don't have a collision system. Of course, we have the most basic system - bounding box + moveWithCollisions = collisions!

 

However... making a "real" game, (like my current project is going to be someday in the future hopefully), using a simple bounding box won't do. Having a game within the Titanic doesn't work with having simple bounding boxes.

 

So... we need a plan. I think step one would be to make it so you can resize the bounding box... cause I can't find a way to do this.

Eventually, having a system that allows for more complex bounding "boxes" should be implemented - a system that allows for walls and objects and people and the everyday "stuff".

 

So Step 1: Is it possible to resize the bounding box, and even more importantly *show* the bounding box?

 

----------

TL;DR

Looky here: http://www.babylonjs-playground.com/#KYMGU This bad. We fix.

Link to comment
Share on other sites

Have you tried using oimo? I haven't used it personally but collision testing is a necessary part of any physics engine, so I'd imagine that what you're asking for is already implemented there.

 

(It might also be helpful to look for the keywords "broad phase" and "narrow phase" - the former being checking bounding boxes and the latter being checking actual meshes.)

Link to comment
Share on other sites

The thing with oimo is that it's a physics engine... with fancy smancy physics stuff! What babylon needs is a simple mesh collision system... so instead of fancy bouncing balls we have a player hitting the ground and walls. Basically oimo is too complex for what we need! ;)

 

Thanks for the keywords, sadly nothing about narrow phase and babylon came up in google. Whenever I start actually building a collision system I can use this. :)

 

 

Here guys, here be another example for ye:

http://www.babylonjs-playground.com/#KYMGU#1

 

 

EDIT: OK WELL I FOUND THE PROBLEM... the problem is... collisions use the ellipsoid only! Yeah! So all the bounding box stuff isn't used at all... silly. me.

Now that I know the problem, Ima try to make a better version of moveWithCollisions that allows you to choose the shape of the bounding box thing. :D

Link to comment
Share on other sites

Yeah, sorry, I missed your TL;DR the first time. Yeah, it looks like all bodies get a default-sized ellipsoid regardless of geometry, and you're meant to customize it.

 

With that said, now that I look into it BJS's version of narrow-phase collisions is mesh1.intersectsMesh(mesh2, true) , which I see you're already using. Is that not enough for what you're doing?

Link to comment
Share on other sites

From babylon.scene.ts:

private _activeMesh(mesh: AbstractMesh): void {    if (mesh.skeleton && this.skeletonsEnabled) {        this._activeSkeletons.pushNoDuplicate(mesh.skeleton);    }    if (mesh.showBoundingBox || this.forceShowBoundingBoxes) {        this._boundingBoxRenderer.renderList.push(mesh.getBoundingInfo().boundingBox);    }    ...
Link to comment
Share on other sites

collision is testing the defined ellipsoid of either a (moving/colliding) mesh or a camera against the entire mesh(es) that it tries to collide into. So, it is ellipsoid vs. complex mesh.

 

A more complex test (mesh against a mesh) would take quite some time to calculate, so forget about moving freely in the scene... There is a reason reason why it was implemented like that. A compromise for the greater good  :) It is the same reason why Omio supports only spheres and boxes. it wouldn't be able to deliver real-time calculations if it was more complex.

Link to comment
Share on other sites

Hi guys.  I did a little playing.

 

http://www.babylonjs-playground.com/#1REST6

 

In this version, I manually set the height of skull.ellipsoid... to approx the height of the bounding box.

 

I tried to determine the dimensions of the bounding box, but failed (so far).  I was SO hoping for:

 

skull.ellipsoid = skull.getBoundingInfo().boundingBox.getSize();  :)

 

Gwenael once posted about this issue...

 

http://www.html5gamedevs.com/topic/4326-how-to-get-height-and-width-of-a-mesh/#entry26872

 

I think his formula is wrong.  I don't think we can use .length on a vector.  But I think I understand what he was trying to do.  He wanted to subtract the X values of a certain 2 points to get a width, then subtract the Y values of a certain 2 points to get a height, and the same with Z values. 

 

Let's add a boundingBox.getSize()... (and one for boundingSphere) so users (like Wingnut) don't get a tumor trying to compute the bb size.  :)  (if possible).  (thx)

Link to comment
Share on other sites

Ellipsoid against meshes (as Raanan mentioned) is the current way of working of the collision system. This is not ellipsoid against box. 

 

And, while working with Ubi Soft and others great games developers, I can tell you this is how they ALL work (sometimes they do not use ellipsoid but capsules but you get my point)

Link to comment
Share on other sites

Ahhhhh I see! As you can see, 99% of this post is me finding out everything I thought was true wasn't. So bear with me here, lol.

 

 

So for collisions on walls Ubisoft uses ellipsoid and not a plane/cube?

 

Now I see that having complex meshes would never work, but how about having a simple cube, or even a plane. Is this unheard of?

 

Also, is there a way to see the ellipsoid? That'd be sweet! :D

 

If not, I'll get try my best on adding it. Still a n00b but learning.

Link to comment
Share on other sites

So for collisions on walls Ubisoft uses ellipsoid and not a plane/cube?

 

Most games mainly use boxes and spheres. When people use ellipsoids (or capsules) it's usually to model a controllable character, where you don't want it to get caught on little corners and doorways and so on. I'd imagine that that's why BJS provides ellipsoid-based methods like moveWithCollisions. If you called that API on a wall then I guess it would use the wall's ellipsoid for collision testing, but I don't think that's the intended use. ;)

 

 

Now I see that having complex meshes would never work, but how about having a simple cube, or even a plane. Is this unheard of?

 

Usually games use separate models for collision testing. So for a wall, say, the model being rendered might have little ridges and bullet holes and whatever, but in the physics engine it's just one big box. (Not a plane - collision testing is usually done with volumes, not surfaces.)

Link to comment
Share on other sites

Ok... so it makes sense to have cubes implemented into Babylon? Just makin sure it isn't a feature no one would use, or if there isn't a better way. 

 

I'm not sure I follow what you want to do. Collision testing with cubes should be what 

 

   mesh1.intersectsMesh(mesh2, false) 

 

 does. That is, it tests for collisions between axis-aligned bounding boxes (or maybe spheres, I haven't checked), because that's generally the fastest kind of collision check one can do.

 

If you don't mean AABBs, but rather checking for collisions between a cube with arbitrary orientation, it would probably be easiest to just make a Box mesh and move it around checking intersectsMesh(mesh,true) on whatever it might collide with.  (Well, provided you want to keep things simple and ad-hoc, that is. If you want it to perform well it would be best to use a physics engine so that you get proper broad- and narrow-phase tests.)

Link to comment
Share on other sites

Oh hell, I might as well give my take on the subject.  And Josh, don't worry about being completely wrong about how something works.  I've done it 100 times on forum, so far.  :)

 

Ok, let's pretend we have an airliner model with wide wings, and a standard sawhorse sitting alongside the runway.  And let's assume that we will NOT be using a physics engine.

 

The airliner will have a collision ellipsoid, of course.  It's reasonably spherical.   To cover the airliner's length and width, you might tend to lengthen/widen the airliner ellipsoid by increasing its X and Z components... until the ellipsoid "includes" the width and length of the airliner.

 

And no, you don't get to see the collision ellipsoid, nor do you get:

 

airliner.ellipsoid = airliner.boundingBox.getSize();

 

Nobody has coded that yet.  Maybe YOU will. Meantime, learn to enjoy pain. :)  Now back to our story.

 

Next, we try to pass the fat-ellipsoid airliner's wing OVER the sawhorse.  It should not intersect, because the wing is much higher than the sawhorse.  But... you get an intersect... because the airliner's ellipse is rounded.  The ellipse's "bounding area" doesn't "fit" the wing with good precision.

 

If you put an invisible box around the entire airliner, and checked for sawhorse collisions with IT'S ellipsoid, it gets even worse.  Now the airliner wing can't even pass over a coin without intersecting with it.  Terrible precision.

 

But now let's pretend that you assembled the airliner model from 5 separate mesh... mainbody, nose, tail, leftwing, rightwing.  EACH of those meshes... has a collision ellipsoid.  The wing ellipsoids could be set WIDE on the X-axis, narrow on the Z-axis, and quite thin on the Y-axis (wing thickness).  NOW the wing can pass over the sawhorse without collision detect.  BUT, you need to check for collisions on FIVE ellipsoids instead of just one.

 

For modern physics engines, there is a similar thing called a "compound imposter". 

 

Back to BJS standard non-physics collisions:  By assembling the airliner model in a certain way, we are able to make a compound "collider" as well.  Because it uses 5 ellipses, it represents the shape of the airliner in a fairly accurate way.  You KNOW which wing (or nose, tail, body) had the intersect collision, and you can do damage simulating on THAT wing ONLY.

 

Am I correct about this?  Does this method work?  I dunno.  Never tried it.  But it sounds good in theory.  Maybe this is "Wingy being completely wrong about how something works" #101.  :)

Link to comment
Share on other sites

I think having multiple ellipses is a good idea. A very good idea.  :D :D :D

 

So how about this for a future collision system! Not working on it yet, just getting what we know and trying to make the best balance between simplicity, optimising, and simply having an awesome collision system

 

1) Multiple types of "impostors". Ellipse, (sphere included of course) Cube, and maybe Cylinder?

2) Make it easy to add new impostors if someone wants to. We wanna make Babylon as extensive as possible! Cause that's the beauty of it! <3 <3

3) Multiple impostors per mesh. Basically an array of shiny shapes.

4) Make these nice impostors visible!

 

Looks good? Anything to add, change, or veto?

Link to comment
Share on other sites

I think it's a great idea, all of it.  Keep in mind that one of the early steps in doing proof-of-concepts... is learning EXACTLY how the current BJS collision system... works.  Josh, do you know how to "borrow" collision and intersect functions from abstractMesh, and put them LOCALLY into your test scenes?  Usually, it takes a lot of pasting and some minor adjusting to the top function declaration line of each function.

 

That's your start.  Bring local (into your test code)... every abstractMesh function that includes "intersect" and "collider" and "collision".  Put a console.log message at the top of each function, so you KNOW that YOUR local functions are being called during collision processing, and NOT the default BJS functions.

 

Now you've got most of the BJS collision system in your test code, where you can insert console.log messages all over the place... and truly master the current collision system.  Test every kind of collision you can think-up, and watch the collision functions do their thing.  I or others would be glad to help you assemble this collision testbed (especially if we can have a copy of it for ourselves and maybe for a playground demo).

 

Once you completely understand the current collision system, then your "game plan" and dreams... might change.  You will be able to see exactly WHY the current collision system is not meeting your needs.  And then, your "plan" might become a series of "precision strikes" (ar ar ar... precision, strikes, collision stuff).  :)

 

I think you did the same(ac) thing with the Samac Editor.  You had to get to know the editor you started-with, before you could properly analyze the ways it could be improved.

 

Imagining and speculating is great fun, I do it all the time.  But accurate and plausible imagining... takes some serious legwork.  POC - proof of concept testing is the key.  I'm no expert, but I have noticed that when I talk to experts about dreams I have, it is best to speak in terminology that the framework authors understand.  YOU can learn that terminology... via learning the current collision system.  Try to keep all your POC's... playground-able.  Then the entire forum becomes your idea team, your feedback team, and your POC test analysis team.

 

Who but you?  You have always been a fine trailblazer, and you are one of the fastest (maybe THE fastest) BJS self-starters I have ever seen.  You dream large and you're not scared to take-on monster projects, with plenty of spirit.  And I think you will thoroughly enjoy bringing all the collision/intersect functions into your new collision testbed and torturing them.  There's no quicker way to learn how it all works... and to do test modifications. 

 

At minimum, you will learn exactly how to build a CUSTOM collision system that fills your personal/project needs... and it might evolve into large framework changes... once you prove it performs nicely.

 

It all starts with some github searches for 'intersect' and 'colli'  :)

 

Thoughts?  Be well.  Good luck.

Link to comment
Share on other sites

Well?  Did you start on the BJS Crash Test Dummies collision testing/learning app?  What is taking so long?  I want to play with it.  :)

 

Did you know that you can "see" mesh ellipses by parenting a wireframe sphere to a mesh, and setting it's scaling and positional offsets exactly like the ellipsoid?  I knew ya did.

 

I was thinking about some Tools that might help us with this.  .showVectorAsEllipse(), .showVectorAsPosition(), .showVectorAsDirectionWIthMagnitude(), etcVectors temporarily shown as spheres, arrows, and position indicators.  *shrug*  Then seeing our collision ellipse would be...

 

BABYLON.Tools.ShowVectorAsEllipse(myMesh.ellipsoid)

 

But, there's trouble with that.  It requires a mesh be added to the scene... and a renderable vector... just doesn't qualify as a mesh, and we probably don't want it to.

 

So. it's probably best to create a local function in the testing lab...  that does these things.  mymesh.showEllipsoid().  :)

 

Got that testing lab done yet, Josh?  We'll want keypress control of all axes of our colliders.  Up, down, left, right, forward, back, and rotation on all 3 axes (6 directions), too.  We'll need velocity and direction controls for our auto-collider, and don't forget about the elusive and rare collide-from-bottom... and the yet-unwritten rotateWithCollisions().  C'MON!!!  ;)

 

We'll need buttons and readouts... and they need to be made in such a way that these buttons work in the playground AND for home-testing.  A good way to determine if your code is being run in the playground... is to check for the existence of a HTML element with id="JSEditor" or something like that.  If it exists... you append your "toolbar" onto PG elements.  If not, you create your home-based toolbar element and append your gui into it.  So you get the same buttons and readouts for home and for PG. 

 

You might need to collapse the editor to get lots of room for gui in the PG.  You've seen me do it with the 10-camera demo.  (this demo needs updating for virtualJoysticks issue)  But, it's buttons and readouts work fine, home or PG.  (All that dynamic html sure clutters-up the PG editor, though, huh?  *nod*)

 

C'MON!  hehe.

Link to comment
Share on other sites

Ahhh nice idea! Adding buttons and hiding the screen is brilliant!!!

 

Here is the old version with your button system added!

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

 

EDIT: updated a bit http://www.babylonjs-playground.com/#1REST6#3

 

I decided to add a nifty function

 createButton(text,function, id)

 

which basically adds a button on the top. :D

 

I also added a global object "Game". Whatever variables attached to this, (the skull is in this example) can be accessed within the chrome/firefox console! Good for debugging!

 

Now on to a better testing lab :D

Link to comment
Share on other sites

Ooh! Cool! All thanks to wingnut :) :)

 

Is bootstrap up to date? For some reason I can't make the buttons change sizes :(

 

Also, would you mind attaching jquery to the PG? It would make things like this easier and more fluid. 

 

And one final thing - I'm pretty sure the fps counter makes the playground run wayyyy slower... updating the browser like that is often very expensive. :( I would add a interval to update the fps:

 

window.setInterval(updateFPS, 2000);

 

Just an idea. :)

 

Sorry for throwing all these problems at you, you don't need to do them if you dont want to. :)

Link to comment
Share on other sites

Here's a tiny bit better. Made the hider/show a little cleaner, to remove distractions. Also, a grid. And a button to hide/show the bar thing.

 

So, wingnut. What do you mean by moving all the colliders?

 

EDIT: Oh! Look! Haha! Hide editor has been added! xD

Link to comment
Share on other sites

Hi Josh, nice work on everything!

 

What I meant was that the mesh which will be involved in collisions... need to be moved somehow (to cause intersects).  I've never used a gamepad, but they seem to have plenty of buttons to move nearly anything in any way, once a mesh is selected.  Have we got a virtualGampad (canvas) in BJS?  hmm.

 

You might consider moveWithCollision() being a different testbed than rotateWithCollision(), just to save you some onKey eventListeners. 

 

And then there's scaleWithCollision().  ScaleWithCollision() probably has limited use, but rotateWithCollision() is important for anyone trying to turn a boat around near a dock.  Either end of the boat could hit the dock during a turn-around, especially a boat with steerable water-thrust drive that can turn 360 degrees.  I've seen many tugs on the Mississippi River... move sideways, using their water-jet drive nozzles.

 

The same deal applies to helicopter blades and other propeller things... like windmills. Naturally, you don't need to model these meshes in anything hi-rez.  Just move the pivot points (to the end) of a few sticks, and start rotating those puppies, smacking other collision-active things, much like a baseball bat or pinball flipper might do.

 

Thanks for experimenting with these things, Josh!  I am VERY interested in all of your discoveries.  I talked about rotateWithCollisions with Vahith, quite recently.  You might want to take a sniff at his/her thread to see if there is anything useful.  I gave Vahith a rotateWithCollisions function, but it was not fleshed whatsoever, yet.  It just rotated, and did nothing about rotation-caused collisions.  But it might be wise to check with Vahith and see if he/she has advanced that function.

 

Just maybe... rotateWithCollisions could be a b*tch to code.  At minimum, Vahith might have a pile of failed attempts to learn-from.  :)

 

Thanks again!  Cool project!  And thanks to DK and you for spearheading the new playground features.  They rock!

 

Let's think about what DK said recently, too.  Something about "raising a collision event".  If I understand that correctly, we would no longer need move/scale/rotate "with collision" functions.  Instead, we just have... collisions.  Any intersect... fires an onCollision event, and then it would be the programmer's job/choice if they wanted to determine WHAT MOVEMENT (translating, rotating, scaling) was happening at the time. I'm sure DK would pass any info he had ABOUT the collision... WITH the event, if possible.

 

At least I THINK that's how it would work.

 

I like that idea, and thanks for bringing it to our attention, dk.  Just so we don't bog scenes for those who don't need those events firing.  Maybe the actionManager already has onIntersectionTrigger and we could propagate THAT trigger event.  *shrug*  Maybe not.  :)  Maybe we can do anything we want, cuz that's what is delicious about JS and open source.  :)

 

Thoughts, about any of this, anyone?  (thx)

Link to comment
Share on other sites

...we would no longer need move/scale/rotate "with collision" functions.  Instead, we just have... collisions.  Any intersect... fires an onCollision event, and then it would be the programmer's job/choice if they wanted to determine WHAT MOVEMENT (translating, rotating, scaling) was happening at the time.

 

You sound very much like someone who's about to implement 60% of a physics engine. ;) Detecting and handling collisions is, in my limited experience, more than half of the hard work a physics engine does. 

 

That is, moveWithCollisions is handy for mockups in that it solves a very common use case ("move a player around a static scene") in a minimal, quick-n-dirty way. But if you want something as robust as what you've described here (apply arbitrary transforms to arbitrary primitives and then detect all collisions throughout the scene), you might find that the amount of work and overhead are similar or greater to the work needed to use a physics engine, since you're tackling many of the same problems.

 

Not to say you shouldn't do it, of course - implementing physics/collision engines is fun! :D

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