Jump to content

How to go about collisions in Babylon


SuperPudding
 Share

Recommended Posts

Hello to everyone,

I'm new to web developing and to babylon js. I'm building a web application for simulating simple physical systems as a high school computer science project.
Right now I'm struggling with collisions. I know what calculations to do when two meshes collide assuming I know the collision point, but I couldn't find a way to get that.
I'm trying to create my own physics so preferably this would be done without an external physics engine. All I need is to know when and where meshes intersect.

I also have an idea but I could not make it work. Perhaps someone here can help with this.
I thought to check for intersection using mesh.IntersectsMesh(otherMesh) and then dividing the meshes into sub-meshes. I can than check intersection between sub-meshes. By dividing the meshes into smaller and smaller sub-meshes I can get the point of intersection (for the desired accuracy) if I know which sub-meshes intersect and which do not.
My problem is that I can't find a way to check intersection between sub-meshes, as they do not behave exactly like normal, independent meshes.

If anyone has a way to help with that, or alternatively another way to go about it, I would be very thankful.
Thanks in advance

Link to comment
Share on other sites

Hi SuperPudding,

interesting moniker :)

Have you checked the collision demo on the playground? might provide you with some insight as to how to use collisions in babylon.

You can also search for information about intersections here - http://doc.babylonjs.com/tutorials/Intersect_Collisions_-_mesh and here - http://doc.babylonjs.com/tutorials/Cameras,_Mesh_Collisions_and_Gravity

Link to comment
Share on other sites

Thanks for your answers. Unfortunately it still wasn't what I was looking for.

eboo, the post you sent me to was about not being able to detect a collision. I actually can detect collisions, I'm looking for a way to get the point of contact.

RaananW, I checked those tutorials out already. They are not very clear as to how all the methods work and how to use them.

 

I'll try to explain exactly what I'm looking for:
As I uderstand there are two ways to go about collisions natively. Either using the "scene.collisionsEnabled = true" and then "mesh.checkCollisions = true" for meshes, or using "mesh.intersectrsMesh()".
The first method doesn't work for me. It stops only the camera from intersecting a mesh but it does nothing for mesh to mesh collisions for some reason. The second method works but it isn't very accurate and it doesn't give me information about the contact point, only a boolean about whether or not the collision takes place.

My idea was to devide colliding meshes into sub-meshes and checking intersection between them. If the sub-meshes are small I can approximately know the region in which the point of contact is by knowing which sub-meshes intersect.
The problem with that is that I don't know how to check for intersection between sub-meshes, only between regular meshes, and that I don't know how to get the position of a sub-mesh.

Does anybody know of a way to do that?

 

By the way, I've found a mesh property called "onCollide" but I can't get it to work. can someone please explain what it is and how to use it? Can it help me with my problem?

Link to comment
Share on other sites

  • 1 month later...

@RaananW @eboo

Hello again, I've left this problem aside for a while but it's time I found a solution.
I can't get my head around the implementation of collision response in babylon. Most tutorials aren't very clear and everything I have tried so far hasn't worked like I meant it to.

I really need someone to explain this to me, and possibly point me to a working playground.
Just to be clear I'm trying to program mesh-mesh collisions, not camera-mesh.

What I really want to do is find an impulse based model. I found a page on Wikipedia called "collision response" that explained it really well:
 

j_r = \frac { -(1+e) \mathbf{v}_r \cdot \mathbf{\hat{n}} } { {m_1}^{-1} + {m_2}^{-1} + ({\mathbf{I}_1}^{-1} (\mathbf{r}_1 \times \mathbf{\hat{n}} ) \times \mathbf{r}_1 + {\mathbf{I}_2}^{-1} (\mathbf{r}_2 \times \mathbf{\hat{n}} ) \times \mathbf{r}_2) \cdot \mathbf{\hat{n}} }


I have most of the variables here, what I really need is a way to know when two meshes collide, and to get their point of contact.

 

