Skip to content

Commit

Permalink
Fix #527 apply panorama pose and sphere correction together
Browse files Browse the repository at this point in the history
  • Loading branch information
mistic100 committed Mar 7, 2021
1 parent 0ad4290 commit 052c8a6
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 43 deletions.
54 changes: 31 additions & 23 deletions docs/.vuepress/components/Playground.vue
Original file line number Diff line number Diff line change
Expand Up @@ -157,24 +157,21 @@
</Tab>

<Tab label="Advanced options">
<div class="md-layout md-gutter">
<div class="md-layout md-gutter" style="margin-bottom: 30px">
<div class="md-layout-item md-size-33">
<md-field>
<label>Correction, pan</label>
<md-input v-model="options.sphereCorrection.pan" :disabled="!imageData"/>
</md-field>
<label class="md-caption">Correction, pan</label>
<vue-slider v-model="sphereCorrection.pan" :min="-180" :max="180" :marks="[-180,-90,0,90,180]"
:drag-on-click="true" :disabled="!imageData"/>
</div>
<div class="md-layout-item md-size-33">
<md-field>
<label>Correction, tilt</label>
<md-input v-model="options.sphereCorrection.tilt" :disabled="!imageData"/>
</md-field>
<label class="md-caption">Correction, tilt</label>
<vue-slider v-model="sphereCorrection.tilt" :min="-90" :max="90" :marks="[-90,0,90]"
:drag-on-click="true" :disabled="!imageData"/>
</div>
<div class="md-layout-item md-size-33">
<md-field>
<label>Correction, roll</label>
<md-input v-model="options.sphereCorrection.roll" :disabled="!imageData"/>
</md-field>
<label class="md-caption">Correction, roll</label>
<vue-slider v-model="sphereCorrection.roll" :min="-180" :max="180" :marks="[-180,-90,0,90,180]"
:drag-on-click="true" :disabled="!imageData"/>
</div>
</div>

