Jump to content

Can't get Cannon.js to work in my Babylon.js scene


SuperPudding
 Share

Recommended Posts

Hello everyone,
I'm trying to implement the Cannon.js physics engine into a Babylon.js scene.
For some reason it's giving me weird problems:

If, for example, I try to create a "BABYLON.CannonJSPlugin" and then use "setTimeStep(number)" it throws an exception.
Another thing is that if I use "scene.enablePhysics(gravityVector, physicsPlugin)" and then "scene.getPhysicsEngine()" it returns null.

I use Babylon.js version 2.3 and I'm building the scene in Microsoft Visual Studio 2012.

Any ideas on what may cause those things?
Thanks in advance.

@RaananW I'm tagging you because you've helped me a lot in the past.

Link to comment
Share on other sites

@Deltakosh

I have "<script src="js/cannon.js"></script>" in my html page (and of course I have a reference to babylon itself, which works just fine).
I think that for some reason it doesn't recognize functions related to the physics engine or impostors.
In the playground all those functions work perfectly, so it's probably something with either the work environment or the version of babylon(?) but I have no idea what to change.

Link to comment
Share on other sites

@Deltakosh

This is the code in the head of the html page:
 

<head runat="server">
    <meta charset="utf-8"/>
    <title></title>
    <script src="js/babylon.2.2.js"></script>
    <script src="js/cannon.js"></script>
    <style>
        body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
        #renderCanvas {
            width: 60%;
            height: 60%;
        }
    </style>
</head>

("renderCanvas" is the id of the canvas I hasve in the body)

In the end of the body there is another "<script src=...>" that references to my main javascript file.
These are the first few lines from that file (the marked out one is where the exception is thrown):

/// <reference path="babylon.2.2.d.ts" />

//creating scene
var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, true);
var scene = new BABYLON.Scene(engine);
var g = new BABYLON.Vector3(0, 0, 0);
var dt = 0.01;
var physicsPlugin = new BABYLON.CannonJSPlugin();
physicsPlugin.setTimeStep(dt); // (exception)
scene.enablePhysics(g, physicsPlugin);

 

Edit: I just noticed that I use here babylon version 2.2 and above I said I use 2.3. That's because I changed between those a few times (some things didn't work well in 2.2 so I tried 2.3, but eventually I managed to solve those regardless of the version and I returned to 2.2)

Link to comment
Share on other sites

New Update: I tried babylon version 2.4 and it solved some of the problems, but not all.

the physicsEngine functions like "setTimeStep()" now work, but impostors functions like "setLinearVelocity(vector)" still throw exceptions.
I'll keep updating. If anyone has an idea what to do now I'll be very grateful.

Link to comment
Share on other sites

Hello SuperPudding,

Maybe the context is wrong when you call the functions? I think you have to publish more of your code. And as Deltakosh asked, what exception did you get?

I know your setTimeStep is working now, but to be correct, I assume the call has to be after the enablePhysics call. You can test it in the playgrounds (http://www.babylonjs-playground.com/#3YVZP).

 

Link to comment
Share on other sites

@Steffen

I actually checked it in the playground and it works both after and before "enablePhysics".

About the exception, I don't know that kind it was. All I know is that it stopped at this line.
I'm not really familiar with debugging in javascript and have never tried dealing with exceptions (I debug mostly using alerts).

About publishing the whole code, that may be problematic because most of it is irrelevant and some very chaotic. If I publish more I should probably make it more understandable before...

Another thing I found out is when I use "scene.enablePhysics" and then "scene.getPhysicsEngine()" it returns "undefined" (which is different, before I switched to 2.4 it returned null).

Link to comment
Share on other sites

Quote

I actually checked it in the playground and it works both after and before "enablePhysics".

With the playground example I posted? Is it some kind of browser-specific? Because if I run the example it only works if I call the setTimeStep function after enablePhysics.

To be sure that you have the right version of babylonjs and cannonjs, you can download the files used by the playground:

http://www.babylonjs.com/babylon.js

http://www.babylonjs.com/cannon.js

Maybe there are some other js-files conflicting? You can make a fresh clean sample and test it.

Link to comment
Share on other sites

@RaananW

I switched to 2.4 already.
The functions of the plugin itself seem to work but I get exceptions when I try calling functions of "BABYLON.PhysicsImpostor" (like setLinearVelocity) or when I try referencing impostors (for example "CannonJSPlugin.sleepBody(impostor)").

About the type of exceptions, I don't know how to check (never learned how to debug in javascript other than alerts).

Link to comment
Share on other sites

@Steffen

I haven't noticed the playground you posted.
When I said I checked and it worked I meant that I didn't get a run-time error (like it did do in my non-playground application before I used 2.4).

I looked at your playground and you are right, it needs to be set after I enable the physics.

Link to comment
Share on other sites

@RaananW

In the beginning of the javascript file I have this:

var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, true);
var scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color3(0.1, 0.1, 0.25);
var g = new BABYLON.Vector3(0, 0, 0);
var dt = 0.01;
var physicsPlugin = new BABYLON.CannonJSPlugin();
alert(physicsPlugin.isSupported());
alert(physicsPlugin);
scene.enablePhysics(g, physicsPlugin);
physicsPlugin.setTimeStep(dt);

