From 7cc778e1cc8723a83d721c2fbd2f25dada5e3912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Pe=CC=81ault?= Date: Mon, 26 Sep 2022 20:00:17 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8Globe:=20Position=20camera=20to=20curr?= =?UTF-8?q?ent=20continent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Quite complex to figure out but needed to use spherical coordinates to apply to the camera, inspired from Three.js Thanks @Tape on Discord/Three.js! --- .../organisms/InteractiveGlobe.svelte | 5 ++- src/modules/globe/index.ts | 31 +++++++++++++------ src/routes/+layout.server.ts | 3 +- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/components/organisms/InteractiveGlobe.svelte b/src/components/organisms/InteractiveGlobe.svelte index 8c63c38..63ff01a 100644 --- a/src/components/organisms/InteractiveGlobe.svelte +++ b/src/components/organisms/InteractiveGlobe.svelte @@ -52,7 +52,10 @@ autoRotate, speed, sunAngle: 2, - rotationStart: randomContinent.rotation, + rotationStart: { + x: randomContinent.rotation_x, + y: randomContinent.rotation_y, + }, enableMarkers, enableMarkersLinks: enableMarkersLinks && type !== 'cropped', markers, diff --git a/src/modules/globe/index.ts b/src/modules/globe/index.ts index 44a0626..ca4b3ee 100644 --- a/src/modules/globe/index.ts +++ b/src/modules/globe/index.ts @@ -16,11 +16,7 @@ export class Globe { this.width = this.el.offsetWidth this.height = this.el.offsetHeight this.markers = options.markers || [] - this.globeZoom = 1.3075 - this.globeRotation = { - lat: degToRad(-this.options.rotationStart) || 0, - // lng: degToRad(-this.options.rotationStart.lng) || 0, - } + this.zoom = 1.3075 // Calculate the current sun position from a given location const locations = [ @@ -93,7 +89,12 @@ export class Globe { // Create camera this.camera = new Camera(this.gl) - this.camera.position.set(0, 0, this.globeZoom) + this.camera.position.set(setFromSphericalCoords( + this.zoom, + degToRad(this.options.rotationStart.y || 40), // phi: y + degToRad(this.options.rotationStart.x || 0), // theta: x + )) + this.camera.lookAt(0,0,0) // Create controls this.controls = new Orbit(this.camera, { @@ -285,8 +286,7 @@ export class Globe { // Rotate globe if not dragging neither hovering marker if (this.params.autoRotate && !this.hoveringMarker) { - this.globeRotation.lat += this.params.speed * delta - this.globe.rotation.y = this.globeRotation.lat + this.globe.rotation.y += this.params.speed * delta } // Update controls and renderer @@ -340,7 +340,7 @@ type Options = { autoRotate: boolean speed: number sunAngle: number - rotationStart?: number + rotationStart?: { x: number, y: number } enableMarkers?: boolean enableMarkersLinks?: boolean markers?: any[] @@ -390,6 +390,19 @@ const latLonToVec3 = (lat: number, lng: number) => { return new Vec3(x,y,z) } + +/** + * Get position from spherical coordinates + */ +const setFromSphericalCoords = (radius: number, phi: number, theta: number) => { + const sinPhiRadius = Math.sin(phi) * radius + const x = sinPhiRadius * Math.sin(theta) + const y = Math.cos(phi) * radius + const z = sinPhiRadius * Math.cos(theta) + + return new Vec3(x,y,z) +} + /** * Convert Degrees to Radians */ diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts index f6a508f..0701f1c 100644 --- a/src/routes/+layout.server.ts +++ b/src/routes/+layout.server.ts @@ -44,7 +44,8 @@ export const load: PageServerLoad = async () => { continents: continent (filter: { countries: { slug: { _neq: "_empty" }}}) { name slug - rotation + rotation_x + rotation_y } settings {