简体   繁体   English

使用three.js更改alt场景中gltf模型的位置

[英]change position of gltf-model in a-frame scene using three.js

I have gltf-model loaded to a-frame and I want to move it by y-axis by 20. I use this code: 我已将gltf-model加载到a框架,并且想将其沿y轴移动20。我使用以下代码:

The problem appears in a-frame scene, actually the object is moved up (check shadows and scene inspector in "after" images), but it still displayed on it's previous position. 问题出现在一个框架的场景中,实际上该对象被向上移动(在“之后”的图像中检查阴影和场景检查器),但是它仍显示在其先前位置。 It seems that the scene needs some kind of refresh. 似乎场景需要某种刷新。

The question is, how to move it properly with three.js code? 问题是,如何使用Three.js代码正确移动它?
BEFORE: BEFORE1 BEFORE2 之前: BEFORE1 BEFORE2


AFTER: AFTER1 AFTER2 后: 1后

Code: 码:

<html>

<a-scene>
  <a-sky color="#f9f2cf"></a-sky>

  <!-- LIGHT a-frame no need to export from blender -->
  <a-light color="#fff" position="-8 5 0" intensity="3.5" light="intensity:2"></a-light>
  <a-light color="#fff" position="0 5 -14.163" intensity="3.5" light="intensity:2"></a-light>
  <a-light color="#fff" position="0 5 14.192" intensity="3.5" light="intensity:2"></a-light>
  <a-light color="#fff" position="0 -9.574 -2.443" intensity="3.5" light="intensity:2"></a-light>
  <a-light color="#fff" position="8.5 5 0" intensity="3.5" light="intensity:2"></a-light>

  <!-- CAMERA with wasd controls and circle cursor -->
  <a-camera fly look-controls wasd-controls position="17.020 16.700 7.958" rotation="-34.149 89.382 0.000">  
    <a-entity 
      cursor="fuse: true; fuseTimeout: 500"
      position="0 0 -1"
      geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03"
      material="color: black; shader: flat">
    </a-entity>
  </a-camera>

  <a-assets>
    <!-- GLTF animation samples -->
    <a-asset-item id="afb_animation" src="models/afb_animation.gltf"></a-asset-item>
  </a-assets>

  <a-entity id="_afb_animation" position="0 0 0"  gltf-model="#afb_animation" ></a-entity>
</a-scene>

<!-- script change model position -->
<script>

  $( document ).ready(function() {

    var xAxis = new THREE.Vector3(1,0,0);

    setTimeout(function(){
      console.log("rotation: done");

      document.querySelector('#_afb_animation').sceneEl.object3D.translateY(20);

    }, 3000);

  });
</script>

One way to solve your problem is using the setAttribute method (official wiki here ) on the position component . 解决问题的一种方法是在position组件上使用setAttribute方法( 此处为官方Wiki)。

For example: 例如:

entity.setAttribute('position', { x: 1, y: 2, z: 3 });

where entity is any A-Frame entity. 其中,entity是任何A-Frame实体。

Example 1 例子1

So, in the following code I registered an A-Frame component called move-my-model that allows me to move my entity (in my case is a <a-box> entity but it will work also with your model) adding 10 to its y-position after 3000ms with setTimeout (such as your code example): 因此,在下面的代码中,我注册了一个名为move-my-modelA框架组件,该组件允许我移动实体(在我的情况下是<a-box>实体,但它也适用于您的模型),向其中添加10 setTimeout在3000ms之后的y位置(例如您的代码示例):

 <script src="https://aframe.io/releases/0.7.0/aframe.min.js"></script> <script> AFRAME.registerComponent('move-my-model', { init: function () { setTimeout( () => { let position = this.el.getAttribute("position") position.y += 10 this.el.setAttribute("position", position) }, 3000) } }) </script> <a-scene> <a-sky color="#f9f2cf"></a-sky> <!-- LIGHT a-frame no need to export from blender --> <a-light color="#fff" position="-8 5 0" intensity="3.5" light="intensity:2"></a-light> <a-light color="#fff" position="0 5 -14.163" intensity="3.5" light="intensity:2"></a-light> <a-light color="#fff" position="0 5 14.192" intensity="3.5" light="intensity:2"></a-light> <a-light color="#fff" position="0 -9.574 -2.443" intensity="3.5" light="intensity:2"></a-light> <a-light color="#fff" position="8.5 5 0" intensity="3.5" light="intensity:2"></a-light> <!-- CAMERA with wasd controls and circle cursor --> <a-camera fly look-controls wasd-controls position="17.020 16.700 7.958" rotation="-34.149 89.382 0.000"> <a-entity cursor="fuse: true; fuseTimeout: 500" position="0 0 -1" geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03" material="color: black; shader: flat"> </a-entity> </a-camera> <a-box move-my-model position="5.020 8.500 7.958" rotation="0 0 0" color="#4CC3D9"></a-box> </a-scene> 

Example 2 例子2

