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;
我希望能够将 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;