The JavaScript function exclusively reveals the final element, which is Three.js

I'm currently working on a fence generator function using Three.js, but for some reason, my function is only returning the last fence created. It's really puzzling to me...

function createFence(nb){
  var i;
  var position = -5;
  var loadingManager;
  for(i = 0; i < nb ; i++) {
    var fenceArray = [];
    loadingManager = new THREE.LoadingManager( function () {
      scene.add( fenceArray[i] );
    });

    var loader = new THREE.ColladaLoader( loadingManager );
    loader.load( 'fence/model.dae', function ( collada ) {
      fenceArray[i] = collada.scene;
      fenceArray[i].position.x = position;
      fenceArray[i].position.z = -5;
    });
    position += 3;      
  }
}

createFence(3);

Answer №1

It appears that there are a few issues with the code provided. However, one key problem seems to be related to the outdated async issue. The loaders in use function asynchronously, meaning that the execution of the code happens at a later time, while the current code assumes synchronous behavior. As a result, all the fences end up reading the value when the looping is completed, leading to delayed triggers. Below is a refactored version of the function to address this behavior:

function generateFence(nb){
  
  // Initially loading the model once as it will be reused.
  // Wrap it in a promise for future reference.
  
  const value = -5;
  const fences = new THREE.Group;
  const model = new Promise(function( resolve ){
  
    THREE.ColladaLoader( loadingManager ).load( 'fence/model.dae', resolve );
    
  });
  
  // Use `let` declaration for accurate looping values 
  // even during asynchronous operations.
  
  for( let i = 0; i < nb; i++ ){
    
    // Async operation after `then`, ensuring loaded model usage.
    
    model.then(model => {
      
      // Clone the model to create multiple instances
      
      const fence = model.scene.clone();
      
      // Calculate x position based on value and i's state
      
      fence.position.set( value + i * 3, 0, -5 );
      fences.add( fence );
      
    });
    
  }
  
  return fences;
  
}

// Returns a THREE.Group. Adds loaded fences to a hidden scene group.
scene.add( generateFence(3) );

The main issue likely stems from identical fences due to async actions, causing all to be positioned similarly and appear as one.

Answer №2

There are a few issues that need to be addressed.

  • The code is creating a loading manager for each fence when only one is needed
  • The same fence is being loaded 5 times unnecessarily; it should be loaded once and then cloned
  • The loading manager is not utilized effectively as the scene is already obtained from the ColladaLoader, making the loading manager redundant in this context
  • The use of value in a callback results in all instances of fences being placed at the exact same location due to its single instance

To improve functionality, consider the following adjusted code:

function generateFence(nb){
  const loader = new THREE.ColladaLoader();
  loader.load( 'fence/model.dae', function ( collada ) {
    const copy = collada.scene.clone();
    scene.add(copy);
    let value = -5;
    for(var i = 0; i < nb ; i++) {
      copy.position.x = value;
      copy.position.z = -5;
      value += 3;
    }
  });
}

generateFence(3);

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

Following the path of JavaScript function calls

As I explore my Chrome console, I find myself puzzled by the mystery of the JavaScript file that gets called when I import a file from my computer after clicking on an input file tag. It seems to happen without any clear indication of which method triggere ...

Integrate Vue.js project to store images in MS Azure cloud storage

I am currently exploring the VueJs framework and looking to integrate my project with Azure. However, I am unsure of the process. Previously, I worked with Firebase - is it a similar technique where we configure storage within the project? Recently, I cre ...

Adjust date by one day using the Datetimepicker tool

