@esengine/pathfinding 11.0.0 → 12.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/IIncrementalPathfinding-3qs7e_pO.d.ts +450 -0
- package/dist/chunk-GTFFYRZM.js +36 -0
- package/dist/chunk-GTFFYRZM.js.map +1 -0
- package/dist/chunk-TPT7Q3E3.js +1648 -0
- package/dist/chunk-TPT7Q3E3.js.map +1 -0
- package/dist/ecs.d.ts +503 -0
- package/dist/ecs.js +1033 -0
- package/dist/ecs.js.map +1 -0
- package/dist/index.d.ts +886 -192
- package/dist/index.js +1650 -1066
- package/dist/index.js.map +1 -1
- package/dist/nodes.d.ts +143 -0
- package/dist/nodes.js +1174 -0
- package/dist/nodes.js.map +1 -0
- package/package.json +25 -9
package/dist/ecs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ecs/PathfindingAgentComponent.ts","../src/ecs/PathfindingMapComponent.ts","../src/ecs/PathfindingSystem.ts"],"sourcesContent":["/**\n * @zh 寻路代理组件\n * @en Pathfinding Agent Component\n */\n\nimport {\n Component,\n ECSComponent,\n Serializable,\n Serialize,\n Property\n} from '@esengine/ecs-framework';\nimport type { IPoint } from '../core/IPathfinding';\nimport { PathfindingState } from '../core/IIncrementalPathfinding';\n\n// =============================================================================\n// 寻路代理组件 | Pathfinding Agent Component\n// =============================================================================\n\n/**\n * @zh 寻路代理组件\n * @en Pathfinding Agent Component\n *\n * @zh 附加到需要寻路的实体上,管理寻路请求和结果\n * @en Attach to entities that need pathfinding, manages path requests and results\n *\n * @example\n * ```typescript\n * const entity = scene.createEntity('Agent');\n * const agent = entity.addComponent(new PathfindingAgentComponent());\n *\n * // Set initial position\n * agent.x = 10;\n * agent.y = 10;\n *\n * // Request path to target\n * agent.requestPathTo(50, 50);\n *\n * // In movement system, follow the path\n * const waypoint = agent.getNextWaypoint();\n * if (waypoint) {\n * // Move towards waypoint\n * // When reached, call agent.advanceWaypoint()\n * }\n * ```\n */\n@ECSComponent('PathfindingAgent')\n@Serializable({ version: 1, typeId: 'PathfindingAgent' })\nexport class PathfindingAgentComponent extends Component {\n // =========================================================================\n // 位置属性 | Position Properties\n // =========================================================================\n\n /**\n * @zh 当前位置 X 坐标\n * @en Current position X coordinate\n */\n @Serialize()\n @Property({ type: 'number', label: 'Position X' })\n x: number = 0;\n\n /**\n * @zh 当前位置 Y 坐标\n * @en Current position Y coordinate\n */\n @Serialize()\n @Property({ type: 'number', label: 'Position Y' })\n y: number = 0;\n\n // =========================================================================\n // 目标属性 | Target Properties\n // =========================================================================\n\n /**\n * @zh 目标位置 X 坐标\n * @en Target position X coordinate\n */\n @Serialize()\n @Property({ type: 'number', label: 'Target X' })\n targetX: number = 0;\n\n /**\n * @zh 目标位置 Y 坐标\n * @en Target position Y coordinate\n */\n @Serialize()\n @Property({ type: 'number', label: 'Target Y' })\n targetY: number = 0;\n\n /**\n * @zh 是否有新的寻路请求待处理\n * @en Whether there is a new path request pending\n */\n hasRequest: boolean = false;\n\n // =========================================================================\n // 配置属性 | Configuration Properties\n // =========================================================================\n\n /**\n * @zh 寻路优先级(数值越小优先级越高)\n * @en Pathfinding priority (lower number = higher priority)\n */\n @Serialize()\n @Property({ type: 'number', label: 'Priority', min: 0, max: 100 })\n priority: number = 50;\n\n /**\n * @zh 每帧最大迭代次数\n * @en Maximum iterations per frame\n */\n @Serialize()\n @Property({ type: 'number', label: 'Max Iterations/Frame', min: 10, max: 1000 })\n maxIterationsPerFrame: number = 100;\n\n /**\n * @zh 是否启用动态重规划\n * @en Whether dynamic replanning is enabled\n */\n @Serialize()\n @Property({ type: 'boolean', label: 'Dynamic Replan' })\n enableDynamicReplan: boolean = true;\n\n /**\n * @zh 向前探测距离(用于障碍物检测)\n * @en Lookahead distance for obstacle detection\n */\n @Serialize()\n @Property({ type: 'number', label: 'Lookahead Distance', min: 1, max: 20 })\n lookaheadDistance: number = 5;\n\n /**\n * @zh 路径验证间隔(帧数)\n * @en Path validation interval (in frames)\n */\n @Serialize()\n @Property({ type: 'number', label: 'Validation Interval', min: 1, max: 60 })\n validationInterval: number = 10;\n\n // =========================================================================\n // 运行时状态(不序列化)| Runtime State (not serialized)\n // =========================================================================\n\n /**\n * @zh 当前寻路状态\n * @en Current pathfinding state\n */\n state: PathfindingState = PathfindingState.Idle;\n\n /**\n * @zh 当前请求 ID\n * @en Current request ID\n */\n currentRequestId: number = -1;\n\n /**\n * @zh 当前路径点列表\n * @en Current path waypoints\n */\n path: IPoint[] = [];\n\n /**\n * @zh 当前路径索引\n * @en Current path index\n */\n pathIndex: number = 0;\n\n /**\n * @zh 路径总代价\n * @en Total path cost\n */\n pathCost: number = 0;\n\n /**\n * @zh 寻路进度 (0-1)\n * @en Pathfinding progress (0-1)\n */\n progress: number = 0;\n\n /**\n * @zh 上次验证的帧号\n * @en Last validation frame number\n */\n lastValidationFrame: number = 0;\n\n /**\n * @zh 寻路完成回调\n * @en Pathfinding complete callback\n */\n onPathComplete?: (found: boolean, path: readonly IPoint[]) => void;\n\n /**\n * @zh 寻路进度回调\n * @en Pathfinding progress callback\n */\n onPathProgress?: (progress: number) => void;\n\n // =========================================================================\n // 公共方法 | Public Methods\n // =========================================================================\n\n /**\n * @zh 请求寻路到目标位置\n * @en Request path to target position\n *\n * @param targetX - @zh 目标 X 坐标 @en Target X coordinate\n * @param targetY - @zh 目标 Y 坐标 @en Target Y coordinate\n */\n requestPathTo(targetX: number, targetY: number): void {\n this.targetX = targetX;\n this.targetY = targetY;\n this.hasRequest = true;\n this.state = PathfindingState.Idle;\n this.progress = 0;\n }\n\n /**\n * @zh 取消当前寻路\n * @en Cancel current pathfinding\n */\n cancelPath(): void {\n this.hasRequest = false;\n this.state = PathfindingState.Cancelled;\n this.path = [];\n this.pathIndex = 0;\n this.progress = 0;\n this.currentRequestId = -1;\n }\n\n /**\n * @zh 获取下一个路径点\n * @en Get next waypoint\n *\n * @returns @zh 下一个路径点或 null @en Next waypoint or null\n */\n getNextWaypoint(): IPoint | null {\n if (this.pathIndex < this.path.length) {\n return this.path[this.pathIndex];\n }\n return null;\n }\n\n /**\n * @zh 前进到下一个路径点\n * @en Advance to next waypoint\n */\n advanceWaypoint(): void {\n if (this.pathIndex < this.path.length) {\n this.pathIndex++;\n }\n }\n\n /**\n * @zh 检查是否到达路径终点\n * @en Check if reached path end\n *\n * @returns @zh 是否到达终点 @en Whether reached end\n */\n isPathComplete(): boolean {\n return this.pathIndex >= this.path.length;\n }\n\n /**\n * @zh 检查是否正在寻路\n * @en Check if pathfinding is in progress\n *\n * @returns @zh 是否正在寻路 @en Whether pathfinding is in progress\n */\n isSearching(): boolean {\n return this.state === PathfindingState.InProgress;\n }\n\n /**\n * @zh 检查是否有有效路径\n * @en Check if has valid path\n *\n * @returns @zh 是否有有效路径 @en Whether has valid path\n */\n hasValidPath(): boolean {\n return this.state === PathfindingState.Completed && this.path.length > 0;\n }\n\n /**\n * @zh 获取剩余路径点数量\n * @en Get remaining waypoint count\n *\n * @returns @zh 剩余路径点数量 @en Remaining waypoint count\n */\n getRemainingWaypointCount(): number {\n return Math.max(0, this.path.length - this.pathIndex);\n }\n\n /**\n * @zh 获取当前路径的总长度\n * @en Get total path length\n *\n * @returns @zh 路径总长度 @en Total path length\n */\n getPathLength(): number {\n return this.path.length;\n }\n\n /**\n * @zh 重置组件状态\n * @en Reset component state\n */\n reset(): void {\n this.state = PathfindingState.Idle;\n this.currentRequestId = -1;\n this.path = [];\n this.pathIndex = 0;\n this.pathCost = 0;\n this.progress = 0;\n this.hasRequest = false;\n this.lastValidationFrame = 0;\n }\n\n /**\n * @zh 组件从实体移除时调用\n * @en Called when component is removed from entity\n */\n public onRemovedFromEntity(): void {\n this.reset();\n this.onPathComplete = undefined;\n this.onPathProgress = undefined;\n }\n}\n","/**\n * @zh 寻路地图组件\n * @en Pathfinding Map Component\n */\n\nimport {\n Component,\n ECSComponent,\n Serializable,\n Serialize,\n Property\n} from '@esengine/ecs-framework';\nimport type { IPathfindingMap, IPathSmoother } from '../core/IPathfinding';\nimport type { IIncrementalPathfinder } from '../core/IIncrementalPathfinding';\n\n// =============================================================================\n// 地图类型 | Map Type\n// =============================================================================\n\n/**\n * @zh 地图类型\n * @en Map type\n */\nexport type PathfindingMapType = 'grid' | 'navmesh';\n\n// =============================================================================\n// 寻路地图组件 | Pathfinding Map Component\n// =============================================================================\n\n/**\n * @zh 寻路地图组件\n * @en Pathfinding Map Component\n *\n * @zh 挂载在场景实体上,持有地图实例和增量寻路器\n * @en Attached to scene entity, holds map instance and incremental pathfinder\n *\n * @example\n * ```typescript\n * const mapEntity = scene.createEntity('PathfindingMap');\n * const mapComp = mapEntity.addComponent(new PathfindingMapComponent());\n *\n * // Configure map\n * mapComp.width = 100;\n * mapComp.height = 100;\n * mapComp.iterationsBudget = 2000;\n *\n * // Map and pathfinder will be initialized by PathfindingSystem\n * ```\n */\n@ECSComponent('PathfindingMap')\n@Serializable({ version: 1, typeId: 'PathfindingMap' })\nexport class PathfindingMapComponent extends Component {\n // =========================================================================\n // 地图配置 | Map Configuration\n // =========================================================================\n\n /**\n * @zh 地图类型\n * @en Map type\n */\n @Serialize()\n @Property({\n type: 'enum',\n label: 'Map Type',\n options: [\n { value: 'grid', label: 'Grid' },\n { value: 'navmesh', label: 'NavMesh' }\n ]\n })\n mapType: PathfindingMapType = 'grid';\n\n /**\n * @zh 网格宽度(仅 grid 类型)\n * @en Grid width (grid type only)\n */\n @Serialize()\n @Property({ type: 'number', label: 'Map Width', min: 1, max: 10000 })\n width: number = 100;\n\n /**\n * @zh 网格高度(仅 grid 类型)\n * @en Grid height (grid type only)\n */\n @Serialize()\n @Property({ type: 'number', label: 'Map Height', min: 1, max: 10000 })\n height: number = 100;\n\n /**\n * @zh 是否允许对角移动\n * @en Whether diagonal movement is allowed\n */\n @Serialize()\n @Property({ type: 'boolean', label: 'Allow Diagonal' })\n allowDiagonal: boolean = true;\n\n /**\n * @zh 是否避免穿角\n * @en Whether to avoid corner cutting\n */\n @Serialize()\n @Property({ type: 'boolean', label: 'Avoid Corners' })\n avoidCorners: boolean = true;\n\n // =========================================================================\n // 系统配置 | System Configuration\n // =========================================================================\n\n /**\n * @zh 每帧处理的最大代理数\n * @en Maximum agents processed per frame\n */\n @Serialize()\n @Property({ type: 'number', label: 'Max Agents/Frame', min: 1, max: 100 })\n maxAgentsPerFrame: number = 10;\n\n /**\n * @zh 每帧总迭代次数预算\n * @en Total iterations budget per frame\n */\n @Serialize()\n @Property({ type: 'number', label: 'Iterations Budget', min: 100, max: 10000 })\n iterationsBudget: number = 1000;\n\n /**\n * @zh 是否启用路径平滑\n * @en Whether path smoothing is enabled\n */\n @Serialize()\n @Property({ type: 'boolean', label: 'Enable Smoothing' })\n enableSmoothing: boolean = true;\n\n /**\n * @zh 路径平滑类型\n * @en Path smoothing type\n */\n @Serialize()\n @Property({\n type: 'enum',\n label: 'Smoothing Type',\n options: [\n { value: 'los', label: 'Line of Sight' },\n { value: 'catmullrom', label: 'Catmull-Rom' },\n { value: 'combined', label: 'Combined' }\n ]\n })\n smoothingType: 'los' | 'catmullrom' | 'combined' = 'los';\n\n // =========================================================================\n // 缓存配置 | Cache Configuration\n // =========================================================================\n\n /**\n * @zh 是否启用路径缓存\n * @en Whether path caching is enabled\n */\n @Serialize()\n @Property({ type: 'boolean', label: 'Enable Cache' })\n enableCache: boolean = true;\n\n /**\n * @zh 缓存最大条目数\n * @en Maximum cache entries\n */\n @Serialize()\n @Property({ type: 'number', label: 'Cache Size', min: 100, max: 10000 })\n cacheMaxEntries: number = 1000;\n\n /**\n * @zh 缓存过期时间(毫秒),0 表示不过期\n * @en Cache TTL in milliseconds, 0 means no expiration\n */\n @Serialize()\n @Property({ type: 'number', label: 'Cache TTL (ms)', min: 0, max: 60000 })\n cacheTtlMs: number = 5000;\n\n // =========================================================================\n // 调试配置 | Debug Configuration\n // =========================================================================\n\n /**\n * @zh 是否显示调试信息\n * @en Whether to show debug info\n */\n @Serialize()\n @Property({ type: 'boolean', label: 'Debug Mode' })\n debugMode: boolean = false;\n\n /**\n * @zh 是否显示网格\n * @en Whether to show grid\n */\n @Serialize()\n @Property({ type: 'boolean', label: 'Show Grid' })\n showGrid: boolean = false;\n\n /**\n * @zh 是否显示路径\n * @en Whether to show paths\n */\n @Serialize()\n @Property({ type: 'boolean', label: 'Show Paths' })\n showPaths: boolean = false;\n\n // =========================================================================\n // 运行时实例(不序列化)| Runtime Instances (not serialized)\n // =========================================================================\n\n /**\n * @zh 地图实例\n * @en Map instance\n */\n map: IPathfindingMap | null = null;\n\n /**\n * @zh 增量寻路器实例\n * @en Incremental pathfinder instance\n */\n pathfinder: IIncrementalPathfinder | null = null;\n\n /**\n * @zh 路径平滑器实例\n * @en Path smoother instance\n */\n smoother: IPathSmoother | null = null;\n\n /**\n * @zh 是否已初始化\n * @en Whether initialized\n */\n initialized: boolean = false;\n\n // =========================================================================\n // 统计信息 | Statistics\n // =========================================================================\n\n /**\n * @zh 当前活跃请求数\n * @en Current active request count\n */\n activeRequests: number = 0;\n\n /**\n * @zh 本帧使用的迭代次数\n * @en Iterations used this frame\n */\n iterationsUsedThisFrame: number = 0;\n\n /**\n * @zh 本帧处理的代理数\n * @en Agents processed this frame\n */\n agentsProcessedThisFrame: number = 0;\n\n /**\n * @zh 缓存命中次数\n * @en Cache hit count\n */\n cacheHits: number = 0;\n\n /**\n * @zh 缓存未命中次数\n * @en Cache miss count\n */\n cacheMisses: number = 0;\n\n // =========================================================================\n // 公共方法 | Public Methods\n // =========================================================================\n\n /**\n * @zh 设置网格单元格是否可通行\n * @en Set grid cell walkability\n *\n * @param x - @zh X 坐标 @en X coordinate\n * @param y - @zh Y 坐标 @en Y coordinate\n * @param walkable - @zh 是否可通行 @en Is walkable\n */\n setWalkable(x: number, y: number, walkable: boolean): void {\n if (this.map && 'setWalkable' in this.map) {\n (this.map as { setWalkable(x: number, y: number, walkable: boolean): void })\n .setWalkable(x, y, walkable);\n\n if (this.pathfinder) {\n this.pathfinder.notifyObstacleChange(x - 1, y - 1, x + 1, y + 1);\n }\n }\n }\n\n /**\n * @zh 设置矩形区域是否可通行\n * @en Set rectangular area walkability\n *\n * @param x - @zh 起始 X @en Start X\n * @param y - @zh 起始 Y @en Start Y\n * @param width - @zh 宽度 @en Width\n * @param height - @zh 高度 @en Height\n * @param walkable - @zh 是否可通行 @en Is walkable\n */\n setRectWalkable(\n x: number,\n y: number,\n rectWidth: number,\n rectHeight: number,\n walkable: boolean\n ): void {\n if (this.map && 'setRectWalkable' in this.map) {\n (this.map as { setRectWalkable(x: number, y: number, w: number, h: number, walkable: boolean): void })\n .setRectWalkable(x, y, rectWidth, rectHeight, walkable);\n\n if (this.pathfinder) {\n this.pathfinder.notifyObstacleChange(\n x - 1,\n y - 1,\n x + rectWidth + 1,\n y + rectHeight + 1\n );\n }\n }\n }\n\n /**\n * @zh 检查位置是否可通行\n * @en Check if position is walkable\n *\n * @param x - @zh X 坐标 @en X coordinate\n * @param y - @zh Y 坐标 @en Y coordinate\n * @returns @zh 是否可通行 @en Is walkable\n */\n isWalkable(x: number, y: number): boolean {\n return this.map?.isWalkable(x, y) ?? false;\n }\n\n /**\n * @zh 重置统计信息\n * @en Reset statistics\n */\n resetStats(): void {\n this.iterationsUsedThisFrame = 0;\n this.agentsProcessedThisFrame = 0;\n }\n\n /**\n * @zh 获取剩余迭代预算\n * @en Get remaining iteration budget\n *\n * @returns @zh 剩余预算 @en Remaining budget\n */\n getRemainingBudget(): number {\n return Math.max(0, this.iterationsBudget - this.iterationsUsedThisFrame);\n }\n\n /**\n * @zh 获取缓存统计信息\n * @en Get cache statistics\n *\n * @returns @zh 缓存统计 @en Cache statistics\n */\n getCacheStats(): { enabled: boolean; hits: number; misses: number; hitRate: number } {\n const pathfinderWithCache = this.pathfinder as { getCacheStats?: () => { hits: number; misses: number; hitRate: number } };\n if (pathfinderWithCache?.getCacheStats) {\n const stats = pathfinderWithCache.getCacheStats();\n this.cacheHits = stats.hits;\n this.cacheMisses = stats.misses;\n return {\n enabled: this.enableCache,\n hits: stats.hits,\n misses: stats.misses,\n hitRate: stats.hitRate\n };\n }\n return {\n enabled: this.enableCache,\n hits: this.cacheHits,\n misses: this.cacheMisses,\n hitRate: this.cacheHits + this.cacheMisses > 0\n ? this.cacheHits / (this.cacheHits + this.cacheMisses)\n : 0\n };\n }\n\n /**\n * @zh 组件从实体移除时调用\n * @en Called when component is removed from entity\n */\n public onRemovedFromEntity(): void {\n if (this.pathfinder) {\n this.pathfinder.clear();\n }\n\n this.map = null;\n this.pathfinder = null;\n this.smoother = null;\n this.initialized = false;\n }\n}\n","/**\n * @zh 寻路系统\n * @en Pathfinding System\n */\n\nimport {\n EntitySystem,\n Matcher,\n ECSSystem,\n type Entity\n} from '@esengine/ecs-framework';\nimport { PathfindingAgentComponent } from './PathfindingAgentComponent';\nimport { PathfindingMapComponent } from './PathfindingMapComponent';\nimport { PathfindingState } from '../core/IIncrementalPathfinding';\nimport type { IIncrementalPathfinder, IPathProgress } from '../core/IIncrementalPathfinding';\nimport { IncrementalAStarPathfinder } from '../core/IncrementalAStarPathfinder';\nimport { GridMap } from '../grid/GridMap';\nimport { LineOfSightSmoother, CatmullRomSmoother, CombinedSmoother } from '../smoothing/PathSmoother';\nimport { PathValidator } from '../core/PathValidator';\n\n// =============================================================================\n// 代理队列项 | Agent Queue Item\n// =============================================================================\n\n/**\n * @zh 代理队列项\n * @en Agent queue item\n */\ninterface AgentQueueItem {\n entity: Entity;\n component: PathfindingAgentComponent;\n}\n\n// =============================================================================\n// 寻路系统 | Pathfinding System\n// =============================================================================\n\n/**\n * @zh 寻路系统\n * @en Pathfinding System\n *\n * @zh 处理所有 PathfindingAgentComponent,支持时间切片和动态重规划\n * @en Processes all PathfindingAgentComponents, supports time slicing and dynamic replanning\n *\n * @example\n * ```typescript\n * // Add system to scene\n * scene.addSystem(new PathfindingSystem());\n *\n * // Create map entity\n * const mapEntity = scene.createEntity('Map');\n * mapEntity.addComponent(new PathfindingMapComponent());\n *\n * // Create agents\n * const agent = scene.createEntity('Agent');\n * const pathAgent = agent.addComponent(new PathfindingAgentComponent());\n * pathAgent.requestPathTo(50, 50);\n *\n * // System handles pathfinding automatically each frame\n * ```\n */\n@ECSSystem('Pathfinding', { updateOrder: 0 })\nexport class PathfindingSystem extends EntitySystem {\n private mapEntity: Entity | null = null;\n private mapComponent: PathfindingMapComponent | null = null;\n private pathValidator: PathValidator;\n\n private agentQueue: AgentQueueItem[] = [];\n private frameCounter: number = 0;\n\n constructor() {\n super(Matcher.all(PathfindingAgentComponent));\n this.pathValidator = new PathValidator();\n }\n\n /**\n * @zh 系统初始化\n * @en System initialization\n */\n protected onInitialize(): void {\n this.findMapEntity();\n this.initializeMap();\n }\n\n /**\n * @zh 系统激活时调用\n * @en Called when system is enabled\n */\n protected onEnable(): void {\n this.findMapEntity();\n }\n\n /**\n * @zh 处理实体\n * @en Process entities\n */\n protected process(entities: readonly Entity[]): void {\n if (!this.mapComponent?.pathfinder) {\n this.findMapEntity();\n if (!this.mapComponent?.pathfinder) {\n return;\n }\n }\n\n this.frameCounter++;\n this.mapComponent.resetStats();\n\n this.buildAgentQueue(entities);\n\n this.processAgentsWithBudget();\n\n this.validatePaths(entities);\n }\n\n // =========================================================================\n // 私有方法 | Private Methods\n // =========================================================================\n\n /**\n * @zh 查找地图实体\n * @en Find map entity\n */\n private findMapEntity(): void {\n if (!this.scene) return;\n\n const entities = this.scene.entities.findEntitiesWithComponent(PathfindingMapComponent);\n if (entities.length > 0) {\n const entity = entities[0]!;\n const mapComp = entity.getComponent(PathfindingMapComponent);\n if (mapComp) {\n this.mapEntity = entity;\n this.mapComponent = mapComp;\n\n if (!mapComp.initialized) {\n this.initializeMap();\n }\n }\n }\n }\n\n /**\n * @zh 初始化地图\n * @en Initialize map\n */\n private initializeMap(): void {\n if (!this.mapComponent) return;\n if (this.mapComponent.initialized) return;\n\n if (!this.mapComponent.map) {\n if (this.mapComponent.mapType === 'grid') {\n this.mapComponent.map = new GridMap(\n this.mapComponent.width,\n this.mapComponent.height,\n {\n allowDiagonal: this.mapComponent.allowDiagonal,\n avoidCorners: this.mapComponent.avoidCorners\n }\n );\n }\n }\n\n if (!this.mapComponent.pathfinder && this.mapComponent.map) {\n this.mapComponent.pathfinder = new IncrementalAStarPathfinder(\n this.mapComponent.map,\n {\n enableCache: this.mapComponent.enableCache,\n cacheConfig: {\n maxEntries: this.mapComponent.cacheMaxEntries,\n ttlMs: this.mapComponent.cacheTtlMs\n }\n }\n );\n }\n\n if (!this.mapComponent.smoother && this.mapComponent.enableSmoothing) {\n switch (this.mapComponent.smoothingType) {\n case 'catmullrom':\n this.mapComponent.smoother = new CatmullRomSmoother();\n break;\n case 'combined':\n this.mapComponent.smoother = new CombinedSmoother();\n break;\n case 'los':\n default:\n this.mapComponent.smoother = new LineOfSightSmoother();\n break;\n }\n }\n\n this.mapComponent.initialized = true;\n }\n\n /**\n * @zh 构建代理优先级队列\n * @en Build agent priority queue\n */\n private buildAgentQueue(entities: readonly Entity[]): void {\n this.agentQueue.length = 0;\n\n for (const entity of entities) {\n const agent = entity.getComponent(PathfindingAgentComponent);\n if (!agent) continue;\n\n if (!agent.hasRequest &&\n (agent.state === PathfindingState.Idle ||\n agent.state === PathfindingState.Completed ||\n agent.state === PathfindingState.Cancelled)) {\n continue;\n }\n\n this.agentQueue.push({ entity, component: agent });\n }\n\n this.agentQueue.sort((a, b) => a.component.priority - b.component.priority);\n }\n\n /**\n * @zh 使用预算处理代理\n * @en Process agents with budget\n */\n private processAgentsWithBudget(): void {\n const pathfinder = this.mapComponent!.pathfinder!;\n const maxAgents = this.mapComponent!.maxAgentsPerFrame;\n let remainingBudget = this.mapComponent!.iterationsBudget;\n let agentsProcessed = 0;\n\n for (const { component: agent } of this.agentQueue) {\n if (agentsProcessed >= maxAgents || remainingBudget <= 0) {\n break;\n }\n\n if (agent.hasRequest && agent.state === PathfindingState.Idle) {\n this.startNewRequest(agent, pathfinder);\n }\n\n if (agent.state === PathfindingState.InProgress) {\n const iterations = Math.min(\n agent.maxIterationsPerFrame,\n remainingBudget\n );\n\n const progress = pathfinder.step(agent.currentRequestId, iterations);\n this.updateAgentFromProgress(agent, progress, pathfinder);\n\n remainingBudget -= progress.nodesSearched;\n this.mapComponent!.iterationsUsedThisFrame += progress.nodesSearched;\n }\n\n agentsProcessed++;\n }\n\n this.mapComponent!.agentsProcessedThisFrame = agentsProcessed;\n }\n\n /**\n * @zh 启动新的寻路请求\n * @en Start new pathfinding request\n */\n private startNewRequest(\n agent: PathfindingAgentComponent,\n pathfinder: IIncrementalPathfinder\n ): void {\n if (agent.currentRequestId >= 0) {\n pathfinder.cancel(agent.currentRequestId);\n pathfinder.cleanup(agent.currentRequestId);\n }\n\n const request = pathfinder.requestPath(\n agent.x,\n agent.y,\n agent.targetX,\n agent.targetY,\n { priority: agent.priority }\n );\n\n agent.currentRequestId = request.id;\n agent.state = PathfindingState.InProgress;\n agent.hasRequest = false;\n agent.progress = 0;\n agent.path = [];\n agent.pathIndex = 0;\n\n this.mapComponent!.activeRequests++;\n }\n\n /**\n * @zh 从进度更新代理状态\n * @en Update agent state from progress\n */\n private updateAgentFromProgress(\n agent: PathfindingAgentComponent,\n progress: IPathProgress,\n pathfinder: IIncrementalPathfinder\n ): void {\n agent.state = progress.state;\n agent.progress = progress.estimatedProgress;\n\n agent.onPathProgress?.(progress.estimatedProgress);\n\n if (progress.state === PathfindingState.Completed) {\n const result = pathfinder.getResult(agent.currentRequestId);\n if (result && result.found) {\n const smoother = this.mapComponent?.smoother;\n const map = this.mapComponent?.map;\n\n if (smoother && map && this.mapComponent?.enableSmoothing) {\n agent.path = smoother.smooth(result.path, map);\n } else {\n agent.path = [...result.path];\n }\n\n agent.pathIndex = 0;\n agent.pathCost = result.cost;\n\n agent.onPathComplete?.(true, agent.path);\n } else {\n agent.path = [];\n agent.state = PathfindingState.Failed;\n agent.onPathComplete?.(false, []);\n }\n\n pathfinder.cleanup(agent.currentRequestId);\n this.mapComponent!.activeRequests--;\n } else if (progress.state === PathfindingState.Failed) {\n agent.path = [];\n agent.onPathComplete?.(false, []);\n pathfinder.cleanup(agent.currentRequestId);\n this.mapComponent!.activeRequests--;\n }\n }\n\n /**\n * @zh 周期性验证路径有效性\n * @en Periodically validate path validity\n */\n private validatePaths(entities: readonly Entity[]): void {\n const map = this.mapComponent?.map;\n if (!map) return;\n\n for (const entity of entities) {\n const agent = entity.getComponent(PathfindingAgentComponent);\n if (!agent || !agent.enableDynamicReplan) continue;\n if (agent.path.length === 0 || agent.isPathComplete()) continue;\n\n if (this.frameCounter - agent.lastValidationFrame < agent.validationInterval) {\n continue;\n }\n\n agent.lastValidationFrame = this.frameCounter;\n\n const checkEnd = Math.min(\n agent.pathIndex + agent.lookaheadDistance,\n agent.path.length\n );\n\n const result = this.pathValidator.validatePath(\n agent.path,\n agent.pathIndex,\n checkEnd,\n map\n );\n\n if (!result.valid) {\n agent.x = agent.path[agent.pathIndex]?.x ?? agent.x;\n agent.y = agent.path[agent.pathIndex]?.y ?? agent.y;\n agent.requestPathTo(agent.targetX, agent.targetY);\n }\n }\n }\n}\n"],"mappings":"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","names":["Component","ECSComponent","Serializable","Serialize","Property","PathfindingAgentComponent","Component","x","y","targetX","targetY","hasRequest","priority","maxIterationsPerFrame","enableDynamicReplan","lookaheadDistance","validationInterval","state","PathfindingState","Idle","currentRequestId","path","pathIndex","pathCost","progress","lastValidationFrame","onPathComplete","onPathProgress","requestPathTo","cancelPath","Cancelled","getNextWaypoint","length","advanceWaypoint","isPathComplete","isSearching","InProgress","hasValidPath","Completed","getRemainingWaypointCount","Math","max","getPathLength","reset","onRemovedFromEntity","undefined","type","label","min","version","typeId","Component","ECSComponent","Serializable","Serialize","Property","PathfindingMapComponent","Component","mapType","width","height","allowDiagonal","avoidCorners","maxAgentsPerFrame","iterationsBudget","enableSmoothing","smoothingType","enableCache","cacheMaxEntries","cacheTtlMs","debugMode","showGrid","showPaths","map","pathfinder","smoother","initialized","activeRequests","iterationsUsedThisFrame","agentsProcessedThisFrame","cacheHits","cacheMisses","setWalkable","x","y","walkable","notifyObstacleChange","setRectWalkable","rectWidth","rectHeight","isWalkable","resetStats","getRemainingBudget","Math","max","getCacheStats","pathfinderWithCache","stats","hits","misses","enabled","hitRate","onRemovedFromEntity","clear","type","label","options","value","min","version","typeId","EntitySystem","Matcher","ECSSystem","PathfindingSystem","EntitySystem","Matcher","all","PathfindingAgentComponent","mapEntity","mapComponent","pathValidator","agentQueue","frameCounter","PathValidator","onInitialize","findMapEntity","initializeMap","onEnable","process","entities","pathfinder","resetStats","buildAgentQueue","processAgentsWithBudget","validatePaths","scene","findEntitiesWithComponent","PathfindingMapComponent","length","entity","mapComp","getComponent","initialized","map","mapType","GridMap","width","height","allowDiagonal","avoidCorners","IncrementalAStarPathfinder","enableCache","cacheConfig","maxEntries","cacheMaxEntries","ttlMs","cacheTtlMs","smoother","enableSmoothing","smoothingType","CatmullRomSmoother","CombinedSmoother","LineOfSightSmoother","agent","hasRequest","state","PathfindingState","Idle","Completed","Cancelled","push","component","sort","a","b","priority","maxAgents","maxAgentsPerFrame","remainingBudget","iterationsBudget","agentsProcessed","startNewRequest","InProgress","iterations","Math","min","maxIterationsPerFrame","progress","step","currentRequestId","updateAgentFromProgress","nodesSearched","iterationsUsedThisFrame","agentsProcessedThisFrame","cancel","cleanup","request","requestPath","x","y","targetX","targetY","id","path","pathIndex","activeRequests","estimatedProgress","onPathProgress","result","getResult","found","smooth","pathCost","cost","onPathComplete","Failed","enableDynamicReplan","isPathComplete","lastValidationFrame","validationInterval","checkEnd","lookaheadDistance","validatePath","valid","requestPathTo","updateOrder"]}
|