将模型加载到实体中

时间:2019-01-15 12:40:57

标签: three.js aframe

我正在尝试将模型有条件地加载到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 );
          }
        );
      }
  }

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

2 个答案:

答案 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中预先加载模型,这样用户就不必等待网络了。预加载大型和小型模型。