import cover from './cover' import { loadLib } from '@/utils' import { FuseModelAttrs, FuseModel, GuidePath, MeasureType, Measure as StoreMeasure, MeasurePosition } from '@/store' import type { Emitter } from 'mitt' type SceneModelAttrs = FuseModelAttrs & { select: boolean } export type SceneModel = ToChangeAPI & { bus: Emitter< Pick & { loadError: void, loadDone: void, loadProgress: number, changeSelect: boolean, transformChanged: { position?: SceneLocalPos, scale?: number, rotation?: SceneLocalPos, bottom?: number } } > destroy: () => void enterRotateMode: () => void enterMoveMode: () => void leaveTransform: () => void enterAlignment: () => void leaveAlignment: () => void enterScaleSet:() => ScaleSet leaveScaleSet: () => void } export interface ScaleSet { setLength: (length: number) => void, startMeasure: () => void } export type ModelAttrRange = { [key in 'opacity' | 'bottom' | 'scale' as `${key}Range`]: { min: number, max: number, step: number } } export type AddModelProps = Pick & FuseModelAttrs & { type: string, isDynamicAdded: boolean, mode: 'many' | 'single' } & ModelAttrRange export type SceneGuidePath = Pick export interface SceneGuide { bus: Emitter<{ changePoint: number; playComplete: void }> play: () => void pause: () => void clear: () => void } export type ScenePos = { localPos: SceneLocalPos, modelId: FuseModel['id'] } export type ScreenPos = { trueSide: boolean, pos: ScreenLocalPos, modelId: FuseModel['id'] } export interface CameraComeToProps { position: SceneLocalPos; target?: SceneLocalPos; dur?: number, modelId?: FuseModel['id'], distance?: 1 | 2 | 3 } export type CalcPathProps = [[SceneGuidePath, SceneGuidePath], Partial>] export interface MeasureBase { destroy?: () => void show: () => void hide: () => void fly: () => void bus: Emitter<{ update: [MeasurePosition['point'][], MeasurePosition['modelId'][]]; highlight: boolean }> changeSelect: (isHight: boolean) => void setPositions: (points: MeasurePosition['point'][], modelIds: MeasurePosition['modelId'][]) => void } export type Measure = MeasureBase & ( T extends MeasureType.area ? { getArea: () => {value: number} } : { getDistance: () => {value: number} } ) export type StartMeasure = Measure & { bus: Emitter<{ submit: [MeasurePosition['point'][], MeasurePosition['modelId'][]]; cancel: void; invalidPoint: string }> } export interface SDK { layout: HTMLDivElement, sceneBus: Emitter<{ 'cameraChange': void }> setBackdrop: (drop: string) => void addModel: (props: AddModelProps) => SceneModel calcPathInfo: (paths: CalcPathProps[0], info: CalcPathProps[1]) => Required getPositionByScreen: (screenPos: ScreenLocalPos, modelId?: FuseModel['id']) => ScenePos | null getScreenByPosition: (localPos: SceneLocalPos, modelId?: FuseModel['id']) => ScreenPos | null screenshot: (width: number, height: number) => Promise getPose: () => { position: SceneLocalPos, target: SceneLocalPos } comeTo: (pos: CameraComeToProps) => void enterSceneGuide: (data: SceneGuidePath[]) => SceneGuide, drawMeasure(type: T, points: MeasurePosition['point'][], modelIds: MeasurePosition['modelId'][]): Measure, startMeasure(type: T): StartMeasure , } export let sdk: SDK export type InialSDKProps = { layout: HTMLDivElement } export let initialed = false export const initialSDK = async (props: InialSDKProps) => { if (initialed) return; initialed = true const libs = [ `./lib/proj4/proj4.js`, `./lib/jquery/jquery-3.1.1.min.js`, `./lib/other/BinaryHeap.js`, `./lib/tween/tween.min.js`, ] await Promise.all(libs.map(loadLib)) await loadLib(`./lib/potree/potree.js`) const localSdk = cover(props.layout, false) as unknown as SDK sdk = localSdk sdk.layout = props.layout } export default sdk