What causes Three.js OBJ conversion to render as mesh successfully but log as undefined?

I'm just getting started with Three.js and I'm experimenting a lot. Although I'm new to Javascript as well, the issue I'm facing seems to be more about variable scoping and callback function protocols than it is about Three.js itself... which makes it even more frustrating!

Here's the complete code of my app.js. Special thanks to WestLangley for the geo2line function that's working in this code, and to the Three.js developers for the ObjLoader & JSONLoaders that are also functioning in this experimental app.

// Initialization Variables
var scene;
var camera;
var renderer;

// Light Variables
var light;
var lightScene;

// Object Variables
var lineSphere;
var cube1;
var geodesicMesh;
var geodesicLine;
var lineGeometry;
var floorGeometry;
var floor;
var line1;

// Material Variables
var lineBlueMaterial;
var lineRedMaterial;
var geodesicMaterial;
var floorMaterial;

// Render Variables
var render;

// Callback Variables
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 looks great, and the icosahedron renders perfectly as a geometry.

But I've encountered an issue on line 113 where 'loadedMesh' shows up as 'Undefined' in the console. From my understanding, this shouldn't happen because I declared this variable in the global context and the callback function is supposed to only set its value globally, right? It shouldn't be declaring it internally.

Since it's undefined, I can't proceed with what I planned next, which is to pass the mesh object through the geo2line function on line 117 (hoping to basically set the geodesicMesh variable as the loadedMesh variable) and then display it as a series of dashed lines.

So, what am I missing here?

Thank you!

Answer â„–1

The loader's callback function is asynchronous. The reason you are logging undefined is because the variable loadedMesh is currently undefined:

// Callback Variables
var loadedMesh;   //loadedMesh === undefined

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to properly format an HTML input box for numeric entry and ensure correct formatting of the minus sign

I need assistance with formatting an HTML text input box to only accept numeric values using JavaScript. Specifically, the input should allow digits, a minus sign, or a dot/comma (which will be converted to a dot). However, I want to prevent multiple conse ...

How can I alter the icon's color?

Is it possible for the icon's color to change to red when the condition is greater than 0, and to gray when the condition is equal to zero? <TouchableOpacity onPress={() => { if (Object.values(selectedIt ...

Passing an array from the PHP View to a JavaScript function and plotting it

Greetings, I am currently facing the following tasks: Retrieving data from a database and saving it to an array (CHECK) Sending the array from Controller to View (CHECK) Passing that array to a JavaScript function using json_encode (CHECK) Plotting the ...

Uncovering the hidden gems within a data attribute

Trying my best to explain this clearly. What I have is a data-attribute that holds a large amount of data. In this case, I need to extract each individual basket product ID and display them as separate strings. The challenging part for me is locating thi ...

Transferring JavaScript to PHP

I have a challenge where I need to pass a string stored in a variable to a MySQL table using PHP. Currently, my workaround involves using a hidden <input>. I assign the variable value to it and submit it through a form. It works, but it's not e ...

What is the purpose of the Express 4 namespace parameter?

Having worked extensively with Express 4, I recently attempted to implement a namespaced route with a parameter. This would involve routes like: /:username/shows /:username/shows/:showname/episodes I figured this scenario was ideal for express namespacin ...

When using @mouseover, it is not possible to modify a variable's value

The hover event is not functioning properly in this Vue component. Although I was able to call a function on hover successfully, I encountered issues when trying to change the hover variable directly. <template> <div @mouseover="hover = t ...

"Exploring the World Wide Web with Internet Explorer Driver and Webdriver

After trying everything I know to make internet explorer work with webdriver.io, I've encountered a confusing issue. To start, download the internet explorer driver from this link: http://www.seleniumhq.org/download/. The file is an .exe named ' ...

Wind - Best practices for managing the status of multiple entities within a single display prior to executing the save changes function

In my system, there are three main entities: Project, Attachment, and Messages. A project can have multiple attachments and messages associated with it. The issue arises on the project detail view, where I display the project's messages and any attac ...

NodeJS and ExpressJS fail to redirect to the main landing page

I am currently developing a shopping cart application using nodejs/expressjs. I have encountered an issue with redirecting back to the homepage ('/') after the user submits their credentials during sign up. Despite my search for relevant articles ...

A step-by-step guide on uploading a file to an AWS S3 bucket using a pre-signed URL in a Node

I am currently using S3 upload function in Node.js to upload files to an S3 bucket. The frontend of the application is built on Angular. However, my client now requires that all uploads be directed to the S3 bucket via a presigned URL. I am wondering if th ...

Generate a collection of information by gathering metadata from Xray

I've been struggling to populate an array with metadata retrieved using Xray. The issue arises when the function is called by an API endpoint on my server to fetch links from my application. My main challenge seems to be related to promises, as there ...

Compose an email without the need to access the website

Is there a way to send email reminders to users without having to load the website pages? In the reminder section, users can select a date for their reminder and an email will be automatically sent to them on that date without requiring them to access the ...

Data within object not recognized by TableCell Material UI element

I am currently facing an issue where the content of an object is not being displayed within the Material UI component TableCell. Interestingly, I have used the same approach with the Title component and it shows the content without any problems. function ...

Stopping the interval in Vue before the component is destroyed

I am currently facing an issue with a countdown timer implemented on a component. The timer functions properly, however, I want it to stop counting down once the user navigates away from the page where the component is located. I have attempted to use cl ...

Exploring the Possibilities of WebAudio API through Asynchronous Events

Is there a way to trigger events after an oscillator finishes playing using the webaudio API? I am attempting to update my Vue component reactively to display data in the DOM while a note is being played. Here's a snippet of my code: <template> ...

What is the best way to update the value of a preact signal from a different component?

export const clicked = signal(false); const handleClickDay = (date) => { const day = date.getDate().toString().padStart(2,'0') const month = (date.getMonth()+1).toString().padStart(2,'0') const year = da ...

Designate the preferred location for requesting the desktop site

Is there a way to specify the location of the 'Request desktop site' option? Here is the code I am currently using: var detector = new MobileDetect(window.navigator.userAgent); if(detector.mobile() != null || detector.phone() != null || det ...

Transforming a single object into multiple arrays using AngularJS

Just starting out with AngularJS and I've got some data that looks like this { day1: 0, day2: 0, day3: 0, day4: 2 } Is there a way to convert this data into arrays structured like below? [     ["day1": 0],     ["day2": 0],   ...

A novel RxJS5 operator, resembling `.combineLatest`, yet triggers whenever an individual observable emits

I am searching for a solution to merge multiple Observables into a flattened tuple containing scalar values. This functionality is similar to .combineLatest(), but with the added feature that it should emit a new value tuple even if one of the source obser ...