avansel
Version:
Free OpenSource ThreeJS Javascript Virtual Tours viewer
97 lines (82 loc) • 2.84 kB
text/typescript
import { MathUtils } from 'three';
import { pano } from '../config.json'
interface AxisBounds {
min: number,
max: number
}
interface SideBounds {
x: AxisBounds,
y: AxisBounds
}
interface Position {
x: number,
y: number,
z: number
}
interface Level {
size: number,
tileSize: number
}
interface TileInfo {
x: number,
y: number,
offsetX: number,
offsetY: number,
width: number,
height: number
}
export const sides = [ 'f', 'b', 'l', 'r', 'u', 'd' ]
export const latLngToPos = (lat:number, lng: number): Position => {
const phi = MathUtils.degToRad( 90 - lat );
const theta = MathUtils.degToRad( lng );
const radius = 50;
let pos: Position = { x: 0, y: 0, z: 0 }
pos.x = radius * Math.sin( phi ) * Math.cos( theta );
pos.y = radius * Math.cos( phi );
pos.z = radius * Math.sin( phi ) * Math.sin( theta );
return pos
}
const minFor = (value: number, count: number, extend: number) => {
value = Math.round(value * count) - extend
if(value < 0) value = 0
return value
}
const maxFor = (value: number, count: number, extend: number) => {
value = Math.round(value * count) + extend
if(value > (count - 1)) value = count - 1
return value
}
export const tilesFor = (level: number, levelData: Level, bounds: SideBounds):Array<TileInfo> => {
if(!bounds?.x?.min && !bounds?.x?.max) return []
const { tileSize, size } = levelData
const tileBaseSize = pano.tileBase + pano.maxLevels - level
const tileSizePart = Math.round(tileSize / (size / tileBaseSize) * 1000) / 1000
const tiles = [];
const max = Math.ceil(tileBaseSize / tileSizePart)
let xMin = minFor(bounds.x.min, max, 2)
let xMax = maxFor(bounds.x.max, max, 2)
let yMin = minFor(bounds.y.min, max, 2)
let yMax = maxFor(bounds.y.max, max, 2)
for(var x = xMin; x <= xMax; x ++){
for(var y = yMin; y <= yMax; y ++){
if( x >= xMin && x <= xMax && y >= yMin && y <= yMax ){
const offsetX = x * tileSizePart
const offsetY = y * tileSizePart
const width = ((x + 1) * tileSizePart) > tileBaseSize ? (tileBaseSize - x * tileSizePart) : tileSizePart
const height = ((y + 1) * tileSizePart) > tileBaseSize ? (tileBaseSize - y * tileSizePart) : tileSizePart
tiles.push({ x, y, offsetX, offsetY, width, height })
}
}
}
return tiles
}
export const normLng = (lng: number): number => {
while(lng > 360) lng -= 360
while(lng < 0) lng += 360
return lng
}
export const normLat = (lat: number): number => {
if(lat > 90) lat = lat - (90 - lat)
if(lat < -90) lat = lat + (lat - 90)
return lat
}