我正在尝试将模型有条件地加载到a实体中。原因是我有一个场景,我想让用户选择是否加载大型模型。到目前为止,我的场景中包含以下实体:
id="modelname-entity"
scale="2 2 2"
position="0 0 -5"
drag-rotate="rotateY:false;"
model-rotate-loadprogress="modelUrl:modelname.gltf;modelRef:modelname-model"
></a-entity>
具有组件model-rotate-loadprogress
,该组件使用THREE.js语法加载gltf模型:
AFRAME.registerComponent('model-rotate-loadprogress',{
schema : {
modelUrl: {
type: "string"
},
modelRef: {
type: "string"
}
},
init : function(){
this.loadModel();
},
loadModel: function() {
if (!this.data.modelUrl || !this.data.modelRef) {
console.warn("Model details not given for model rotate loader");
return;
}
if ( document.getElementById(this.data.modelRef) ) {
console.warn("Assets already has an asset with the ID of " , this.data.modelRef );
}
// Using THREE.js file loader
var dis = this;
var loader = new THREE.GLTFLoader().setPath( '/assets/static/models/' );
loader.load(
this.data.modelUrl,
gltf => {
// Add the model to the scene for now.
dis.el.sceneEl.object3D.add(gltf.scene);
},
xhr => {
console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
},
error => {
console.error( error );
}
);
}
}
该模型会加载并显示到场景中,但是我该如何将其附加到实体上呢?
答案 0 :(得分:1)
我得到的模型填充<a-entity>
的方式与将其附加到场景的方式类似。这是最终的代码:
loadGLTFModel: function() {
var dis = this;
var loader = new THREE.GLTFLoader().setPath( this.PATH_MODELS );
loader.load(
`${this.PATH_MODELS}${this.data.gltfModel}`,
gltf => {
dis.el.object3D.add(gltf.scene)
},
progress => {
this.onProgress(progress);
},
error => {
console.error( "ERROR : " , error );
}
);
},
onProgress: function(progress) {
this.progressBar.setAttribute("geometry", {
thetaLength: (progress.loaded / progress.total * 360)
})
},
如果我建议将重模型添加到<a-assets>
中,这是推荐的处理方式,这将导致整个应用程序被阻塞,直到所有资产都已加载并准备就绪为止。在我的情况下,用户可以选择跳过下载。如果用户选择加载模型,则他/她将获得一个进度条(实际上是一个环),该进度条将被更新。
以下是如何加载obj和mtl模型的代码:
loadOBJModel: function() {
var dis = this;
if (!this.data.mtlMaterial) {
console.error("No material given for model");
return;
}
var mtlLoader = new THREE.MTLLoader();
mtlLoader.load(
`${this.PATH_MODELS}${this.data.mtlMaterial}`,
materials => {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( this.PATH_MODELS );
objLoader.load(
this.data.objModel,
object => {
dis.el.object3D.add(object)
},
progress => {
this.onProgress(progress);
},
error => {
console.error( "ERROR : " , error );
}
);
}
);
},
答案 1 :(得分:0)
无需调用GLTFLoader。使用gltf-model component:
loadModel: function() {
if (!this.data.modelUrl || !this.data.modelRef) {
console.warn("Model details not given for model rotate loader");
return;
}
if ( document.getElementById(this.data.modelRef) ) {
console.warn("Assets already has an asset with the ID of " , this.data.modelRef );
}
this.el.setAttribute(‘gltf-model’, ‘url(‘ + this.data.modelUrl + ‘)’);
}
我建议在a-assets中预先加载模型,这样用户就不必等待网络了。预加载大型和小型模型。