Utilizing JSONLoader to load several models simultaneously

Seeking advice on the most effective method for loading multiple models exported from Blender to JSON format.

In the provided example below, I am utilizing the static_objects array containing predefined object data and model URLs. These URLs are then iterated through in a for loop and passed to the JSONLoader. However, encountering incorrect references when accessing the static_objects array within the JSONLoader.load method.

Refer to the example code snippet.

var renderer, camera, scene, controls;

/////// JSOn DATA ////
var static_objects = [  
      {  
         name:"ground",
         pos:{  
            x:-45.0, y:-1, z:14.0
         },
         size:20,
         model_url: "obj.moon_ground.json",
      },
      {  
         name:"cylinder",
         pos:{  
            x:-20.0, y:0.0, z:0.0
         },
         size:10,
         model_url:"obj.cylinder.json",
      }
];

var ObjectsToLoad =  static_objects.length || 0;
///////////////////////////

// Remaining JavaScript functions omitted for brevity //

initAll();

Answer №1

To simplify the code and focus on the issue at hand, here is the original function:

function initObjects(){
    for(var o = 0; o < static_objects.length; o++ ){
        var loader = new THREE.JSONLoader();
        var o_data = static_objects[o];
        loader.load(o_data.model_url, function(){
            console.log("loading object "+ o_data.name ) <----- it always refers to same object /// 
        })
    }
}

In JavaScript, variables declared with var are not scoped how you might expect in other languages. The scope of a variable defined with var is the entire function, which could lead to unexpected behavior when initializing variables inline.

A better approach would be:

function initObjects(){
    var loader = new THREE.JSONLoader();
    var o_data = undefined;

    for(var o = 0; o < static_objects.length; o++ ){

        if ( o_data === undefined ) {
            o_data = static_objects[o];
        }

        loader.load(o_data.model_url, function(){
            console.log("loading object "+ o_data.name ) <----- it always refers to same object /// 
        })
    }
}

ES6 introduces let and const keywords, which provide block scoping. However, using these keywords may require transpilation for compatibility across all browsers. Until then, it's best practice to declare variables at the beginning of your functions to maintain clarity in your code.

Answer №2

My approach to this problem involved utilizing an existing function in the load method instead of creating a new one.

function loadObjects(){
    console.log("  - StaticObjects");
    var loader = new THREE.JSONLoader();
    for(var o = 0; o < static_objects.length; o++ ){
        var o_data = static_objects[o];
        loader.load( o_data.model_url, initObject(o) );
    }
}

function initObject(o_id){
    console.log("loading object "+ o_id );
    return function(geometry, materials) {
        geometry.translate( 0.0, 0.0, -2.0 ); 
        mesh =  new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
        mesh.scale.set( static_objects[o_id].size, static_objects[o_id].size, static_objects[o_id].size ) ;
        mesh.position.set(  static_objects[o_id].pos.x, static_objects[o_id].pos.y, static_objects[o_id].pos.z );
        mesh.traverse( function( node ) { if ( node instanceof THREE.Mesh ) { node.castShadow = true; node.receiveShadow = true;  } } );
        ObjectsToLoad--;
        scene.add(mesh);
    }
} 

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

In Vue, applying CSS styles to D3's SVG elements may not work as expected when using the scoped attribute

Here is the code snippet of my component: <template> <div id="something" class="card"> </div> </template> const height = 200; const width = 200; let graph = d3 .select('#something') .append('svg') ...

Is it necessary for me to add the scraped information before I can retrieve it?

I am currently extracting data from a different website and have had some success with it. However, I am facing a challenge. After fetching the data, I am required to append it inside a div to accurately extract the necessary information using getElement ...

Displaying Additional Information - Displaying Fewer Information reveals a total of 31 rows rather than

My HTML table consists of 370 rows and includes a 'Show More - Show Less' button that initially displays only the first 30 rows. Everything was functioning perfectly until I integrated a search feature. I implemented the search function from w3s ...

Error message: Iframe chrome encountered a Uncaught DOMException when attempting to access the 'localStorage' property from 'Window': Document does not have permission

