Uncaught ReferenceError: $hxClasses is not defined in Haxe js project - javascript

I am having an issue that I discussed on the Haxe IRC channel but was unable to come up with a fix. It seems to be a bug with the compiler.
Here is the Haxe code:
package;
import js.Lib;
import js.three.Three;
import haxe.Timer;
class Main {
public var timer:Timer;
public var renderer:WebGLRenderer;
public var scene:Scene;
public var camera:PerspectiveCamera;
public function new() {
timer = new Timer(30);
var w = Lib.window.innerWidth;
var h = Lib.window.innerHeight;
scene = new Scene();
// create a red cube
var material = new MeshLambertMaterial({color:0xff0000});
var geometry = new CubeGeometry(50, 50, 50, 1, 1, 1, material, null);
var cube = new Mesh(geometry, new MeshFaceMaterial());
cube.position.set(0, 100, 0);
scene.add(cube);
// add some light
var pointLight = new PointLight(0xffffff, 1, 0);
pointLight.position.set(10, 50, 130);
scene.add(pointLight);
// and a camera
camera = new PerspectiveCamera(70, w/h, 1, 1000);
camera.position.z = 500;
scene.add(camera);
// setup renderer in the document
renderer = new WebGLRenderer(null);
renderer.setSize(w, h);
Lib.document.body.appendChild(renderer.domElement);
untyped Lib.window.onload = onLoad;
}
public function onLoad() {
timer.run = function(){
renderer.render(scene, camera, null, null);
}
}
public static function main() {
new Main();
}
}
The solution is to get the compiler to add the following to the beginning of the JS file that it creates.
var $_, $hxClasses = $hxClasses || {},
As it stands right now the first line in the JS file looks like this
$estr = function() { return js.Boot.__string_rec(this,''); }
Not sure what needs to be done to fix this or a possible work around other than adding in that line by hand after compilation ?

