Jump to content

More Precise Collisions


cefleet
 Share

Recommended Posts

Greetings all, 
First time poster long time lurker. My question is regarding collisions. I'm using:

mesh1.intersectsMesh(mesh2, true)

and: 

mesh1.checkCollision = true; 

However that is not precise enough because of the bounding blocks and the odd shape of the meshes. I would like to know if there is a way to calculate a mesh to mesh collision if the bounding block collision is detected? Or is there a better way to detect collisions? IE is there a callback on ellipsoidal collisions that can be used?
Essentially I am making the player loose a life on collision on a 3D side scrolling game.  I can make it "bounce off" the obstacle, using "checkCollision" but I can only get it to tell me something when I'm hitting it using "intersectMesh". So my "bouncing" and "hit" detection are different. I need them to be the same.
Thanks for any help in advanced. 

  

Link to comment
Share on other sites

Hello and welcome!

 

checkCollisions is for collisions and not for intersectsMesh. As you mentioned, intersectsMesh only uses bounding boxes for performance reasons.

 

The problem with mesh vs. mesh collisions is that you have to go through all triangles of both meshes which will kill your fps

 

But you can still use collisions engine here. You can define mesh.ellipsoid to get an impostor around your mesh and then use mesh.moveWithCollisions to check the mesh ellipsoid against all meshes which have checkCollisions = true.

 

To know if a collision occured, just register a function on mesh.onCollide.

Link to comment
Share on other sites

Ok the mesh.onCollide is what I was looking for. Thank you. I don't know how I missed that one. I marked it as solved. **Edit** maybe I spoke too soon.
I set this.

mesh.onCollide = function(){   console.log('I am colliding with something')}

but it never runs that function. Am I missing something?
**end of edit**

**Edit #2**. (I feel like a dork) 
This is fixed in 2.2 and I was on 2.1. It works exactly as I expected in 2.2.

**end of edit 2**
 

One follow up question however. By "imposter around your mesh" are you referring to just an ellipsoid that is adjusted using offset and scale? I can do that. However, is there a built in function to detect the size of an object and attempt to make the ellipsoid around it or does that need to be done manually?

Link to comment
Share on other sites

http://playground.babylonjs.com/#18U5SO#1

Cefleet, at least in THIS case, the .ellipsoid is already in place, automatically.  (in case you hadn't found that answer yet)  You might still need to size it, and offset it from dragging in the dirt.  Ground-dragging ellipsoids can cause constant collisions.  But worse than that, ellipsoid chafe, and unexpected collisions with pet excrement.  :o

And, welcome to the forum!  Tell us about your dreams and projects when you get a chance, C... we love show and tell.  

What Jamaican?   Err... I mean whacha makin'?  Anything demented? 

Aside to Iceman and DellaFree: You'd think... between Della's terrain-following skills, Ice's animating skills, and my bloviating skills, we'd have this darned rabbit hopping up and down the hills properly, by now, eh?  :)

Link to comment
Share on other sites

  • 4 weeks later...

Sorry for this late reply. @wingnut I'll make another post about what it is that I am working on in just a few minutes.

 

But back to this subject. I'm testing something but I need to know if I am doing something wrong or there is a bug or if I'm reading wrong but when I do :

 

mesh.onCollide = function(colMesh){   console.log('I am colliding with '+colMesh.id);}

it works until I am colliding with 2 objects. Then it only runs for the first mesh for every game tic. My test are basically this:

I have a ground mesh (not babylon.js ground just a generic ground) and a wall mesh. My character walks across the ground and it gives me the message "I am colliding with Ground" every game tick. However when I get to the wall, I can tell that I am colliding with the wall because my character is stopped, but it never says "I am colliding with Wall". It just always says "I am colliding with Ground". That is until I make my character jump then it will say "I am colliding with Wall" until I land back on the ground. 

 

Am I missing something or will "onCollide" be called just once per game tic?

Link to comment
Share on other sites

Hi again, Cefleet!  Thanks for the About Cefleet post... what a great cause your school is.  It's very cool that you are using BJS.  Excellent.

 