I have been attempting to adjust the date of my input by one day either forward or backwards, but I seem to be stuck and not making any progress. Take a look at my code: function function backDay() { var date = $('input#datetimepicker').va ...

Transforming jQuery object into HTML code

I need assistance with a JavaScript task where I am trying to parse and replace an item within an HTML string, but then struggling to convert it back to a string. Specifically, I am having difficulty turning the new jQuery object back to HTML. var compile ...

Waiting for a method to finish in Node.js/Javascript

Currently, I am in the process of creating a trade bot for Steam. However, I have encountered an issue where the for-loop does not wait for the method inside it to finish before moving on to the next iteration. As a result, the code is not functioning as i ...

Transform a JSON string into an array of JSON objects using Java

Data is formatted as a String like this : String jsonData = "{"name":"A","age":23},{"name":"B","age":24}"; I am looking to transform the string above into an Array of Objects: Person[] persons; In which, persons[0].name => "A" persons[0].age => ...

Unable to retrieve information from the json-server

For my current project in Backbone.js, I'm utilizing the json-server package to populate it with data. I've created a db.json file containing the data and executed the command json-server --watch db.json. The server started successfully and is ru ...

Round up all the hyperlinks within a paragraph and organize them neatly into a list

Let me present a scenario: <p class="links">Lorem <a href="#">diam</a> nonummy nibh <a href="#">Lorem</a></p> Following that, I have a lineup: <ul class="list"> </ul> How do I achieve this using jQuery? ...

Guide to moving a 3D model and initiating animation in threejs when a key is pressed

In the midst of a project where a person (gltf object) walks based on key presses, I have successfully updated the object position accordingly. However, I'm encountering difficulty in rotating the object when the left/right keys are pressed and ensur ...

When using the * selector in jQuery on Chrome, it targets and selects scrollbars

Here's the code I'm currently using: $("*").bind("mousedown.sg", { 'self':this }, this.sgMousedown); This code binds an event listener to all elements on the page, and it functions properly in most browsers except for Chrome. In Chrom ...

Trouble locating the ID selector within a nested Backbone view

Within this code snippet, I am utilizing the element controller pattern to display a collection of products. The main view template is rendering properly, showing all elements and the div selector "#cart-wrapper". However, when the main view calls the nest ...

Ways to fix a "define is not defined" issue when utilizing jasmine karma with compiled typescript for component testing

I'm faced with an issue in my typescript app where the compiled code is stored in a single file named myjs.js within the js folder. Additionally, I have karma jasmine configured on my workspace. Inside myjs.js, there's a segment of code like thi ...

Dimensions of Bootstrap carousel

I am attempting to create a Bootstrap carousel with full-width images (width: 100%) and a fixed height. However, when I set the width to 100%, the height automatically takes on the same value. I am unsure if the issue lies within my files. <div id="m ...

Retrieve both the name and id as values in an angular select dropdown

<select (change)="select($event.target.value)" [ngModel]="gen" class="border border-gray-200 bg-white h-10 pl-6 pr-40 rounded-lg text-sm focus:outline-none appearance-none block cursor-pointer" id="gend ...

In JavaScript, there is a missing piece of logic when iterating through an array to find

I am working on a solution to populate empty values when data is not available for specific months. You can view my progress on Plunker here: http://plnkr.co/edit/f0IklkUfX8tkRZrn2enx?p=preview $scope.year = [ {"month":"mar", "val":"23"}, {"month":"feb", ...

Unable to modify the active property of the specified object as it is read-only

Presented here is the interface: export interface ProductCommand extends ProductDetailsCommand { } This is the ProductDetailsCommand interface: export interface ProductDetailsCommand { id: string; active: boolean; archive: boolean; title: ...

Firefox failing to trigger key events within iframe

For fun, I created my own little JSFiddle website where I built a Snake implementation that works great in Chrome. However, when I try to use it in Firefox, I can't control the player with the arrow keys or WASD. You can check it out here: I read on ...

Is there a way to connect and interact with a different ng-controller's ng-model within a separate ng-controller?

Is it possible to access the ng-model from another ng-controller and if so, how can it be done? In this scenario, I am using two controllers. The first controller has a model called mddl1, while the second controller does not have any other model. However, ...

Pug template syntax for importing JavaScript files with links

My Programming Dilemma In my NodeJS webserver setup, I use Express and Pug to serve HTML and JavaScript files. Here's a snippet of how it looks: index.pug html head title Hello body h1 Hello World! script(src='s ...

switch between showing and hiding dynamic table rows

As I dynamically add rows to a table, each row can either be a parent row or a child row. My goal is to toggle the visibility of child rows when the parent row is clicked. if (response != null && response != "") { ...