THREE.js: 设置球体的绝对旋转,而不是累积旋转?

THREE.js: Set absolute rotation of sphere, rather than cumulative rotation?

我希望能够将 Three.js 球体的旋转设置为一个绝对值,但每当我设置 rotateY 时,我应用的值会在上次旋转中加上或减去, 而不是成为新的绝对旋转设置。

在有关立方体 (Three.js Set absolute local rotation) 的相关回答中,立方体具有 rotation 属性,并且 cube.rotation.x = someValue 导致我正在寻找的那种绝对旋转.

但是我正在使用的 SphereGeometry 对象(以世界地图作为其纹理)没有 rotation 属性。

我想我可以跟踪以前的轮换,并只应用差异,但我认为这最终会受到累积舍入误差的影响。

还有其他方法吗?某种重置方法?

  async orient(lon: number, lat: number): Promise<void> {
    if (Globe.mapFailed)
      throw new Error('Map not available');
    else if (!Globe.mapImage)
      await new Promise<void>((resolve, reject) => Globe.waitList.push({ resolve, reject }));

    if (!this.initialized) {
      this.camera = new PerspectiveCamera(FIELD_OF_VIEW, 1);
      this.scene = new Scene();
      this.globe = new SphereGeometry(GLOBE_RADIUS, 50, 50);

      const mesh = new Mesh(
        this.globe,
        new MeshBasicMaterial({
          map: new CanvasTexture(Globe.mapCanvas)
        })
      );

      this.renderer = new WebGLRenderer({ alpha: true });
      this.renderer.setSize(GLOBE_PIXEL_SIZE, GLOBE_PIXEL_SIZE);
      this.rendererHost.appendChild(this.renderer.domElement);
      this.scene.add(mesh);
      this.camera.position.z = VIEW_DISTANCE;
      this.camera.rotation.order = 'YXZ';
      this.initialized = true;
    }

    this.globe.rotateY(PI / 20); // Just a sample value I experimented with
    this.camera.rotation.z = (lat >= 0 ? PI : 0);
    requestAnimationFrame(() => this.renderer.render(this.scene, this.camera));
  }

更新:

我现在的解决方法是:

    this.globe.rotateX(-this.lat);
    this.globe.rotateY(this.lon);
    this.lon = to_radian(lon);
    this.lat = to_radian(lat);
    this.globe.rotateY(-this.lon);
    this.globe.rotateX(this.lat);

我正在保存之前完成的旋转,以便我可以撤消它们,然后应用新的旋转。 (Degree/radian 转换,以及需要反转的经度旋转符号,使过程有点模糊。)

我认为您感到困惑 geometry.rotateY(rot) with mesh.rotation.y = rot。如文档中所述:

.rotateY(): Rotate the geometry about the Y axis. This is typically done as a one time operation, and not during a loop. Use Object3D.rotation for typical real-time mesh rotation.

geometry.rotateY(rot) 应该只使用一次,因为它会更新所有顶点位置的值,所以它必须遍历每个顶点并更新它。如果您需要修改几何体的“原始状态”,这将很有用,例如需要开始面向 z-axis.

的角色模型

mesh.rotation.y = rot; 可能是您要查找的内容。这是您在实时旋转期间使用的,因此固有顶点位置保持不变,您只是旋转整个网格。例如,当您的角色在整个地图上 运行。

this.mesh = new Mesh(geometry, material);

// Set rotation to an absolute rotation value
this.mesh.rotation.y = Math.PI / 20;

// Increment rotation a relative amount (like once per frame):
this.mesh.rotation.y += Math.PI / 20;