I have a few strange ideas for your "two-collisions at once" issue, but I am no expert in these things, and it would be good to have a playground demo to do some testings.

 

First, if you have have not played-with mesh.moveWithCollisions, (mentioned by Deltakosh) I'd say do that... and see if it can fix your unwanted ground collisions.  A forum search for "moveWithCollisions" will bring plenty of returns, too.  It is a heavily-used and often-talked-about function.  Maybe... with it... and some mesh.ellipsoidOffset(0, .01, 0) or similar... maybe something will work, there.

 

I think it is .applyGravity that keeps pushing your camera or character .ellipsoid (or bounding box) into a continuous ground collision.  But you need gravity ON... for jumps, right? 

 

Let's take a look at one of DellaFree's playgrounds where he used a ray to place a sphere at ground height continuously... http://www.babylonjs-playground.com/#1L0CBO#2

 

Line 125, in the render loop... he's got a little code that essentially makes the sphere be "terrain following".  The main thing... he uses the ray to test the ground height and thus the sphere does not need gravity testing.  If you were to adapt his "Am I on the ground?" testing... to YOUR issue, you might be able to turn-OFF gravity on the camera or mesh that you are moving.  Essentially, YOU would get to choose IF/NOT the mesh/cam .ellipsoid is rubbing on the ground.  Your ray-based "what altitude?" checker would also need to operate correctly when the player jumps-up onto the top of a mesh, too... and I think the ray system would work for that, too.

 

Let's pretend that the character or cam landed on the point of a up-pointing cone.  With gravity, it might slide down (because the collision ellipsoid is round).  With ray-testing, the char or cam would probably stay-atop and maybe be able to walk on the steep cone angles.  Fun with jumping.  :)

 

In most cases, jumps are a type of parabola trajectory.  http://www.babylonjs-playground.com/#25OQ8V#5  That is a non-physics-engine cannonball-firing demo kindly made for me by Jerome, but it doesn't work anymore.  Thread area is here.   All in all, there might be some parabola formula in the line 105 area that you can use for your jumping.  While a jump is in progress, you will need to keep firing your ray in the render loop, making sure that the jump stops when it hits the ground or lands upon something with a landing surface.

 

To be brief, once you have some other way of testing if you are "landed", then you no longer need to apply gravity to that character/cam, and maybe the .ellipsoid (or bounding box) won't drag on the ground anymore.  Then, you ONLY need to concern yourself with sideways collisions. The ray takes care of the walking surface.

 

You still have an issue of laterally colliding with two or more mesh at the same time, but at least the ground collision issue is out of the way.  I'm not an expert in any of these things, but these are some ideas that MIGHT be useful.  Hopefully, the experts will comment.  Party on!

Link to comment
Share on other sites

Thanks for the reply. I'm not sure I follow you, and maybe I didn't explain it well. I've always used mesh.moveWithCollisions, and my ellipsoid is how I want it to be.

The issue is that if I am on the ground the "onCollide" is never called for the other item that my character is running into. If checkCollision is set its stops the character from moving so I know it is colliding, but the onColIide is never called for that mesh until I am no longer touching the first mesh. I need the "onCollide" to be called on both items. I need to know if I am on the ground and if I am touching a wall, enemy, bullet, whatever.  My workaround is to use both "onCollide" and "intersectMesh" but it seems redundant and they are measuring different things.

Link to comment
Share on other sites

Hey Cefleet, you just need to check the parameter sent with onCollide which is...the other mesh collided :)

 

I'm not convinced that there is not something buggy here with the onCollide function. I've done all of the things you have all mentioned It just never works properly. I can observer that onCollide is called only on one of the two collisions that are happening. Also it seems it sometimes says it is colliding with the wrong mesh. IE If I am on top of the wall it says I am colliding with ground. But if I am colliding with nothing it correctly doesn't say I'm colliding with anything.

Link to comment
Share on other sites

Thank you for the help, but I'm sorry but I have only learned how to build a scene inside of blender and I don't even know where to start with the playground. I'm currently in a 7 day game jam so I don't have time to learn it right now.