Instead, if you need a more complex animation, I wrote an A-Frame component called animation-move on my own when I worked the first time on the A-Frame framework, that is: 相反,如果您需要更复杂的动画,那么当我第一次在A-Frame框架上工作时,我自己编写了一个名为animation-move的A-Frame组件,即:

 <script src="https://aframe.io/releases/0.7.0/aframe.min.js"></script> <script> AFRAME.registerComponent('animation-move', { schema: { path: { default: [], parse: function (value) { return JSON.parse(value); } }, animationStepTime: { type: 'int', default: 0 } }, init: function(){ this.next = 0; let object = this.el; for (let prop in this.data.path[this.next]) { object.setAttribute( prop, this.data.path[this.next][prop] ); } }, tick: function (time, timeDelta) { let updated = false if ( this.next >= this.data.path.length ) { this.next = 0; } let delta = this.data.animationStepTime / (16.7 * ((this.data.animationStepTime+timeDelta)/this.data.animationStepTime)); let object = this.el; for (let prop in this.data.path[this.next]) { let attr = object.getAttribute(prop); let nextStep = this.data.path[this.next][prop]; let xDelta = Math.abs( (this.next-1 >= 0) ? nextStep.x - this.data.path[this.next-1][prop].x : nextStep.x - this.data.path[this.data.path.length-1][prop].x)/delta; let yDelta = Math.abs( (this.next-1 >= 0) ? nextStep.y - this.data.path[this.next-1][prop].y : nextStep.y - this.data.path[this.data.path.length-1][prop].y)/delta; let zDelta = Math.abs( (this.next-1 >= 0) ? nextStep.z - this.data.path[this.next-1][prop].z : nextStep.z - this.data.path[this.data.path.length-1][prop].z)/delta; if (attr.x != nextStep.x) { if ((this.next-1 >= 0 && nextStep.x < this.data.path[this.next-1][prop].x) || (this.next == 0 && nextStep.x < this.data.path[this.data.path.length-1][prop].x)) { if (attr.x-xDelta < nextStep.x) { attr.x = nextStep.x; } else { attr.x -= xDelta; updated = true; } } else if (this.next-1 >= 0 && nextStep.x > this.data.path[this.next-1][prop].x || (this.next == 0 && nextStep.x > this.data.path[this.data.path.length-1][prop].x)) { if (attr.x+xDelta > nextStep.x) { attr.x = nextStep.x; } else { attr.x += xDelta; updated = true; } } else { attr.x = nextStep.x; } } if (attr.y != nextStep.y) { if (this.next-1 >= 0 && nextStep.y < this.data.path[this.next-1][prop].y || (this.next == 0 && nextStep.y < this.data.path[this.data.path.length-1][prop].y)) { if (attr.y-yDelta < nextStep.y) { attr.y = nextStep.y; } else { attr.y -= yDelta; updated = true; } } else if (this.next-1 >= 0 && nextStep.y > this.data.path[this.next-1][prop].y || (this.next == 0 && nextStep.y > this.data.path[this.data.path.length-1][prop].y)) { if (attr.y+yDelta > nextStep.y) { attr.y = nextStep.y; } else { attr.y += yDelta; updated = true; } } else { attr.y = nextStep.y; } } if (attr.z != nextStep.z) { if (this.next-1 >= 0 && nextStep.z < this.data.path[this.next-1][prop].z || (this.next == 0 && nextStep.z < this.data.path[this.data.path.length-1][prop].z)) { if (attr.z-zDelta < nextStep.z) { attr.z = nextStep.z; } else { attr.z -= zDelta; updated = true; } } else if (this.next-1 >= 0 && nextStep.z > this.data.path[this.next-1][prop].z || (this.next == 0 && nextStep.z > this.data.path[this.data.path.length-1][prop].z)) { if (attr.z+zDelta > nextStep.z) { attr.z = nextStep.z; } else { attr.z += zDelta; updated = true; } } else { attr.z = nextStep.z; } } object.setAttribute( prop, attr.x+' '+attr.y+' '+attr.z ); } if (!updated) { this.next++; } } }); </script> <a-scene> <a-sky color="#f9f2cf"></a-sky> <!-- LIGHT a-frame no need to export from blender --> <a-light color="#fff" position="-8 5 0" intensity="3.5" light="intensity:2"></a-light> <a-light color="#fff" position="0 5 -14.163" intensity="3.5" light="intensity:2"></a-light> <a-light color="#fff" position="0 5 14.192" intensity="3.5" light="intensity:2"></a-light> <a-light color="#fff" position="0 -9.574 -2.443" intensity="3.5" light="intensity:2"></a-light> <a-light color="#fff" position="8.5 5 0" intensity="3.5" light="intensity:2"></a-light> <!-- CAMERA with wasd controls and circle cursor --> <a-camera fly look-controls wasd-controls position="17.020 16.700 7.958" rotation="-34.149 89.382 0.000"> <a-entity cursor="fuse: true; fuseTimeout: 500" position="0 0 -1" geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03" material="color: black; shader: flat"> </a-entity> </a-camera> <a-box animation-move='path: [ {"position": {"x": 15.020, "y": 15.500, "z": 7.958}}, {"position": {"x": 10, "y": 17.000, "z": 5}} ]; animationStepTime: 1500' rotation="0 0 0" color="#4CC3D9"></a-box> </a-scene> 

More complex example 更复杂的例子

Here you can find my A-Frame example with some other A-Frame components such as the last one! 在这里,您可以找到我的A框架示例以及其他一些A框架组件,例如最后一个! This example shows the reconstructed facade of the St. Margherita church of l'Aquila (Italy) with some light animation and interactive panels. 此示例显示了拉奎拉(意大利)圣玛格丽特教堂的重建外立面,并带有一些灯光动画和交互式面板。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM