UNPKG

@photo-sphere-viewer/cubemap-tiles-adapter

Version:
1 lines 40.5 kB
{"version":3,"sources":["src/index.ts","src/CubemapTilesAdapter.ts","../shared/Queue.ts","../shared/tiles-utils.ts","src/utils.ts"],"sourcesContent":["export { CubemapTilesAdapter } from './CubemapTilesAdapter';\nexport * from './model';\n","import type { AdapterConstructor, PanoramaPosition, Position, TextureData, Viewer } from '@photo-sphere-viewer/core';\nimport { AbstractAdapter, CONSTANTS, PSVError, events, utils } from '@photo-sphere-viewer/core';\nimport { CubemapAdapter, CubemapData, CubemapFaces } from '@photo-sphere-viewer/cubemap-adapter';\nimport { BoxGeometry, BufferAttribute, Group, Mesh, MeshBasicMaterial, Texture, Vector3 } from 'three';\nimport { Queue, Task } from '../../shared/Queue';\nimport { buildDebugTexture, buildErrorMaterial, createWireFrame } from '../../shared/tiles-utils';\nimport { CubemapMultiTilesPanorama, CubemapTilesAdapterConfig, CubemapTilesPanoData, CubemapTilesPanorama } from './model';\nimport { CubemapTileConfig, checkPanoramaConfig, getCacheKey, getTileConfig, getTileConfigByIndex, isTopOrBottom } from './utils';\n\ntype CubemapMesh = Mesh<BoxGeometry, MeshBasicMaterial[]>;\ntype CubemapTilesMesh = Mesh<BoxGeometry, MeshBasicMaterial[]>;\ntype CubemapTilesTextureData = TextureData<\n Texture[],\n CubemapTilesPanorama | CubemapMultiTilesPanorama,\n CubemapTilesPanoData\n>;\ntype CubemapTile = {\n face: number;\n col: number;\n row: number;\n angle: number;\n config: CubemapTileConfig;\n url: string;\n};\n\nconst CUBE_SEGMENTS = 16;\nconst NB_VERTICES_BY_FACE = 6;\nconst NB_VERTICES_BY_PLANE = NB_VERTICES_BY_FACE * CUBE_SEGMENTS * CUBE_SEGMENTS;\nconst NB_VERTICES = 6 * NB_VERTICES_BY_PLANE;\nconst NB_GROUPS_BY_FACE = CUBE_SEGMENTS * CUBE_SEGMENTS;\n\nconst ATTR_UV = 'uv';\nconst ATTR_POSITION = 'position';\n\nconst CUBE_HASHMAP: CubemapFaces[] = ['left', 'right', 'top', 'bottom', 'back', 'front'];\nconst ERROR_LEVEL = -1;\n\nfunction tileId(tile: CubemapTile) {\n return `${tile.face}:${tile.col}x${tile.row}/${tile.config.level}`;\n}\n\nfunction prettyTileId(tile: CubemapTile) {\n return `${tileId(tile)}\\n${CUBE_HASHMAP[tile.face]}`;\n}\n\nfunction meshes(group: Group) {\n return group.children as [CubemapMesh, CubemapTilesMesh];\n}\n\nconst getConfig = utils.getConfigParser<CubemapTilesAdapterConfig>({\n showErrorTile: true,\n baseBlur: true,\n antialias: true,\n blur: false,\n debug: false,\n});\n\nconst vertexPosition = new Vector3();\n\n/**\n * Adapter for tiled cubemaps\n */\nexport class CubemapTilesAdapter extends AbstractAdapter<\n CubemapTilesPanorama | CubemapMultiTilesPanorama,\n CubemapTilesPanoData,\n Texture[],\n Group\n> {\n static override readonly id = 'cubemap-tiles';\n static override readonly VERSION = PKG_VERSION;\n static override readonly supportsDownload = false;\n\n private readonly config: CubemapTilesAdapterConfig;\n\n private readonly state = {\n tileConfig: null as CubemapTileConfig,\n tiles: {} as Record<string, boolean>,\n faces: {} as Record<number, number>,\n geom: null as BoxGeometry,\n materials: [] as MeshBasicMaterial[],\n errorMaterial: null as MeshBasicMaterial,\n inTransition: false,\n };\n\n // @internal\n public adapter: CubemapAdapter;\n private readonly queue = new Queue();\n\n static withConfig(config: CubemapTilesAdapterConfig): [AdapterConstructor, any] {\n return [CubemapTilesAdapter, config];\n }\n\n constructor(viewer: Viewer, config: CubemapTilesAdapterConfig) {\n super(viewer);\n\n this.config = getConfig(config);\n\n if (!CubemapAdapter) {\n throw new PSVError('CubemapTilesAdapter requires CubemapAdapter');\n }\n\n this.adapter = new CubemapAdapter(this.viewer, {\n blur: this.config.baseBlur,\n });\n\n if (this.viewer.config.requestHeaders) {\n utils.logWarn(\n 'CubemapTilesAdapter fallbacks to file loader because \"requestHeaders\" where provided. '\n + 'Consider removing \"requestHeaders\" if you experience performances issues.',\n );\n }\n }\n\n override init() {\n super.init();\n\n this.viewer.addEventListener(events.TransitionDoneEvent.type, this);\n this.viewer.addEventListener(events.PositionUpdatedEvent.type, this);\n this.viewer.addEventListener(events.ZoomUpdatedEvent.type, this);\n }\n\n override destroy() {\n this.viewer.removeEventListener(events.TransitionDoneEvent.type, this);\n this.viewer.removeEventListener(events.PositionUpdatedEvent.type, this);\n this.viewer.removeEventListener(events.ZoomUpdatedEvent.type, this);\n\n this.__cleanup();\n\n this.state.errorMaterial?.map?.dispose();\n this.state.errorMaterial?.dispose();\n this.adapter.destroy();\n\n delete this.adapter;\n delete this.state.geom;\n delete this.state.errorMaterial;\n\n super.destroy();\n }\n\n /**\n * @internal\n */\n handleEvent(e: Event) {\n switch (e.type) {\n case events.PositionUpdatedEvent.type:\n case events.ZoomUpdatedEvent.type:\n this.__refresh();\n break;\n\n case events.TransitionDoneEvent.type:\n this.state.inTransition = false;\n if ((e as events.TransitionDoneEvent).completed) {\n this.__switchMesh(this.viewer.renderer.mesh as Group);\n }\n break;\n }\n }\n\n override supportsTransition(panorama: CubemapTilesPanorama | CubemapMultiTilesPanorama) {\n return !!panorama.baseUrl;\n }\n\n override supportsPreload(panorama: CubemapTilesPanorama | CubemapMultiTilesPanorama) {\n return !!panorama.baseUrl;\n }\n\n override textureCoordsToSphericalCoords(point: PanoramaPosition, data: CubemapTilesPanoData): Position {\n return this.adapter.textureCoordsToSphericalCoords(point, data);\n }\n\n override sphericalCoordsToTextureCoords(position: Position, data: CubemapTilesPanoData): PanoramaPosition {\n return this.adapter.sphericalCoordsToTextureCoords(position, data);\n }\n\n override async loadTexture(\n panorama: CubemapTilesPanorama | CubemapMultiTilesPanorama,\n loader = true,\n ): Promise<CubemapTilesTextureData> {\n checkPanoramaConfig(panorama, { CUBE_SEGMENTS });\n\n const firstTile = getTileConfig(panorama, 0, { CUBE_SEGMENTS });\n const panoData: CubemapData = {\n isCubemap: true,\n flipTopBottom: panorama.flipTopBottom ?? false,\n faceSize: firstTile.faceSize,\n };\n\n if (panorama.baseUrl) {\n const textureData = await this.adapter.loadTexture(panorama.baseUrl, loader);\n\n return {\n panorama,\n panoData: {\n ...panoData,\n baseData: textureData.panoData,\n },\n cacheKey: textureData.cacheKey,\n texture: textureData.texture,\n };\n } else {\n return {\n panorama,\n panoData: {\n ...panoData,\n baseData: null,\n },\n cacheKey: getCacheKey(panorama, firstTile),\n texture: null,\n };\n }\n }\n\n createMesh(): Group {\n // mesh for the base panorama\n const baseMesh = this.adapter.createMesh();\n\n // mesh for the tiles\n const cubeSize = CONSTANTS.SPHERE_RADIUS * 2;\n const geometry = new BoxGeometry(cubeSize, cubeSize, cubeSize, CUBE_SEGMENTS, CUBE_SEGMENTS, CUBE_SEGMENTS)\n .scale(1, 1, -1)\n .toNonIndexed() as BoxGeometry;\n\n geometry.clearGroups();\n for (let i = 0, k = 0; i < NB_VERTICES; i += NB_VERTICES_BY_FACE) {\n geometry.addGroup(i, NB_VERTICES_BY_FACE, k++);\n }\n\n const materials: MeshBasicMaterial[] = [];\n const material = new MeshBasicMaterial({\n opacity: 0,\n transparent: true,\n depthTest: false,\n depthWrite: false,\n });\n for (let i = 0; i < 6; i++) {\n for (let j = 0; j < NB_GROUPS_BY_FACE; j++) {\n materials.push(material);\n }\n }\n\n const tilesMesh = new Mesh(geometry, materials);\n tilesMesh.renderOrder = 1;\n\n const group = new Group();\n group.add(baseMesh);\n group.add(tilesMesh);\n return group;\n }\n\n /**\n * Applies the base texture and starts the loading of tiles\n */\n setTexture(group: Group, textureData: CubemapTilesTextureData, transition: boolean) {\n const [baseMesh] = meshes(group);\n\n if (textureData.texture) {\n this.adapter.setTexture(baseMesh, {\n panorama: textureData.panorama.baseUrl,\n texture: textureData.texture,\n panoData: textureData.panoData.baseData,\n });\n } else {\n baseMesh.visible = false;\n }\n\n if (transition) {\n this.state.inTransition = true;\n } else {\n this.__switchMesh(group);\n }\n }\n\n setTextureOpacity(group: Group, opacity: number) {\n const [baseMesh] = meshes(group);\n this.adapter.setTextureOpacity(baseMesh, opacity);\n }\n\n disposeTexture({ texture }: CubemapTilesTextureData) {\n texture?.forEach(t => t.dispose());\n }\n\n disposeMesh(group: Group) {\n const [baseMesh, tilesMesh] = meshes(group);\n\n baseMesh.geometry.dispose();\n baseMesh.material.forEach(m => m.dispose());\n\n tilesMesh.geometry.dispose();\n tilesMesh.material.forEach((m) => {\n m.map?.dispose();\n m.dispose();\n });\n }\n\n /**\n * Compute visible tiles and load them\n */\n private __refresh() {\n if (!this.state.geom || this.state.inTransition) {\n return;\n }\n\n const panorama = this.viewer.config.panorama as CubemapTilesPanorama | CubemapMultiTilesPanorama;\n const zoomLevel = this.viewer.getZoomLevel();\n const tileConfig = getTileConfig(panorama, zoomLevel, { CUBE_SEGMENTS });\n\n const verticesPosition = this.state.geom.getAttribute(ATTR_POSITION) as BufferAttribute;\n const tilesToLoad: Record<string, CubemapTile> = {};\n\n for (let i = 0; i < NB_VERTICES; i += 1) {\n vertexPosition.fromBufferAttribute(verticesPosition, i);\n vertexPosition.applyEuler(this.viewer.renderer.sphereCorrection);\n\n if (this.viewer.renderer.isObjectVisible(vertexPosition)) {\n const face = Math.floor(i / NB_VERTICES_BY_PLANE);\n\n // compute position of the segment (6 vertices)\n const segmentIndex = Math.floor((i - face * NB_VERTICES_BY_PLANE) / 6);\n const segmentRow = Math.floor(segmentIndex / CUBE_SEGMENTS);\n const segmentCol = segmentIndex - segmentRow * CUBE_SEGMENTS;\n\n let config = tileConfig;\n while (config) {\n let row = Math.floor(segmentRow / config.facesByTile);\n let col = Math.floor(segmentCol / config.facesByTile);\n const angle = vertexPosition.angleTo(this.viewer.state.direction);\n\n const tile: CubemapTile = {\n face,\n row,\n col,\n angle,\n config,\n url: null,\n };\n if (panorama.flipTopBottom && isTopOrBottom(face)) {\n col = config.nbTiles - col - 1;\n row = config.nbTiles - row - 1;\n }\n const id = tileId(tile);\n\n if (tilesToLoad[id]) {\n tilesToLoad[id].angle = Math.min(tilesToLoad[id].angle, angle);\n break;\n } else {\n tile.url = panorama.tileUrl(CUBE_HASHMAP[face], col, row, config.level);\n\n if (tile.url) {\n tilesToLoad[id] = tile;\n break;\n } else {\n // if no url is returned, try a lower tile level\n config = getTileConfigByIndex(panorama, config.level - 1, { CUBE_SEGMENTS });\n }\n }\n }\n }\n }\n\n this.state.tileConfig = tileConfig;\n this.__loadTiles(Object.values(tilesToLoad));\n }\n\n /**\n * Loads tiles and change existing tiles priority\n */\n private __loadTiles(tiles: CubemapTile[]) {\n this.queue.disableAllTasks();\n\n tiles.forEach((tile) => {\n const id = tileId(tile);\n\n if (this.state.tiles[id]) {\n this.queue.setPriority(id, tile.angle);\n } else {\n this.state.tiles[id] = true;\n this.queue.enqueue(new Task(id, tile.angle, task => this.__loadTile(tile, task)));\n }\n });\n\n this.queue.start();\n }\n\n /**\n * Loads and draw a tile\n */\n private __loadTile(tile: CubemapTile, task: Task): Promise<any> {\n return this.viewer.textureLoader\n .loadImage(tile.url, null, this.viewer.state.textureData.cacheKey)\n .then((image) => {\n if (!task.isCancelled()) {\n if (this.config.debug) {\n image = buildDebugTexture(image, tile.config.level, prettyTileId(tile)) as any;\n }\n\n const mipmaps = this.config.antialias && tile.config.level > 0;\n const material = new MeshBasicMaterial({ map: utils.createTexture(image, mipmaps) });\n this.__swapMaterial(tile, material, false);\n this.viewer.needsUpdate();\n }\n })\n .catch((err) => {\n if (!utils.isAbortError(err) && !task.isCancelled() && this.config.showErrorTile) {\n if (!this.state.errorMaterial) {\n this.state.errorMaterial = buildErrorMaterial();\n }\n this.__swapMaterial(tile, this.state.errorMaterial, true);\n this.viewer.needsUpdate();\n }\n });\n }\n\n /**\n * Applies a new texture to the faces\n */\n private __swapMaterial(tile: CubemapTile, material: MeshBasicMaterial, isError: boolean) {\n const panoData = this.viewer.state.textureData.panoData as CubemapTilesPanoData;\n const uvs = this.state.geom.getAttribute(ATTR_UV) as BufferAttribute;\n\n for (let c = 0; c < tile.config.facesByTile; c++) {\n for (let r = 0; r < tile.config.facesByTile; r++) {\n // position of the face\n const faceCol = tile.col * tile.config.facesByTile + c;\n const faceRow = tile.row * tile.config.facesByTile + r;\n\n // first vertex for this face (6 vertices in total)\n const firstVertex = tile.face * NB_VERTICES_BY_PLANE + 6 * (CUBE_SEGMENTS * faceRow + faceCol);\n\n // in case of error, skip the face if already showing valid data\n if (isError && this.state.faces[firstVertex] > ERROR_LEVEL) {\n continue;\n }\n // skip this face if its already showing an higher resolution\n if (this.state.faces[firstVertex] > tile.config.level) {\n continue;\n }\n this.state.faces[firstVertex] = isError ? ERROR_LEVEL : tile.config.level;\n\n // swap material\n const matIndex = this.state.geom.groups.find(g => g.start === firstVertex).materialIndex;\n this.state.materials[matIndex] = material;\n\n // define new uvs\n let top = 1 - r / tile.config.facesByTile;\n let bottom = 1 - (r + 1) / tile.config.facesByTile;\n let left = c / tile.config.facesByTile;\n let right = (c + 1) / tile.config.facesByTile;\n\n if (panoData.flipTopBottom && isTopOrBottom(tile.face)) {\n top = 1 - top;\n bottom = 1 - bottom;\n left = 1 - left;\n right = 1 - right;\n }\n\n uvs.setXY(firstVertex, left, top);\n uvs.setXY(firstVertex + 1, left, bottom);\n uvs.setXY(firstVertex + 2, right, top);\n uvs.setXY(firstVertex + 3, left, bottom);\n uvs.setXY(firstVertex + 4, right, bottom);\n uvs.setXY(firstVertex + 5, right, top);\n }\n }\n\n uvs.needsUpdate = true;\n }\n\n private __switchMesh(group: Group) {\n const [, tilesMesh] = meshes(group);\n\n this.__cleanup();\n\n this.state.materials = tilesMesh.material;\n this.state.geom = tilesMesh.geometry;\n\n if (this.config.debug) {\n const wireframe = createWireFrame(this.state.geom);\n this.viewer.renderer.addObject(wireframe);\n this.viewer.renderer.setSphereCorrection(this.viewer.config.sphereCorrection, wireframe);\n }\n\n setTimeout(() => this.__refresh());\n }\n\n /**\n * Clears loading queue, dispose all materials\n */\n private __cleanup() {\n this.queue.clear();\n this.state.tiles = {};\n this.state.faces = {};\n this.state.materials = [];\n this.state.inTransition = false;\n }\n}\n","/**\n * @internal\n */\nconst enum Status {\n DISABLED,\n PENDING,\n RUNNING,\n CANCELLED,\n DONE,\n ERROR,\n}\n\n/**\n * @internal\n */\nexport class Task {\n status: Status = Status.PENDING;\n\n constructor(\n public readonly id: string,\n public priority: number,\n private readonly fn: (task: Task) => Promise<any>,\n ) {}\n\n start() {\n this.status = Status.RUNNING;\n return this.fn(this).then(\n () => {\n this.status = Status.DONE;\n },\n () => {\n this.status = Status.ERROR;\n },\n );\n }\n\n cancel() {\n this.status = Status.CANCELLED;\n }\n\n isCancelled() {\n return this.status === Status.CANCELLED;\n }\n}\n\n/**\n * @internal\n */\nexport class Queue {\n private runningTasks: Record<string, boolean> = {};\n private tasks: Record<string, Task> = {};\n\n constructor(private readonly concurency = 8) {}\n\n enqueue(task: Task) {\n this.tasks[task.id] = task;\n }\n\n clear() {\n Object.values(this.tasks).forEach(task => task.cancel());\n this.tasks = {};\n this.runningTasks = {};\n }\n\n setPriority(taskId: string, priority: number) {\n const task = this.tasks[taskId];\n if (task) {\n task.priority = priority;\n if (task.status === Status.DISABLED) {\n task.status = Status.PENDING;\n }\n }\n }\n\n disableAllTasks() {\n Object.values(this.tasks).forEach((task) => {\n task.status = Status.DISABLED;\n });\n }\n\n start() {\n if (Object.keys(this.runningTasks).length >= this.concurency) {\n return;\n }\n\n const nextTask = Object.values(this.tasks)\n .filter(task => task.status === Status.PENDING)\n .sort((a, b) => b.priority - a.priority)\n .pop();\n\n if (nextTask) {\n this.runningTasks[nextTask.id] = true;\n\n nextTask.start().then(() => {\n if (!nextTask.isCancelled()) {\n delete this.tasks[nextTask.id];\n delete this.runningTasks[nextTask.id];\n this.start();\n }\n });\n\n this.start(); // start tasks until max concurrency is reached\n }\n }\n}\n","import { PSVError, utils } from '@photo-sphere-viewer/core';\nimport { BufferGeometry, LineSegments, Material, MeshBasicMaterial, Object3D, WireframeGeometry } from 'three';\n\n/**\n * Checks if the zoomRange properties are coherent\n * @internal\n */\nexport function checkTilesLevels(levels: Array<{ zoomRange: [number, number] }>) {\n let previous = 0;\n levels.forEach((level, i) => {\n if (!level.zoomRange || level.zoomRange.length !== 2) {\n throw new PSVError(`Tiles level ${i} is missing \"zoomRange\" property`);\n }\n if (level.zoomRange[0] >= level.zoomRange[1]\n || level.zoomRange[0] !== previous\n || (i === 0 && level.zoomRange[0] !== 0)\n || (i === levels.length - 1 && level.zoomRange[1] !== 100)) {\n throw new PSVError(`Tiles levels' \"zoomRange\" are not orderer or are not covering the whole 0-100 range`);\n }\n previous = level.zoomRange[1];\n });\n}\n\nexport function getTileIndexByZoomLevel<T extends { zoomRange: [number, number] }>(\n levels: T[],\n zoomLevel: number,\n): number {\n return levels.findIndex((level) => {\n return zoomLevel >= level.zoomRange[0] && zoomLevel <= level.zoomRange[1];\n });\n}\n\n/**\n * Generates an material for errored tiles\n * @internal\n */\nexport function buildErrorMaterial(): MeshBasicMaterial {\n const canvas = new OffscreenCanvas(512, 512);\n\n const ctx = canvas.getContext('2d');\n\n ctx.fillStyle = '#333';\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n ctx.font = `${canvas.width / 5}px serif`;\n ctx.fillStyle = '#a22';\n ctx.textAlign = 'center';\n ctx.textBaseline = 'middle';\n ctx.fillText('⚠', canvas.width / 2, canvas.height / 2);\n\n return new MeshBasicMaterial({ map: utils.createTexture(canvas) });\n}\n\n/**\n * Creates a wireframe geometry, for debug\n * @internal\n */\nexport function createWireFrame(geometry: BufferGeometry): Object3D {\n const wireframe = new WireframeGeometry(geometry);\n const line = new LineSegments<WireframeGeometry, Material>(wireframe);\n line.material.depthTest = false;\n line.material.depthWrite = false;\n line.material.opacity = 0.25;\n line.material.transparent = true;\n return line;\n}\n\nconst DEBUG_COLORS = ['dodgerblue', 'limegreen', 'indianred'];\n\n/**\n * Applies a color filter to an tile image and shows the id of the tile\n * @internal\n */\nexport function buildDebugTexture(image: HTMLImageElement, level: number, id: string): HTMLCanvasElement {\n const canvas = document.createElement('canvas');\n canvas.width = image.width;\n canvas.height = image.height;\n const ctx = canvas.getContext('2d');\n\n ctx.fillStyle = DEBUG_COLORS[level % DEBUG_COLORS.length];\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n\n ctx.globalCompositeOperation = 'multiply';\n ctx.drawImage(image, 0, 0);\n\n const fontSize = image.width / 7;\n ctx.globalCompositeOperation = 'source-over';\n ctx.fillStyle = 'white';\n ctx.font = `${fontSize}px monospace`;\n ctx.textAlign = 'center';\n id.split('\\n').forEach((id2, i) => {\n ctx.fillText(id2, image.width / 2, image.height / 2 + fontSize * (0.3 + i));\n });\n\n return canvas;\n}\n","import { PSVError } from '@photo-sphere-viewer/core';\nimport { MathUtils } from 'three';\nimport { checkTilesLevels, getTileIndexByZoomLevel } from '../../shared/tiles-utils';\nimport { CubemapMultiTilesPanorama, CubemapTileLevel, CubemapTilesPanorama } from './model';\n\nexport type CubemapTileConfig = CubemapTileLevel & {\n level: number;\n tileSize: number;\n facesByTile: number;\n};\n\nfunction isMultiTiles(\n panorama: CubemapTilesPanorama | CubemapMultiTilesPanorama,\n): panorama is CubemapMultiTilesPanorama {\n return !!(panorama as CubemapMultiTilesPanorama).levels;\n}\n\nfunction computeTileConfig(tile: CubemapTileLevel, level: number, data: { CUBE_SEGMENTS: number }): CubemapTileConfig {\n return {\n ...tile,\n level,\n tileSize: tile.faceSize / tile.nbTiles,\n facesByTile: data.CUBE_SEGMENTS / tile.nbTiles,\n };\n}\n\nexport function getTileConfig(\n panorama: CubemapTilesPanorama | CubemapMultiTilesPanorama,\n zoomLevel: number,\n data: { CUBE_SEGMENTS: number },\n): CubemapTileConfig {\n let tile: CubemapTileLevel;\n let level: number;\n if (!isMultiTiles(panorama)) {\n level = 0;\n tile = {\n ...panorama,\n zoomRange: [0, 100],\n };\n } else {\n level = getTileIndexByZoomLevel(panorama.levels, zoomLevel);\n tile = panorama.levels[level];\n }\n return computeTileConfig(tile, level, data);\n}\n\nexport function getTileConfigByIndex(\n panorama: CubemapTilesPanorama | CubemapMultiTilesPanorama,\n level: number,\n data: { CUBE_SEGMENTS: number },\n): CubemapTileConfig {\n if (!isMultiTiles(panorama) || !panorama.levels[level]) {\n return null;\n } else {\n return computeTileConfig(panorama.levels[level], level, data);\n }\n}\n\nexport function checkPanoramaConfig(\n panorama: CubemapTilesPanorama | CubemapMultiTilesPanorama,\n data: { CUBE_SEGMENTS: number },\n) {\n if (typeof panorama !== 'object' || !panorama.tileUrl) {\n throw new PSVError('Invalid panorama configuration, are you using the right adapter?');\n }\n if (isMultiTiles(panorama)) {\n panorama.levels.forEach(level => checkTile(level, data));\n checkTilesLevels(panorama.levels);\n } else {\n checkTile(panorama, data);\n }\n}\n\nfunction checkTile(tile: CubemapTilesPanorama | CubemapTileLevel, data: { CUBE_SEGMENTS: number }) {\n if (!tile.faceSize || !tile.nbTiles) {\n throw new PSVError('Invalid panorama configuration, are you using the right adapter?');\n }\n if (tile.nbTiles > data.CUBE_SEGMENTS) {\n throw new PSVError(`Panorama nbTiles must not be greater than ${data.CUBE_SEGMENTS}.`);\n }\n if (!MathUtils.isPowerOfTwo(tile.nbTiles)) {\n throw new PSVError('Panorama nbTiles must be power of 2.');\n }\n}\n\n/**\n * Checks if it is the top or bottom tile\n */\nexport function isTopOrBottom(face: number) {\n return face === 2 || face === 3;\n}\n\n/**\n * Returns a path used for cache key\n */\nexport function getCacheKey(\n panorama: CubemapTilesPanorama | CubemapMultiTilesPanorama,\n firstTile: CubemapTileConfig,\n): string {\n // some tiles might be \"null\"\n for (let i = 0; i < firstTile.nbTiles; i++) {\n const url = panorama.tileUrl('front', i, firstTile.nbTiles / 2, firstTile.level);\n if (url) {\n return url;\n }\n }\n\n return panorama.tileUrl.toString();\n}\n"],"mappings":"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","names":["import_core","import_three","import_core","import_three"]}