首页 > 解决方案 > 将模型加载到 a-entity

问题描述

我正在尝试将模型有条件地加载到一个实体中。这样做的原因是我有一个场景,我想让用户选择是否加载大型模型。到目前为止,我有一个包含以下实体的场景:

  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 );
          }
        );
      }
  }

模型加载并显示到场景中,但是如何将它附加到实体上呢?

标签: three.jsaframe

解决方案


我得到模型的填充<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 );
                   }
               );
             }
          );

      },

推荐阅读