mistic100 / Photo-Sphere-Viewer

A JavaScript library to display 360° sphere panoramas.
https://photo-sphere-viewer.js.org
MIT License
1.89k stars 681 forks source link

Real-world compass headings - configuration? #1300

Closed jywarren closed 4 months ago

jywarren commented 5 months ago

Describe your problem

I'm trying to get my photospheres to display with their image north pointed to real-world north -- that is, if I go to that site today, and look at the photosphere, it'll line up.

I used

           const viewer = new Viewer({
                container: 'viewer',
                panorama: 'test.jpg',
                panoData: {
                  poseHeading: 100
                },

But as I turn my phone around to test, it starts with the same image direction visible no matter how I am standing regarding the real-world compass directions. Am I missing something about how to configure a panorama to be pegged to the true real-world compass directions?

Thank you so much! This is such a lovely library! <3

Online demo URL

No response

Photo Sphere Viewer version

5.7.3

Plugins loaded

Gyro, stereo

Additional context

No response

mistic100 commented 4 months ago

did you try this ? https://photo-sphere-viewer.js.org/plugins/gyroscope.html#absoluteposition

jywarren commented 4 months ago

TY I will!

jywarren commented 4 months ago

Ah, actually I do have that set.

            import { Viewer } from '@photo-sphere-viewer/core';
            import { GyroscopePlugin } from '@photo-sphere-viewer/gyroscope-plugin';
            import { StereoPlugin } from '@photo-sphere-viewer/stereo-plugin';

            const baseUrl = '';//'https://jywarren.github.io/sfpcrr/';

            let params = new URLSearchParams(document.location.search);

            const viewer = new Viewer({
                container: 'viewer',
                panorama: baseUrl + (params.get("url") || 'spheres/providence.jpg'),
                panoData: {
                  poseHeading: (params.get("heading") || 0), // 0 to 360
                },
                defaultZoomLvl: 0,
                navbar: [
                  'stereo'
                ],
                plugins: [
                    StereoPlugin,
                    [GyroscopePlugin, {
                      absolutePosition: true,
                      moveMode: 'fast',
                    }]
                ],
            });
            window.viewer = viewer;
            viewer.addEventListener('ready', () => {
              viewer.getPlugin(GyroscopePlugin).start();
            }, { once: true });

Is there perhaps a load order issue? I.e. the poseHeading is initialized first, then the gyroscope plugin starts too late?

Thank you!!

mistic100 commented 4 months ago

Those are two totally different things, poseHeading is applied on the 3D sphere object itself, it rotates the sphere in the scene, after that it is locked.

With absolutePosition: true the alpha angle reported by the gyroscope is directly applied to the scene camera yaw; without any offset.

You might be in the case explained in the big yellow WARNING box on the documentation page. For which I cannot do anything.

jywarren commented 4 months ago

Ok, I see - thank you! I'm going to research more about this, i found what seems like a good overview at https://leanpub.com/gyronormjs

mistic100 commented 4 months ago

I was able to fix a bug which makes the heading remaining the same between gyroscope activations on the same session.

However it does not changes the fact that if you reload the page, the initial device orientation will be used as the origin. Because the API is not meant to find where the North is, it is only relative positionning since activation.

There is the geolocation API but it does not give a static compass value, only "heading" when the device is in movement, so not useable here.

mistic100 commented 4 months ago

Found the "deviceorientationabsolute" event which seems promising, but of course iOS does not support it.

github-actions[bot] commented 4 months ago

This feature/bug fix has been released in version 5.7.4.

jywarren commented 4 months ago

Thank you - i see that various implementations of compass functionality in JS seem to use that geolocation heading -- but if I understand you, that is not really a compass but calculating heading based on multiple lat/lon coordinates over time, so you have to be moving for it to "guess" which way you're facing? i.e. https://joeyklee.github.io/compass.js/docs/global.html#getHeading

I do see there is a webkitcompassheading value documented here: https://developer.apple.com/documentation/webkitjs/deviceorientationevent/1804777-webkitcompassheading and mentioned here: https://developer.mozilla.org/en-US/docs/Web/API/DeviceOrientationEvent#instance_properties

I see a recommendation of usage here:

window.addEventListener('deviceorientation', function(event) {
  if (event.webkitCompassHeading) {
    // You may consider adding/distracting landscape/portrait mode value here
    alpha = event.webkitCompassHeading;
    if (alpha < 0) { alpha += 360; }
    if (alpha > 360) { alpha -= 360; }
  }
}  

Do you think this could be a workable iOS solution? Thank you so much.

jywarren commented 4 months ago

Ah, indeed this is a great page with all browsers' compass APIs documented: https://chrishewett.com/blog/device-orientation-test-page/

including deviceorientationabsolute for Chrome/Android and webkitCompassHeading for iOS.

Also wanted to report back that your latest changes WORK perfectly on my (Android) Pixel 5. However, there is a lot of jitter. So I turned moveMode: 'smooth' back on (which hadn't been necessary before) and it's much better. So all good, just a small note for others looking to do this!

Do you accept PRs from others? Would you be open to a PR adapting this to webkitCompassHeading as well? Thank you again!

mistic100 commented 3 months ago

Yes you can try to add it. It will probably had to be included in alphaOffset.