UNPKG

@v2x-three/core

Version:

V2X Three.js 核心库 - 开放式的Three.js工具集,支持React和Vue项目

2,314 lines (2,291 loc) 151 kB
import * as THREE from 'three'; export { THREE }; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; export { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; import { MapControls } from 'three/examples/jsm/controls/MapControls.js'; export { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; export { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'; /** * 🎨 智能气泡管理器 * * 功能特性: * - 科技感毛玻璃蓝色半透明气泡 * - 智能避障定位算法 * - 内容自适应布局 * - 设备关联和状态同步 */ interface BubbleConfig { /** 气泡唯一标识 */ id: string; /** 关联的3D对象 */ target: THREE.Object3D; /** 目标世界坐标位置 */ targetPosition?: THREE.Vector3; /** 气泡标题 */ title: string; /** 气泡内容 */ content: BubbleContent; /** 是否启用自动定位 */ autoPosition?: boolean; /** 手动指定位置偏移 */ offset?: { x: number; y: number; }; /** 气泡类型样式 */ type?: 'info' | 'warning' | 'error' | 'success'; /** 是否显示连接线(已废弃,不再使用) */ showConnector?: boolean; /** 最大宽度 */ maxWidth?: number; /** 气泡位置偏好 */ positionPreference?: 'bottom' | 'top' | 'auto'; /** 气泡关闭回调 */ onClose?: (id: string) => void; } interface BubbleContent { /** 设备状态 */ status?: 'online' | 'offline' | 'warning' | 'maintenance' | 'error' | 'moving'; /** 键值对数据 */ data?: Record<string, any>; /** 自定义HTML内容 */ html?: string; /** React组件内容 */ component?: any; /** 操作按钮 */ actions?: BubbleAction[]; /** HLS视频流URL */ videoUrl?: string; /** 视频类型 */ videoType?: 'hls' | 'rtmp' | 'webrtc'; } interface BubbleAction { label: string; icon?: string; onClick: () => void; type?: 'primary' | 'secondary' | 'danger'; } /** * 智能气泡管理器 */ declare class BubbleManager { private container; private camera; private bubbles; private readonly BUBBLE_STYLES; constructor(camera: THREE.Camera, container: HTMLElement); /** * 初始化事件监听器 */ private initializeEventListeners; /** * 创建气泡容器 */ private createBubbleContainer; /** * 添加气泡 */ addBubble(config: BubbleConfig): string; /** * 移除气泡 */ removeBubble(id: string): boolean; /** * 显示气泡 */ showBubble(id: string): boolean; /** * 隐藏气泡 */ hideBubble(id: string): boolean; /** * 更新气泡内容 */ updateBubbleContent(id: string, content: Partial<BubbleContent>): boolean; /** * 创建气泡元素 */ private createBubbleElement; /** * 生成内容HTML */ private generateContentHTML; /** * 计算最佳位置(优先显示在下方) */ private calculateOptimalPosition; /** * 世界坐标转屏幕坐标 */ private worldToScreen; /** * 更新气泡位置 */ private updateBubblePosition; /** * 更新所有气泡位置 */ private updateAllBubblePositions; /** * 初始化HLS.js用于视频播放 */ private initializeHLS; /** * 创建视频播放器元素 */ private createVideoPlayer; /** * 设置视频播放(支持HLS) */ private setupVideoPlayer; /** * 启用/禁用气泡管理器 */ setEnabled(enabled: boolean): void; /** * 获取所有气泡信息 */ getAllBubbles(): Array<{ id: string; config: BubbleConfig; visible: boolean; }>; /** * 清理所有气泡 */ dispose(): void; } /** * 🏷️ 智能标签管理器 * * 功能特性: * - 跟随3D物体的标签文本 * - 自动隐藏超出视野的标签 * - 支持点击交互显示/隐藏 * - 高性能批量更新 * - 灵活的样式配置 */ interface LabelConfig { /** 标签唯一标识 */ id: string; /** 关联的3D对象 (可选, 优先级低于 updateCallback 和 targetPosition) */ target?: THREE.Object3D; /** 目标世界坐标位置 (可选, 优先级低于 updateCallback) */ targetPosition?: THREE.Vector3; /** * 位置更新回调 (最高优先级) * 返回 Vector3 更新位置, 返回 null 则隐藏标签 */ updateCallback?: () => THREE.Vector3 | null; /** 标签文本内容 */ text: string; /** 标签类型样式 */ type?: 'default' | 'vehicle' | 'device' | 'warning' | 'info'; /** 是否启用自动跟随 */ autoFollow?: boolean; /** 手动指定位置偏移 */ offset?: { x: number; y: number; z: number; }; /** 是否可点击 */ clickable?: boolean; /** 点击回调 */ onClick?: (id: string) => void; /** 最大显示距离 */ maxDistance?: number; /** 标签样式自定义 */ style?: Partial<LabelStyle>; } interface LabelStyle { fontSize: string; color: string; backgroundColor: string; border: string; borderRadius: string; padding: string; fontFamily: string; boxShadow: string; backdropFilter: string; maxWidth: string; minWidth: string; zIndex: string; } /** * 智能标签管理器 */ declare class LabelManager { private camera; private container; private labels; private raycaster; private mouse; private isEnabled; private animationFrameId; private readonly DEFAULT_STYLES; constructor(camera: THREE.Camera, container: HTMLElement); /** * 初始化事件监听器 */ private initializeEventListeners; /** * 处理窗口大小变化 */ private handleResize; /** * 处理鼠标点击 */ private handleClick; /** * 处理鼠标移动 */ private handleMouseMove; /** * 更新鼠标位置 */ private updateMousePosition; /** * 创建标签容器 */ private createLabelContainer; /** * 启动更新循环 */ private startUpdateLoop; /** * 停止更新循环 */ private stopUpdateLoop; /** * 添加标签 */ addLabel(config: LabelConfig): string; /** * 移除标签 */ removeLabel(id: string): boolean; /** * 显示标签 */ showLabel(id: string): boolean; /** * 隐藏标签 */ hideLabel(id: string): boolean; /** * 切换标签显示状态 */ toggleLabel(id: string): boolean; /** * 更新标签文本 */ updateLabelText(id: string, text: string): boolean; /** * 更新标签的目标位置 */ updateLabelTargetPosition(id: string, position: THREE.Vector3): boolean; /** * 创建标签元素 */ private createLabelElement; /** * 更新单个标签位置 */ private updateLabelPosition; /** * 检查位置是否在视野内 */ private isPositionInView; /** * 世界坐标转屏幕坐标 */ private worldToScreen; /** * 更新所有标签位置 */ private updateAllLabels; /** * 批量添加标签 */ addLabels(configs: LabelConfig[]): string[]; /** * 批量移除标签 */ removeLabels(ids: string[]): boolean[]; /** * 获取所有标签信息 */ getAllLabels(): Array<{ id: string; config: LabelConfig; visible: boolean; }>; /** * 启用/禁用标签管理器 */ setEnabled(enabled: boolean): void; /** * 清理所有标签 */ dispose(): void; } declare function createLabelManager(camera: THREE.Camera, container: HTMLElement): LabelManager; /** * 🔄 RSM数据适配器 - 统一版本 * * 基于RSM协议的统一车辆数据管理 * RSMMessage作为前后端统一的数据交互对象 */ /** * RSM消息格式(前后端统一标准) */ interface RSMMessage { /** 消息类型,固定值"rsm" */ msgType: 'rsm'; /** RSU编号,八位字符串 */ rsuId: string; /** 消息序列号 [0..127] */ msgCnt?: number; /** UTC时间戳,精确到毫秒 */ timestamp: number; /** 参考经度 [-180..180] */ refLongitude?: number; /** 参考纬度 [-90..90] */ refLatitude?: number; /** 参考高程 [-409.6..6143.9] */ refElevation?: number; /** RSM包唯一ID */ uuid: string; /** 交通参与者信息列表 */ participants: RSMParticipant[]; } /** * 车辆ID的推荐类型 * - `plateNo`: 车牌号,最稳定 * - `tempId`: 临时字符串ID * - `ptcId`: rsuId + ptcId 组合 */ type VehicleIdType = 'plateNo' | 'tempId' | 'ptcId'; /** * RSM参与者数据格式 - 系统标准数据结构 */ interface RSMParticipant { /** 参与者局部ID [0..65535] */ ptcId: number; /** 参与者类型: 0-未知, 1-机动车, 2-非机动车, 3-行人, 4-RSU, 5-保留 */ ptcType: 0 | 1 | 2 | 3 | 4 | 5; /** 数据来源: 0-未知, 1-自身, 2-V2X, 3-视觉, 4-毫米波雷达, 5-loop, 6-lidar, 7-integrated */ sourceType: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7; /** 临时编号,8位字符串(可选) */ id?: string; /** 车牌号,16位字符串(可选) */ plateNo?: string; /** 目标检测UTC时间戳,毫秒 */ ptcTimestamp: number; /** 经度 [-180..180],小数点后7位 */ longitude: number; /** 纬度 [-90..90],小数点后7位 */ latitude: number; /** 位置精度 [0..15] */ posConfidence?: number; /** 高程 [-409.6..6143.9] */ elevation?: number; /** 高程精度 [0..15] */ eleConfidence?: number; /** 速度 [0..500] m/s */ speed: number; /** 速度精度 [0..7] */ spdConfidence?: number; /** 航向角 [0..360] 度,正北方向顺时针 */ heading: number; /** 航向角精度 [0..7] */ headConfidence?: number; /** 方向盘转角 [-126..127],分辨率1.5度 */ steeringAngle?: number; /** 方向盘转角精度 [0..3] */ strConfidence?: number; /** 纵向加速度 [-2000..+2001],分辨率0.01 m/s² */ lonAccel?: number; /** 横向加速度 [-2000..+2001],分辨率0.01 m/s² */ latAccel?: number; /** 垂直加速度 [-127..127],分辨率0.02g */ vertAccel?: number; /** 横摆角速度 [-32767..32767],分辨率0.01°/s */ yawRate?: number; /** 挡位状态: 0-空挡, 1-停车挡, 2-前进挡, 3-倒挡, 7-无效 */ transmission?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7; /** 目标物宽度 [0..1023] cm */ width: number; /** 目标物长度 [0..4095] cm */ length: number; /** 目标物高度 [0..127],分辨率5cm */ height?: number; /** 车辆类型 [0..255] */ vehicleClass: number; /** 燃料类型 [0..10]: 0-未知, 1-汽油, 2-乙醇, 3-柴油, 4-电动, 5-混合动力等 */ fuelType?: number; } /** * 车辆运行时信息(系统内部使用) */ interface VehicleRuntimeInfo { /** 车辆唯一标识符,格式:rsuId_ptcId */ vehicleId: string; /** RSU来源信息 */ rsuId: string; /** 消息时间戳 */ messageTimestamp: number; /** 系统状态 */ systemStatus: 'moving' | 'stopped' | 'parked' | 'offline' | 'warning' | 'error'; /** 最后更新时间 */ lastUpdated: number; } /** * 完整的车辆数据(RSM + 运行时信息) */ interface VehicleData extends RSMParticipant { /** 运行时信息 */ runtime: VehicleRuntimeInfo; } declare class RSMDataAdapter { /** * 将RSM参与者转换为车辆数据 */ static participantToVehicleData(participant: RSMParticipant, rsuId: string, messageTimestamp: number): VehicleData; /** * 获取稳定车辆ID * 优先使用 plateNo, 其次是 id, 最后是 rsuId_ptcId */ static getStableVehicleId(participant: RSMParticipant, rsuId: string): { vehicleId: string; type: VehicleIdType; }; /** * 标准化参与者数据,处理真实RSM消息的格式差异 */ private static normalizeParticipant; /** * 标准化尺寸数据 * 处理可能的单位差异和异常值 */ private static normalizeDimension; /** * 将RSM消息转换为车辆数据列表 */ static convertRSMMessage(rsmMessage: RSMMessage): VehicleData[]; /** * 批量转换RSM消息 */ static convertRSMBatch(rsmMessages: RSMMessage[]): VehicleData[]; /** * 推断系统状态 */ private static inferSystemStatus; /** * 映射RSM参与者类型到标准类型 */ static mapPtcTypeToString(ptcType: number): string; /** * 角度转换:度 -> 弧度 */ static degreesToRadians(degrees: number): number; /** * 角度转换:弧度 -> 度 */ static radiansToDegrees(radians: number): number; /** * 厘米转米 */ static cmToMeters(cm: number): number; /** * 获取车辆尺寸(转换为米) */ static getVehicleDimensions(participant: RSMParticipant): { width: number; length: number; height?: number; }; /** * 获取加速度(转换为m/s²) */ static getAcceleration(participant: RSMParticipant): { longitudinal?: number; lateral?: number; vertical?: number; }; /** * 验证RSM消息 */ static validateRSMMessage(rsmMessage: RSMMessage): boolean; /** * 验证参与者数据 */ static validateParticipant(participant: RSMParticipant): boolean; /** * 创建测试用RSM消息 */ static createTestRSMMessage(options?: { rsuId?: string; participantCount?: number; baseLatitude?: number; baseLongitude?: number; }): RSMMessage; } type ExtendedRSMParticipant = VehicleData; /** * 📦 数组数据管理器 * * 负责管理数组模式的RSM车辆数据 * 支持场景播放、帧控制和数据检索 */ /** * RSM数据帧 */ interface RSMFrame { /** 帧序号 (从0开始) */ frame_id: number; /** 时间戳 (相对开始时间的秒数) */ timestamp: number; /** 该帧的RSM消息列表 */ rsmMessages: RSMMessage[]; } /** * 场景信息 */ interface ScenarioInfo { /** 场景ID */ id: string; /** 场景名称 */ name: string; /** 场景描述 */ description?: string; /** 场景时长 (秒) */ duration: number; /** 帧率 (fps) */ frame_rate: number; } /** * 播放配置 */ interface PlaybackConfig { /** 是否自动播放 */ auto_play: boolean; /** 是否循环播放 */ loop: boolean; /** 默认播放速度倍数 */ default_speed: number; } /** * 数组数据源 */ interface ArrayDataSource { /** 数据源类型 */ type: 'array'; /** 场景信息 */ scenario: ScenarioInfo; /** 时间帧数据 */ frames: RSMFrame[]; /** 播放配置 */ playback_config?: PlaybackConfig; } /** * 数据统计信息 */ interface DataStatistics { /** 总帧数 */ totalFrames: number; /** 总时长(秒) */ totalDuration: number; /** 帧率 */ frameRate: number; /** 车辆数量统计 */ vehicleCount: { /** 最小车辆数 */ min: number; /** 最大车辆数 */ max: number; /** 平均车辆数 */ average: number; }; /** 数据大小(字节) */ dataSize: number; } /** * 数组数据管理器事件 */ interface ArrayDataManagerEvents { /** 数据加载完成 */ 'data:loaded': (source: ArrayDataSource, statistics: DataStatistics) => void; /** 数据加载错误 */ 'data:error': (error: Error) => void; /** 帧变化 */ 'frame:change': (frame: RSMFrame, vehicles: VehicleData[], frameIndex: number) => void; /** 播放状态变化 */ 'playback:statusChange': (isPlaying: boolean, frameIndex: number) => void; } /** * 数组数据管理器 */ declare class ArrayDataManager { private dataSource; private currentFrameIndex; private eventListeners; private statistics; constructor(); /** * 初始化事件监听器 */ private initializeEventListeners; /** * 加载数据源 */ loadData(source: ArrayDataSource): Promise<void>; /** * 加载JSON数据文件 */ loadFromJSON(jsonData: any): Promise<void>; /** * 获取当前帧 */ getCurrentFrame(): RSMFrame | null; /** * 获取指定索引的帧 */ getFrameAt(frameIndex: number): RSMFrame | null; /** * 设置当前帧索引 */ setCurrentFrameIndex(frameIndex: number): boolean; /** * 跳转到下一帧 */ nextFrame(): boolean; /** * 跳转到上一帧 */ previousFrame(): boolean; /** * 跳转到指定时间 */ seekToTime(timeInSeconds: number): boolean; /** * 跳转到指定进度(0-1) */ seekToProgress(progress: number): boolean; /** * 将帧数据转换为车辆数据 */ convertFrameToVehicleData(frame: RSMFrame): VehicleData[]; /** * 获取总帧数 */ getTotalFrames(): number; /** * 获取总时长(秒) */ getDuration(): number; /** * 获取帧率 */ getFrameRate(): number; /** * 获取当前进度(0-1) */ getProgress(): number; /** * 获取当前时间(秒) */ getCurrentTime(): number; /** * 获取场景信息 */ getScenarioInfo(): ScenarioInfo | null; /** * 获取播放配置 */ getPlaybackConfig(): PlaybackConfig | null; /** * 获取数据统计信息 */ getStatistics(): DataStatistics | null; /** * 获取指定时间范围的帧 */ getFramesInRange(startTime: number, endTime: number): RSMFrame[]; /** * 搜索包含特定车辆ID的帧 */ findFramesWithVehicle(vehicleId: string): RSMFrame[]; /** * 获取所有出现过的车辆ID */ getAllVehicleIds(): Set<string>; /** * 验证数据源 */ private validateDataSource; /** * 计算数据统计信息 */ private calculateStatistics; /** * 事件监听 */ on<K extends keyof ArrayDataManagerEvents>(event: K, handler: ArrayDataManagerEvents[K]): void; /** * 移除事件监听 */ off<K extends keyof ArrayDataManagerEvents>(event: K, handler: ArrayDataManagerEvents[K]): void; /** * 触发事件 */ private emit; /** * 清理资源 */ dispose(): void; /** * 重置到初始状态 */ reset(): void; } /** * 创建数组数据管理器 */ declare function createArrayDataManager(): ArrayDataManager; /** * 🌐 WebSocket数据管理器 * * 负责管理实时WebSocket RSM数据流 * 支持连接管理、消息缓存、重连机制 */ /** * WebSocket连接配置 */ interface WebSocketConfig { /** WebSocket服务器地址 */ url: string; /** 连接协议 */ protocols?: string | string[]; /** 重连配置 */ reconnect?: { /** 是否启用自动重连 */ enabled: boolean; /** 最大重连次数 */ maxAttempts: number; /** 重连间隔(毫秒) */ interval: number; /** 重连间隔递增因子 */ backoffFactor?: number; }; /** 缓冲区配置 */ buffer?: { /** 缓冲区大小 */ maxSize: number; /** 是否启用暂停缓存 */ enablePauseBuffer: boolean; }; /** 消息过滤器 */ filters?: { /** RSU过滤列表,空表示接收所有 */ rsuIds?: string[]; /** 参与者类型过滤 */ ptcTypes?: number[]; /** 最小更新间隔(毫秒) */ minUpdateInterval?: number; }; /** 连接超时设置 */ timeout?: { /** 连接超时(毫秒) */ connect: number; /** 消息超时(毫秒) */ message: number; }; /** 认证配置 */ auth?: { /** 认证token */ token?: string; /** 认证类型 */ type?: 'bearer' | 'basic' | 'custom'; /** 自定义认证头 */ headers?: Record<string, string>; }; } /** * 连接状态 */ type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error' | 'closed'; /** * WebSocket消息格式 */ interface WebSocketMessage { /** 消息类型 */ type: 'rsm' | 'heartbeat' | 'auth' | 'error' | 'control'; /** 消息数据 */ data: any; /** 时间戳 */ timestamp: number; /** 消息ID */ messageId?: string; } /** * 连接统计信息 */ interface WebSocketStatistics { /** 接收消息数量 */ messagesReceived: number; /** 处理消息数量 */ messagesProcessed: number; /** 接收字节数 */ bytesReceived: number; /** 连接时间 */ connectionTime: number; /** 最后消息时间 */ lastMessageTime: number; /** 重连次数 */ reconnectCount: number; /** 错误次数 */ errorCount: number; } /** * WebSocket管理器事件 */ interface WebSocketManagerEvents { /** 连接状态变化 */ 'connection:statusChange': (status: ConnectionStatus, error?: Error) => void; /** 连接成功 */ 'connection:connected': () => void; /** 连接断开 */ 'connection:disconnected': (error?: Error) => void; /** 重连开始 */ 'connection:reconnecting': (attempt: number, maxAttempts: number) => void; /** 连接错误 */ 'connection:error': (error: Error) => void; /** 接收到RSM消息 */ 'message:rsm': (rsmMessage: RSMMessage, vehicles: VehicleData[]) => void; /** 接收到原始消息 */ 'message:raw': (message: WebSocketMessage) => void; /** 消息错误 */ 'message:error': (error: Error, rawMessage?: any) => void; /** 缓冲区状态变化 */ 'buffer:statusChange': (isPaused: boolean, bufferSize: number) => void; /** 缓冲区溢出 */ 'buffer:overflow': (droppedMessages: number) => void; } declare class WebSocketManager { private ws; private config; private connectionState; private reconnectTimer; private reconnectAttempts; private messageBuffer; private isPaused; private statistics; private lastMessageTimestamp; private eventListeners; constructor(config: WebSocketConfig); /** * 初始化事件监听器 */ private initializeEventListeners; /** * 连接到WebSocket服务器 */ connect(): Promise<void>; /** * 断开连接 */ disconnect(): void; /** * 发送消息 */ send(message: WebSocketMessage): boolean; /** * 发送认证消息 */ authenticate(): boolean; /** * 发送心跳 */ sendHeartbeat(): boolean; /** * 暂停数据处理(开始缓存) */ pause(): void; /** * 恢复数据处理 */ resume(): void; /** * 获取缓存的消息 */ getBufferedMessages(): RSMMessage[]; /** * 清空消息缓存 */ clearBuffer(): void; /** * 跳转到最新数据 */ jumpToLatest(): void; /** * 获取连接状态 */ getConnectionStatus(): ConnectionStatus; /** * 检查是否已连接 */ isConnected(): boolean; /** * 获取连接统计信息 */ getStatistics(): WebSocketStatistics; /** * 手动重连 */ reconnect(): Promise<void>; /** * 处理连接打开 */ private handleConnectionOpen; /** * 处理消息接收 */ private handleMessage; /** * 处理任何格式的消息 - 极简版本,确保所有消息都能被处理 */ private processAnyMessage; /** * 尝试将任何消息作为RSM消息处理 */ private attemptRSMProcessing; /** * 检测是否看起来像车辆数据 */ private looksLikeVehicleData; /** * 从疑似车辆数据构造RSM消息 */ private constructRSMFromVehicleData; /** * 统一的RSM消息处理方法 */ private handleRSMMessage; /** * 处理连接错误 */ private handleConnectionError; /** * 处理连接关闭 */ private handleConnectionClose; /** * 安排重连 */ private scheduleReconnect; /** * 设置连接状态 */ private setStatus; /** * 缓存消息 */ private bufferMessage; /** * 处理RSM消息 */ private processRSMMessage; /** * 检查是否应该处理RSM消息 - 极简版本,基本不过滤 */ private shouldProcessRSMMessage; /** * 开始心跳 */ private startHeartbeat; /** * 处理心跳响应 */ private handleHeartbeatResponse; /** * 事件监听 */ on<K extends keyof WebSocketManagerEvents>(event: K, handler: WebSocketManagerEvents[K]): void; /** * 移除事件监听 */ off<K extends keyof WebSocketManagerEvents>(event: K, handler: WebSocketManagerEvents[K]): void; /** * 触发事件 */ private emit; /** * 清理资源 */ dispose(): void; } /** * 创建WebSocket数据管理器 */ declare function createWebSocketManager(config: WebSocketConfig): WebSocketManager; /** * 🎮 播放控制器 * * 统一管理数组和WebSocket模式的播放控制 * 支持播放、暂停、快进、进度控制等功能 */ /** * 播放状态 */ interface PlaybackState { /** 是否正在播放 */ isPlaying: boolean; /** 播放进度 (0-1) */ progress: number; /** 播放速度倍数 */ speed: number; /** 总时长(秒) */ duration: number; /** 当前时间(秒) */ currentTime: number; /** 播放模式 */ mode: 'array' | 'websocket' | 'idle'; /** 是否循环播放 */ loop: boolean; /** 是否暂停缓存 (WebSocket模式) */ isPaused?: boolean; /** 缓存消息数量 (WebSocket模式) */ bufferSize?: number; } /** * 播放控制配置 */ interface PlaybackControlConfig { /** 默认播放速度 */ defaultSpeed?: number; /** 播放速度范围 */ speedRange?: { min: number; max: number; }; /** 是否启用循环播放 */ enableLoop?: boolean; /** 更新间隔(毫秒) */ updateInterval?: number; } /** * 播放控制器事件 */ interface PlaybackControllerEvents { /** 播放状态变化 */ 'playback:stateChange': (state: PlaybackState) => void; /** 播放开始 */ 'playback:play': () => void; /** 播放暂停 */ 'playback:pause': () => void; /** 播放停止 */ 'playback:stop': () => void; /** 播放速度变化 */ 'playback:speedChange': (speed: number) => void; /** 播放进度变化 */ 'playback:progressChange': (progress: number, currentTime: number) => void; /** 播放结束 */ 'playback:ended': () => void; /** 车辆数据更新 */ 'data:update': (vehicles: VehicleData[], frameIndex?: number) => void; /** 播放错误 */ 'playback:error': (error: Error) => void; } /** * 播放控制器 */ declare class PlaybackController { private arrayDataManager; private webSocketManager; private config; private state; private playbackTimer; private eventListeners; constructor(config?: PlaybackControlConfig); /** * 初始化事件监听器 */ private initializeEventListeners; /** * 设置数组数据管理器 */ setArrayDataManager(arrayDataManager: ArrayDataManager): void; /** * 设置WebSocket数据管理器 */ setWebSocketManager(webSocketManager: WebSocketManager): void; /** * 绑定数组管理器事件 */ private bindArrayManagerEvents; /** * 绑定WebSocket管理器事件 */ private bindWebSocketManagerEvents; /** * 开始播放 */ play(): void; /** * 暂停播放 */ pause(): void; /** * 停止播放 */ stop(): void; /** * 设置播放速度 */ setSpeed(speed: number): void; /** * 跳转到指定进度(0-1) */ seekTo(progress: number): void; /** * 跳转到指定时间 */ seekToTime(timeInSeconds: number): void; /** * 设置循环播放 */ setLoop(loop: boolean): void; /** * 下一帧(仅数组模式) */ nextFrame(): boolean; /** * 上一帧(仅数组模式) */ previousFrame(): boolean; /** * 恢复播放(WebSocket模式) */ resume(): void; /** * 跳转到最新数据(WebSocket模式) */ jumpToLatest(): void; /** * 获取播放状态 */ getPlaybackState(): PlaybackState; /** * 检查是否正在播放 */ isPlaying(): boolean; /** * 获取当前进度 */ getProgress(): number; /** * 获取播放速度 */ getSpeed(): number; /** * 获取总时长 */ getDuration(): number; /** * 获取当前时间 */ getCurrentTime(): number; /** * 获取播放模式 */ getMode(): 'array' | 'websocket' | 'idle'; /** * 启动数组模式播放 */ private startArrayPlayback; /** * 启动WebSocket模式播放 */ private startWebSocketPlayback; /** * 触发状态变化事件 */ private emitStateChange; /** * 事件监听 */ on<K extends keyof PlaybackControllerEvents>(event: K, handler: PlaybackControllerEvents[K]): void; /** * 移除事件监听 */ off<K extends keyof PlaybackControllerEvents>(event: K, handler: PlaybackControllerEvents[K]): void; /** * 触发事件 */ private emit; /** * 清理资源 */ private cleanup; /** * 销毁控制器 */ dispose(): void; /** * 重置到初始状态 */ reset(): void; } /** * 创建播放控制器 */ declare function createPlaybackController(config?: PlaybackControlConfig): PlaybackController; /** * 🔍 车辆数据访问器 * * 提供统一的车辆数据访问接口 * 支持数据查询、过滤、排序和统计 */ /** * 车辆查询条件 */ interface VehicleQueryCondition { /** 车辆ID列表 */ ids?: string[]; /** 车辆类型过滤 */ types?: Array<0 | 1 | 2 | 3 | 4 | 5>; /** 位置区域过滤 */ bounds?: { minLat: number; maxLat: number; minLon: number; maxLon: number; }; /** 速度范围过滤 */ speedRange?: { min: number; max: number; }; /** 距离过滤(基于指定中心点) */ distance?: { centerLat: number; centerLon: number; radius: number; }; /** 时间范围过滤 */ timeRange?: { start: number; end: number; }; /** 数据源过滤 */ sources?: number[]; /** 文本搜索(车辆ID) */ search?: string; } /** * 排序配置 */ interface VehicleSortConfig { /** 排序字段 */ field: 'vehicleId' | 'ptcTimestamp' | 'speed' | 'distance' | 'ptcType'; /** 排序方向 */ order: 'asc' | 'desc'; } /** * 分页配置 */ interface VehiclePaginationConfig { /** 页码(从1开始) */ page: number; /** 每页数量 */ pageSize: number; } /** * 查询结果 */ interface VehicleQueryResult { /** 车辆数据列表 */ vehicles: VehicleData[]; /** 总数量 */ total: number; /** 分页信息 */ pagination?: { page: number; pageSize: number; totalPages: number; hasNext: boolean; hasPrev: boolean; }; } /** * 统计信息 */ interface VehicleStatistics { /** 总车辆数 */ total: number; /** 按类型分组统计 */ byType: Record<string, number>; /** 按数据源分组统计 */ bySource: Record<string, number>; /** 速度统计 */ speed: { min: number; max: number; average: number; median: number; }; /** 位置边界 */ bounds: { minLat: number; maxLat: number; minLon: number; maxLon: number; }; /** 更新时间范围 */ timeRange: { earliest: number; latest: number; }; } /** * 车辆数据访问器 */ declare class VehicleDataAccessor { private vehicleData; private indexedData; constructor(initialData?: VehicleData[]); /** * 设置车辆数据 */ setVehicleData(vehicles: VehicleData[]): void; /** * 添加车辆数据 */ addVehicle(vehicle: VehicleData): void; /** * 更新车辆数据 */ updateVehicle(vehicle: VehicleData): void; /** * 移除车辆数据 */ removeVehicle(vehicleId: string): boolean; /** * 批量更新车辆数据 */ batchUpdateVehicles(vehicles: VehicleData[]): void; /** * 清空所有车辆数据 */ clear(): void; /** * 根据ID获取车辆 */ getVehicleById(id: string): VehicleData | undefined; /** * 获取所有车辆数据 */ getAllVehicles(): VehicleData[]; /** * 查询车辆数据 */ queryVehicles(condition?: VehicleQueryCondition, sort?: VehicleSortConfig, pagination?: VehiclePaginationConfig): VehicleQueryResult; /** * 根据类型获取车辆 */ getVehiclesByType(type: string): VehicleData[]; /** * 根据数据源获取车辆 */ getVehiclesBySource(source: string): VehicleData[]; /** * 获取指定位置附近的车辆 */ getVehiclesNearLocation(centerLat: number, centerLon: number, radiusInMeters: number): VehicleData[]; /** * 获取指定区域内的车辆 */ getVehiclesInBounds(bounds: { minLat: number; maxLat: number; minLon: number; maxLon: number; }): VehicleData[]; /** * 搜索车辆(基于车辆ID) */ searchVehicles(searchText: string): VehicleData[]; /** * 获取统计信息 */ getStatistics(): VehicleStatistics; /** * 获取车辆数量 */ getVehicleCount(): number; /** * 检查车辆是否存在 */ hasVehicle(vehicleId: string): boolean; /** * 获取所有车辆ID */ getAllVehicleIds(): string[]; /** * 获取所有车辆类型 */ getAllVehicleTypes(): string[]; /** * 获取所有数据源 */ getAllDataSources(): string[]; /** * 应用查询条件 */ private applyQueryCondition; /** * 应用排序 */ private applySorting; /** * 更新索引 */ private updateIndexes; /** * 从索引中移除 */ private removeFromIndexes; /** * 清空索引 */ private clearIndexes; /** * 计算两点间距离(米) */ private calculateDistance; /** * 角度转弧度 */ private toRadians; } /** * 创建车辆数据访问器 */ declare function createVehicleDataAccessor(initialData?: VehicleData[]): VehicleDataAccessor; /** * 地理坐标系统管理器 * 负责处理WGS84经纬度坐标与Three.js 3D世界坐标的转换 * 支持UTM投影和本地坐标系转换,精度<1米 */ interface GeographicCoordinate { longitude: number; latitude: number; altitude?: number; } interface LocalCoordinate { x: number; y: number; z: number; } interface World3DCoordinate { x: number; y: number; z: number; } interface UTMConfig { zone: number; hemisphere: 'north' | 'south'; } declare class CoordinateSystem { private originLat; private originLng; private originAlt; private scale; private utmConfig; private utmProjection; private wgs84Projection; constructor(originLat: number, originLng: number, originAlt?: number, scale?: number); /** * 自动计算UTM区域 */ private calculateUTMZone; /** * 获取UTM投影字符串 */ private getUTMProjectionString; /** * WGS84经纬度转换为UTM坐标 */ private geographicToUTM; /** * UTM坐标转换为WGS84经纬度 */ private utmToGeographic; /** * 地理坐标转换为本地坐标 */ geographicToLocal(coord: GeographicCoordinate): LocalCoordinate; /** * 本地坐标转换为地理坐标 */ localToGeographic(coord: LocalCoordinate): GeographicCoordinate; /** * 本地坐标转换为Three.js世界坐标 * 注意:Three.js使用右手坐标系,Y轴向上 */ localToWorld3D(coord: LocalCoordinate): World3DCoordinate; /** * Three.js世界坐标转换为本地坐标 */ world3DToLocal(coord: World3DCoordinate): LocalCoordinate; /** * 地理坐标直接转换为Three.js世界坐标(组合转换) */ geographicToWorld3D(coord: GeographicCoordinate): World3DCoordinate; /** * Three.js世界坐标直接转换为地理坐标(组合转换) */ world3DToGeographic(coord: World3DCoordinate): GeographicCoordinate; /** * 创建Three.js Vector3对象 */ createVector3FromGeographic(coord: GeographicCoordinate): THREE.Vector3; /** * 从Three.js Vector3获取地理坐标 */ getGeographicFromVector3(vector: THREE.Vector3): GeographicCoordinate; /** * 计算两个地理坐标之间的距离(米) */ calculateDistance(coord1: GeographicCoordinate, coord2: GeographicCoordinate): number; /** * 获取坐标系统信息 */ getInfo(): { origin: { latitude: number; longitude: number; altitude: number; }; scale: number; utmZone: UTMConfig; projection: string; }; /** * 更新坐标系原点 */ updateOrigin(lat: number, lng: number, alt?: number): void; /** * 设置缩放比例 */ setScale(scale: number): void; } declare function createCoordinateSystem(originLat: number, originLng: number, originAlt?: number, scale?: number): CoordinateSystem; /** * 🚀 Data-Driven Vehicle System * * This system is designed for high-performance rendering of a large number of vehicles * using a single InstancedMesh per vehicle type. It is data-driven, meaning it * updates vehicle positions and rotations based on incoming data streams (e.g., RSM). * * It is self-contained and handles its own model loading based on configuration. * * Features: * - High-performance rendering with THREE.InstancedMesh. * - Configurable models per participant type (ptcType). * - Automatic fallback to colored primitive shapes for unconfigured types. * - Smooth animation using temporal interpolation with easing. * - Efficiently handles vehicle creation, updates, and removal. * - Built-in click detection to identify individual vehicles. */ /** * 模型配置 */ interface VehicleModelConfig { url: string; /** * 💥 [性能关键] 是否用模型的包围盒替代原始模型进行渲染。 * 对于高精度模型,强烈建议开启此项以保证性能。 * @default true */ useBoundingBox?: boolean; } /** * DataDrivenVehicleSystem 的配置选项 */ interface DataDrivenVehicleSystemOptions { /** 每种参与者类型的最大实例数 */ maxInstancesPerType?: number; /** 定义 ptcType 到模型的映射 */ models?: Map<number, VehicleModelConfig | string>; /** Draco解码器路径 */ dracoDecoderPath?: string; /** * 缓冲区处理间隔(毫秒)。 * 系统处理累积数据并启动新动画的频率。 * 🚀 10Hz RSM适配:推荐100ms间隔 * 🔧 1Hz RSM:使用1000ms间隔 * @default 100 */ processingInterval?: number; /** * 🚀 启用数据平滑处理,用于高频数据(如10Hz) * @default true */ enableDataSmoothing?: boolean; /** * 🎯 历史数据缓存大小,用于数据平滑 * @default 3 */ historyCacheSize?: number; } declare class DataDrivenVehicleSystem { private scene; private camera; private domElement; private coordinateSystem; private instancedMeshes; private activeAnimations; private vehicleDataMap; private vehicleIdToIndex; private availableIndices; private modelGeometries; private modelMaterials; private maxInstancesPerType; private animationFrameId; private raycaster; private onVehicleClick?; private loader; private modelConfigs; private isInitialized; private messageBuffer; private processingIntervalHandle; private processingInterval; private enableDataSmoothing; private historyCacheSize; private vehicleHistory; private stats; private defaultScale; private groundMeshes; private groundRaycaster; constructor(scene: THREE.Scene, camera: THREE.Camera, domElement: HTMLElement, coordinateSystem: CoordinateSystem, options?: DataDrivenVehicleSystemOptions); /** * 注册用于高度检测的地面/路面模型。 * @param meshes - 一个包含所有地面网格的数组。 */ setGroundMeshes(meshes: THREE.Mesh[]): void; initialize(): Promise<void>; private _extractModelData; private ensureMeshForPtcType; /** * 💥 主要修改:processRSMData 现在只负责将数据放入缓冲区 * @param vehicles - 从 WebSocket 接收到的车辆数据数组 */ processRSMData(data: VehicleData[]): void; /** * 🚀 新增:启动周期性处理缓冲区的循环 */ private startProcessingLoop; /** * 🚀 新增:停止处理循环 */ private stopProcessingLoop; /** * 🚀 新增:实际处理数据并更新车辆状态的核心逻辑 * 🎯 10Hz适配:优化处理逻辑和动画时长计算 */ private _processBufferedData; private getVehicleId; private addVehicle; private removeVehicle; private updateVehicleHeight; update(): void; private start; private stop; setOnVehicleClick(callback: (vehicleId: string, vehicleData: VehicleData) => void): void; getVehicleWorldPosition(vehicleId: string): THREE.Vector3 | null; getVehicleData(vehicleId: string): VehicleData | undefined; getStats(): { vehicleCount: number; created: number; updated: number; }; getVehicleCount(): number; getLegendData(): { type: number; name: string; color: string; }[]; private onCanvasClick; /** * 🚀 10Hz适配:数据平滑处理方法 * 使用加权平均对高频数据进行平滑,减少抖动 */ private smoothVehicleData; /** * 🎯 加权平均计算方法 */ private weightedAverage; dispose(): void; } /** * 🏭 创建并初始化一个 DataDrivenVehicleSystem 实例 * @param scene The THREE.Scene to add vehicles to. * @param camera The THREE.Camera for raycasting. * @param domElement The canvas element for click events. * @param coordinateSystem The V2X coordinate system instance. * @param options Configuration options for the system. * @returns A promise that resolves to the fully initialized vehicle system. */ declare function createDataDrivenVehicleSystem(scene: THREE.Scene, camera: THREE.Camera, domElement: HTMLElement, coordinateSystem: CoordinateSystem, options?: DataDrivenVehicleSystemOptions): Promise<DataDrivenVehicleSystem>; /** * 🚗 V2X车辆管理器 - 数据驱动车辆3D可视化系统 * * 设计理念: * 1. 📊 数据驱动:专为RSM协议数据优化,自动处理车辆生命周期 * 2. 🎯 高性能:支持大规模车辆渲染,批量更新优化 * 3. 🔄 实时同步:位置、状态、属性实时更新和动画 * 4. 🎨 智能交互:自动绑定点击事件和气泡系统 * 5. 🌐 地理坐标:完整支持地理坐标与3D世界坐标转换 */ /** * 车辆类型枚举(基于RSM ptcType标准化) */ type VehicleType = 'unknown' | 'vehicle' | 'non_motor_vehicle' | 'pedestrian' | 'rsu'; /** * 车辆状态枚举(基于实际运行状态) */ type VehicleStatus = 'moving' | 'stopped' | 'parked' | 'offline' | 'warning' | 'error'; /** * 车辆移动配置接口 */ interface MoveToConfig { /** 目标地理坐标 */ latitude: number; longitude: number; altitude?: number; /** 移动持续时间(秒) */ duration?: number; /** 目标航向角(弧度) */ heading?: number; /** 动画缓动函数 */ ease?: string; /** 完成回调 */ onComplete?: () => void; /** 进度回调 */ onUpdate?: (progress: number) => void; } /** * 车辆移动结果 */ interface MoveResult { success: boolean; distance: number; duration: number; error?: string; } /** * 手动车辆配置(用于addVehicle) */ interface VehicleConfig { /** 车辆唯一标识 */ id: string; /** 车辆名称 */ name: string; /** 车辆类型 */ type: VehicleType; /** 初始状态 */ status?: VehicleStatus; /** 3D世界坐标位置 */ position?: THREE.Vector3; /** 地理坐标位置 */ geographicPosition?: { latitude: number; longitude: number; altitude?: number; }; /** 初始航向角(弧度) */ heading?: number; /** 车辆3D模型URL */ modelUrl?: string; /** 车辆缩放比例 */ scale?: number; /** 自定义数据 */ data?: Record<string, any>; /** 点击回调 */ onClick?: (controller: VehicleController) => void; /** 气泡配置 */ bubbleConfig?: Partial<BubbleConfig>; } /** * 车辆实例信息(运行时状态) */ interface VehicleInfo extends VehicleConfig { /** 3D对象引用 */ object3D: THREE.Object3D; /** 当前状态 */ status: VehicleStatus; /** RSM参与者数据 */ rsmData?: VehicleData; /** 是否显示气泡 */ bubbleVisible: boolean; /** 创建时间 */ createdAt: Date; /** 最后更新时间 */ updatedAt: Date; /** GSAP动画实例 */ gsapTween?: any; /** 动画混合器 */ mixer?: THREE.AnimationMixer; /** 车轮动画 */ wheelAction?: THREE.AnimationAction; } /** * 兼容旧版本的移动配置 */ interface MoveAnimationConfig { targetGeographicPosition: { latitude: number; longitude: number; altitude?: number; }; duration?: number; targetHeading?: number; ease?: string; onComplete?: () => void; onUpdate?: (progress: number) => void; } /** * 🎮 车辆控制器 - 单个车辆的操作接口 */ declare class VehicleController { private vehicleInfo; private manager; constructor(vehicleInfo: VehicleInfo, manager: VehicleManager); get id(): string; get name(): string; get type(): VehicleType; get status(): VehicleStatus; get object3D(): THREE.Object3D; get info(): VehicleInfo; get rsmData(): VehicleData | undefined; /** * 获取当前地理坐标 */ get geographicPosition(): { latitude: number; longitude: number; altitude?: number; } | undefined; /** * 移动到指定地理坐标 */ moveTo(config: MoveToConfig): MoveResult; /** * 设置航向角 */ setHeading(heading: number): void; /** * 设置车辆状态 */ setStatus(status: VehicleStatus): void; /** * 更新自定义数据 */ updateData(data: Record<string, any>): void; /** * 显示气泡 */ showBubble(): boolean; /** * 隐藏气泡 */ hideBubble(): boolean; /** * 切换气泡显示状态 */ toggleBubble(): boolean; } /** * 🚗 车辆管理器 - 核心车辆管理系统 */ declare class VehicleManager { private scene; private camera; private container; private bubbleManager?; coordinateSystem?: CoordinateSystem; private vehicles; private vehicleGroup; private modelLoader; private defaultVehicleModelUrl; private raycaster; private mouse; private boundClick; private readonly VEHICLE_STYLES; constructor(scene: THREE.Scene, camera: THREE.Camera, container: HTMLElement, bubbleManager?: BubbleManager, coordinateSystem?: CoordinateSystem, defaultVehicleModelUrl?: string); /** * 初始化交互系统 */ private initializeInteractionSystem; /** * 处理RSM参与者数据批量更新 */ processRSMData(rsmParticipants: VehicleData[]): Promise<void>; /** * 从RSM数据创建新车辆 */ private createVehicleFromRSMData; /** * 从RSM数据更新现有车辆 - 使用平滑动画 */ private updateVehicleFromRSMData; /** * 从RSM数据推断车辆状态 */ private inferStatusFromRSMData; /** * 将RSM ptcType映射为标准车辆类型 */ private mapPtcTypeToStandardType; /** * 手动添加车辆 */ addVehicle(config: VehicleConfig): Promise<VehicleController>; /** * 移除车辆 */ removeVehicle(vehicleId: string): Promise<boolean>; /** * 获取所有车辆控制器 */ getAllVehicles(): VehicleController[]; /** * 获取指定车辆控制器 */ getVehicle(vehicleId: string): VehicleController | undefined; /** * 按类型获取车辆 */ getVehiclesByType(type: VehicleType): VehicleController[]; /** * 按状态获取车辆 */ getVehiclesByStatus(status: VehicleStatus): VehicleController[]; /** * 移动车辆到指定位置(带详细结果) */ moveVehicleToLocationWithResult(vehicleId: string, config: MoveAnimationConfig): MoveResult; /** * 移动车辆(兼容旧版API) */ moveVehicleToLocation(vehicleId: string, config: MoveAnimationConfig): boolean; /** * 显示车辆气泡 */ showVehicleBubble(vehicleId: string): boolean; /** * 隐藏车辆气泡 */ hideVehicleBubble(vehicleId: string): boolean; /** * 更新车辆气泡内容 */ updateVehicleBubbleContent(vehicle: VehicleInfo): void; /** * 创建车辆气泡 */ private createVehicleBubble; /** * 加载车辆3D模型 */ private loadVehicleModel; /** * 处理点击事件 */ private handleClick; /** * 查找车辆ID */ private findVehicleId; /** * 处理车辆点击 */ private handleVehicleClick; /** * 更新动画(每帧调用) */ update(delta: number): void; /** * 清理资源 */ dispose(): void; /** * 获取车辆类型显示名称 */ private getVehicleTypeDisplayName; /** * 获取车辆状态显示名称 */ private getVehicleStatusDisplayName; } /** * 创建车辆管理器实例 */ declare function createVehicleManager(scene: THREE.Scene, camera: THREE.Camera, container: HTMLElement, bubbleManager?: BubbleManager, coordinateSystem?: CoordinateSystem, defaultVehicleModelUrl?: string): VehicleManager; /** * 🛟 V2X设备管理器 - 智能设备3D交互系统 * * 这个管理器就像"智能设备的指挥官"👨‍💼,负责: * 1. 📍 在3D场景中添加各种设备(RSU、摄像头、雷达等) * 2. 🖱️ 为每个设备绑定点击事件,无需手动raycasting * 3. 🎨 自动关联气泡系统,点击即显示设备信息 * 4. 🔄 统一管理设备状态变化和视觉效果 * 5. 🎯 提供高性能的3D交互体验 */ /** * 设备类型定义 */ type DeviceType = 'rsu' | 'camera' | 'radar' | 'vehicle' | 'sensor' | 'gateway'; /** * 设备状态定义 */ type DeviceStatus = 'online' | 'offline' | 'warning' | 'maintenance' | 'error' | 'moving'; /** * 设备配置接口 */ interface DeviceConfig { /** 设备唯一标识 */ id: string; /** 设备名称 */ name: string; /** 设备类型 */ type: DeviceType; /** 设备状态 */ status: DeviceStatus; /** 3D世界坐标位置 */ position?: THREE.Vector3; /** 地理坐标位置(纬度、经度、高度) */ geographicPosition?: { latitude: number; longitude: number; altitude?: number; }; /** 设备数据 */ data?: Record<string, any>; /** 自定义3D模型URL(可选,不提供则使用默认几何体) */ modelUrl?: string; /** 设备大小缩放 */ scale?: number; /** 点击回调函数 */ onClick?: (device: DeviceInfo) => void; /** 气泡配置(可选,不提供则使用默认配置) */ bubbleConfig?: Partial<BubbleConfig>; } /** * 设备信息接口(包含运行时状态) */ interface DeviceInfo extends DeviceConfig { /** 3D对象引用 */ object3D: THREE.Object3D; /** 是否显示气泡 */ bubbleVisible: boolean; /** 创建时间 */ createdAt: Date; /** 最后更新时间 */ updatedAt: Date; } /** * 🛟 V2X设备管理器 */ declare class DeviceManager { private scene; private camera; private container; private bubbleManager?; private coordinateSystem?; private devices; private deviceGroup; private raycaster; private mouse; private hoveredDevice; private boundClick; private boundMouseMove; private readonly DEVICE_STYLES; constructor(scene: THREE.Scene, camera: THREE.Camera, container: HTMLElement, bubbleManager?: BubbleManager, coordinateSystem?: CoordinateSystem); private initializeInteractionSystem; addDevice(config: DeviceConfig): Promise<DeviceInfo>; private createDevice3D; private loadDeviceModel; private createDeviceBubble; private getDeviceTypeDisplayName; private getStatusDisplayName; private handleClick; private handleMouseMove; private getIntersects; private findDeviceId; private updateDeviceHoverState; private handleDeviceClick; toggleDeviceBubble: (deviceId: string) => void; showDeviceBubble(deviceId: string): boolean; hideDeviceBubble(deviceId: string): boolean; removeDevice(deviceId: string): boolean; updateDeviceStatus(deviceId: string, status: DeviceStatus): boolean; getDevice: (deviceId: string) => DeviceInfo | undefined; getAllDevices: () => DeviceInfo[]; getDevicesByType: (type: DeviceType) => DeviceInfo[]; getDevicesByStatus: (status: DeviceStatus) => DeviceInfo[]; showAllBubbles: () => void; hideAllBubbles: () => void; dispose(): void; moveDeviceToLocation(deviceId: string, config: MoveAnimationConfig): boolean; private moveDeviceBasic; private updateDeviceBubbleContent; } declare function createDeviceManager(scene: THREE.Scene, camera: THREE.Camera, container: HTMLElement, bubbleManager?: BubbleManager, coordinateSystem?: CoordinateSystem): DeviceManager; /** * 🌎 V2X Three.js 环境管理器 - 你的3D世界天空画师 * * 这个文件就像是"电影摄影师的灯光团队"🎬,负责创建和管理3D场景的 * 天空背景、环境光照,让你的3D世界看起来更真实、更有电影感! * * 🤔 什么是环境管理? * 想象你在拍电影: * 1. 🌅 天空背景:决定场景是白天、黄昏还是夜晚 * 2. 💡 环境光照:来自天空的自然光线,照亮所有物体 * 3. ✨ 反射效果:金属表面反射出真实的天空 * 4. 🎨 色彩氛围:整个场景的色调和情绪 * * 🏞️ HDR技术解释: * HDR(High Dynamic Range,高动态范围)就像"超级照片"📸: * - 普通照片:只能记录有限的明暗范围 * - HDR照片:可以记录从极暗到极亮的所有细节 * - 在3D中:提供真实的光照信息,让反射和阴影更自然 * * 🎭 支持的功能: * - 🌅 HDR环境贴图加载:真实的天空光照 * - 🎨 自定义天空盒:渐变色天空效果 * - 💡 光照强度控制:调节环境光亮度 * - 🔄 平滑环境切换:在不同环境间过渡 * - 📦 环境预加载:提前准备多个环境 */ /** * 🌎 环境管理器主类 - 你的3D世界天空大师 * * 这个类就像是"电影布景师"🎭,专门负责设计和管理3D场景的 * 天空背景和环境光照,让你的3D世界拥有电影级的视觉效果! * * @example * ```typescript * // 创建环境管理器 * const envManager = new EnvironmentManager(scene, renderer); * * // 加载HDR环境(比如日落天空) * await envManager.loadHDREnvironment('sunset.hdr'); * * // 调节光照强度 * envManager.setIntensity(1.5); // 让环境光更亮 * * // 创建渐变天空 * envManager.createGradientSky(0x87ceeb, 0xffffff, 0.6); * ``` */ declare class EnvironmentManager { private scene; private renderer; private pmremGenerator; private currentEnvMap; private rgbeLoader; private envIntensity; private backgroundIntensity; /** * 🏗️ 构造函数 - 创建环境管理器 * * 就像搭建一个"摄影棚"🎬,需要准备各种灯光设备和背景布: * 1. 🎭 连接到3D场景和渲染器 * 2. ⚡ 初始化HDR处理工具 * 3. 🎨 设置默认的环境效果 * * @param scene Three.js场景对象 * @param renderer Three.js渲染器对象 */ constructor(scene: THREE.Scene, renderer: THREE.WebGLRenderer); /** * 🎨 设置默认环境 - 创建基础氛围 * * 这个方法就像"电影开拍前的基础布光"💡,设置一个基本的 * 环境氛围,确保即使没有HDR贴图,场景也有合适的外观! */ private setupDefaultEnvironment; /** * 🌅 加载HDR环境贴图 - 导入真实世界的光照 * * 这个方法就像"导入专业摄影师拍摄的360度全景照片"📸, * 让你的3D世界拥有真实世界的光照和反射效果! * * @param url HDR文件的网络地址或本地路径 * @param onProgress 可选的加载进度回调函数 * @returns Promise<THREE.Texture> 处理好的环境贴图 */ loadHDREnvironment(url: string, onProgress?: (progress: ProgressEvent) => void): Promise<THREE.Texture>; /** * 🌍 设置环境贴图 - 更换3D世界的天空 * * 这个方法就像"更换电影拍摄的背景布景"🎬,把新的环境贴图 * 应用到3D场景中,立刻改变整个世界的光照和氛围! * * @param envMap 新的环境贴图纹理 */ setEnvironmentMap(envMap: THREE.Texture): void; /** * 💡 设置环境光强度 - 调节世界的亮度 * * 这个方法就像"调节摄影棚的灯光亮度"💡,让你可以 * 让场景更亮(白天感)或更暗(夜晚感)! * * @param intensity 强度值,范围0-2(0=全黑,1=正常,2=超亮) */ setIntensity(intensity: number): void; /** * 🎨 设置背景强度 - 调节天空的亮度 * * 这个方法就像"调节背景灯的亮度"🎨,可以让天空背景 * 更突出或更低调,而不影响物体的光照效果! * * @param intensity 背景强度值,范围0-1(0=全暗,1=正常) */ setBackgroundIntensity(intensity: number): void; /** * 🔆 更新环境光强度 - 应用光照强度变化 * * 这个方法就像"实际转动灯光调节旋钮"💡,通过调节 * 渲染器的曝光度来控制整个场景的亮度! */ private updateEnvironmentIntensity; /** * 🎨 更新背景强度 - 应用背景亮度变化 * * 这个方法负责调节背景的显示强度,不过目前通过 * 环境光强度来间接控制(保持视觉一致性)。 */ private updateBackgroundIntensity; /** * 📊 获取当前环境强度 * * @returns number 当前环境光强度值 */ getIntensity(): number; /** * 📊 获取当前背景强度 * * @returns number 当前背景强度值 */ getBackgroundIntensity(): number; /** * 🔄 切换背景显示模式 - 更换天空类型 * * 这个方法就像"更换舞台背景"🎭,可以在不同类型的 * 背景之间切换:真实环境、纯色背景、或透明背景! *