Found the issue - three.js has Date.hx and Timer.hx files in it (older versions) delete them and it works (on my win install it's in c:\Motion-Twin\haxe\lib\three,js\0,2,46\ and c:\Motion-Twin\haxe\lib\three,js\0,2,46\haxe)

Related

how to convert 3D obj file to particles in three.js

I'm trying to play around with particles in three.js but, there's a problem with converting obj file (3D model) into particles in three.js. The following is the code snippets. I tried but, all failed.
Is there anyone who can help correcting the errors or provide with any examples of getting vertices/particles from a 3D model in obj?
Thanks a lot.
var p_geom = new THREE.Geometry();
var p_material = new THREE.ParticleBasicMaterial({
color: 0xFFFFFF,
size: 1.5
});
var loader = new THREE.OBJLoader();
loader.load( 'human.obj',function(object){
object.traverse( function(child){
if ( child instanceof THREE.Mesh ) {
// child.material.map = texture;
var scale = 10.0;
object.attributes.position.array.forEach(function() {
p_geom.vertices.push(new THREE.Vector3(this.x * scale, this.y * scale, this.z * scale));
})
}
});
scene.add(p)
});
p = new THREE.ParticleSystem(
p_geom,
p_material
);
You are using an outdated code reference. With recent three.js version, the code looks more like the following:
const loader = new THREE.OBJLoader();
loader.load('human.obj', function(object) {
const vertices = [];
object.traverse(function(child) {
if (child.isMesh) {
vertices.push(...child.geometry.attributes.position.array);
}
});
const p_geom = new THREE.BufferGeometry();
const p_material = new THREE.PointsMaterial({
color: 0xFFFFFF,
size: 1.5
});
p_geom.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
const p = new THREE.Points(p_geom, p_material);
p.scale.set(10, 10, 10);
scene.add(p)
});

TextGeometry of Three.js with React not working

Trying to add 3D text in my react application by three JavaScript. Following code is giving a blank page in output. This is my 1st attempt with Three.js. Any help will be appreciated,
Same code is working while I am adding any other geometry with same format.
class ThreeScene extends Component {
componentDidMount() {
const width = this.mount.clientWidth
const height = this.mount.clientHeight
//ADD SCENE
this.scene = new THREE.Scene()
//ADD CAMERA
this.camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)
this
.camera
.position
.set(-15, 0, 25);
this
.camera
.lookAt(this.scene.position);
// Add Font Loader
this.loader = new THREE.FontLoader();
const self = this;
this
.loader
.load('fonts/helvetiker_regular.typeface.json', function (font) {
var material = new THREE.MeshPhongMaterial({color: 0x0033ff, specular: 0x555555, shininess: 30});
var geometry = new THREE.TextGeometry('Hello', {
font: font,
size: 80,
height: 5,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 10,
bevelSize: 8,
bevelSegments: 5
});
self.textData = new THREE.Mesh(geometry, material);
self
.scene
.add(self.textData);
self.light = new THREE.DirectionalLight(0xffffff);
self
.light
.position
.set(0, 1, 1)
.normalize();
self
.scene
.add(self.light);
});
this.renderer = new THREE.WebGLRenderer({antialias: true});
this
.renderer
.setSize(width, height)
this
.mount
.appendChild(this.renderer.domElement);
this.start()
}
renderScene = () => {
this
.renderer
.render(this.scene, this.camera)
}
}
Your font defined here is causing that issue...
.load('fonts/helvetiker_regular.typeface.json',
Try using placing the file (fonts/helvetiker_regular.typeface.json') into your public folder (e.g fonts) and then access that using
.load('/fonts/helvetiker_regular.typeface.json',
So, I ran into the same issue. You want to make sure that you are including the json code example from the THREE.js. You can find it in there github repo if you do not have it locally.
Font Code
This is the most basic code to get it up and runnin ghten you can fill out your styling params.
let loader = new THREE.FontLoader();
let font = loader.parse(fontJSON);
let geometry = new THREE.TextGeometry("Hello World",{font: font, size: 1, height:1 });
let material = new THREE.MeshBasicMaterial({color:0xffffff});
let text = new THREE.Mesh(geometry, material);
text.position.x = 1;
scene.add(text)
NOTE: You will get an error for fontJSON is undefined if you do not include let fontJSON = {code from three.js github library}

Three.JS + OOP in javascript, can't pass a 3D JSON object to other class

It was hard to describe the problem in a single line so this is the situation.
I am going to build a big Javascript project with Three.js so I'm trying to grasp it's OOP concepts.
1) I created a 3D world Object
2) A base 3D_object class with child classes
3) In the sample bellow you see an option 1 and an option 2 these should produce the same result, but somehow they don't. Any idea why ? The complete source is in the snippet.
(Three.js should be included before the script and I am assuming there is a 'resources/object.json' file )
Here is a github link of the project, maybe someone will find it this way. (probably need to run it on a local python server for example to bypass the cross-origin file loading problem in chrome)
//create world
var myWorld = new World(500,500);
myWorld.AddWorldToPage();
//load simple model in the world
var cube = new Cube();
myWorld.addToScene(cube);
// load json model in the world
//option 1
// myWorld.addToSceneTemp();
//option 2 OO (not working)
var jsonObject = new Object_3D_JSON();
function afterModelLoaded(){
console.log("after loading is done");
myWorld.addToScene(jsonObject);
}
jsonObject.loadModel(afterModelLoaded);
myWorld.render();
// Inhertit convencience method
//=====================================================================================================
function inheritsF / rom(child, parent) {
child.prototype = new parent();
child.prototype.constructor = child;
}
// 3D Objects
//=====================================================================================================
// 3D object class
//=====================================================================================================
function Object_3DClass() {
this._geometry = new THREE.BoxGeometry(1, 1, 1);
this._material = new THREE.MeshBasicMaterial({
color: 0xff00ff
});
this._mesh = new THREE.Mesh(this._geometry, this._material);
}
//Get 3D mesh
Object_3DClass.prototype.getMesh = function() {
return this._mesh;
}
//Animate Object
Object_3DClass.prototype.animateFrame = function() {
this._mesh.rotation.x += 0.01;
this._mesh.rotation.y += 0.01;
}
Object_3DClass.prototype.setPosition = function(x, y, z) {
this._mesh.position.set(x, y, z);
}
// END 3D object class
//===================================================================================================
// 3D Cube class
//=====================================================================================================
function Cube() {
this._geometry = new THREE.BoxGeometry(1, 1, 1);
this._material = new THREE.MeshBasicMaterial({
color: 0x00ff00
});
this._mesh = new THREE.Mesh(this._geometry, this._material);
}
inheritsFrom(Cube, Object_3DClass)
// END OF 3D Cube class
//=====================================================================================================
// 3D JSON Model class
//=====================================================================================================
function Object_3D_JSON() {
// instantiate a loader
this._loader = new THREE.JSONLoader();
this._mesh = null;
}
inheritsFrom(Object_3D_JSON, Object_3DClass);
//loadModel
Object_3D_JSON.prototype.loadModel = function(whenReady_Fn) {
// _geometry = this._geometry;
var self = this;
// load a resource
this._loader.load(
// resource URL
'resources/object.json',
// Function when resource is loaded
function(geometry, materials) {
console.log("loading");
// this._material = new THREE.MultiMaterial( materials );
self._material = new THREE.MeshBasicMaterial({
color: 0xffffff
});
self._mesh = new THREE.Mesh(geometry, materials);
self._geometry = geometry;
whenReady_Fn();
// scene.add( this._mesh );
},
//onProgress
function() {},
//onError
function() {
console.log("resource not found");
}
);
}
// END OF 3D JSON Model class
//=====================================================================================================
// World class
//=====================================================================================================
var World = (function() {
// World constructor
function World(width, height) {
//private members
//===========================
this._width = width;
this._height = height;
this._scene = new THREE.Scene();
this._camera = new THREE.PerspectiveCamera(75, this._width / this._height, 0.1, 1000);
this._camera.position.set(6.8, 9.5, 12.2);
this._camera.lookAt(new THREE.Vector3(0, 0, 0));
this._renderer = new THREE.WebGLRenderer();
this._renderer.setSize(this._width, this._height);
this._worldName = "Tubrines";
this._object_3DList = [];
return _privatePrintMessage.call(this, "message");
}
//public
//===========================
//functions
World.prototype.AddWorldToPage = function() {
document.body.appendChild(this._renderer.domElement);
}
World.prototype.render = function() {
//zichzelf meegeven aan AnimationFrame
requestAnimationFrame(this.render.bind(this));
this._object_3DList[0].animateFrame();
this._renderer.render(this._scene, this._camera);
}
World.prototype.addToScene = function(object_3DClass) {
this._scene.add(object_3DClass.getMesh());
this._object_3DList.push(object_3DClass);
}
World.prototype.addToSceneTemp = function() {
_scene = this._scene;
_object_3DList = this._object_3DList;
// instantiate a loader
var loader = new THREE.JSONLoader();
// load a resource
loader.load(
// resource URL
'resources/object.json',
// Function when resource is loaded
function(geometry, materials) {
// var material = new THREE.MultiMaterial( materials );
var material = new THREE.MeshBasicMaterial({
color: 0xff00ff
});
var mesh = new THREE.Mesh(geometry, material);
_scene.add(mesh);
_object_3DList.push(mesh);
});
}
//private functions
//===========================
function _privatePrintMessage(message) {
// return prefix + this._foo;
console.log("World class: " + this._worldName + " " + message);
}
return World;
})();
// END OF World class
//=====================================================================================================
//create world
var myWorld = new World(500, 500);
myWorld.AddWorldToPage();
//load simple model in the world
var cube = new Cube();
myWorld.addToScene(cube);
// load json model in the world
//option 1
// myWorld.addToSceneTemp();
//option 2 OO (not working)
var jsonObject = new Object_3D_JSON();
function afterModelLoaded() {
console.log("after loading is done");
myWorld.addToScene(jsonObject);
}
jsonObject.loadModel(afterModelLoaded);
myWorld.render();
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>My first three.js app</title>
<style>
body {
margin: 0;
}
canvas {
width: 100%;
height: 100%
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<script src="script.js"></script>
</body>
</html>
You are trying to pass a list of materials without telling three.js it's a multimaterial.
Change this line:
self._mesh = new THREE.Mesh( geometry , materials );
to:
var materialSet = new THREE.MultiMaterial( materials );
self._mesh = new THREE.Mesh( geometry , materialSet );
And now that you're using the proper json supplied material, you need to add a light to the scene, otherwise the lambert materials in your model will not show. (lambert materials require lights, basic materials do not, which is why the cube worked).
this._scene = new THREE.Scene();
var spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( 100, 1000, 100 );
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 1024;
spotLight.shadow.mapSize.height = 1024;
spotLight.shadow.camera.near = 500;
spotLight.shadow.camera.far = 4000;
spotLight.shadow.camera.fov = 30;
this._scene.add( spotLight );

Babylon.js - e.Gamepads is not a constructor

Just following along with a Babylon tutorial and it might be that its using an older version of BabylonJS - but I am getting the error:
e.Gamepads is not a constructor
with the following code
var bApp = bApp || {};
bApp.init = function(){
//get the canvas
var canvas = document.getElementById('renderCanvas');
//create a BabylonJS engine object, true for antialias
var engine = new BABYLON.Engine(canvas, true);
//create a scene
var scene = new BABYLON.Scene(engine);
//create a camera
var camera = new BABYLON.ArcRotateCamera('camera', 0, 0, 15, BABYLON.Vector3.Zero(), scene);
//let the user move the camera
camera.attachControl(canvas);
//light
var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0,1,0), scene);
var sun = BABYLON.Mesh.CreateSphere('sun', 16, 4, scene);
engine.runRenderLoop(function () {
scene.render();
});
// the canvas/window resize event handler
window.addEventListener('resize', function(){
engine.resize();
});
}
window.addEventListener('DOMContentLoaded', function(){
bApp.init();
});
The tutorial seems to an older version of Babylon (2.1) and I am trying to use 2.4.

Loading Blender scene in BabylonJS

I made a scene in Blender that I exported into a .babylon, and now I am importing it into the game. The map is 351KB, and I am loading it into the game like this:
var BABYLON;
var canvas = document.getElementById('gamecanvas');
var engine = new BABYLON.Engine(canvas, true);
var scene = new BABYLON.Scene(engine);
var light = new BABYLON.PointLight('light', new BABYLON.Vector3(0,0,10), scene);
var player = new BABYLON.FreeCamera('player', new BABYLON.Vector3(1,1,1), scene); //IMPORTANT LINE
var player_height = 2;
var player_speed = 1;
var player_inertia = 0.9;
var mouse_position = new BABYLON.Vector2(mouse_position.x, mouse_position.y);
function INIT_GAME(){
engine.runRenderLoop(function(){ //IMPORTANT LINE
scene.render();
});
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
canvas.requestPointerLock = canvas.requestPointerLock || canvas.mozRequestPointerLock;
canvas.requestPointerLock();
scene.enablePhysics(); //IMPORTANT LINE
scene.setGravity(new BABYLON.Vector3(0, -10, 0)); //IMPORTANT LINE
player.attachControl(canvas, true); //IMPORTANT LINE
player.ellipsoid = new BABYLON.Vector3(1, player_height, 1);
player.checkCollisions = true;
player.applyGravity = true;
player.keysUp = [87];
player.keysDown = [83];
player.keysLeft = [65];
player.keysRight = [68];
player.inertia = player_inertia;
player.speed = player_speed;
window.addEventListener('resize', function(){
engine.resize();
});
BABYLON.SceneLoader.Load('Scenes', 'zombie_map.babylon', engine); //IMPORTANT LINE
}
I've attempted to narrow everything down to what you should need to look at, but I left it all there just in case there was something I missed. (INIT_GAME is loaded on page load). My problem is, I think the scene is loading, but it just gives me a strange loading icon, which I presume is just Babylon trying to load in the scene I passed it. My questions are:
Am I loading everything in properly?
What is the proper format to import a .babylon scene?
Is the size of the map too big for the browser, and if so, how can I compress it?
I can provide a link to the site if you need to see the results head-on. Let me know, thanks!
I think the solution is very simple.
Add a slash after your rootURL.
So replace
BABYLON.SceneLoader.Load('Scenes', 'zombie_map.babylon', engine); //IMPORTANT LINE
with
BABYLON.SceneLoader.Load('Scenes/', 'zombie_map.babylon', engine); //IMPORTANT LINE
Try this and let me know how it goes.

Categories