However this is what I have been able to observer this morning. There are two issues I was describing appear to be the same issue. My ground is a single mesh. However it is hilly. If my character is inside of the bounding box of those hills (IE the vally) the onCollide will not fire on any item except for the ground mesh. Once I am at the top of the hill (out of the bounding box) onCollide appears to work as expected. IE I can collide with more than one thing, just as long as I am not inside the bounding box of another item. 

Link to comment
Share on other sites

Hi again C...  sorry to hear that you are having problems.  I'm just beginning to learn Blender and I haven't installed an exporter in mine, yet.  In your exporter, do you have a choice to Export Javascript file?  http://www.html5gamedevs.com/topic/14206-tower-of-babel-20-released/  ... see the picture.

 

If your Blender models are simple and untextured, (keep the height-mapped ground simple, too, if possible)... then would you please export your scene to JS?  (thx)  You can set 'Include initScene()' true, too. 

 

Then, if you could zip or not, and publish that somewhere, or attach it here so I can DL it, then maybe I can make a playground from it.  After that, maybe we can get everyone involved in some experiments.

 

When I first read your issue, I didn't know you had a heightMapped (bumpy) ground.  I think my solve is still appropriate, though.  You might need to turn-off ground collisions.  You would use ray-checking (like Della's terrain-following sphere) to keep your character at ground height.  It also can be used for jumping... because the ray will monitor the parabola of the jump... and even check for landing surfaces that are not the ground (jumping up onto a box, for example).

 

Once you are able to turn off ground collisions, then check your symptoms again.  The bumpy ground bounding box should not be an issue anymore, I would think (just like when you're on a mountain top - not inside the ground's b-box.)

 

By chance, are you hoping to have mesh slide/tumble up and down mountains and valleys?  Just curious.

 

How are you testing scenes?  Using a sceneLoader?  Babylon Sandbox?  (thx). 

 

I'm not very experienced in any of these things, but I want to keep your ball rolling (ar ar ar bumpy terrain humor).  So, if you can get a basic Blender scene in JS, and we can make it into a playground... we're going to learn more and see bugs easier.  You could be correct, there could be problems with the collision system.  It was recently tweaked for WebWorkers support, I believe.

 

But, if I understand what you are describing... I'd say this is normal behavior.  You have a continuous collision condition when you are inside a boundingBox of a mesh with collision checking TRUE.  I would expect that to cause all sorts of issues when trying to check collisions on ANOTHER mesh.  Since you never "clear" the collision condition for the ground, certain properties in the code are never reset... and therefore are not ready to check for more collisions (pure speculation, but certainly possible).  You never come out-of collision condition when you are in the valley (inside the bbox).

 

I am doing lots of speculating and theorizing here... most of which is probably wrong.  But, let's see if we can somehow get this issue into a playground where lots of eyes can see it.  Don't dread the playground.  It's weird at first, but it will become your best friend in no time.  Just try to cram mainline code into a function called createScene, push the CLEAR button on the playground, and paste your code in there.  Hit RUN... start experimenting, hit save as often as you like, and a new URL will be at the top of the playground after each SAVE.  Bookmark it, come back later and fight with it some more... save and bookmark again... watch your console, watch the playground error announcements, and kick royal butt.   Easy.  

 

But if/when you DO export to JS... you'll see that it produces a rather weird JS file layout.  I might be able to convert that weirdness into less-weird for ya, if needed.  Something more playground-ready.  :)  Party on!  Keep us posted.

Link to comment
Share on other sites

Hey Wingnut. (and others who have helped). I really really appreciate you all taking the time to work with me on this. I just wrapped up the gamedev competition so I will take some time in the next couple of days to look over some things. You can play the "electron/atom" downloadable version here.
 
https://github.com/aletheiagamestudio/Week-of-Awesome-2015/blob/master/toDieIsToGain.zip?raw=true

or I will post an website version next week some time.

 

However when I say I'm using my own exporter, I really just modified the one that comes with babylon.js that exports the babylon file to have some more data that is read when the mesh is loaded. (I extended the mesh loading in my engine to look for things like "Enemy","Obstacle", "Trigger", etc). So I don't know enough python or about blender gui making to make my own exporter export JS. But I'm guessing I should learn because that is GREAT idea. I never tried TOB but may look at it sometime. 

 

