I have encountered an issue with setting the rotation of a Three.js sphere to an absolute value. Whenever I use rotateY
, the value I apply gets added or subtracted from the previous rotation instead of setting a new absolute rotation.
In a similar scenario involving a cube (Three.js Set absolute local rotation), changing cube.rotation.x = someValue
achieves the absolute rotation that I am aiming for.
Unfortunately, the SphereGeometry
object I am using (which has a world map texture) does not have a rotation
attribute.
I could potentially keep track of past rotations and only apply the difference, but this approach might eventually lead to cumulative round-off errors.
Is there any alternative method to accomplish this? Perhaps a reset function of some sort?
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));
}
Update:
As a temporary solution, I implemented the following workaround:
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);
I am storing the previous rotations performed so that I can reverse them before applying new rotations. The conversion between degrees and radians, along with the need to reverse the sign of longitude rotation, make the process slightly complex.