通过单击重置按钮重置相机旋转

萨比尔33

我想做一个按钮。如果我单击该按钮,它将重置所有位置。如您进入VR。输入后,您会看到前面的一些图像。但有时由于运动,前景会移至其他位置。如果您想再次看到,则需要重新加载。所以我想制作一个按钮,将每个位置恢复原样。我怎样才能做到这一点?

<a-camera position="2 0 15" sound__click="src: #click-sound; on: click; positional: false;" id="listener">
  <a-cursor raycaster="objects: .clickable" 
            fuse-timeout="2000"
            material="color: #F4D03F; shader: flat" 
            opacity="0.9">
  </a-cursor>

</a-camera>



<a-gui-button resetOrientation
          id="resetOrientation"
          class="clickable"              
          position="0.184 -10 -0.032"
          width="2.5" height="0.75"
          key-code="59"
          value="Reset"
          font-family="Helvetica"
          background-color="#A04000"

      >
      </a-gui-button>

这是html代码。这是我的javaScript

AFRAME.registerComponent('resetOrientation', {
init: function () {
var button = document.querySelector("#resetOrientation");
var cameraPosition = document.querySelector("#listener");
var resetRotation = { x: 0, y: 0, z: 0 };
button.addEventListener('click', function () {
  var old = cameraPosition.getAttribute('rotation');
  console.log(old);
  var adjustedRotation = {
    x: adjustedRotation.x - old.x,
    y: adjustedRotation.y - old.y,
    z: adjustedRotation.z - old.z
  }
  cameraPosition.setAttribute("rotation", adjustedPosition);
   });
}
});

我该如何解决?

恩戈文

我们有一个recenterSupermedium组件。

而不是不旋转照相机,我们将整个场景包装在一个实体中,然后旋转它。因为在尝试读取VR中的相机旋转并尝试使用整个矩阵来取消设置时有些混乱,因为three.js处理了VR相机的姿势。SteamVR也存在疯狂的矛盾之处,因此我们在其中做了一些特殊的事情。迭戈花了几天时间在这个问题上:

/**
 * Pivot the scene when user enters VR to face the links.
 */
AFRAME.registerComponent('recenter', {
  schema: {
    target: {default: ''}
  },

  init: function () {
    var sceneEl = this.el.sceneEl;
    this.matrix = new THREE.Matrix4();
    this.frustum = new THREE.Frustum();
    this.rotationOffset = 0;
    this.euler = new THREE.Euler();
    this.euler.order = 'YXZ';
    this.menuPosition = new THREE.Vector3();
    this.recenter = this.recenter.bind(this);
    this.checkInViewAfterRecenter = this.checkInViewAfterRecenter.bind(this);
    this.target = document.querySelector(this.data.target);

    // Delay to make sure we have a valid pose.
    sceneEl.addEventListener('enter-vr', () => setTimeout(this.recenter, 100));
    // User can also recenter the menu manually.
    sceneEl.addEventListener('menudown', this.recenter);
    sceneEl.addEventListener('thumbstickdown', this.recenter);
    window.addEventListener('vrdisplaypresentchange', this.recenter);
  },

  recenter: function () {
    var euler = this.euler;
    euler.setFromRotationMatrix(this.el.sceneEl.camera.el.object3D.matrixWorld, 'YXZ');
    this.el.object3D.rotation.y = euler.y + this.rotationOffset;
    // Check if the menu is in camera frustum in next tick after a frame has rendered.
    setTimeout(this.checkInViewAfterRecenter, 0);
  },

  /*
   * Sometimes the quaternion returns the yaw in the [-180, 180] range.
   * Check if the menu is in the camera frustum after recenter it to
   * decide if we apply an offset or not.
   */
  checkInViewAfterRecenter: (function () {
    var bottomVec3 = new THREE.Vector3();
    var topVec3 = new THREE.Vector3();

    return function () {
      var camera = this.el.sceneEl.camera;
      var frustum = this.frustum;
      var menuPosition = this.menuPosition;

      camera.updateMatrix();
      camera.updateMatrixWorld();
      frustum.setFromMatrix(this.matrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse));

      // Check if menu position (and its bounds) are within the frustum.
      // Check bounds in case looking angled up or down, rather than menu central.
      menuPosition.setFromMatrixPosition(this.target.object3D.matrixWorld);
      bottomVec3.copy(menuPosition).y -= 3;
      topVec3.copy(menuPosition).y += 3;

      if (frustum.containsPoint(menuPosition) ||
          frustum.containsPoint(bottomVec3) ||
          frustum.containsPoint(topVec3)) { return; }

      this.rotationOffset = this.rotationOffset === 0 ? Math.PI : 0;
      // Recenter again with the new offset.
      this.recenter();
    };
  })(),

  remove: function () {
    this.el.sceneEl.removeEventListener('enter-vr', this.recenter);
  }
});

在HTML中:

 <a-entity id="scenePivot" recenter="target: #frontObject">
    <a-entity id="frontObject" data-description="When resetting, this object will be checked to see if user is facing it or not to confirm the reset."
  </a-entity>

  <a-camera></a-camera>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章