I'm willing to take any other suggestion, this way might not even be doable.
I tried a lot and nothing worked so far (for example I tried using the "onCollide" callback and it didn't fire at all).
Anyone with a working playground?

Link to comment
Share on other sites

Instead of implementing complicated mathematical collision systems, why not give a physics engine a try? They actually have impulse-based colliders.

In this case you will need to disable the internal collision system, and enable one of the physics engines integrated in babylon.js. Read the getting started tutorial, see if it fits your needs - http://doc.babylonjs.com/overviews/Using_The_Physics_Engine

Link to comment
Share on other sites

@RaananW

The project I'm trying to build is a simulator for simple physical phenomena. I want it to be as mathematically accurate as possible, that's why my first choise was this model.

Anyway, I've looked at the tutorial for the physics engine and it looks great, I just have a few questions:
1. Is there a way to enable only the collision response? (I already have everything else working and having to switch to the engine would require quite a lot of work)
2. Can I only get the new velocities after a collision and assign them myself instead of the engine doing it automatically? (Again, I have many working property updates done using timers and registerBeforeRender and I'm afraid of changing too much.)
3. Can I set the center of mass of an object manually? Is there a way to move it from it's geometric center?

My main problem with an external engine is that it does "too much" of the work for me. It's a great thing but I already have kind of a physics engine I created myself (which was part of the goal of my project), and messing with that now that I'm close to finishing could take a lot of work.

If it were possible to do the things I asked about it would be an easy solution for me.
Thanks in advance

Link to comment
Share on other sites

 

I feel like this is too complicated. I've been trying things in the playground for hours.
All I really need is collision detection, not even the response.
I want to know when and where meshes intersect. Cannon.js is definitely capable of providing this information but I don't know how to get it specifically.

One of my problems is that the engine assumes the center of mass of the body is the same as mesh.position, which is not always true in my project.
Another one is that it assumes there is air resistance (it slows down objects without them colliding with anything).

I'm not even sure it's worth integrating a physics engine just for collision detection.
I am really looking for a way to do that manually but after weeks of searching I still haven't found how.

By the way I'm sorry if I'm bothering you @RaananW but you have been great help before and I'm really short on time with those collisions.

Link to comment
Share on other sites

Hi, I'll be on my desktop in a few hours only, but a few points, as always :)

the physics engine actually has no air resistance. A new velocity is calculated only when bodies collide. You can fake air resistance, but it's off per default as far as I remember.

Physics engines are able to provide you with all of the things you needed and more. To do that you will have to interface directly with the physics engine, as this is not the scope of the Babylon plugin system.

I'm not sure what you mean with collision only. You don't want the body to change velocities? Just detect collisions? Cannon collision groups might be helpful, but I'm not really sure as I have never tested.......

if you need collision only, constantly check for intersection using the mesh.intersects function. Would that be enough? This way you have no external system disturbing your calculations.

Link to comment
Share on other sites

@RaananW

When I say I want detection only I mean that I want to set the new velocities myself. This is because I already have a lot of physics that I created manually (again, I know it's probably not as good as an external engine but the whole point of my project was to create the physics myself).

The use of a physics engine for that seems complicated to me because it's doing a lot of things automatically and those things interfere with the physics I already have.

The Idea of checking for intersection without an external engine is what I wanted to do from the beginning, it's simpler.
My problem with this method is that I don't know how to get the point of intersection (not just a boolean about the intersection happening but also where it's happening).
I actually wrote about this in earlier comments on this topic.
If it's not possible to get it directly I've had an idea about dividing meshes into submeshes and intersecting them but I don't know if that is possible as well.

Another reason I looked into submeshes is to make the detection more accurate (if I check intersection for a whole mesh I get a bounding box that is usually very inaccurate).

In the end my problems are from lack of experience and knowledge about Babylon. In many cases I just don't know if what I want to do is possible and where to find it.

 

 

Unrelated to the rest: If there is not supposed to be air resistance defaultly in Cannon.js then there seem to be a problem, because it lowers the speed of bodies slowly as they move even when they don't collide with anything (I put an alert of the velocity inside the registerBeforeRender() function to check that).

Link to comment
Share on other sites

@RaananW

I feel like my previous comment was a bit messy so I'll dedicate this one to my problems, without rambling about the rest:

  1. I need to know when a collision happens, and that is solved with "mesh.intersectsMesh()", but quite inaccurately.
  2. I need to know where a collision happens (a vector3). I still wasn't able to solve this and that is my main problem.


An idea I had for making checking intersections more accurately and for finding an approximate intersection point is using submeshes.
My idea for an algorithm was:

  • Checking intersection between two meshes.
  • If they intersect, deviding each mesh into 2 submeshes and checking which half of the first mesh intersect which half of the second mesh.
  • If any submeshes intersect, deviding those submeshes further and checking intersection again.
  • This is to be repeated until the desired accuracy has been achived.

This method will create smaller and smaller bounding boxes, which will create a more accurate detection.
Another thing it will do is narrow down the volume in which the intersection point can be (in the desired level of accuracy I can just take the position of the submesh as the point of intersection).

I just don't know if it's possible to access the properties of submeshes like you would for normal meshes, and if it is I don't know how to do it.

Of course, I'm open for other ideas for how to do this, but I would really like some feedback about this one (no one commented about it when I mentioned it previously).

Link to comment
Share on other sites

  • 4 weeks later...

If anyone is looking at this for help, I haven't managed to pull this off.
I've built an algorithm for approximately finding the point of intersection of two meshes (using my submesh idea), and for calculationg the impulse acting on them, but no matter what I've tried the approximations have never been good enough, it still looks strange.

Inspite of that I do have a solution that mostly lets me keep my own physiscs engine:
I check in each frame if the meshes are colliding using "mesh.intersectsMesh(otherMesh)", if they do, I disable my local physics and enable Cannon.js for these particular meshses.
After they seperate I perform the reverse procedure.

Anyway, I consider this topic closed.
Thanks for everyone that helped me, especially @RaananW, I trully appreciate it.

Link to comment
Share on other sites

  • 10 months later...

@MackeyK24 to delete the mesh I use this 

this.manager.safeDestroy(this.mesh);
 
but how to apply it to the collision system if I want to make the function safeDestroy () execute in the call back or what actions should I use?
 
   public start(): void {
            
            // The trigger is OnIntersectionEnterTrigger
            this.mesh.actionManager =  new BABYLON.ActionManager(this.scene);
            var sphere = this.scene.getMeshByName('sphere');
            var triggerOptions = { trigger: BABYLON.ActionManager.OnIntersectionEnterTrigger, parameter:sphere};
            
            var action = new BABYLON.SetValueAction(triggerOptions, this.manager, 'safeDestroy',this.mesh);
            this.mesh.actionManager.registerAction(action);                     
        }


// or maybe this will do it

 export class ExecuteCodeAction extends Action {
        constructor(triggerOptions: any, public func: (evt: ActionEvent) => void, condition?: Condition) {
            super(triggerOptions, condition);
        }

        public execute(evt: ActionEvent): void {
            this.func(evt);
        }
    }
Link to comment
Share on other sites

On 3/31/2017 at 6:02 AM, MrVR said:

@MackeyK24 to delete the mesh I use this 

this.manager.safeDestroy(this.mesh);
 
but how to apply it to the collision system if I want to make the function safeDestroy () execute in the call back or what actions should I use?
 

   public start(): void {
            
            // The trigger is OnIntersectionEnterTrigger
            this.mesh.actionManager =  new BABYLON.ActionManager(this.scene);
            var sphere = this.scene.getMeshByName('sphere');
            var triggerOptions = { trigger: BABYLON.ActionManager.OnIntersectionEnterTrigger, parameter:sphere};
            
            var action = new BABYLON.SetValueAction(triggerOptions, this.manager, 'safeDestroy',this.mesh);
            this.mesh.actionManager.registerAction(action);                     
        }


// or maybe this will do it

 export class ExecuteCodeAction extends Action {
        constructor(triggerOptions: any, public func: (evt: ActionEvent) => void, condition?: Condition) {
            super(triggerOptions, condition);
        }

        public execute(evt: ActionEvent): void {
            this.func(evt);
        }
    }

 

There is already a API in the scene Manager to handle intersections : this.setIntersectionMeshes then can use this.OnIntersectionEnter and this.OnIntersectionStay and this.OnIntersectionExit...

I will list some of Space Shoot example script that show the usage in more detail.

 

Link to comment
Share on other sites

Yo @MrVR ... Take a look:

/* Babylon Mesh Component Template */
/* <reference path="{*path*}/Assets/Babylon/Library/babylon.d.ts" /> */

module PROJECT {
    export class AsteroidController extends BABYLON.MeshComponent {

        private asteroidName:string;
        private asteroidInstance:BABYLON.InstancedMesh;

        public start() :void {
            // Detail Mesh Instance
            this.asteroidInstance = SceneController.MasterAsteroid.createInstance(SceneController.MasterAsteroid.name + "." + this.mesh.name);
            this.asteroidInstance.position = BABYLON.Vector3.Zero();
            this.asteroidInstance.parent = this.mesh;

            // Boundry Exit            
            this.asteroidName = this.mesh.name;
            this.setIntersectionMeshes([SceneController.ShotBoundry]);
            this.onIntersectionExit = (collider:BABYLON.AbstractMesh) => {
                if (this.mesh != null && collider.name === "Boundry") {
                    //console.log("===> Asteroid Exiting Boundry: " + this.asteroidName);
                    this.manager.safeDestroy(this.mesh);
                }
            };
           
            // Asteroid movement
            if (this.mesh.physicsImpostor != null) {
                var speed:number = this.getProperty("moveSpeed", -1);
                var tumble:number = this.getProperty("tumbleRate", 1);
                this.mesh.physicsImpostor.setLinearVelocity(new BABYLON.Vector3(0, 0, (1 * speed)));
                this.mesh.physicsImpostor.setAngularVelocity(new BABYLON.Vector3(this.manager.randomNumber(0, 1) * tumble, this.manager.randomNumber(0, 1) * tumble, this.manager.randomNumber(0, 1) * tumble));
            }
        }

        public destroy():void {
            if (this.asteroidInstance != null){
                this.asteroidInstance.dispose();
                this.asteroidInstance = null;
            }
            //console.log("===> Destroyed asteroid: " + this.asteroidName);
        }
    }
}

 

Note this part:

 

          this.setIntersectionMeshes([SceneController.ShotBoundry]);
            this.onIntersectionExit = (collider:BABYLON.AbstractMesh) => {
                if (this.mesh != null && collider.name === "Boundry") {
                    //console.log("===> Asteroid Exiting Boundry: " + this.asteroidName);
                    this.manager.safeDestroy(this.mesh);
                }
            };

 

Easy Peezy :)

 

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