Expand Down Expand Up @@ -235,22 +232,22 @@
export default {
data: () => ({
psv : null,
file : null,
imageData: null,
options : {
psv : null,
file : null,
imageData : null,
sphereCorrection: { pan: 0, tilt: 0, roll: 0 },
options : {
...omit(cloneDeep(DEFAULTS), ['panorama', 'panoData', 'container', 'plugins', 'navbar', 'loadingImg']),
sphereCorrection: { pan: 0, tilt: 0, roll: 0 }
},
panoData : {
panoData : {
fullWidth : null,
fullHeight : null,
croppedWidth : null,
croppedHeight: null,
croppedX : null,
croppedY : null,
},
navbar : [
navbar : [
{ code: 'autorotate', label: DEFAULTS.lang.autorotate, enabled: true },
{ code: 'zoom', label: DEFAULTS.lang.zoom, enabled: true },
{ code: 'download', label: DEFAULTS.lang.download, enabled: true },
Expand Down Expand Up @@ -294,19 +291,30 @@
this.psv = new Viewer({
container : 'viewer',
loadingImg: 'https://photo-sphere-viewer.js.org/assets/photosphere-logo.gif',
sphereCorrectionReorder: true,
});
this.loadPsv();
},
watch: {
options: {
options : {
deep: true,
handler() {
this.applyOptions();
},
},
navbar : {
sphereCorrection: {
deep: true,
handler() {
this.psv.setOption('sphereCorrection', {
pan : this.sphereCorrection.pan / 180 * Math.PI,
tilt: this.sphereCorrection.tilt / 180 * Math.PI,
roll: this.sphereCorrection.roll / 180 * Math.PI,
});
},
},
navbar : {
deep: true,
handler() {
this.psv.setOption('navbar', this.getNavbar());
Expand Down Expand Up @@ -355,7 +363,7 @@
},
loadDefaultFile() {
this.imageData = 'https://photo-sphere-viewer.js.org/assets/sphere.jpg';
this.imageData = 'https://photo-sphere-viewer-data.netlify.app/assets/sphere.jpg';
this.computePanoData(6000, 3000);
this.file = null;
this.loadPsv();
Expand Down
6 changes: 5 additions & 1 deletion docs/guide/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,14 @@ Requires two fingers to rotate the panorama. This allows standard touch-scroll n

Sphere rotation angles, in radians.

**Note** : This parameter is ignored if the XMP data and/or `panoData` contains heading/pitch/roll data.
**Note** : if the XMP data and/or `panoData` contains heading/pitch/roll data, they will be applied before `sphereCorrection`.

![pan-tilt-toll](/assets//pan-tilt-roll.png)

::: warning Future change in computation
In a future version the order in which the angles are applied will change. It is highly recommended to set `sphereCorrectionReorder: true` to any new viewer to enable the new behaviour.
:::

#### `moveSpeed`
- type: `double`
- default `1`
Expand Down
5 changes: 3 additions & 2 deletions src/Viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,8 @@ export class Viewer extends EventEmitter {
this.prop.loadingPromise = this.textureLoader.loadTexture(this.config.panorama, options.panoData)
.then((textureData) => {
this.renderer.setTexture(textureData);
this.renderer.setSphereCorrection(textureData.panoData, options.sphereCorrection);
this.renderer.setPanoramaPose(textureData.panoData);
this.renderer.setSphereCorrection(options.sphereCorrection);

if (zoomProvided) {
this.zoom(options.zoom);
Expand Down Expand Up @@ -560,7 +561,7 @@ export class Viewer extends EventEmitter {
break;

case 'sphereCorrection':
this.renderer.setSphereCorrection(this.prop.panoData, value);
this.renderer.setSphereCorrection(value);
break;

case 'navbar':
Expand Down
1 change: 1 addition & 0 deletions src/data/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const DEFAULTS = {
defaultLong : 0,
defaultLat : 0,
sphereCorrection : null,
sphereCorrectionReorder: false,
moveSpeed : 1,
zoomButtonIncrement: 2,
autorotateDelay : null,
Expand Down
2 changes: 1 addition & 1 deletion src/services/DataHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export class DataHelper extends AbstractService {

this.psv.renderer.raycaster.setFromCamera(screen, this.psv.renderer.camera);

const intersects = this.psv.renderer.raycaster.intersectObjects(this.psv.renderer.scene.children);
const intersects = this.psv.renderer.raycaster.intersectObjects(this.psv.renderer.scene.children, true);

if (intersects.length === 1) {
return intersects[0].point;
Expand Down
62 changes: 46 additions & 16 deletions src/services/Renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ export class Renderer extends AbstractService {
*/
this.mesh = null;

/**
* @member {external:THREE.Group}
* @readonly
* @private
*/
this.meshContainer = null;

/**
* @member {external:THREE.Raycaster}
* @readonly
Expand Down Expand Up @@ -105,6 +112,7 @@ export class Renderer extends AbstractService {
delete this.scene;
delete this.camera;
delete this.mesh;
delete this.meshContainer;
delete this.raycaster;

super.destroy();
Expand Down Expand Up @@ -202,13 +210,12 @@ export class Renderer extends AbstractService {
}

/**
* @summary Apply a SphereCorrection to a Mesh
* @summary Apply a panorama data pose to a Mesh
* @param {PSV.PanoData} [panoData]
* @param {PSV.SphereCorrection} [sphereCorrection]
* @param {external:THREE.Mesh} [mesh=this.mesh]
* @package
*/
setSphereCorrection(panoData, sphereCorrection, mesh = this.mesh) {
setPanoramaPose(panoData, mesh = this.mesh) {
if (!isNil(panoData?.poseHeading) || !isNil(panoData?.posePitch) || !isNil(panoData?.poseRoll)) {
// By Google documentation the angles are applied on the camera in order : heading, pitch, roll
// here we apply the reverse transformation on the sphere
Expand All @@ -218,18 +225,35 @@ export class Renderer extends AbstractService {
-THREE.Math.degToRad(panoData?.poseRoll || 0),
'ZXY'
);

if (sphereCorrection) {
logWarn('sphereCorrection was ignored because panoData already contains pose angles.');
}
}
else if (sphereCorrection) {
else {
mesh.rotation.set(0, 0, 0);
}
}

/**
* @summary Apply a SphereCorrection to a Mesh
* @param {PSV.SphereCorrection} [sphereCorrection]
* @param {external:THREE.Mesh} [mesh=this.meshContainer]
* @package
*/
setSphereCorrection(sphereCorrection, mesh = this.meshContainer) {
if (sphereCorrection) {
const cleanCorrection = this.psv.dataHelper.cleanSphereCorrection(sphereCorrection);

if (!this.config.sphereCorrectionReorder) {
const nonZeros = (cleanCorrection.tilt !== 0) + (cleanCorrection.pan !== 0) + (cleanCorrection.roll !== 0);
if (nonZeros > 1) {
logWarn(`"sphereCorrection" computation will change in a future version.
Please set "sphereCorrectionReorder: true" and modify your correction accordingly.`);
}
}

mesh.rotation.set(
cleanCorrection.tilt,
cleanCorrection.pan,
cleanCorrection.roll
cleanCorrection.roll,
this.config.sphereCorrectionReorder ? 'ZXY' : 'XYZ'
);
}
else {
Expand Down Expand Up @@ -261,7 +285,9 @@ export class Renderer extends AbstractService {
this.mesh = this.__createSphere();
}

this.scene.add(this.mesh);
this.meshContainer = new THREE.Group();
this.meshContainer.add(this.mesh);
this.scene.add(this.meshContainer);

// create canvas container
this.renderer.domElement.className = 'psv-canvas';
Expand Down Expand Up @@ -324,6 +350,7 @@ export class Renderer extends AbstractService {
let positionProvided = isExtendedPosition(options);
const zoomProvided = 'zoom' in options;

const group = new THREE.Group();
let mesh;

if (this.prop.isCubemap) {
Expand All @@ -347,7 +374,8 @@ export class Renderer extends AbstractService {
mesh.material.transparent = true;
mesh.material.opacity = 0;

this.setSphereCorrection(panoData, options.sphereCorrection, mesh);
this.setPanoramaPose(panoData, mesh);
this.setSphereCorrection(options.sphereCorrection, group);
}

// rotate the new sphere to make the target position face the camera
Expand All @@ -356,11 +384,11 @@ export class Renderer extends AbstractService {

// Longitude rotation along the vertical axis
const verticalAxis = new THREE.Vector3(0, 1, 0);
mesh.rotateOnWorldAxis(verticalAxis, cleanPosition.longitude - this.prop.position.longitude);
group.rotateOnWorldAxis(verticalAxis, cleanPosition.longitude - this.prop.position.longitude);

// Latitude rotation along the camera horizontal axis
const horizontalAxis = new THREE.Vector3(0, 1, 0).cross(this.camera.getWorldDirection(new THREE.Vector3())).normalize();
mesh.rotateOnWorldAxis(horizontalAxis, cleanPosition.latitude - this.prop.position.latitude);
group.rotateOnWorldAxis(horizontalAxis, cleanPosition.latitude - this.prop.position.latitude);

// TODO: find a better way to handle ranges
if (this.config.latitudeRange || this.config.longitudeRange) {
Expand All @@ -370,7 +398,8 @@ export class Renderer extends AbstractService {
}
}

this.scene.add(mesh);
group.add(mesh);
this.scene.add(group);
this.psv.needsUpdate();

return new Animation({
Expand Down Expand Up @@ -400,13 +429,14 @@ export class Renderer extends AbstractService {
.then(() => {
// remove temp sphere and transfer the texture to the main sphere
this.setTexture(textureData);
this.scene.remove(mesh);
this.scene.remove(group);

mesh.geometry.dispose();
mesh.geometry = null;

if (!this.prop.isCubemap) {
this.setSphereCorrection(panoData, options.sphereCorrection);
this.setPanoramaPose(panoData);
this.setSphereCorrection(options.sphereCorrection);
}

// actually rotate the camera
Expand Down

0 comments on commit 052c8a6

Please sign in to comment.