Prevent collision between 2 meshes

In this example Babylon.js Playground, how can I stop the box colliding with the tube?

If I am moving the box from top to bottom and the tube is in the way, the box should stop and not be able to move over.

I was reading Cameras, Mesh Collisions and Gravity - Babylon.js Documentation but I am having trouble implementing this.

I dont understand how the ellipsoid vectors work. Is this the problem?

Or is the approach I should take different?

Hi constantinos,

When I first read your question, I though you were asking how to prevent collision between two colliding meshes; if that is your question, I think collisionMask is probably the best way to do that.

However, rereading your question, it sounds like what you’re asking is how to stop moving as a result of collision, not how to stop collision. That’s a little more of an involved problem, but essentially you’ll need to account for collisions in your own movement code. In your current playground on line 47, you directly set the box’s position without checking for collision, so the box just goes where you told it to go regardless of what it runs into on the way. Essentially, a collision system by itself can tell you when a collision happens, but it won’t tell you what to do because of that.

It works more easily with the cameras—as shown in the documentation page you linked—because the camera comes ready-made with logic for what to do based on collisions, gravity, and the like. The implementation for that is here (and in the surrounding methods); in case you’re trying to do something similar, hopefully that can provide a good example.

1 Like

Hi guys! Babylon.js Playground

That’s a little box-dragging demo using moveWithCollisions at line 173… as the mover.

Although we cannot see the invisible ellipsoids, try dragging a box in a way that makes it go corner-to-corner with another box. You can see that they DO overlap a tiny bit… due to round-shaped collision ellipsoids.

Also notice this does not use the fancy new “dragBehavior” (drag center sphere)… but instead, it uses older DOM event listeners, and a utility func called getGroundPosition at line 65.

getGroundPosition has one little flaw. The ground plane MUST be “behind” any click-on-box point, or the drag will fail. Example: Click on TOP of red box, where there is no ground behind the box. No drag. There MUST BE ground behind the click-point… to get the box to drag.

I suppose the BEST thing… would be to attempt a dragBehavior modification/option… that uses a .moveWithCollisions() for its mesh-mover. Let’s listen for more thoughts on that, and maybe some tests. Be prepared for slow weekend forum… though. It’s going to take some substantial hacking on the dragBehavior device… to make it use moveWithCollisions(), IF it can be done at all.

.moveWithColisions does not use a POSITION to move-to. I think it uses a direction and magnitude… making it plenty challenging to deal-with. onPointerMove runs very fast when moving mouse, and line 171 is always calculating a diff BY SUBTRACTING two positions, and THAT means diff is a direction with magnitude (an arrow, with magnitude = arrow length) :wink:

So, moveWithCollisions does VERY fast TINY moves in a direction… and NOT tiny steps to a preset/future position. To sum, I don’t know how well a “hacked” dragBehavior… will enjoy that. heh.

If we ONLY had an actionManager.intersectEnterTrigger([a list of mesh]) with a executeCodeAction that does { get me out of intersect state in the same direction you entered-it from }. Currently, actionManagers only intersect-test with ONE other mesh that you must specify when registering the trigger. There is no such trigger as onIntersectEnter(any scene mesh except ground).

And, there’s problems with the “reverse that last drag move” (reject the overlap)… involving mouse move-speed at time of impact, and how deep into overlapping… we ARE… at time of onIntersectEnter. Could be trouble. DragBehavior might need to “remember” its trail. To de-overlap, maybe it goes backwards down “memory lane”… until onIntersectExit triggers, and then hang-out there. :slight_smile:

AND, we might be overlapping 10-20 mesh all at the same time! OMG. Gotta back-out until ALL of them… exit intersect with dragged mesh. erf.

Not only do we need to reject the dragged mesh from overlapping any mesh in the list, but we also have to stop the pointer from continued dragging, and send IT back to where it was located… just before the intersect happened (so pointer stays-with overlap-rejected dragged-mesh).

We just aren’t there, yet. We just don’t have an easy add-on for dragBehavior… that refuses to allow mesh overlap with ANY mesh in a list of mesh. (Though I need to study dragBehavior more… learn its capabilities.)

In many scenes, the list could be ALL mesh except ground… which could mean LOTS of intersect testing on MANY scene mesh. That’s a BJS dragBehavior performance killer, and DOM onPointerMove perf killer, too. hmm.

Not very good news, eh Constantinos? Sorry. I dunno if webWorkers or SIMD (reduced instruction set/risc) would help us with those intense scene-wide collision/overlap testings… I doubt it. (Wingy scratches his beard in pondering.) Stay tuned for more/better comments.

Don’t apply the position directly, as this way, you’ll bypass any collision detection. Use a direction vector and moveWithCollision.
Using a tube doesn’t seem to work. No idea why, as I haven’t really used moveWithCollision.

https://www.babylonjs-playground.com/#JDXFPE#1

Thanks for your replies guys. Let me clarify!

What I want to achieve is very similar to this Babylon.js Playground from this thread PointerDragBehavior with collision (pinging @timetocode @trevordev)

The difference is that I don’t want to drag the mesh, I want the mesh to follow the mouse, unless it hits another mesh. If the mesh hits a wall, then it should be able to wall slide like the example above.

Instead of using

scene.onPointerMove

I am now using

scene.onPointerObservable.add((pointerInfo)

Example: https://www.babylonjs-playground.com/#JDXFPE#2

My problem now, is that I dont know what delta is (?). Can I get it from pointerInfo?

sphere.position.x -= event.delta.x

Also, now that I am using onPointerObservable, is there a better way to get the mousePointer location instead of using scene.pick(scene.pointerX, scene.pointerY) ?

In conclusion, I will have a bunch of tubes on the ground and I want to make sure that the box does NOT go through them.

I hope this makes things clearer.

So, a quick question - what is the delta, and why do you need it? Delta from the old poisiton to the new one? simply cache it and subtract, but I am not sure why you need it?

Sorry I am a beginner so I couldn’t understand how that playground with delta works. I don’t know if you need delta and I was asking what is it. Actually I am a bit confused right now.

I am just asking what is the right approach to take based on what I have.

There seems to be many ways to do things but some ways are not compatible with others…

There are always a million ways to do one thing. sometimes is is very clear what the right way is, but usually it depends on the developer and on the specific use case. in the case of an object following the mouse (like the plyground) you dont need a delta (which is the change between current and last value), since you always set the position to be the current mouse position (current collision between mouse and scene, to be exact).

You can use another event - on collision (or on mesh intersects), and stop following the mouse in cas the object intersects with the target mesh. so, technically, you check if the mouse “collides” with this object (the wall), and dont update the position of the followed mesh, if it does. Does that make sense? or did I make things complicated?

1 Like