Как получить реальное положение в пространстве объекта в кадре?

#aframe

Вопрос:

Я пробовал несколько способов получить положение элемента сразу после анимации, но каждый раз я получаю жестко запрограммированную позицию объекта, который я ввел. Я использовал функцию галочки для постоянного отслеживания объекта. Это следующие способы, которыми я пытался отслеживать текущее местоположение объекта, но один из них возвращает позицию, которую я назначил объекту. Является ли это ошибкой в aframe 1.2.0, потому что в предыдущих версиях он работал нормально.

 Object.values(el.getAttribute('position')) el.object3D.animations Object.values(document.querySelector('#duck1').object3D.getWorldPosition(new THREE.Vector3())) Object.values(el.object3D.getWorldPosition(new THREE.Vector3()))   

Для справки я также добавил живой код. Сразу после наведения курсора мыши на куб запустится анимация. После окончания анимации местоположение объекта будет показано в console.log записи

Код:

 lt;htmlgt; lt;headgt;  lt;meta name="viewport" content="width=device-width, initial-scale=1"gt;  lt;script src="https://aframe.io/releases/1.2.0/aframe.min.js"gt;lt;/scriptgt;  lt;scriptgt;  AFRAME.registerComponent('eventhandling', {  tick: function () {  var el = this.el;  var entity = document.querySelector('#duck1');  el.addEventListener('animationcomplete', function(){  console.log("getAttribute: " Object.values(el.getAttribute('position')));  console.log("object3D.position: " (el.object3D.animations));  console.log("document.querySelector: "  Object.values(document.querySelector('#duck1').object3D.getWorldPosition(new THREE.Vector3())));  console.log("object3D.getWorldPosition(new THREE.Vector3()): " Object.values(el.object3D.getWorldPosition(new THREE.Vector3())));  entity.emit('starteventforAnimation');   });  }  });    lt;/scriptgt; lt;/headgt;  lt;bodygt;  lt;a-scenegt; lt;a-entity class="rota" id="duck1" color="#FF0000" scale="0.1 0.1 .1" position="2 0 -7" animation="property: rotation;from: ; to:0 -360 0; loop:true; easing:linear; dur:30000; pauseEvents: mouseenter; resumeEvents: starteventforAnimation " animation__mouseenter="property: rotation;from: ; to:0 360 0; easing:linear; dur:4000; startEvents: mouseenter ;pauseEvents: starteventforAnimation; resumeEvents: mouseenter" eventhandlinggt;  lt;a-box class="rota" color="#FF0000" gltf-model="spaceship.glb" position="20 0 -10" scale="2 3 3" collison-check="el: #otherduck; radius: 0.15; other-radius: 0.15;"gt; lt;/a-boxgt;  lt;/a-entitygt; lt;a-camera position="0 1.2 1.3"gt;lt;a-cursor objects=".rota" gt;lt;/a-cursorgt;lt;/a-cameragt; lt;   lt;/a-scenegt; lt;/bodygt; lt;/htmlgt; 

Комментарии:

1. слушателей не должно быть tick , вы добавляете новый в каждом цикле рендеринга

Ответ №1:

Вы ищете что-то под названием «мировое положение».

Сфера всегда находится в одном и том же положении относительно коробки. Вращение коробки заставляет сферу двигаться, потому что вращается вся система отсчета. Его локальное положение остается прежним, но его мировое положение меняется.

Одним из способов занять мировое положение было бы:

 // local position this.el.getAttribute("position");  // grab the reference to the underlaying object const mesh = this.el.getObject3D("mesh"); // or const mesh = this.el.object3D;   // create a vector where the position will be copied to const worldpos = new THREE.Vector3();  // get the world position - it's in the worldpos vector mesh.getWorldPosition(worldpos);    

Как я сделал это здесь:

 lt;script src="https://aframe.io/releases/1.2.0/aframe.min.js"gt;lt;/scriptgt; lt;scriptgt;  AFRAME.registerComponent("foo", {  init: function() {  // i'll keep the local position here  this.localpos = new THREE.Vector3();  // I'll keep the world position here  this.worldpos = new THREE.Vector3();  // this is the reference to the lt;pgt; element  this.textEl = document.querySelector("p")  },  // utility function  posToString: function(pos) {  return pos.x.toFixed(2)   " "   pos.y.toFixed(2)   " "   pos.z.toFixed(2);  },  // called on each frame  tick: function() {  // getAttribute("position") has the local position  // this.el.object3D.position has the local position  // this.el.getObject3D("mesh").position has the local position  this.localpos.copy(this.el.getAttribute("position"))  this.el.getObject3D("mesh").getWorldPosition(this.worldpos)   // compose the displayed message  let msg = "";  msg  = "Sphere local position:"   this.posToString(this.localpos)  msg  = "lt;brgt;"  msg  = "Sphere world position:"   this.posToString(this.worldpos)  this.textEl.innerHTML = msg  }  }) lt;/scriptgt; lt;p style="position: fixed; z-index: 999;"gt;lt;/pgt; lt;a-scenegt;  lt;a-box position="0 1 -4" color="blue"   animation="property: rotation;from: ; to:0 -360 0; loop:true; easing:linear; dur:3000"gt;  lt;a-sphere position="2 0 0" color="green" radius="0.25" foogt;lt;/a-spheregt;  lt;/a-boxgt; lt;/a-scenegt;