Reputation: 185
I'm new to Three.js and doing a fair bit of experimentation. I'm also pretty new to Javascript, and the issue I seem to be having is one more related to variable scoping and callback function protocols than it is to Three.js... that makes it all the more frustrating!
Here's the full code of my app.js, and thanks to WestLangley for the geo2line function I've got working in this code and the Three.js developers for the ObjLoader & JSONLoaders I've got working in this experimental app.
// Initialization Vars
var scene;
var camera;
var renderer;
// Light Vars
var light;
var lightScene;
// Object Vars
var lineSphere;
var cube1;
var geodesicMesh;
var geodesicLine;
var lineGeometry;
var floorGeometry;
var floor;
var line1;
// Material Vars
var lineBlueMaterial;
var lineRedMaterial;
var geodesicMaterial;
var floorMaterial;
// Render Vars
var render;
// Callback Vars
var loadedMesh;
function init() {
scene = new THREE.Scene();
cameras();
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// LIGHTS
lights();
// MATERIALS
materials();
// GEOMETRIES
geometries();
camera.position.z = 5;
render = function () {
requestAnimationFrame( render );
lineSphere.rotation.x += 0.02;
lineSphere.rotation.y += 0.02;
lineSphere.rotation.z += 0.01;
//geodesicMesh.rotation.x += 0.03;
//geodesicMesh.rotation.y += 0.03;
renderer.render(scene, camera);
};
render();
}
function cameras() {
camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
}
function lights() {
light = new THREE.PointLight(0xAAAA66, 2, 100);
light.position.set(50,50,50);
scene.add(light);
lightScene = new THREE.PointLight(0x66AAAA, 2, 100);
lightScene.position.set (0,5,0);
scene.add(lightScene);
}
function materials() {
geodesicMaterial = new THREE.MeshPhongMaterial( {
color: 0x0000ff,
specular: 0x8888ff,
shininess: 20,
shading: THREE.FlatShading } );
lineBlueMaterial = new THREE.LineDashedMaterial ({
color: 0xff0000,
dashSize: .1,
gapSize: .1,
linewidth: 3 });
lineRedMaterial = new THREE.LineDashedMaterial ({
color: 0xff0000,
dashSize: .1,
gapSize: .1,
linewidth: 3 });
}
function geometries() {
sphereGeometry = new THREE.SphereGeometry( 3, 24, 24 );
lineSphere = new THREE.Line( geo2line(sphereGeometry), lineBlueMaterial, THREE.linePieces );
scene.add( lineSphere );
geodesicMesh = loadObjAsMesh( 'assets/objects/v2-icosahedron-simplest.obj' , function ( mesh ) { loadedMesh = mesh; scene.add( mesh ); return mesh; } );
//loadedMesh;
console.log ( loadedMesh );
//geodesicMesh.computeLineDistances();
//geodesicLine = new THREE.Line ( geo2line( geodesicMesh ), lineRedMaterial, THREE.linePieces );
//scene.add( geodesicLine );
}
function geo2line( geo ) {
var geometry = new THREE.Geometry();
var vertices = geometry.vertices;
for ( i = 0; i < geo.faces.length; i++ ) {
var face = geo.faces[ i ];
if ( face instanceof THREE.Face3 ) {
vertices.push( geo.vertices[ face.a ].clone() );
vertices.push( geo.vertices[ face.b ].clone() );
vertices.push( geo.vertices[ face.b ].clone() );
vertices.push( geo.vertices[ face.c ].clone() );
vertices.push( geo.vertices[ face.c ].clone() );
vertices.push( geo.vertices[ face.a ].clone() );
} else if ( face instanceof THREE.Face4 ) {
vertices.push( geo.vertices[ face.a ].clone() );
vertices.push( geo.vertices[ face.b ].clone() );
vertices.push( geo.vertices[ face.b ].clone() );
vertices.push( geo.vertices[ face.c ].clone() );
vertices.push( geo.vertices[ face.c ].clone() );
vertices.push( geo.vertices[ face.d ].clone() );
vertices.push( geo.vertices[ face.d ].clone() );
vertices.push( geo.vertices[ face.a ].clone() );
}
}
geometry.computeLineDistances();
return geometry;
}
function loadObjAsMesh( obj , callback ) { // Obj Resource URL: Example: 'assets/monster.obj'
var geometry;
var mesh;
var loader = new THREE.OBJLoader();
loader.load(
obj , function ( object ) {
geometry = new THREE.Geometry().fromBufferGeometry( object.children["0"].geometry );
mesh = new THREE.Mesh ( geometry, geodesicMaterial );
console.log( mesh );
//scene.add( mesh );
callback( mesh );
} );
}
function loadJSON( obj ) { // Obj Resource URL: Example: 'assets/monster.obj'
var loader = new THREE.JSONLoader();
loader.load(
obj , function ( object ) { return( object ); } );
}
The rotating sphere runs beautifully, and the icosahedron renders as a geometry just fine.
However I'm hitting the wall at line 113, where 'loadedMesh' returns in the console as 'Undefined.' As I understand it, this shouldn't be happening because I've declared this variable in the global context and the callback function is only setting it's value (globally, I think?), and not actually declaring it internally.
As it's coming back as undefined, I can't do what I want to do next, which is pass the mesh object through the geo2line function via line 117 (hoping to set the geodesicMesh variable as the loadedMesh variable really), and then render it out as a series of dashed lines.
So, what am I failing to understand here?
Thanks!
Upvotes: 0
Views: 378
Reputation: 5431
The callback in the loader is async. You're logging undefined because it is undefined:
// Callback Vars
var loadedMesh; //loadedMesh === undefined
Upvotes: 1