@v2x-three/core
Version:
V2X Three.js 核心库 - 开放式的Three.js工具集,支持React和Vue项目
2,314 lines (2,291 loc) • 151 kB
TypeScript
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;
/**
* 🔄 切换背景显示模式 - 更换天空类型
*
* 这个方法就像"更换舞台背景"🎭,可以在不同类型的
* 背景之间切换:真实环境、纯色背景、或透明背景!
*