如何加载多个模型并将其添加到AR threex-artoolkit场景?

时间:2019-03-27 20:22:37

标签: javascript three.js collada artoolkit jsartoolkit

对于这个项目,我试图创建一个AR场景,其中不同的标记将显示不同的模型。

我能够使用Collada加载器加载和添加.DAE模型,并且按预期的方式,当用户进入网站时,浏览器会请求用户许可使用相机。

这是通过使用ColladaLoader来实现的,正如我之前所说的,将模型添加到名为model1的变量中,对其进行缩放,然后调用init函数。

此init函数创建渲染器,创建场景并添加相机等,处理浏览器调整大小并添加模型标记。

由于添加了一个模型,所以我认为可以添加更多模型,我只需复制并粘贴此colladaloader并将其指向其他模型并为其设置一个新标记。幸运的是,当我在移动设备上访问网站时,它非常缓慢,并要求我允许使用相机7/8次(是我加载模型的次数)。我认为这是由于加载了每个模型之后,它们都调用了init函数。因此,它创建并添加了与模型一样多的场景,相机,渲染等。

检查页面,您会发现每个模型都有一个新的canvas元素,而应该只有一个。

  <script type="text/javascript">


  var model1, axe, tree, sword, planks, minerals;

  var loader = new THREE.ColladaLoader();
  loader.load('greathallnow.DAE', function(collada) {

      model1 = collada.scene;
      model1.scale.x = model1.scale.y = model1.scale.z = 0.5;


      init();

  });

  var loader = new THREE.ColladaLoader();
  loader.load('axeyes.dae', function(collada) {

      axe = collada.scene;
      axe.scale.x = axe.scale.y = axe.scale.z = 0.3;


      init();

  });

  var loader = new THREE.ColladaLoader();
  loader.load('tree.dae', function(collada) {

      tree = collada.scene;
      tree.scale.x = tree.scale.y = tree.scale.z = 0.01;


      init();

  });

  var loader = new THREE.ColladaLoader();
  loader.load('swordplz.dae', function(collada) {

      sword = collada.scene;
      sword.scale.x = sword.scale.y = sword.scale.z = 0.3;


      init();

  });

  var loader = new THREE.ColladaLoader();
  loader.load('planks.dae', function(collada) {

      planks = collada.scene;
      planks.scale.x = planks.scale.y = planks.scale.z = 0.05;


      init();

  });

  var loader = new THREE.ColladaLoader();
  loader.load('stoneblockplural.dae', function(collada) {

      minerals = collada.scene;
      minerals.scale.x = minerals.scale.y = minerals.scale.z = 0.25;


      init();

  });





  function init() {
      // init renderer
      var renderer = new THREE.WebGLRenderer({
          antialias: true,
          alpha: true
      });
      renderer.setClearColor(new THREE.Color('lightgrey'), 0)
      renderer.setSize(640, 480);
      renderer.domElement.style.position = 'absolute'
      renderer.domElement.style.top = '0px'
      renderer.domElement.style.left = '0px'
      document.body.appendChild(renderer.domElement);

      // array of functions for the rendering loop
      var onRenderFcts = [];

      // init scene and camera
      var scene = new THREE.Scene();



      // Create a camera
      var camera = new THREE.Camera();
      scene.add(camera);
      var light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1);
      scene.add(light);



      var arToolkitSource = new THREEx.ArToolkitSource({
          sourceType: 'webcam'
      });
      arToolkitSource.init(function onReady() {
          onResize()
      });

      // handle resize
      window.addEventListener('resize', function() {
          onResize()
      });

      function onResize() {
          arToolkitSource.onResize()
          arToolkitSource.copySizeTo(renderer.domElement)
          if (arToolkitContext.arController !== null) {
              arToolkitSource.copySizeTo(arToolkitContext.arController.canvas)
          }
      }



      // create atToolkitContext
      var arToolkitContext = new THREEx.ArToolkitContext({
              cameraParametersUrl: THREEx.ArToolkitContext.baseURL + 'data/camera_para.dat',
              detectionMode: 'mono',
          })
          // initialize it
      arToolkitContext.init(function onCompleted() {
          // copy projection matrix to camera
          camera.projectionMatrix.copy(arToolkitContext.getProjectionMatrix());
      })

      // update artoolkit on every frame
      onRenderFcts.push(function() {
          if (arToolkitSource.ready === false) return
          arToolkitContext.update(arToolkitSource.domElement)
      })




      var markerRoot = new THREE.Group;
      scene.add(markerRoot);
      var artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot, {
          type: 'pattern',
          patternUrl: THREEx.ArToolkitContext.baseURL + 'data/ghall-marker.patt',
      });


      var markerRoot2 = new THREE.Group;
      scene.add(markerRoot2);
      var artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot2, {
          type: 'pattern',
          patternUrl: THREEx.ArToolkitContext.baseURL + 'data/axe.patt',
      });

      var markerRoot3 = new THREE.Group;
      scene.add(markerRoot3);
      var artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot3, {
          type: 'pattern',
          patternUrl: THREEx.ArToolkitContext.baseURL + 'data/tree.patt', });

      var markerRoot4 = new THREE.Group;
      scene.add(markerRoot4);
      var artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot4, {
          type: 'pattern',
          patternUrl: THREEx.ArToolkitContext.baseURL + 'data/sword.patt', });

      var markerRoot5 = new THREE.Group;
      scene.add(markerRoot5);
      var artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot5, {
          type: 'pattern',
          patternUrl: THREEx.ArToolkitContext.baseURL + 'data/planks.patt', });

      var markerRoot6 = new THREE.Group;
      scene.add(markerRoot6);
      var artoolkitMarker = new THREEx.ArMarkerControls(arToolkitContext, markerRoot6, {
          type: 'pattern',
          patternUrl: THREEx.ArToolkitContext.baseURL + 'data/minerals.patt', });




      markerRoot.add(model1);
      markerRoot2.add(axe);
      markerRoot3.add(tree);
      markerRoot4.add(sword);
      markerRoot5.add(planks);
      markerRoot6.add(minerals);





      // render the scene
      onRenderFcts.push(function() {
          renderer.render(scene, camera);
      })

      // run the rendering loop
      var lastTimeMsec = null
      requestAnimationFrame(function animate(nowMsec) {
          // keep looping
          requestAnimationFrame(animate);
          // measure time
          lastTimeMsec = lastTimeMsec || nowMsec - 1000 / 60;
          var deltaMsec = Math.min(200, nowMsec - lastTimeMsec);
          lastTimeMsec = nowMsec;
          TWEEN.update();
          // call each update function
          onRenderFcts.forEach(function(onRenderFct) {
              onRenderFct(deltaMsec / 1000, nowMsec / 1000);
          })
      });
  }

  </script>

我不认为每个模型都需要调用init函数,相反,我认为应该全部加载它们,然后只有一个init()可以将它们全部添加到场景并渲染它们。希望这也会改善性能。我只是不确定该怎么做?

如果您访问https://arevisit.madamot.com

,就会看到我遇到的问题

或者您可以查看此YouTube视频中当前发生的情况 https://youtu.be/DjJdsBtfgvM

非常感谢, 亚当

0 个答案:

没有答案