Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make sure Three.js is loaded before other files in Meteor?

I'm using Meteor 0.6.3 with Meteorite. I am trying to develop a game using Three.js that uses Meteor for multiplayer. Full code here. I have tried using the Atmosphere package here, but I get:

ReferenceError: THREE is not defined

My workaround has been to include Three.js in the header of my template file. This works when I don't call Three.js functions until client startup. I ran into issue when I tried to use a prototype to define my ally class. I had code like:

var Enemy = function() {
 this.mesh = new THREE.Mesh();
};

var Enemy = function(){};
Enemy.prototype = new Entity();

This gives an error that THREE is not defined, even though code works fine if written as:

var Entity = function() {
 this.mesh = new THREE.Mesh();
};

var Enemy = function() {
 this.mesh = new THREE.Mesh();
};

I would like to be able to use prototyping like this to manage several types of entities that will have the same basic interfaces. Here are some things I have also tried:

  1. Based on the documentation, I have tried placing a three.min.js in project/, project/client/, project/client/compatability/ and project/lib/. Each time it either says THREE is not defined or Meteor crashes.

  2. Defining these prototypes in the html file where we call Three.js.

To clarify my question, I'm wondering if anyone can suggest how to structure my files such that it will load Three.js then all of my type files then try to initiate the client in Meteor.startup(). Here is the current file structure:

project/model.js
project/server/server.js
project/client/game.css
project/client/game.html
project/client/game.js

Please let me know if there's any more information I should provide. I hope I'm not butchering any keywords too badly!

like image 533
maaachine Avatar asked May 28 '13 13:05

maaachine


4 Answers

Edit: In newer Versions of Meteor you can put three.js into client/compatibility. See þăדᴚῖↄқ's Answer.


Three.js does not attach itself to the global window object. Instead, it defines just a var THREE.

Meteor, on the other hand, creates a scope for every file loaded, so every var defined in this script is not global. That's why THREE is not globally visible.

Adding a window.THREE = THREE; at the end of the three.js source file solves this problem.

like image 190
macrozone Avatar answered Sep 27 '22 15:09

macrozone


Finally, in Meteor 1.3 and up, NPM modules are supported out-of-the-box. Adding Three.js is as simple as running

npm install three

in the root of your Meteor app, then in your code, in any file, just put this at the top:

import THREE from 'three'

and that's it!

Meteor 1.3 is in beta still, so to try it out you need to run

meteor update --release [email protected]

in your app.

like image 39
trusktr Avatar answered Sep 26 '22 15:09

trusktr


In Meteor, scripts placed in the /lib directory load before everything else. I'd recommend grabbing the latest version of Three.js from https://github.com/mrdoob/three.js/zipball/master and dropping it in there.

like image 21
rpowell Avatar answered Sep 28 '22 15:09

rpowell


Don't put THREE.js into lib. Put it in client/compatibility.

From the docs:

Some JavaScript libraries only work when placed in the client/compatibility subdirectory. Files in this directory are executed without being wrapped in a new variable scope. This means that each top-level var defines a global variable. In addition, these files are executed before other client-side JavaScript files.

Your problem, as stated in other answers, is that defining a variable with var creates a variable local to the module's scope and not the whole project. I didn't need to include window.THREE = THREE;

like image 33
circuitBurn Avatar answered Sep 29 '22 15:09

circuitBurn