[英]Three.js Manipulate an object from ObjLoader
I am trying to manipulate (eg change position, scale, rotation) an object loaded using OBJLoader in Three.js. 我试图操纵(例如更改位置,缩放,旋转)在Three.js中使用OBJLoader加载的对象。 While this is easy to do so once, I cannot work out how to do this when I want eg during the animate loop, or anywhere outside of the initial load callback.
虽然这很容易做到这一点,但是当我想要时,例如在动画循环期间,或者在初始加载回调之外的任何地方,我都无法解决这个问题。
Here is my code: 这是我的代码:
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;
The key points to note here are: 这里要注意的关键点是:
Cannot read property 'position' of undefined
. Cannot read property 'position' of undefined
。 obj
outside the function (as a global), and then reference it accordingly. obj
(作为全局),然后相应地引用它,则此错误仍然存在。 I've tried similar code with the JSON loader, to the same results (I am able to manipulate it within the load, but not afterwards). 我已经尝试了与JSON加载器类似的代码,得到了相同的结果(我能够在加载中操作它,但之后却没有)。
Loaders in THREE.js
are asynchronous, so the best way around this is to simply use a Promise
, or use the new await. THREE.js
中的THREE.js
是异步的,因此最好的方法是简单地使用Promise
,或使用新的await。 Heres the promise implementation. 继承人承诺实施。 I simply wrapped all the
THREE.js
loader code inside the promise and call resolve
at the end. 我只是将所有
THREE.js
加载器代码包含在promise中,并在最后调用resolve
。 Then just use .then
to execute whenever the asynchronous request is done. 然后只要异步请求完成就使用
.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; });
Update Corrected a little mistake where it would reject
while onProgress
. 更新纠正了在
onProgress
reject
一个小错误。 My Bad, read the THREE.js docs again and noticed that the order of load
is url, onSuccess, onProgress, onError
, so the final should be url, resolve, () => {}, reject
. 我的坏,再次阅读THREE.js文档并注意到
load
的顺序是url, onSuccess, onProgress, onError
,所以final应该是url, resolve, () => {}, reject
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.