Magento 2.x and Babylon 3+ problem

I used to have Babylon ver2.5 working perfectly well with Magento 2.1. Here is a sample of the commands I used to initialise Babylon

require([‘jquery’,‘handjs’,‘cannon’,‘babylon’, ‘Emthemes_FlyingEffectCart/js/catalog-add-to-cart’],function(){ runBabylon();
});

var runBabylon = function($)
{ // some PHP code
var canvas = document.getElementById(“renderCanvas”);
var engine = new BABYLON.Engine(canvas, true);
//rest of code
}
After installing Babylon 3.3 I get the error
ReferenceError: BABYLON is not defined
I am perfectly sure there is not problem on the Magento side. I suspect the problem lies with universalModuleDefinition but I might be wrong. I also suspect Typescript compilation of Babylon.
I remember in the good old days with plain JS Babylon was initialized using
var BABYLON;
(function (BABYLON) { …}
Has anybody used the latest version with Magento?
BTW there seems to be a problem downloading Babylon from github (either zip or using Smartgit)

Hey Jacob, wanna try Babylon.js v4.0? we have this doc for all module related questions:
https://doc.babylonjs.com/features/es6_support

Same issue with v4.0 @Delkatosh. The issue seems to be related to conflict between requirejs & Webpack bundling. Can I find babylon.js core (and Cannon) in raw JS without Webpack anywhere?

Well we compile raw JS from TS using TS + webpack but babylon.js on our preview CDN should work directly

pinging @sebavan as he may have more ideas regarding this conflict

Babylon is a UMD module so it is compatible with require but I guess the require dependency should be named as you can see on this thread :

OK, I moved one step forward. Using BJS 3.3 from CDN I traced that the code is entering
else if(typeof define === ‘function’ && define.amd) {…}

If I replace
define(“babylonjs”, amdDependencies, factory)
with
root[“BABYLON”] = factory(CANNON,OIMO,earcut);
BABYLON initializes successfully but doesn’t load eg: Cannon

So how can I return root[“BABYLON”] and it’s amdDependencies ?

@sebavan @Delkatosh

You should try with 4.0 as he header is now a proper Webpack one and 3.3 is known to have such kind of issues.

About the dependencies, you can inject them when needed, they have been removed from the dependency list to better decoupled the frameworks.

And if you do not rely on physics for instance you won t need oimo and even if you do, you would not need both OIMO and Cannon.

So to load them, either you would need to require them in a global name or you could pass them to the physicsEngine when you create the plugin in the constructor.

With version 4, I still need to return root[“BABYLON”] in define.amd

else if(typeof define === ‘function’ && define.amd)
//define(“babylonjs”, [], factory);
root[“BABYLON”] = factory();

But Cannon loads well. So I guess I need to minify Babylon with this change.
BTW has cannon Physics code been incorporated AS IS from www.cannonjs.org or has it been modified by the BABYLON team?

I do not understand why you need this change,

Could you try instead of require([‘jquery’,‘handjs’,‘cannon’,‘babylon’, ‘Emthemes_FlyingEffectCart/js/catalog-add-to-cart’],function(){ runBabylon();
});

to use require([‘jquery’,‘handjs’,‘cannon’,‘babylon’, ‘Emthemes_FlyingEffectCart/js/catalog-add-to-cart’],function($, hands, CANNON, BABYLON) { runBabylon(BABYLON);
});

basically the function should see the required amd modules in arguments ?

Thanks for the continued help. I tried what you recommended (a million times ). I get the following error
BABYLON.Engine is not a constructor

Here is my requirejs-config.js if it can be of any help
var config = {
map: {
‘*’: {
“handjs”: “Emthemes_Ardzan/js/hand.min.1.3.8”,
“cannon”: “Emthemes_Ardzan/js/cannon”,
“babylon”: “Emthemes_Ardzan/js/babylon”
}
}
};

According to this post define in the AMD declaration is causing a conflict

I guess it is because you use babylon instead of babylonjs in your require dependencies.

As you can try with this sample, it all works as expected:

function runBabylon(OIMO, BABYLON) {
    // Get the canvas
    const canvas = document.getElementById("renderCanvas");

    // This creates a basic Babylon Engine
    var engine = new BABYLON.Engine(canvas);

    // This creates a basic Babylon Scene object (non-mesh)
    var scene = new BABYLON.Scene(engine);

    // This creates and positions a free camera (non-mesh)
    var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);

    // This targets the camera to scene origin
    camera.setTarget(BABYLON.Vector3.Zero());

    // This attaches the camera to the canvas
    camera.attachControl(canvas, true);

    // This creates a light, aiming 0,1,0 - to the sky (non-mesh)
    var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);

    // Default intensity is 1. Let's dim the light a small amount
    light.intensity = 0.7;

    // Our built-in 'sphere' shape. Params: name, subdivs, size, scene
    var sphere = BABYLON.Mesh.CreateSphere("sphere1", 16, 2, scene);

    // Move the sphere upward 1/2 its height
    sphere.position.y = 2;

    // Our built-in 'ground' shape. Params: name, width, depth, subdivs, scene
    var ground = BABYLON.Mesh.CreateGround("ground1", 6, 6, 2, scene);

    scene.enablePhysics(new BABYLON.Vector3(0, -9, 0), new BABYLON.OimoJSPlugin(undefined, OIMO));

    sphere.physicsImpostor = new BABYLON.PhysicsImpostor(sphere, BABYLON.PhysicsImpostor.SphereImpostor, { mass: 1, restitution: 0.9 }, scene);
    ground.physicsImpostor = new BABYLON.PhysicsImpostor(ground, BABYLON.PhysicsImpostor.BoxImpostor, { mass: 0, restitution: 0.9 }, scene);

    engine.runRenderLoop(() => {
        scene.render();
    });
}

//The requirejs config
requirejs.config({
    baseUrl: '.',
    paths: {
        babylonjs: 'https://preview.babylonjs.com/babylon.max',
        oimo: 'https://preview.babylonjs.com/oimo',
        pep: 'https://code.jquery.com/pep/0.4.3/pep'
    },
    shim : {
        babylonjs: {deps: ['pep']}
    }
});

require(['pep', 'oimo', 'babylonjs'], function(_, OIMO, BABYLON) { 
    runBabylon(OIMO, BABYLON); 
});

replacing babylonjs by babylon fails cause using the defined name is important here.

I have tried that as well. In Magento but to no avaiL. “babylonjs” is just a naming convention. Your reqirejs.config is not applicable in Magento as it gives security errors. Thirdly, in Magento we don’t need to pass anything in function function(_, OIMO, BABYLON) {
but only ($) for jquery.

Anyhow, I removed ‘babylonjs’ in define(“babylonjs”, [], factory) and it’s working PERFECT.

2 Likes