I recently developed a JavaScript widget that utilizes localstorage to set and retrieve properties of the window. Upon opening this widget in Chrome, I encountered an error message: Uncaught DOMException: Failed to read the 'localStorage' prop ...

The functionality of Skrollr on mobile is currently not working properly due to the inability to prevent default actions

Encountering the following error on all chromium browsers while using the Skrollr library and accessing the website through mobile: "[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See < ...

The auto-complete feature on Yahoo search occasionally displays outdated search suggestions

When using Yahoo Autocomplete with a remote php database request and zero time delay, I sometimes encounter the issue of old query results coming back after the most recent query. For example, if I search for "beginner", the results from "beg" may override ...

What is the best way to ensure the flat list only renders once?

My objective is to display the ComponentTwo Flatlist just once, however, I am currently seeing the output as shown in image1, whereas I want it to be displayed like in image2. To showcase this issue, I have included a snack link containing the relevant cod ...

"Utilize Three.js to construct walls that intersect at right angles in a

Is it feasible to generate 3D perpendicular walls using Three.js like the ones shown in this image? I attempted to use THREE.Shape to sketch a rectangle, but I'm unsure how to incorporate additional perpendicular or parallel rectangles. ...

Performing a reverse image search request using Javascript/AJAX to query Google

I have been attempting to perform a reverse image search request using AJAX, but I keep receiving 302 errors. After checking the Firebug console, I discovered that the response header from Google contains a URL linking me to the results. However, I am unsu ...

A JQuery function linked to the click event of the body element triggers another click event right away

$().ready(function(){ $("#move-to").click(function(){ $("body").bind("click",function(){ alert("foo"); }); }); }); Why do I receive an alert message of "foo" immediately after clicking on "move-to"? When I bind the " ...

Efficiently eliminating empty query parameters with URLSearchParams

Recently, while working with query params, I came across the URLSearchParams object. I found myself using it to create a query object like this: const x = { a: 'hello World', b: 23, c: '' } let params = new URLSearchParams(x); con ...

Concentrating on div elements using React

Can the focus() method be used to focus on a div element or any other elements? I have added a tabIndex attribute to a div element: <div ref="dropdown" tabIndex="1"></div> When I click on it, I can see that it gets focused. However, I am att ...

Utilizing the "apply" method with JavaScript OOP callbacks for dynamic context management

Encountering an issue while creating a callback in my custom EACH function utilizing Object-Oriented Programming principles. To achieve this, I have developed a JavaScript library that emulates the familiar habits of JQUERY. Experience it in action by ch ...

In vuex, dynamic modules share common data and do not have unique data

Currently, I am facing an issue with an asynchronous API call that returns an array of objects. After receiving this data, I map it to dynamically registered modules in my store. The process looks something like this: dispatch // prior to this dispatch, ...

The spinal cord of design inquiry

I am currently working on a Backbone view called MainMenuView. Within this, the MainMenuModel consists of an array of sub-models known as ItemModel. The main menu is divided into two pages and includes next and previous buttons for navigation. The first pa ...

Which is the PREFERRED choice for managing multiple form inputs in React: useState or useRef?

DISCLAIMER: As a newcomer to React, I am striving to establish good programming practices. Imagine a straightforward contacts app scenario, where you input names and they appear below the input field. View pic.1 for a visual of the simple contacts app mec ...

Angular 2: Changing HTTP Requests

I am trying to include a single parameter in all my web requests to disable caching forcibly. My goal is to append ?v=1535DC9D930 // Current timestamp in hex to the end of each request. I am coding this in plain ES5 JS, but the documentation is in Types ...

Spin an object placed in a circular formation to face the center point, then give it another spin

After successfully rotating an object around a sphere to face the origin, I am now struggling with rotating it along the axis that goes from the center of the object to the origin of the sphere. All my attempts so far have failed, including using code simi ...

Preventing Body Overflow Without Affecting Iframe Overflow in Meteor.js

Currently, I am working on a project using Meteor for a Point of Sale (POS) system. For those unfamiliar with it, Meteor is a framework that allows for the use of JavaScript, jQuery, and various other web app scripting languages. The goal of this applicati ...

Automatically updating the results section while executing SQL queries in PHP

Here is a JavaScript/Ajax code snippet: <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready (function () { var updater = se ...