The alerts are for debugging.
This goes without run-time errors.

Later on I create objects with user input. They are of type "Body" that I defined myself:

function Body(mesh, geometricCenter, mass, centerOfMass, velocity, angularVelocity, elasticity, inertiaTensor) {
    this.mesh = mesh;
    this.centerOfMass = BABYLON.Mesh.CreateBox(mesh.name + "CenterOfMass", 1, mesh.getScene());
    this.centerOfMass.visibility = 0;
    this.mesh.parent = this.centerOfMass;
    this.centerOfMass.translate(centerOfMass, 1, BABYLON.Space.WORLD);
    this.mesh.translate(geometricCenter.subtract(centerOfMass), 1, BABYLON.Space.WORLD);
    this.mass = mass;
    this.velocity = velocity;
    this.angularVelocity = angularVelocity;
    this.elasticity = elasticity;
    this.inertiaTensor = inertiaTensor;
    this.colliding = false;

    alert("impostor1")
    this.mesh.physicsImpostor = new BABYLON.PhysicsImpostor(this.mesh, BABYLON.PhysicsImpostor.MeshImpostor, { mass: this.mass, restitution: this.elasticity }, mesh.getScene());
    alert("impostor2");
    physicsPlugin.sleepBody(this.mesh.physicsImpostor);
    alert("impostor3");
}

Again, the alerts are for debugging, and "impostor3" never shows up...

 

Edit: If for some reson you can't see the end of the long line in the second snippet try highlighting it.
It says: this.mesh.physicsImpostor = new BABYLON.PhysicsImpostor(this.mesh, BABYLON.PhysicsImpostor.MeshImpostor, { mass: this.mass, restitution: this.elasticity }, mesh.getScene());

Link to comment
Share on other sites

@Steffen

I looked at the files you uploaded. My babylon.js file definintely has much less in it than the one here.
Maybe I have an outdated one? (I downloaded it about two months ago I think).

Edit: Checked again, when I open my file in Visual Studio it looks shorter but its layout is just different (it goes horizontally).
It isn't too short but it's different (I looked at the start and the end and there are some differences).

Link to comment
Share on other sites

hi SP - 

I think I wrote it again, but here again - you are not using the plugin directly at all. everything is being done using the physics impostor of a specific mesh or the physics engine class itself. 

Not isSupported (that is being executed automatically), not setTimeStep (that can be found in the physicsEngine of the scene), not sleep body or any other function.

But still - there must be an exception in the console, saying what went wrong. And you still didn't say what version of cannon you are using.

Link to comment
Share on other sites

@RaananW

I'm using the cannon.js file from the folder "preview release" that came with my download of babylon.js. My babylon.js file and babylon.d.ts file are also from there.

About interacting with the plugin... is there a difference between "physicsPlugin.setTimeStep()" and "scene.getPhysicsEngine().setTimeStep()"?
If not, then how am I supposed to set the time step and do similar stuff?

And again I don't really know how to get the type of exception but I'll try looking into it.

I think this might be a problem of outdated files, maybe when I downloaded babylon those functions were not yet integrated fully (you said yourself they are new in 2.4).
I'm going to try to download it again and see if it makes any difference.

Link to comment
Share on other sites

Yes, of course there is. Calling functions using the right initiator (the physics engine or the physics impostor) will guaranty that the framework will also take the changes into account.

In the case of setting the timestep it doesn't really matter, I must say. But in many other cases, you will always want to use the right call and not the physics plugin directly.

The right call is -  scene.getPhysicsEngine().setTimeStep(???) . This will make sure you have physics enabled.

Use the latest build, or build yourself and let us know.

 

Link to comment
Share on other sites

@RaananW

