Question

I'm learning some WebGL concepts using javascript and the Three.js library, but I've hit a bit of a snag trying to figure out how to use the OBJLoader to load a .obj file using classes. Heres the code:

Model.prototype.loadModel = function () {
    var self = this;
    loader = new THREE.OBJLoader();

    loader.load( this.modelPath, function ( object ) {
        object.traverse( function ( child ) {
            if ( child instanceof THREE.Mesh ) {
                child.material.map = self.modelTexture;
            }
        });
        self.modelObj = object;
        console.log(self.modelObj); // Returns [Object object]
    });
        console.log(self.modelObj); // Returns undefined

    this.modelObj = self.modelObj;
    this.modelObj.position.x = this.x;
    this.modelObj.position.y = this.y;
    this.modelObj.position.z = this.z;
}

I cant get the object to use as this.modelObj out of the anonymous function and I think it's a scope issue. Trying to add this.modelObj to the function parameters results in "missing formal parameter" and using this. inside the function thinks its inside the scope of the function ( or loader )

Was it helpful?

Solution

To have a callback be invoked when the loading is completed, add the callback as a parameter to your function:

Model.prototype.loadModel = function (callback) {
    var self = this;
    var loader = new THREE.OBJLoader();

    loader.load(this.modelPath, function (object) { // inner function will be called on success
        object.traverse(function (child) {
            if (child instanceof THREE.Mesh)
            {
                child.material.map = self.modelTexture;
            }
        });

        self.modelObj = object;
        callback(object); // pass loaded object to callback function
    });
}

When you do it this way you separate the loading logic from the callback, where you will actually consume/use the data you have loaded. Imagine you have multiple cases like these, you won't have to write that loading logic (the inner success function) over and over again.

The XHR (used in AJAX) also accepts an error function and requires your functions to check for a readystate variable. I don't know if that applies to this loader, too. But if you can, you should implement the error case as well.

OTHER TIPS

This is not case of scoping. The problem is that loader.load is asynchronous function call (like AJAX). So you should use callback for example to make your code work properly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top