Mix modules and global definitions

Hi,

Is it in theory possible to mix modules and global THREEJS definitions?

I have a JS library using THREEJS modules compiled with browserify but when I try to use it in a “regular” THREEJS app, it just makes weird things (meshes randomly show up, etc.).
I can go in more details later if needed -

Related SO: https://stackoverflow.com/questions/46051442/mix-modules-and-global-definitions-in-three-js

It seems that the problem is that it doesn’t share the same Object3D base - any good workaround for that?

Yes, if you could create your own class that includes both of these, and then combine property changes, then you should be able to produce a minute version of an engine that combines the two.

Hope I was helpful :smiley:

Can you please elaborate on “combine property changes”?

Basically I want to share the relevant part of THREEJS between:

const globalThree = window.THREE;  
const three = require('three'); // or import
// AMI uses threejs internally
const ami = require('ami.js');  //or import

How does ami include three? If it just uses window.THREE, then you should be able to overwrite that before loading ami.

Right now it is a bad approach:
1- use the npm package to use things such as “Vectors” and “Matrices” (https://github.com/FNNDSC/ami/blob/dev/src/core/core.utils.js#L4)
2- use global THREEJS for Object3D etc. (whatever generates IDs) (https://github.com/FNNDSC/ami/blob/dev/src/helpers/helpers.slice.js#L15)

Really looking forward to clean this mess :slight_smile:

I’m not sure including just parts of three.js in an application that may be used alongside a full three.js app is a good approach. You would be better to just do import * as THREE from 'three' everywhere that you are using anything from the library - your bundler should then make sure that everything is using the same reference to the THREE global.

However, brainstorming a bit, you could do something like this - in AMI, create a file called Three.custom.js. I’m not sure the exact syntax without testing it, but this might work:

export { Vector2, Vector3, OtherComponents...} from 'three';

Then in AMI to import do:

import * as THREECUSTOM from './three.custom.js';

if ( !window.THREE ) { 
 // use THREECUSTOM 
} else { 
 // use global THREE
}

…and make sure that you are importing three.js as a global variable before AMI.

Alternately,you could be using conditional imports here -if you are using babel to compile there’s a plugin that allows this, although I haven’t personally tested it.

Basically, you would set up your three.custom.jsas above, then in AMI do:

if( needWholeLibrary ) {
 
   import * as THREE from 'three';

} else {

   import * as THREE from './three.custom.js'

}