1

If I call this function in Javascript, it works, and it adds the object to the scene:

var loader = new THREE.FBXLoader();

function returnFBX(PATH, scene) {
    loader.load('obj/' + PATH + '.fbx', function (object) {
        scene.add(object);
    });
}

However, if I replace:

scene.add(object);

with:

return object;

It seems to return undefined.

I tried using Promises, as well as the Loading Manager, but both only seem to be able to add the object to the scene, and not return an object.

I think this is because there are two nested functions within each other, as well as the loading being asynchronous. But I'm not sure how to fix this, as this is a standard way to load objects.

qbuffer
  • 383
  • 4
  • 14
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Peter O. Dec 19 '18 at 12:34
  • Just as a pointer, you could always say ```var mesh = scene.children[0]```if you know it is the first thing added to the scene to get the mesh into the main scope. – Adude Mar 15 '23 at 21:10

2 Answers2

2

load is asynchronous - either use a callback or use await, i.e.

const afterload = object => { console.log(object); }

function returnFBX(PATH, scene) {
    loader.load('obj/' + PATH + '.fbx', function (object) {
        afterload(object);
    });
}

or

async function returnFBX(PATH, scene) {
    return loader.load('obj/' + PATH + '.fbx', function (object) {
        return object;
    });
}

let afterloadObject = await returnFBX( ... )
ic3b3rg
  • 14,629
  • 4
  • 30
  • 53
  • For the callback, how would I access the object in the end? Would I replace `console.log(object);` with `return object;`? – qbuffer Dec 17 '18 at 22:45
  • Not really - you have to think of it the other way around - place your logic inside `afterload` – ic3b3rg Dec 17 '18 at 22:47
  • you could also return the promise (`load`) from `returnFBX` and chain a `then` onto it - let me know if you'd like to see an example of that – ic3b3rg Dec 17 '18 at 22:50
  • I can do things such as adding the object to the scene in `afterload` but if I want to access the object outside of this function, I'm not sure how. For instance, if I want to change the scale of the object later on, it would be nice to call something like `object.scale.set(5,5,5);`. Would this be possible with the callback? – qbuffer Dec 17 '18 at 22:55
  • you can declare a variable outside `returnFBX` and set it inside the callback. – ic3b3rg Dec 17 '18 at 22:59
  • Don't think I'm doing this correctly. If I declare a variable outside called `var mesh;` and then inside `afterload` set `mesh = object; scene.add(mesh);`, then it adds the mesh to the scene once I call `returnFBX('myfile', scene)` in my `init()` function. However, if I try to change the scale of the mesh in my `init()` function after calling `returnFBX()`, by doing `mesh.scale.set(5,5,5);` it doesn't do anything, meaning it probably executes that line of code before the object has been added to the scene in the callback. – qbuffer Dec 17 '18 at 23:09
  • 1
    Nevermind, I guess it doesn't really matter if I can't change the object in the `init()` if I just use functions to make changes to the object throughout, and call them in `afterload`. Thanks for the help. – qbuffer Dec 17 '18 at 23:21
0

This is how i did it with loadAsync()

async function LoadModel (...) {
  const result = await loader.loadAsync(...);
  return result;
}

const model = await LoadModel(...);

check how you can wait for object loader: here