我试图操纵(例如改变位置,缩放,旋转)在Three.js中使用OBJLoader加载的对象。虽然这很容易做到一次,但我想知道如何做到这一点,例如在动画循环期间,或在初始加载回调之外的任何地方。
这是我的代码:
function loadObj( path, name )
{
var obj;
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( path );
mtlLoader.load( name+".mtl", function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( path );
objLoader.load( name+".obj", function( object ) {
obj = object;
obj.position.x = 20;
scene.add( obj );
});
});
return obj;
}
var myObj = loadObj( "assets/", "test" );
myObj.position.y = 20;
这里要注意的要点是:
Cannot read property 'position' of undefined
。obj
(作为全局),则会出现此错误,然后相应地引用它。我尝试过使用JSON加载器的相似代码,得到相同的结果(我能够在加载中操作它,但之后却没有。)
答案 0 :(得分:4)
THREE.js
中的加载器是异步的,因此最好的方法是使用Promise
或使用新的await。继承人承诺实施。我只是将所有THREE.js
加载器代码包装在promise中,并在最后调用resolve
。然后只需使用.then
就可以在异步请求完成时执行。
function loadObj( path, name ){
var progress = console.log;
return new Promise(function( resolve, reject ){
var obj;
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( path );
mtlLoader.load( name + ".mtl", function( materials ){
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( path );
objLoader.load( name + ".obj", resolve, progress, reject );
}, progress, reject );
});
}
// This way you can use as many .then as you want
var myObjPromise = loadObj( "assets/", "test" );
myObjPromise.then(myObj => {
scene.add( myObj );
myObj.position.y = 20;
});

更新更正了reject
onProgress
时的一个小错误。我的错,请再次阅读THREE.js文档并注意到load
的顺序为url, onSuccess, onProgress, onError
,因此最终应为url, resolve, () => {}, reject
。