@esengine/pathfinding
Version:
寻路系统 | Pathfinding System - A*, Grid, NavMesh
703 lines (695 loc) • 22.6 kB
TypeScript
import { Component, EntitySystem, Entity } from '@esengine/ecs-framework';
import { S as IVector2, V as IPathPlanner, a7 as IFlowController, a0 as ILocalAvoidance, a2 as ICollisionResolver, _ as IObstacleData } from './FlowController-BztOzQsW.js';
export { ap as CollisionResolverAdapter, ab as DEFAULT_FLOW_CONTROLLER_CONFIG, ao as DEFAULT_ORCA_PARAMS, ar as FlowController, ag as GridPathfinderAdapter, a3 as ICongestionZone, a4 as IFlowAgentData, a5 as IFlowControlResult, a6 as IFlowControllerConfig, au as IGridPathfinderAdapterConfig, av as IIncrementalGridPathPlannerConfig, at as IORCAParams, ak as IncrementalGridPathPlannerAdapter, ae as NavMeshPathPlannerAdapter, am as ORCALocalAvoidanceAdapter, aa as PassPermission, ah as createAStarPlanner, aq as createDefaultCollisionResolver, as as createFlowController, aj as createHPAPlanner, al as createIncrementalAStarPlanner, ai as createJPSPlanner, af as createNavMeshPathPlanner, an as createORCAAvoidance } from './FlowController-BztOzQsW.js';
import './CollisionResolver-CSgWsegP.js';
import '@esengine/ecs-framework-math';
/**
* @zh 统一导航代理组件
* @en Unified Navigation Agent Component
*
* @zh 算法无关的通用导航属性,配合 NavigationSystem 使用
* @en Algorithm-agnostic common navigation properties, works with NavigationSystem
*/
/**
* @zh 导航状态
* @en Navigation state
*/
declare enum NavigationState {
/**
* @zh 空闲
* @en Idle
*/
Idle = "idle",
/**
* @zh 正在导航
* @en Navigating
*/
Navigating = "navigating",
/**
* @zh 已到达
* @en Arrived
*/
Arrived = "arrived",
/**
* @zh 路径被阻挡
* @en Path blocked
*/
Blocked = "blocked",
/**
* @zh 无法到达
* @en Unreachable
*/
Unreachable = "unreachable"
}
/**
* @zh 统一导航代理组件
* @en Unified navigation agent component
*
* @zh 包含算法无关的通用导航属性,不包含算法特定参数
* @en Contains algorithm-agnostic common navigation properties, no algorithm-specific parameters
*
* @example
* ```typescript
* const entity = scene.createEntity('Agent');
*
* // 添加导航代理组件
* const nav = entity.addComponent(new NavigationAgentComponent());
* nav.radius = 0.5;
* nav.maxSpeed = 5.0;
*
* // 设置目标
* nav.setDestination(100, 200);
*
* // NavigationSystem 会自动处理:
* // 1. 使用 IPathPlanner 计算全局路径
* // 2. 使用 ILocalAvoidance 进行局部避让
* // 3. 使用 ICollisionResolver 防止穿透
* ```
*/
declare class NavigationAgentComponent extends Component {
/**
* @zh 代理半径
* @en Agent radius
*/
radius: number;
/**
* @zh 最大速度
* @en Maximum speed
*/
maxSpeed: number;
/**
* @zh 加速度(用于平滑移动)
* @en Acceleration (for smooth movement)
*/
acceleration: number;
/**
* @zh 路径点到达阈值
* @en Waypoint arrival threshold
*/
waypointThreshold: number;
/**
* @zh 目标到达阈值
* @en Destination arrival threshold
*/
arrivalThreshold: number;
/**
* @zh 路径重新计算间隔(秒)
* @en Path recalculation interval (seconds)
*/
repathInterval: number;
/**
* @zh 是否启用导航
* @en Whether navigation is enabled
*/
enabled: boolean;
/**
* @zh 是否自动重新计算被阻挡的路径
* @en Whether to auto repath when blocked
*/
autoRepath: boolean;
/**
* @zh 是否启用平滑转向
* @en Whether to enable smooth steering
*/
smoothSteering: boolean;
/**
* @zh 当前位置
* @en Current position
*/
position: IVector2;
/**
* @zh 当前速度
* @en Current velocity
*/
velocity: IVector2;
/**
* @zh 目标位置
* @en Destination position
*/
destination: IVector2 | null;
/**
* @zh 当前导航状态
* @en Current navigation state
*/
state: NavigationState;
/**
* @zh 当前路径
* @en Current path
*/
path: IVector2[];
/**
* @zh 当前路径点索引
* @en Current waypoint index
*/
currentWaypointIndex: number;
/**
* @zh 上次重新计算路径的时间
* @en Last repath time
*/
lastRepathTime: number;
/**
* @zh 当前增量寻路请求 ID
* @en Current incremental pathfinding request ID
*/
currentRequestId: number;
/**
* @zh 寻路进度 (0-1)
* @en Pathfinding progress (0-1)
*/
pathProgress: number;
/**
* @zh 优先级(数字越小优先级越高)
* @en Priority (lower number = higher priority)
*/
priority: number;
/**
* @zh 是否正在等待路径计算完成
* @en Whether waiting for path computation to complete
*/
isComputingPath: boolean;
/**
* @zh 设置位置
* @en Set position
*
* @param x - @zh X 坐标 @en X coordinate
* @param y - @zh Y 坐标 @en Y coordinate
*/
setPosition(x: number, y: number): void;
/**
* @zh 设置目标位置
* @en Set destination
*
* @param x - @zh 目标 X 坐标 @en Destination X coordinate
* @param y - @zh 目标 Y 坐标 @en Destination Y coordinate
*/
setDestination(x: number, y: number): void;
/**
* @zh 停止导航
* @en Stop navigation
*/
stop(): void;
/**
* @zh 获取当前路径点
* @en Get current waypoint
*
* @returns @zh 当前路径点,如果没有则返回 null @en Current waypoint, or null if none
*/
getCurrentWaypoint(): IVector2 | null;
/**
* @zh 获取到目标的距离
* @en Get distance to destination
*
* @returns @zh 到目标的距离,如果没有目标则返回 Infinity @en Distance to destination, or Infinity if no destination
*/
getDistanceToDestination(): number;
/**
* @zh 获取当前速度大小
* @en Get current speed
*
* @returns @zh 当前速度大小 @en Current speed magnitude
*/
getCurrentSpeed(): number;
/**
* @zh 检查是否已到达目标
* @en Check if arrived at destination
*
* @returns @zh 是否已到达 @en Whether arrived
*/
hasArrived(): boolean;
/**
* @zh 检查路径是否被阻挡
* @en Check if path is blocked
*
* @returns @zh 是否被阻挡 @en Whether blocked
*/
isBlocked(): boolean;
/**
* @zh 检查目标是否无法到达
* @en Check if destination is unreachable
*
* @returns @zh 是否无法到达 @en Whether unreachable
*/
isUnreachable(): boolean;
/**
* @zh 重置组件状态
* @en Reset component state
*/
reset(): void;
/**
* @zh 组件从实体移除时调用
* @en Called when component is removed from entity
*/
onRemovedFromEntity(): void;
}
/**
* @zh 统一导航系统
* @en Unified Navigation System
*
* @zh 可插拔的导航系统,支持运行时切换寻路、避让、碰撞检测算法
* @en Pluggable navigation system, supports runtime swapping of pathfinding, avoidance, and collision detection algorithms
*/
/**
* @zh 导航系统配置
* @en Navigation system configuration
*/
interface INavigationSystemConfig {
/**
* @zh 时间步长
* @en Time step
*/
timeStep?: number;
/**
* @zh 是否启用路径规划阶段
* @en Whether to enable path planning stage
*/
enablePathPlanning?: boolean;
/**
* @zh 是否启用流量控制阶段
* @en Whether to enable flow control stage
*/
enableFlowControl?: boolean;
/**
* @zh 是否启用局部避让阶段
* @en Whether to enable local avoidance stage
*/
enableLocalAvoidance?: boolean;
/**
* @zh 是否启用碰撞解决阶段
* @en Whether to enable collision resolution stage
*/
enableCollisionResolution?: boolean;
/**
* @zh 是否启用代理间碰撞解决
* @en Whether to enable agent-agent collision resolution
*/
enableAgentCollisionResolution?: boolean;
/**
* @zh 是否启用时间切片寻路(需要 IIncrementalPathPlanner)
* @en Whether to enable time-sliced pathfinding (requires IIncrementalPathPlanner)
*
* @zh 启用后,寻路计算会分散到多帧执行,避免卡顿
* @en When enabled, pathfinding computation is spread across multiple frames to avoid stuttering
*/
enableTimeSlicing?: boolean;
/**
* @zh 每帧总迭代预算
* @en Total iteration budget per frame
*
* @zh 所有代理共享此预算,根据优先级分配
* @en All agents share this budget, allocated by priority
*
* @default 1000
*/
iterationsBudget?: number;
/**
* @zh 每帧最大处理代理数
* @en Maximum agents to process per frame
*
* @zh 限制每帧处理的代理数量,避免过载
* @en Limits the number of agents processed per frame to avoid overload
*
* @default 10
*/
maxAgentsPerFrame?: number;
/**
* @zh 每个代理每帧最大迭代数
* @en Maximum iterations per agent per frame
*
* @default 200
*/
maxIterationsPerAgent?: number;
}
/**
* @zh 统一导航系统
* @en Unified Navigation System
*
* @zh 可插拔的导航系统,处理管线:PathPlanning → LocalAvoidance → CollisionResolution
* @en Pluggable navigation system, pipeline: PathPlanning → LocalAvoidance → CollisionResolution
*
* @example
* ```typescript
* import {
* NavigationSystem,
* NavigationAgentComponent,
* createNavMeshPathPlanner,
* createORCAAvoidance,
* createDefaultCollisionResolver
* } from '@esengine/pathfinding/ecs';
*
* // 创建系统
* const navSystem = new NavigationSystem();
*
* // 配置算法(可选,每个阶段都可以独立启用/禁用)
* navSystem.setPathPlanner(createNavMeshPathPlanner(navMesh));
* navSystem.setLocalAvoidance(createORCAAvoidance());
* navSystem.setCollisionResolver(createDefaultCollisionResolver());
*
* scene.addSystem(navSystem);
*
* // 添加障碍物
* navSystem.addObstacle({ vertices: [...] });
*
* // 创建代理
* const agent = scene.createEntity('Agent');
* const nav = agent.addComponent(new NavigationAgentComponent());
* nav.setPosition(0, 0);
* nav.setDestination(100, 100);
*
* // 运行时切换算法
* navSystem.setPathPlanner(createJPSPlanner(gridMap));
* navSystem.setLocalAvoidance(null); // 禁用避让
* ```
*/
declare class NavigationSystem extends EntitySystem {
private config;
private pathPlanner;
private flowController;
private localAvoidance;
private collisionResolver;
/**
* @zh 静态障碍物(墙壁、建筑等)- 由 PathPlanner 和 CollisionResolver 处理
* @en Static obstacles (walls, buildings) - handled by PathPlanner and CollisionResolver
*/
private staticObstacles;
/**
* @zh 动态障碍物(移动物体等)- 由 ORCA 和 CollisionResolver 处理
* @en Dynamic obstacles (moving objects) - handled by ORCA and CollisionResolver
*/
private dynamicObstacles;
private currentTime;
private agentEnterTimes;
/**
* @zh 是否为增量寻路器
* @en Whether the path planner is incremental
*/
private isIncrementalPlanner;
/**
* @zh 等待寻路的代理队列(按优先级排序)
* @en Queue of agents waiting for pathfinding (sorted by priority)
*/
private pendingPathRequests;
constructor(config?: INavigationSystemConfig);
/**
* @zh 设置路径规划器
* @en Set path planner
*
* @param planner - @zh 路径规划器,传入 null 禁用路径规划 @en Path planner, pass null to disable
*
* @zh 如果传入 IIncrementalPathPlanner 且启用了时间切片,会自动使用增量寻路
* @en If passing IIncrementalPathPlanner and time slicing is enabled, will automatically use incremental pathfinding
*
* @example
* ```typescript
* navSystem.setPathPlanner(createNavMeshPathPlanner(navMesh));
* navSystem.setPathPlanner(createAStarPlanner(gridMap));
* navSystem.setPathPlanner(createIncrementalAStarPlanner(gridMap)); // 支持时间切片
* navSystem.setPathPlanner(null); // 禁用
* ```
*/
setPathPlanner(planner: IPathPlanner | null): void;
/**
* @zh 获取当前路径规划器
* @en Get current path planner
*/
getPathPlanner(): IPathPlanner | null;
/**
* @zh 设置流量控制器
* @en Set flow controller
*
* @param controller - @zh 流量控制器,传入 null 禁用流量控制 @en Flow controller, pass null to disable
*
* @example
* ```typescript
* navSystem.setFlowController(createFlowController());
* navSystem.setFlowController(null); // 禁用
* ```
*/
setFlowController(controller: IFlowController | null): void;
/**
* @zh 获取当前流量控制器
* @en Get current flow controller
*/
getFlowController(): IFlowController | null;
/**
* @zh 设置局部避让算法
* @en Set local avoidance algorithm
*
* @param avoidance - @zh 局部避让算法,传入 null 禁用避让 @en Local avoidance, pass null to disable
*
* @example
* ```typescript
* navSystem.setLocalAvoidance(createORCAAvoidance());
* navSystem.setLocalAvoidance(null); // 禁用
* ```
*/
setLocalAvoidance(avoidance: ILocalAvoidance | null): void;
/**
* @zh 获取当前局部避让算法
* @en Get current local avoidance algorithm
*/
getLocalAvoidance(): ILocalAvoidance | null;
/**
* @zh 设置碰撞解决器
* @en Set collision resolver
*
* @param resolver - @zh 碰撞解决器,传入 null 禁用碰撞解决 @en Collision resolver, pass null to disable
*
* @example
* ```typescript
* navSystem.setCollisionResolver(createDefaultCollisionResolver());
* navSystem.setCollisionResolver(null); // 禁用
* ```
*/
setCollisionResolver(resolver: ICollisionResolver | null): void;
/**
* @zh 获取当前碰撞解决器
* @en Get current collision resolver
*/
getCollisionResolver(): ICollisionResolver | null;
/**
* @zh 添加静态障碍物(墙壁、建筑等)
* @en Add static obstacle (walls, buildings, etc.)
*
* @zh 静态障碍物由 PathPlanner 规划路径时考虑,CollisionResolver 防止穿透
* @zh ORCA 不会处理静态障碍物,因为路径规划已经绑开了它们
* @en Static obstacles are considered by PathPlanner for routing, CollisionResolver for penetration prevention
* @en ORCA does NOT process static obstacles since path planning already avoids them
*
* @param obstacle - @zh 障碍物数据 @en Obstacle data
*/
addStaticObstacle(obstacle: IObstacleData): void;
/**
* @zh 添加动态障碍物(移动物体、临时障碍等)
* @en Add dynamic obstacle (moving objects, temporary obstacles, etc.)
*
* @zh 动态障碍物由 ORCA 进行局部避让,CollisionResolver 防止穿透
* @en Dynamic obstacles are handled by ORCA for local avoidance, CollisionResolver for penetration prevention
*
* @param obstacle - @zh 障碍物数据 @en Obstacle data
*/
addDynamicObstacle(obstacle: IObstacleData): void;
/**
* @zh 移除所有静态障碍物
* @en Remove all static obstacles
*/
clearStaticObstacles(): void;
/**
* @zh 移除所有动态障碍物
* @en Remove all dynamic obstacles
*/
clearDynamicObstacles(): void;
/**
* @zh 移除所有障碍物(静态和动态)
* @en Remove all obstacles (static and dynamic)
*/
clearObstacles(): void;
/**
* @zh 获取静态障碍物列表
* @en Get static obstacles list
*/
getStaticObstacles(): readonly IObstacleData[];
/**
* @zh 获取动态障碍物列表
* @en Get dynamic obstacles list
*/
getDynamicObstacles(): readonly IObstacleData[];
/**
* @zh 获取所有障碍物列表(静态+动态)
* @en Get all obstacles list (static + dynamic)
*/
getObstacles(): readonly IObstacleData[];
/**
* @zh 获取所有障碍物用于碰撞检测
* @en Get all obstacles for collision detection
*/
private getAllObstaclesForCollision;
/**
* @zh 设置静态障碍物列表
* @en Set static obstacles list
*
* @param obstacles - @zh 障碍物列表 @en Obstacles list
*/
setStaticObstacles(obstacles: IObstacleData[]): void;
/**
* @zh 设置动态障碍物列表
* @en Set dynamic obstacles list
*
* @param obstacles - @zh 障碍物列表 @en Obstacles list
*/
setDynamicObstacles(obstacles: IObstacleData[]): void;
/**
* @zh 系统销毁时调用
* @en Called when system is destroyed
*/
protected onDestroy(): void;
/**
* @zh 处理实体
* @en Process entities
*/
protected process(entities: readonly Entity[]): void;
/**
* @zh 处理等待中的代理
* @en Handle waiting agent
*/
private handleWaitingAgent;
/**
* @zh 清理已移除代理的进入时间记录
* @en Cleanup enter times for removed agents
*/
private cleanupEnterTimes;
/**
* @zh 处理路径规划(同步模式)
* @en Process path planning (synchronous mode)
*/
private processPathPlanning;
/**
* @zh 处理增量路径规划(时间切片模式)
* @en Process incremental path planning (time slicing mode)
*
* @param agents - @zh 代理列表 @en Agent list
* @param entityMap - @zh 实体 ID 到代理的映射 @en Entity ID to agent mapping
*/
private processIncrementalPathPlanning;
/**
* @zh 推进路径点
* @en Advance waypoint
*/
private advanceWaypoint;
/**
* @zh 计算首选速度
* @en Calculate preferred velocity
*/
private calculatePreferredVelocity;
/**
* @zh 构建代理数据
* @en Build agent data
*/
private buildAgentData;
/**
* @zh 应用避让结果
* @en Apply avoidance result
*/
private applyAvoidanceResult;
/**
* @zh 应用平滑转向
* @en Apply smooth steering
*/
private applySmoothSteering;
/**
* @zh 检查是否到达目标
* @en Check if arrived at destination
*/
private checkArrival;
/**
* @zh 解决代理间碰撞
* @en Resolve agent-agent collisions
*/
private resolveAgentCollisions;
/**
* @zh 查找有效的修正向量(不会进入障碍物)
* @en Find valid correction vector (won't enter obstacles)
*/
private findValidCorrection;
/**
* @zh 查找滑动位置(当目标位置不可行走时)
* @en Find slide position (when target position is not walkable)
*
* @zh 尝试只沿 X 轴或 Y 轴移动,实现沿墙滑动效果
* @en Try moving only along X or Y axis, achieving wall sliding effect
*/
private findSlidePosition;
/**
* @zh 检查位置是否可行走(考虑代理半径)
* @en Check if position is walkable (considering agent radius)
*
* @zh 检查代理边界框的4个角点和中心点,确保整个代理都在可行走区域
* @en Check 4 corners and center of agent bounding box, ensure entire agent is in walkable area
*
* @param position - @zh 位置 @en Position
* @param radius - @zh 代理半径 @en Agent radius
* @param tolerance - @zh 容差比例 (0-1),用于允许轻微重叠 @en Tolerance ratio (0-1), allows slight overlap
*/
private isPositionWalkable;
}
/**
* @zh ORCA 算法配置组件
* @en ORCA Algorithm Configuration Component
*
* @zh 可选组件,仅当使用 ORCA 避让算法时需要,用于覆盖默认 ORCA 参数
* @en Optional component, only needed when using ORCA avoidance, to override default ORCA parameters
*/
/**
* @zh ORCA 算法配置组件
* @en ORCA algorithm configuration component
*
* @zh 可选组件,附加到代理实体上以覆盖默认 ORCA 参数
* @en Optional component, attach to agent entities to override default ORCA parameters
*
* @example
* ```typescript
* const entity = scene.createEntity('Agent');
*
* // 添加导航代理
* entity.addComponent(new NavigationAgentComponent());
*
* // 可选:添加 ORCA 配置以自定义参数
* const orcaConfig = entity.addComponent(new ORCAConfigComponent());
* orcaConfig.timeHorizon = 3.0; // 更长的预测时间
* orcaConfig.neighborDist = 20.0; // 更大的邻居检测范围
* ```
*/
declare class ORCAConfigComponent extends Component {
/**
* @zh 邻居检测距离
* @en Neighbor detection distance
*
* @zh 代理检测邻居的最大距离,更大的值意味着更早开始避让但也更消耗性能
* @en Maximum distance for detecting neighbors, larger value means earlier avoidance but more performance cost
*/
neighborDist: number;
/**
* @zh 最大邻居数量
* @en Maximum number of neighbors
*
* @zh 计算避让时考虑的最大邻居数量,更多邻居意味着更精确但也更消耗性能
* @en Maximum neighbors considered for avoidance, more neighbors means more accurate but slower
*/
maxNeighbors: number;
/**
* @zh 代理避让时间视野
* @en Time horizon for agent avoidance
*
* @zh 预测其他代理未来位置的时间范围,更长意味着更平滑但可能过度避让
* @en Time range for predicting other agents' future positions, longer means smoother but may over-avoid
*/
timeHorizon: number;
/**
* @zh 障碍物避让时间视野
* @en Time horizon for obstacle avoidance
*
* @zh 预测与障碍物碰撞的时间范围,通常比代理视野短
* @en Time range for predicting obstacle collisions, usually shorter than agent horizon
*/
timeHorizonObst: number;
}
export { IFlowController, type INavigationSystemConfig, NavigationAgentComponent, NavigationState, NavigationSystem, ORCAConfigComponent };