Skip to content

Commit

Permalink
fix panoData
Browse files Browse the repository at this point in the history
  • Loading branch information
mistic100 committed Sep 17, 2024
1 parent 395d148 commit 20be91b
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 41 deletions.
4 changes: 4 additions & 0 deletions docs/guide/adapters/equirectangular-video.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,7 @@ const viewer = new Viewer({
},
});
```

::: tip `panoData` support
It is possible to declare the [`panoData`](../config.md#panodata) option if the video does not cover a full sphere.
:::
22 changes: 21 additions & 1 deletion docs/guide/adapters/equirectangular.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ The XMP payload is as follow:
<!-- initial view information -->
<GPano:InitialViewHeadingDegrees>0</GPano:InitialViewHeadingDegrees>
<GPano:InitialViewPitchDegrees>0</GPano:InitialViewPitchDegrees>
<GPano:InitialHorizontalFOVDegrees>0</GPano:InitialHorizontalFOVDegrees>
<GPano:InitialHorizontalFOVDegrees>60</GPano:InitialHorizontalFOVDegrees>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
Expand Down Expand Up @@ -146,6 +146,26 @@ const viewer = new PhotoSphereViewer.Viewer({
});
```

#### Default parameters

If the image does not have a 2:1 ratio and no XMP data are found and no `panoData` is provided, a best effort is done to display the image without distortion. The exact algorithm is as follow:

```js
const fullWidth = Math.max(img.width, img.height * 2);
const fullHeight = Math.round(fullWidth / 2);
const croppedX = Math.round((fullWidth - img.width) / 2);
const croppedY = Math.round((fullHeight - img.height) / 2);

panoData = {
fullWidth: fullWidth,
fullHeight: fullHeight,
croppedWidth: img.width,
croppedHeight: img.height,
croppedX: croppedX,
croppedY: croppedY,
};
```

### Playground