I downloaded the files from GitHub and used the ones in the "preview release" folder in dist.
I added "babylon.js", "babylon.d.ts" and "cannon.js" and it still has the same problems.
In my javascript file I have a reference to "babylon.d.ts" and in the html page I have sripts with "babylon.js" and "cannon.js".
Am I missing any files?

Another thing, I noticed that when I had the call "physicsPlugin.isSupported()" it worked fine, but now that I changed it to "scene.getPhysicsEngine().isSupported()" it crashed.
I checked and it returns 'undefined' although the call was after "scene,enablePhysics(g, physicsPlugin)".

I think I'm missing a reference to a file or something

Link to comment
Share on other sites

@RaananW @Steffen

Ok, I think I'm starting to somewhat understand what's going on.
I tried using the chrome inspector debugging like you guys suggested here.
I discovered that:

  • Some of the functions are missing (for instance the compiler is not aware of the function "scene.getPhysicsEngine().sleepBody(impostor)", but does recognize "impostor.sleep()").
  • Some objects and properties of objects are undefined (probably because of the missing functions).

I tried changing the "scene.getPhysicsEngine().sleepBody(impostor)" to "impostor.sleep()". The run-time error in this line did not happen this time, but there was an error later on in the babylon.js file itself.
The exception stated "cannot read property 'sleep' of udefined at t.sleepBody", which I suspect is again because of missing functions.

Another thing I noticed is that in my constructor (prototype function) "new Body(...)", when I highlight 'this' in the debugger it shows the properties of physicsPlugin, which is very very wrong and has no logical reason for happening.
Edit: Checked again, it works fine. It probably showed it since it was already in another function (where 'this' is physicsPlugin) and when I highligted 'this' it referred to the current 'this' in the other function...

Link to comment
Share on other sites

@RaananW @Steffen

Whenever I create an impostor it is supposed to automatically be added to the active physics engine. right?

this.mesh = mesh;
this.centerOfMass = BABYLON.Mesh.CreateBox(mesh.name + "CenterOfMass", 1, mesh.getScene());
this.centerOfMass.visibility = 0;
this.mesh.parent = this.centerOfMass;
this.centerOfMass.translate(centerOfMass, 1, BABYLON.Space.WORLD);
this.mesh.translate(geometricCenter.subtract(centerOfMass), 1, BABYLON.Space.WORLD);
this.mass = mass;
this.velocity = velocity;
this.angularVelocity = angularVelocity;
this.elasticity = elasticity;
this.inertiaTensor = inertiaTensor;
this.colliding = false;
alert("impostor1")
this.mesh.physicsImpostor = new BABYLON.PhysicsImpostor(this.mesh, BABYLON.PhysicsImpostor.MeshImpostor, { mass: this.mass, restitution: this.elasticity }, mesh.getScene());
alert("impostor2");
var b = this.mesh.physicsImpostor;
alert(b);
this.mesh.physicsImpostor.sleep();
alert("impostor3");

I tried pausing between the alerts "impostor2" and "impostor3" (after the impostor was created). I then checked the properties of the physics engine and its impostor array was empty (had length 0).

 

I feel like all these errors are caused by a single problem but I don't know what it is...

I really need to wrap this up today, this is the very last thing left to implement in my project and it's due Sunday (it's a school final project).

Link to comment
Share on other sites

@RaananW

In the folder with the files for babylon there are some files I have never used and I don't know what they're for:
babylon.core.js, babylon.max.js, babylon.noworker.js
and besides that basically everything outside of the 'dist' folder (do I need any files from 'src' for example?)

Can you tell me what their use is and if there's a possibility that my problems are arising from the fact they're not in my project?

Link to comment
Share on other sites

You only need the cannon.js and Babylon.js.

Warning: dangerous superficial knowledge - correct me if I'm wrong ;)

- Babylon.core: I would suggest, there is only core functionality
- Babylon.max: Babylon.js for debugging (code is readable, bigger size)
- Babylon.noworker: Babylon lib without using workers (threads in JavaScript)

You said your code works in the playground - did you try the linked cannon.js and Babylon.js?

On ‎27‎.‎05‎.‎2016 at 2:09 PM, SuperPudding said:

Some of the functions are missing (for instance the compiler is not aware of the function "scene.getPhysicsEngine().sleepBody(impostor)", but does recognize "impostor.sleep()").

It simply doesn't exist. You have to use

scene.getPhysicsEngine().getPhysicsPlugin().sleepBody(mesh.physicsImpostor);

// or

mesh.physicsImpostor.sleep();

In your pasted code, what is the result of the "alert(b)" ? It has to be [object Object] or so...

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