Anyway my final solution was to make many little invisible boxes that were ground and the single mesh that looked like the ground didn't have collisions. This was a scrolling platformer game so it wasn't as difficult as if the player could freely run around.

 

 

When I first read your issue, I didn't know you had a heightMapped (bumpy) ground.  I think my solve is still appropriate, though.  You might need to turn-off ground collisions.  You would use ray-checking (like Della's terrain-following sphere) to keep your character at ground height.  It also can be used for jumping... because the ray will monitor the parabola of the jump... and even check for landing surfaces that are not the ground (jumping up onto a box, for example).

 

Once you are able to turn off ground collisions, then check your symptoms again.  The bumpy ground bounding box should not be an issue anymore, I would think (just like when you're on a mountain top - not inside the ground's b-box.)

 

By chance, are you hoping to have mesh slide/tumble up and down mountains and valleys?  Just curious.

 

How are you testing scenes?  Using a sceneLoader?  Babylon Sandbox?  (thx). 

 

I'm not very experienced in any of these things, but I want to keep your ball rolling (ar ar ar bumpy terrain humor).  So, if you can get a basic Blender scene in JS, and we can make it into a playground... we're going to learn more and see bugs easier.  You could be correct, there could be problems with the collision system.  It was recently tweaked for WebWorkers support, I believe.

 

But, if I understand what you are describing... I'd say this is normal behavior.  You have a continuous collision condition when you are inside a boundingBox of a mesh with collision checking TRUE.  I would expect that to cause all sorts of issues when trying to check collisions on ANOTHER mesh.  Since you never "clear" the collision condition for the ground, certain properties in the code are never reset... and therefore are not ready to check for more collisions (pure speculation, but certainly possible).  You never come out-of collision condition when you are in the valley (inside the bbox).

 

 

  This is what is happening. I just thought that "intersectsMesh" was for bounding blocks and "OnCollide" was for something else. I'm not sure what exactly but the behavior is different depending on which of these I am using.

Link to comment
Share on other sites

  • 5 weeks later...

Ok so I'm very sorry for the delay. Life has been crazy, I went to DragonCon, my wife lost her job, my sub-renter is no longer going to rent from me and I started my student classes in the last couple of weeks.... but enough of my life details.

 

Here are the three playgrounds I created (I'm using console.log to output the issue If there is a better way let me know). I'm using oncollide to register a collision.

 

http://www.babylonjs-playground.com/#6XOBI#4

This one is colliding with ground and says that it is colliding with ground but never says it is colliding with the box1 even though you can see the box2 move from the collision.

 

http://www.babylonjs-playground.com/#6XOBI#5

This one does not have ground. So you can see it registers a collision as soon as it hits box1 as expected.

http://www.babylonjs-playground.com/#6XOBI#6

this one box2 collides with box1 and registers but as soon as it begins colliding with ground it stops registering collision with box1. 

 

The whole point is that it never registers a collision with two different meshes on the same frame.

Link to comment
Share on other sites

  • 2 weeks later...

Yep I understand now :) than you very much.

 

Unfortunately for performance reason, as long as the closest collision is detected, the system stops computing collisions and raise onCollide with the closest mesh. So I'm afraid that you cannot use this to achieve your goal (Or you will have to bend the collision system a little bit :))

Link to comment
Share on other sites

:)  Thanks dk! 

 

Yeah, cefleet... set the Y height of your collision ellipsoid... a bit smaller... so that the character-to-ground collision is NEVER happening.  This will cause your character or camera to sink into the ground... and start colliding again.  But use a SEPARATE ray to continuously check the ground distance and continuously set the char/cam y position... making it level with the ground again.  This way, your collision ellipse will never hit the ground.

 

DellaFree's terrain follower uses this method.

 

You still won't get multi-mesh intersect detection, but at least the ground won't be adding to your troubles.  *shrug*  AND, sorry to hear about your rough waters, C.  I hope it all improves soon.

Link to comment
Share on other sites

  • 1 year later...

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