Use this demo to find the best values for your image.
Expand Down
4 changes: 0 additions & 4 deletions docs/guide/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,6 @@ panoData: (image, xmpData) => ({
});
```

::: warning
Only the default [equirectangular](./adapters/equirectangular.md) adapter supports `panoData`.
:::

#### `moveSpeed`

- type: `double`
Expand Down
32 changes: 21 additions & 11 deletions packages/cubemap-tiles-adapter/src/CubemapTilesAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ import { CubemapAdapter, CubemapData, CubemapFaces } from '@photo-sphere-viewer/
import { BoxGeometry, BufferAttribute, Group, Mesh, MeshBasicMaterial, Texture, Vector3 } from 'three';
import { Queue, Task } from '../../shared/Queue';
import { buildDebugTexture, buildErrorMaterial, createWireFrame } from '../../shared/tiles-utils';
import { CubemapMultiTilesPanorama, CubemapTilesAdapterConfig, CubemapTilesPanorama } from './model';
import { CubemapMultiTilesPanorama, CubemapTilesAdapterConfig, CubemapTilesPanoData, CubemapTilesPanorama } from './model';
import { CubemapTileConfig, checkPanoramaConfig, getTileConfig, getTileConfigByIndex, isTopOrBottom } from './utils';

type CubemapMesh = Mesh<BoxGeometry, MeshBasicMaterial[]>;
type CubemapTilesMesh = Mesh<BoxGeometry, MeshBasicMaterial[]>;
type CubemapTilesTextureData = TextureData<Texture[], CubemapTilesPanorama | CubemapMultiTilesPanorama, CubemapData>;
type CubemapTilesTextureData = TextureData<
Texture[],
CubemapTilesPanorama | CubemapMultiTilesPanorama,
CubemapTilesPanoData
>;
type CubemapTile = {
face: number;
col: number;
Expand Down Expand Up @@ -58,7 +62,7 @@ const vertexPosition = new Vector3();
*/
export class CubemapTilesAdapter extends AbstractAdapter<
CubemapTilesPanorama | CubemapMultiTilesPanorama,
CubemapData,
CubemapTilesPanoData,
Texture[],
Group
> {
Expand Down Expand Up @@ -156,11 +160,11 @@ export class CubemapTilesAdapter extends AbstractAdapter<
return !!panorama.baseUrl;
}

override textureCoordsToSphericalCoords(point: PanoramaPosition, data: CubemapData): Position {
override textureCoordsToSphericalCoords(point: PanoramaPosition, data: CubemapTilesPanoData): Position {
return this.adapter.textureCoordsToSphericalCoords(point, data);
}

override sphericalCoordsToTextureCoords(position: Position, data: CubemapData): PanoramaPosition {
override sphericalCoordsToTextureCoords(position: Position, data: CubemapTilesPanoData): PanoramaPosition {
return this.adapter.sphericalCoordsToTextureCoords(position, data);
}

Expand All @@ -182,14 +186,20 @@ export class CubemapTilesAdapter extends AbstractAdapter<

return {
panorama,
panoData,
panoData: {
...panoData,
baseData: textureData.panoData,
},
cacheKey: textureData.cacheKey,
texture: textureData.texture,
};
} else {
return {
panorama,
panoData,
panoData: {
...panoData,
baseData: null,
},
cacheKey: panorama.tileUrl('front', 0, 0, 0),
texture: null,
};
Expand Down Expand Up @@ -241,7 +251,7 @@ export class CubemapTilesAdapter extends AbstractAdapter<
this.adapter.setTexture(baseMesh, {
panorama: textureData.panorama.baseUrl,
texture: textureData.texture,
panoData: textureData.panoData,
panoData: textureData.panoData.baseData,
});
} else {
baseMesh.visible = false;
Expand Down Expand Up @@ -281,8 +291,8 @@ export class CubemapTilesAdapter extends AbstractAdapter<
return;
}

const panorama: CubemapTilesPanorama | CubemapMultiTilesPanorama = this.viewer.state.textureData.panorama;
const panoData: CubemapData = this.viewer.state.textureData.panoData;
const panorama = this.viewer.state.textureData.panorama as CubemapTilesPanorama | CubemapMultiTilesPanorama;
const panoData = this.viewer.state.textureData.panoData as CubemapTilesPanoData;
const zoomLevel = this.viewer.getZoomLevel();
const tileConfig = getTileConfig(panorama, zoomLevel, { CUBE_SEGMENTS });

Expand Down Expand Up @@ -396,7 +406,7 @@ export class CubemapTilesAdapter extends AbstractAdapter<
* Applies a new texture to the faces
*/
private __swapMaterial(tile: CubemapTile, material: MeshBasicMaterial, isError: boolean) {
const panoData = this.viewer.state.textureData.panoData as CubemapData;
const panoData = this.viewer.state.textureData.panoData as CubemapTilesPanoData;
const uvs = this.state.geom.getAttribute(ATTR_UV) as BufferAttribute;

for (let c = 0; c < tile.config.facesByTile; c++) {
Expand Down
6 changes: 5 additions & 1 deletion packages/cubemap-tiles-adapter/src/model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Cubemap, CubemapAdapterConfig, CubemapPanorama } from '@photo-sphere-viewer/cubemap-adapter';
import type { Cubemap, CubemapAdapterConfig, CubemapData, CubemapPanorama } from '@photo-sphere-viewer/cubemap-adapter';

/**
* Configuration of a tiled cubemap
Expand Down Expand Up @@ -88,3 +88,7 @@ export type CubemapTilesAdapterConfig = CubemapAdapterConfig & {
*/
debug?: boolean;
};

export type CubemapTilesPanoData = CubemapData & {
baseData: CubemapData;
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { buildDebugTexture, buildErrorMaterial, createWireFrame } from '../../sh
import {
EquirectangularMultiTilesPanorama,
EquirectangularTilesAdapterConfig,
EquirectangularTilesPanoData,
EquirectangularTilesPanorama,
} from './model';
import { EquirectangularTileConfig, checkPanoramaConfig, getTileConfig, getTileConfigByIndex } from './utils';
Expand Down Expand Up @@ -47,7 +48,7 @@ type EquirectangularTilesMesh = Mesh<SphereGeometry, MeshBasicMaterial[]>;
type EquirectangularTilesTextureData = TextureData<
Texture,
EquirectangularTilesPanorama | EquirectangularMultiTilesPanorama,
PanoData
EquirectangularTilesPanoData
>;
type EquirectangularTile = {
row: number;
Expand Down Expand Up @@ -90,7 +91,7 @@ const vertexPosition = new Vector3();
*/
export class EquirectangularTilesAdapter extends AbstractAdapter<
EquirectangularTilesPanorama | EquirectangularMultiTilesPanorama,
PanoData,
EquirectangularTilesPanoData,
Texture,
Group
> {
Expand Down Expand Up @@ -198,11 +199,11 @@ export class EquirectangularTilesAdapter extends AbstractAdapter<
return !!panorama.baseUrl;
}

override textureCoordsToSphericalCoords(point: PanoramaPosition, data: PanoData): Position {
override textureCoordsToSphericalCoords(point: PanoramaPosition, data: EquirectangularTilesPanoData): Position {
return this.adapter.textureCoordsToSphericalCoords(point, data);
}

override sphericalCoordsToTextureCoords(position: Position, data: PanoData): PanoramaPosition {
override sphericalCoordsToTextureCoords(position: Position, data: EquirectangularTilesPanoData): PanoramaPosition {
return this.adapter.sphericalCoordsToTextureCoords(position, data);
}

Expand All @@ -212,41 +213,48 @@ export class EquirectangularTilesAdapter extends AbstractAdapter<
): Promise<EquirectangularTilesTextureData> {
checkPanoramaConfig(panorama, this);

const firstTile = getTileConfig(panorama, 0, this);
const panoData: PanoData = {
isEquirectangular: true,
fullWidth: firstTile.width,
fullHeight: firstTile.width / 2,
croppedWidth: firstTile.width,
croppedHeight: firstTile.width / 2,
croppedX: 0,
croppedY: 0,
poseHeading: 0,
posePitch: 0,
poseRoll: 0,
};

if (panorama.baseUrl) {
const textureData = await this.adapter.loadTexture(panorama.baseUrl, loader, panorama.basePanoData, true);

return {
panorama,
panoData: textureData.panoData,
panoData: {
...panoData,
baseData: textureData.panoData,
},
cacheKey: textureData.cacheKey,
texture: textureData.texture,
};
} else {
const firstTile = getTileConfig(panorama, 0, this);
const panoData: PanoData = {
isEquirectangular: true,
fullWidth: firstTile.width,
fullHeight: firstTile.width / 2,
croppedWidth: firstTile.width,
croppedHeight: firstTile.width / 2,
croppedX: 0,
croppedY: 0,
poseHeading: 0,
posePitch: 0,
poseRoll: 0,
};


return {
panorama,
panoData,
panoData: {
...panoData,
baseData: null,
},
cacheKey: panorama.tileUrl(0, 0, 0),
texture: null,
};
}
}

createMesh(panoData: PanoData): Group {
const baseMesh = this.adapter.createMesh(panoData);
createMesh(panoData: EquirectangularTilesPanoData): Group {
const baseMesh = this.adapter.createMesh(panoData.baseData ?? panoData);

const geometry = new SphereGeometry(
CONSTANTS.SPHERE_RADIUS,
Expand Down Expand Up @@ -303,7 +311,7 @@ export class EquirectangularTilesAdapter extends AbstractAdapter<
this.adapter.setTexture(baseMesh, {
panorama: textureData.panorama.baseUrl,
texture: textureData.texture,
panoData: textureData.panoData,
panoData: textureData.panoData.baseData,
});
} else {
baseMesh.visible = false;
Expand Down Expand Up @@ -343,7 +351,7 @@ export class EquirectangularTilesAdapter extends AbstractAdapter<
return;
}

const panorama: EquirectangularTilesPanorama | EquirectangularMultiTilesPanorama = this.viewer.config.panorama;
const panorama = this.viewer.config.panorama as EquirectangularTilesPanorama | EquirectangularMultiTilesPanorama;
const zoomLevel = this.viewer.getZoomLevel();
const tileConfig = getTileConfig(panorama, zoomLevel, this);

Expand Down
4 changes: 4 additions & 0 deletions packages/equirectangular-tiles-adapter/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,7 @@ export type EquirectangularTilesAdapterConfig = Omit<EquirectangularAdapterConfi
*/
debug?: boolean;
};

export type EquirectangularTilesPanoData = PanoData & {
baseData: PanoData;
};

0 comments on commit 20be91b

Please sign in to comment.