@woosh/meep-engine 2.76.4 → 2.78.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/build/meep.cjs +236 -616
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +236 -616
- package/editor/view/ecs/components/TerrainController.js +9 -16
- package/package.json +1 -1
- package/src/core/collection/heap/Uint32Heap.js +10 -1
- package/src/core/graph/Edge.js +20 -0
- package/src/core/graph/SquareMatrix.js +4 -2
- package/src/core/graph/WeightedEdge.js +5 -9
- package/src/core/graph/coloring/colorizeGraphGreedy.spec.js +1 -1
- package/src/core/graph/coloring/validateGraphColoring.js +1 -1
- package/src/core/graph/eigen/matrix_eigenvalues_in_place.js +21 -0
- package/src/core/graph/eigen/{eigen.spec.js → matrix_eigenvalues_in_place.spec.js} +2 -2
- package/src/core/graph/eigen/matrix_householder_in_place.js +92 -0
- package/src/core/graph/eigen/{eigen.js → matrix_qr_in_place.js} +2 -113
- package/src/core/graph/layout/CircleLayout.js +6 -11
- package/src/core/graph/v2/Graph.js +39 -9
- package/src/core/graph/v2/NodeContainer.js +136 -22
- package/src/engine/ecs/storage/binary/BinarySerializationRegistry.js +8 -6
- package/src/engine/graphics/particles/node-based/codegen/modules/FunctionModuleRegistry.js +1 -1
- package/src/engine/navigation/grid/find_path_on_grid_astar.js +25 -22
- package/src/engine/navigation/grid/find_path_on_grid_astar.spec.js +2 -2
- package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +17 -33
- package/src/core/graph/Graph.js +0 -564
- package/src/core/graph/GraphUtils.js +0 -284
- package/src/engine/ecs/terrain/ecs/splat/SplatMapMaterialPatch.js +0 -464
- package/src/engine/ecs/terrain/ecs/splat/SplatMapOptimizer.js +0 -622
- package/src/engine/ecs/terrain/ecs/splat/SplatMapOptimizerDebugger.js +0 -383
package/build/meep.module.js
CHANGED
|
@@ -70614,6 +70614,26 @@ class Edge {
|
|
|
70614
70614
|
return (this.direction & EdgeDirectionType.Backward) !== 0;
|
|
70615
70615
|
}
|
|
70616
70616
|
|
|
70617
|
+
/**
|
|
70618
|
+
* Checks direction of the edge, if the edge is directed towards supplied node - returns true, false otherwise
|
|
70619
|
+
* @param {N} node
|
|
70620
|
+
* @returns {boolean}
|
|
70621
|
+
*/
|
|
70622
|
+
isDirectedTowards(node) {
|
|
70623
|
+
return (this.first === node && this.direction === EdgeDirectionType.Backward)
|
|
70624
|
+
|| (this.second === node && this.direction === EdgeDirectionType.Forward);
|
|
70625
|
+
}
|
|
70626
|
+
|
|
70627
|
+
/**
|
|
70628
|
+
* Checks direction of the edge, if the edge is directed away from the supplied node - returns true, false otherwise
|
|
70629
|
+
* @param {N} node
|
|
70630
|
+
* @returns {boolean}
|
|
70631
|
+
*/
|
|
70632
|
+
isDirectedAwayFrom(node) {
|
|
70633
|
+
return (this.first === node && this.direction === EdgeDirectionType.Forward)
|
|
70634
|
+
|| (this.second === node && this.direction === EdgeDirectionType.Backward)
|
|
70635
|
+
}
|
|
70636
|
+
|
|
70617
70637
|
/**
|
|
70618
70638
|
* @deprecated
|
|
70619
70639
|
* @returns {number}
|
|
@@ -70649,30 +70669,38 @@ class Edge {
|
|
|
70649
70669
|
*/
|
|
70650
70670
|
Edge.prototype.isEdge = true;
|
|
70651
70671
|
|
|
70672
|
+
/**
|
|
70673
|
+
* Supplementary structure to `Graph`, holds edges and neighbour nodes for fast access
|
|
70674
|
+
* Used internally by `Graph`
|
|
70675
|
+
* @template N
|
|
70676
|
+
*/
|
|
70652
70677
|
class NodeContainer {
|
|
70653
70678
|
/**
|
|
70654
|
-
*
|
|
70679
|
+
* Node being described
|
|
70680
|
+
* @type {N}
|
|
70655
70681
|
*/
|
|
70656
|
-
|
|
70657
|
-
/**
|
|
70658
|
-
*
|
|
70659
|
-
* @type {N}
|
|
70660
|
-
*/
|
|
70661
|
-
this.node = null;
|
|
70682
|
+
node = null;
|
|
70662
70683
|
|
|
70663
|
-
|
|
70664
|
-
|
|
70665
|
-
|
|
70666
|
-
|
|
70667
|
-
|
|
70668
|
-
|
|
70684
|
+
/**
|
|
70685
|
+
* Attached edges
|
|
70686
|
+
* @type {Edge<N>[]}
|
|
70687
|
+
* @private
|
|
70688
|
+
*/
|
|
70689
|
+
__edges = [];
|
|
70669
70690
|
|
|
70670
|
-
|
|
70671
|
-
|
|
70672
|
-
|
|
70673
|
-
|
|
70674
|
-
|
|
70675
|
-
|
|
70691
|
+
/**
|
|
70692
|
+
*
|
|
70693
|
+
* @type {Map<N,number>}
|
|
70694
|
+
* @private
|
|
70695
|
+
*/
|
|
70696
|
+
__neighbors = new Map();
|
|
70697
|
+
|
|
70698
|
+
/**
|
|
70699
|
+
* NOTE: this method allocates memory internally
|
|
70700
|
+
* @returns {N[]}
|
|
70701
|
+
*/
|
|
70702
|
+
get neighbours() {
|
|
70703
|
+
return Array.from(this.__neighbors.keys());
|
|
70676
70704
|
}
|
|
70677
70705
|
|
|
70678
70706
|
/**
|
|
@@ -70691,6 +70719,110 @@ class NodeContainer {
|
|
|
70691
70719
|
return this.__edges;
|
|
70692
70720
|
}
|
|
70693
70721
|
|
|
70722
|
+
/**
|
|
70723
|
+
* NOTE: this method allocates memory internally
|
|
70724
|
+
* @returns {N[]}
|
|
70725
|
+
*/
|
|
70726
|
+
get inNodes() {
|
|
70727
|
+
return this.inEdges.map(e => e.other(this.node));
|
|
70728
|
+
}
|
|
70729
|
+
|
|
70730
|
+
/**
|
|
70731
|
+
* NOTE: this method allocates memory internally
|
|
70732
|
+
* @returns {N[]}
|
|
70733
|
+
*/
|
|
70734
|
+
get outNodes() {
|
|
70735
|
+
return this.outEdges.map(e => e.other(this.node));
|
|
70736
|
+
}
|
|
70737
|
+
|
|
70738
|
+
|
|
70739
|
+
/**
|
|
70740
|
+
* NOTE: this method allocates memory internally
|
|
70741
|
+
* @returns {Edge<N>[]}
|
|
70742
|
+
*/
|
|
70743
|
+
get outEdges() {
|
|
70744
|
+
/**
|
|
70745
|
+
*
|
|
70746
|
+
* @type {Edge<N>[]}
|
|
70747
|
+
*/
|
|
70748
|
+
const result = [];
|
|
70749
|
+
|
|
70750
|
+
this.getOutgoingEdges(result);
|
|
70751
|
+
|
|
70752
|
+
return result;
|
|
70753
|
+
}
|
|
70754
|
+
|
|
70755
|
+
/**
|
|
70756
|
+
* NOTE: this method allocates memory internally
|
|
70757
|
+
* @returns {Edge<N>[]}
|
|
70758
|
+
*/
|
|
70759
|
+
get inEdges() {
|
|
70760
|
+
/**
|
|
70761
|
+
*
|
|
70762
|
+
* @type {Edge<N>[]}
|
|
70763
|
+
*/
|
|
70764
|
+
const result = [];
|
|
70765
|
+
|
|
70766
|
+
this.getIncomingEdges(result);
|
|
70767
|
+
|
|
70768
|
+
return result;
|
|
70769
|
+
}
|
|
70770
|
+
|
|
70771
|
+
|
|
70772
|
+
/**
|
|
70773
|
+
*
|
|
70774
|
+
* @param {Edge<N>[]} result
|
|
70775
|
+
* @returns {number}
|
|
70776
|
+
*/
|
|
70777
|
+
getIncomingEdges(result) {
|
|
70778
|
+
const edges = this.__edges;
|
|
70779
|
+
|
|
70780
|
+
const edge_count = edges.length;
|
|
70781
|
+
|
|
70782
|
+
let result_count = 0;
|
|
70783
|
+
|
|
70784
|
+
for (let i = 0; i < edge_count; i++) {
|
|
70785
|
+
const edge = edges[i];
|
|
70786
|
+
|
|
70787
|
+
if (edge.isDirectedTowards(this.node)) {
|
|
70788
|
+
|
|
70789
|
+
result.push(edge);
|
|
70790
|
+
result_count++;
|
|
70791
|
+
|
|
70792
|
+
}
|
|
70793
|
+
|
|
70794
|
+
}
|
|
70795
|
+
|
|
70796
|
+
return result_count;
|
|
70797
|
+
}
|
|
70798
|
+
|
|
70799
|
+
/**
|
|
70800
|
+
*
|
|
70801
|
+
* @param {Edge<N>[]} result
|
|
70802
|
+
* @returns {number}
|
|
70803
|
+
*/
|
|
70804
|
+
getOutgoingEdges(result) {
|
|
70805
|
+
const edges = this.__edges;
|
|
70806
|
+
|
|
70807
|
+
const edge_count = edges.length;
|
|
70808
|
+
|
|
70809
|
+
let result_count = 0;
|
|
70810
|
+
|
|
70811
|
+
for (let i = 0; i < edge_count; i++) {
|
|
70812
|
+
const edge = edges[i];
|
|
70813
|
+
|
|
70814
|
+
if (edge.isDirectedAwayFrom(this.node)) {
|
|
70815
|
+
|
|
70816
|
+
result.push(edge);
|
|
70817
|
+
result_count++;
|
|
70818
|
+
|
|
70819
|
+
}
|
|
70820
|
+
|
|
70821
|
+
}
|
|
70822
|
+
|
|
70823
|
+
return result_count;
|
|
70824
|
+
}
|
|
70825
|
+
|
|
70694
70826
|
/**
|
|
70695
70827
|
*
|
|
70696
70828
|
* @return {number}
|
|
@@ -70701,12 +70833,14 @@ class NodeContainer {
|
|
|
70701
70833
|
const edges = this.__edges;
|
|
70702
70834
|
const edge_count = edges.length;
|
|
70703
70835
|
|
|
70836
|
+
const current_node = this.node;
|
|
70837
|
+
|
|
70704
70838
|
for (let i = 0; i < edge_count; i++) {
|
|
70705
70839
|
const edge = edges[i];
|
|
70706
70840
|
|
|
70707
70841
|
if (
|
|
70708
|
-
(edge.first ===
|
|
70709
|
-
|| (edge.second ===
|
|
70842
|
+
(edge.first === current_node && edge.direction === EdgeDirectionType.Forward)
|
|
70843
|
+
|| (edge.second === current_node && edge.direction === EdgeDirectionType.Backward)
|
|
70710
70844
|
|
|
70711
70845
|
) {
|
|
70712
70846
|
r++;
|
|
@@ -70730,7 +70864,7 @@ class NodeContainer {
|
|
|
70730
70864
|
|
|
70731
70865
|
/**
|
|
70732
70866
|
*
|
|
70733
|
-
* @param {function(Edge)} visitor
|
|
70867
|
+
* @param {function(Edge<N>)} visitor
|
|
70734
70868
|
* @param {*} [thisArg]
|
|
70735
70869
|
* @returns {number}
|
|
70736
70870
|
*/
|
|
@@ -70862,17 +70996,20 @@ class NodeContainer {
|
|
|
70862
70996
|
}
|
|
70863
70997
|
|
|
70864
70998
|
/**
|
|
70999
|
+
* Reconstruct path from search metadata
|
|
70865
71000
|
* @template T
|
|
70866
71001
|
* @param {NodeContainer<T>} goal_node_container
|
|
70867
|
-
* @param {Map<NodeContainer<T>,NodeContainer<T>>}
|
|
70868
|
-
* @returns {T[]}
|
|
71002
|
+
* @param {Map<NodeContainer<T>,NodeContainer<T>>} came_from
|
|
71003
|
+
* @returns {T[]} Nodes comprising the path from start to goal
|
|
70869
71004
|
*/
|
|
70870
|
-
function construct_path(goal_node_container,
|
|
71005
|
+
function construct_path(goal_node_container, came_from) {
|
|
70871
71006
|
const result = [];
|
|
71007
|
+
|
|
70872
71008
|
let c = goal_node_container;
|
|
71009
|
+
|
|
70873
71010
|
do {
|
|
70874
71011
|
result.unshift(c.node);
|
|
70875
|
-
c =
|
|
71012
|
+
c = came_from.get(c);
|
|
70876
71013
|
} while (c !== undefined);
|
|
70877
71014
|
|
|
70878
71015
|
return result;
|
|
@@ -70881,21 +71018,26 @@ function construct_path(goal_node_container, cameFrom) {
|
|
|
70881
71018
|
/**
|
|
70882
71019
|
* @template N
|
|
70883
71020
|
*/
|
|
70884
|
-
|
|
71021
|
+
class Graph {
|
|
70885
71022
|
|
|
70886
71023
|
/**
|
|
70887
71024
|
*
|
|
70888
71025
|
* @type {Map<N, NodeContainer<N>>}
|
|
71026
|
+
* @readonly
|
|
70889
71027
|
* @private
|
|
70890
71028
|
*/
|
|
70891
71029
|
__nodes = new Map();
|
|
70892
71030
|
/**
|
|
70893
71031
|
*
|
|
70894
71032
|
* @type {Set<Edge<N>>}
|
|
71033
|
+
* @readonly
|
|
70895
71034
|
* @private
|
|
70896
71035
|
*/
|
|
70897
71036
|
__edges = new Set();
|
|
70898
71037
|
|
|
71038
|
+
/**
|
|
71039
|
+
* @readonly
|
|
71040
|
+
*/
|
|
70899
71041
|
on = {
|
|
70900
71042
|
/**
|
|
70901
71043
|
* @type {Signal<N,this>}
|
|
@@ -71029,6 +71171,14 @@ let Graph$1 = class Graph {
|
|
|
71029
71171
|
return container.getEdgeCount();
|
|
71030
71172
|
}
|
|
71031
71173
|
|
|
71174
|
+
/**
|
|
71175
|
+
*
|
|
71176
|
+
* @returns {N[]}
|
|
71177
|
+
*/
|
|
71178
|
+
get nodes() {
|
|
71179
|
+
return Array.from(this.getNodes());
|
|
71180
|
+
}
|
|
71181
|
+
|
|
71032
71182
|
/**
|
|
71033
71183
|
* Do not modify this set directly
|
|
71034
71184
|
* @return {Iterable<N>}
|
|
@@ -71049,10 +71199,10 @@ let Graph$1 = class Graph {
|
|
|
71049
71199
|
*
|
|
71050
71200
|
* @param {N} source
|
|
71051
71201
|
* @param {N} target
|
|
71052
|
-
* @param {EdgeDirectionType} type
|
|
71202
|
+
* @param {EdgeDirectionType} [type] Undirected by default
|
|
71053
71203
|
* @returns {Edge<N>}
|
|
71054
71204
|
*/
|
|
71055
|
-
createEdge(source, target, type) {
|
|
71205
|
+
createEdge(source, target, type = EdgeDirectionType.Undirected) {
|
|
71056
71206
|
const edge = new Edge(source, target);
|
|
71057
71207
|
|
|
71058
71208
|
edge.direction = type;
|
|
@@ -71228,13 +71378,27 @@ let Graph$1 = class Graph {
|
|
|
71228
71378
|
const edge_count = edges.length;
|
|
71229
71379
|
|
|
71230
71380
|
for (let i = 0; i < edge_count; i++) {
|
|
71231
|
-
|
|
71232
|
-
result[i] = edge;
|
|
71381
|
+
result[i] = edges[i];
|
|
71233
71382
|
}
|
|
71234
71383
|
|
|
71235
71384
|
return edge_count;
|
|
71236
71385
|
}
|
|
71237
71386
|
|
|
71387
|
+
/**
|
|
71388
|
+
*
|
|
71389
|
+
* @param {N} node
|
|
71390
|
+
* @returns {N[]}
|
|
71391
|
+
*/
|
|
71392
|
+
getNeighbours(node) {
|
|
71393
|
+
const container = this.__nodes.get(node);
|
|
71394
|
+
|
|
71395
|
+
if (container === undefined) {
|
|
71396
|
+
return [];
|
|
71397
|
+
}
|
|
71398
|
+
|
|
71399
|
+
return container.neighbours;
|
|
71400
|
+
}
|
|
71401
|
+
|
|
71238
71402
|
/**
|
|
71239
71403
|
*
|
|
71240
71404
|
* @param {N} node
|
|
@@ -71350,7 +71514,7 @@ let Graph$1 = class Graph {
|
|
|
71350
71514
|
|
|
71351
71515
|
return r;
|
|
71352
71516
|
}
|
|
71353
|
-
}
|
|
71517
|
+
}
|
|
71354
71518
|
|
|
71355
71519
|
/**
|
|
71356
71520
|
*
|
|
@@ -71359,7 +71523,7 @@ let Graph$1 = class Graph {
|
|
|
71359
71523
|
* @return {Graph}
|
|
71360
71524
|
*/
|
|
71361
71525
|
function computeSystemComponentDependencyGraph(system_count, systems) {
|
|
71362
|
-
const dependency_graph = new Graph
|
|
71526
|
+
const dependency_graph = new Graph();
|
|
71363
71527
|
|
|
71364
71528
|
for (let i = 0; i < system_count; i++) {
|
|
71365
71529
|
const system = systems[i];
|
|
@@ -86095,564 +86259,6 @@ class PeriodicConsolePrinter {
|
|
|
86095
86259
|
}
|
|
86096
86260
|
}
|
|
86097
86261
|
|
|
86098
|
-
/**
|
|
86099
|
-
* Created by Alex on 29/01/14.
|
|
86100
|
-
*/
|
|
86101
|
-
|
|
86102
|
-
|
|
86103
|
-
/**
|
|
86104
|
-
* @callback Graph~visitor
|
|
86105
|
-
* @param {*} node
|
|
86106
|
-
* @param {Edge} edge
|
|
86107
|
-
* @returns {boolean|undefined} if false is returned, traversal should stop
|
|
86108
|
-
*/
|
|
86109
|
-
|
|
86110
|
-
/**
|
|
86111
|
-
* @template N
|
|
86112
|
-
*/
|
|
86113
|
-
class Graph {
|
|
86114
|
-
/**
|
|
86115
|
-
* @template N
|
|
86116
|
-
* @constructor
|
|
86117
|
-
*/
|
|
86118
|
-
constructor() {
|
|
86119
|
-
/**
|
|
86120
|
-
* @private
|
|
86121
|
-
* @type {N[]}
|
|
86122
|
-
*/
|
|
86123
|
-
this.__nodes = [];
|
|
86124
|
-
|
|
86125
|
-
/**
|
|
86126
|
-
* Accelerated data structure for faster lookups
|
|
86127
|
-
* @type {Set<any>}
|
|
86128
|
-
* @private
|
|
86129
|
-
*/
|
|
86130
|
-
this.__nodes_set = new Set();
|
|
86131
|
-
|
|
86132
|
-
/**
|
|
86133
|
-
* @private
|
|
86134
|
-
* @type {Edge<N>[]}
|
|
86135
|
-
*/
|
|
86136
|
-
this.__edges = [];
|
|
86137
|
-
this.onChange = new Signal();
|
|
86138
|
-
}
|
|
86139
|
-
|
|
86140
|
-
/**
|
|
86141
|
-
*
|
|
86142
|
-
* @returns {N[]}
|
|
86143
|
-
*/
|
|
86144
|
-
get nodes() {
|
|
86145
|
-
return this.__nodes;
|
|
86146
|
-
}
|
|
86147
|
-
|
|
86148
|
-
/**
|
|
86149
|
-
*
|
|
86150
|
-
* @returns {Edge<N>[]}
|
|
86151
|
-
*/
|
|
86152
|
-
get edges() {
|
|
86153
|
-
return this.__edges;
|
|
86154
|
-
}
|
|
86155
|
-
|
|
86156
|
-
/**
|
|
86157
|
-
* Converts this graph into a shallow copy of supplied graph
|
|
86158
|
-
* @param {Graph<N>} other
|
|
86159
|
-
*/
|
|
86160
|
-
copy(other) {
|
|
86161
|
-
this.clear();
|
|
86162
|
-
|
|
86163
|
-
this.__nodes = other.__nodes.slice();
|
|
86164
|
-
this.__edges = other.__edges.slice();
|
|
86165
|
-
|
|
86166
|
-
this.__nodes_set = new Set(this.__nodes);
|
|
86167
|
-
}
|
|
86168
|
-
|
|
86169
|
-
/**
|
|
86170
|
-
*
|
|
86171
|
-
* @param {N} start
|
|
86172
|
-
* @param {N} goal
|
|
86173
|
-
* @returns {Array<N>|null} nodes from start to goal in the shortest path including both start and goal.
|
|
86174
|
-
*/
|
|
86175
|
-
findPath(start, goal) {
|
|
86176
|
-
const open = new Set();
|
|
86177
|
-
open.add(start);
|
|
86178
|
-
|
|
86179
|
-
const closed = new Set();
|
|
86180
|
-
|
|
86181
|
-
const cameFrom = new Map();
|
|
86182
|
-
|
|
86183
|
-
function constructPath() {
|
|
86184
|
-
const result = [];
|
|
86185
|
-
let c = goal;
|
|
86186
|
-
do {
|
|
86187
|
-
result.unshift(c);
|
|
86188
|
-
c = cameFrom.get(c);
|
|
86189
|
-
} while (c !== undefined);
|
|
86190
|
-
|
|
86191
|
-
return result;
|
|
86192
|
-
}
|
|
86193
|
-
|
|
86194
|
-
const graph = this;
|
|
86195
|
-
|
|
86196
|
-
function expandNode(current) {
|
|
86197
|
-
graph.traverseSuccessors(current, function (node, edge) {
|
|
86198
|
-
if (closed.has(node)) {
|
|
86199
|
-
return;
|
|
86200
|
-
}
|
|
86201
|
-
if (open.has(node)) {
|
|
86202
|
-
return;
|
|
86203
|
-
}
|
|
86204
|
-
open.add(node);
|
|
86205
|
-
cameFrom.set(node, current);
|
|
86206
|
-
});
|
|
86207
|
-
}
|
|
86208
|
-
|
|
86209
|
-
while (open.size > 0) {
|
|
86210
|
-
const current = open.values().next().value;
|
|
86211
|
-
if (current === goal) {
|
|
86212
|
-
//reached the goal
|
|
86213
|
-
return constructPath();
|
|
86214
|
-
}
|
|
86215
|
-
open.delete(current);
|
|
86216
|
-
closed.add(current);
|
|
86217
|
-
|
|
86218
|
-
//expand node
|
|
86219
|
-
expandNode(current);
|
|
86220
|
-
}
|
|
86221
|
-
|
|
86222
|
-
//no path found
|
|
86223
|
-
return null;
|
|
86224
|
-
}
|
|
86225
|
-
|
|
86226
|
-
/**
|
|
86227
|
-
* Returns true if there is an edge between two given nodes on this graph
|
|
86228
|
-
* @param {N} node1
|
|
86229
|
-
* @param {N} node2
|
|
86230
|
-
* @returns {boolean}
|
|
86231
|
-
*/
|
|
86232
|
-
isEdgeBetween(node1, node2) {
|
|
86233
|
-
if (!this.containsNode(node1) || !this.containsNode(node2)) {
|
|
86234
|
-
return false; // one or both nodes are not part of the graph
|
|
86235
|
-
}
|
|
86236
|
-
const connectingEdge = this.findConnectingEdge(node1, node2);
|
|
86237
|
-
return connectingEdge !== null;
|
|
86238
|
-
}
|
|
86239
|
-
|
|
86240
|
-
/**
|
|
86241
|
-
* Strictly traversable edge exists from source to target
|
|
86242
|
-
* @param {N} source
|
|
86243
|
-
* @param {N} target
|
|
86244
|
-
* @returns {boolean}
|
|
86245
|
-
*/
|
|
86246
|
-
edgeExists(source, target) {
|
|
86247
|
-
if (!this.containsNode(source) || !this.containsNode(target)) {
|
|
86248
|
-
return false; // one or both nodes are not part of the graph
|
|
86249
|
-
}
|
|
86250
|
-
|
|
86251
|
-
return this.traversePredecessors(source, function (destination) {
|
|
86252
|
-
if (destination === target) {
|
|
86253
|
-
//terminate traversal, this will make "traversePredecessors" return true also
|
|
86254
|
-
return false;
|
|
86255
|
-
}
|
|
86256
|
-
});
|
|
86257
|
-
}
|
|
86258
|
-
|
|
86259
|
-
/**
|
|
86260
|
-
*
|
|
86261
|
-
* @param {function(node:N):boolean} visitor
|
|
86262
|
-
* @param {*} [thisArg]
|
|
86263
|
-
*/
|
|
86264
|
-
traverseNodes(visitor, thisArg) {
|
|
86265
|
-
const nodes = this.__nodes;
|
|
86266
|
-
const l = nodes.length;
|
|
86267
|
-
for (let i = 0; i < l; i++) {
|
|
86268
|
-
const node = nodes[i];
|
|
86269
|
-
if (visitor.call(thisArg, node) === false) {
|
|
86270
|
-
return;
|
|
86271
|
-
}
|
|
86272
|
-
}
|
|
86273
|
-
}
|
|
86274
|
-
|
|
86275
|
-
/**
|
|
86276
|
-
*
|
|
86277
|
-
* @param {N} node
|
|
86278
|
-
* @param {function(node:N, edge:Edge<N>):(boolean|void)} visitor
|
|
86279
|
-
*/
|
|
86280
|
-
traverseSuccessors(node, visitor) {
|
|
86281
|
-
const edges = this.__edges;
|
|
86282
|
-
let i = 0;
|
|
86283
|
-
const l = edges.length;
|
|
86284
|
-
|
|
86285
|
-
for (; i < l; i++) {
|
|
86286
|
-
const edge = edges[i];
|
|
86287
|
-
const first = edge.first;
|
|
86288
|
-
const second = edge.second;
|
|
86289
|
-
|
|
86290
|
-
if (first === node && edge.traversableForward()) {
|
|
86291
|
-
if (visitor(second, edge) === false) {
|
|
86292
|
-
//terminate traversal if visitor returns false
|
|
86293
|
-
return;
|
|
86294
|
-
}
|
|
86295
|
-
} else if (second === node && edge.traversableBackward()) {
|
|
86296
|
-
if (visitor(first, edge) === false) {
|
|
86297
|
-
//terminate traversal if visitor returns false
|
|
86298
|
-
return;
|
|
86299
|
-
}
|
|
86300
|
-
}
|
|
86301
|
-
}
|
|
86302
|
-
|
|
86303
|
-
}
|
|
86304
|
-
|
|
86305
|
-
/**
|
|
86306
|
-
*
|
|
86307
|
-
* @param {function(edge:Edge<N>):boolean} visitor
|
|
86308
|
-
*/
|
|
86309
|
-
traverseEdges(visitor) {
|
|
86310
|
-
const edges = this.__edges;
|
|
86311
|
-
let i = 0;
|
|
86312
|
-
const l = edges.length;
|
|
86313
|
-
for (; i < l; i++) {
|
|
86314
|
-
const edge = edges[i];
|
|
86315
|
-
if (visitor(edge) === false) {
|
|
86316
|
-
//terminate traversal if visitor returns false
|
|
86317
|
-
return;
|
|
86318
|
-
}
|
|
86319
|
-
}
|
|
86320
|
-
}
|
|
86321
|
-
|
|
86322
|
-
/**
|
|
86323
|
-
*
|
|
86324
|
-
* @param {N} node
|
|
86325
|
-
* @param {function(N,Edge<N>)} visitor
|
|
86326
|
-
*/
|
|
86327
|
-
traversePredecessors(node, visitor) {
|
|
86328
|
-
const edges = this.__edges;
|
|
86329
|
-
let i = 0;
|
|
86330
|
-
const l = edges.length;
|
|
86331
|
-
for (; i < l; i++) {
|
|
86332
|
-
const edge = edges[i];
|
|
86333
|
-
const first = edge.first;
|
|
86334
|
-
const second = edge.second;
|
|
86335
|
-
|
|
86336
|
-
if (second === node && edge.traversableForward()) {
|
|
86337
|
-
if (visitor(first, edge) === false) {
|
|
86338
|
-
//terminate traversal if visitor returns false
|
|
86339
|
-
return true;
|
|
86340
|
-
}
|
|
86341
|
-
} else if (first === node && edge.traversableBackward()) {
|
|
86342
|
-
if (visitor(second, edge) === false) {
|
|
86343
|
-
//terminate traversal if visitor returns false
|
|
86344
|
-
return true;
|
|
86345
|
-
}
|
|
86346
|
-
}
|
|
86347
|
-
}
|
|
86348
|
-
return false;
|
|
86349
|
-
}
|
|
86350
|
-
|
|
86351
|
-
/**
|
|
86352
|
-
*
|
|
86353
|
-
* @param {N} node
|
|
86354
|
-
* @param {function(N,Edge):(boolean|void)} visitor
|
|
86355
|
-
*/
|
|
86356
|
-
traverseAttachedEdges(node, visitor) {
|
|
86357
|
-
const edges = this.__edges;
|
|
86358
|
-
let i = 0;
|
|
86359
|
-
const l = edges.length;
|
|
86360
|
-
for (; i < l; i++) {
|
|
86361
|
-
const edge = edges[i];
|
|
86362
|
-
const first = edge.first;
|
|
86363
|
-
const second = edge.second;
|
|
86364
|
-
|
|
86365
|
-
if (first === node) {
|
|
86366
|
-
if (visitor(second, edge) === false) {
|
|
86367
|
-
//terminate traversal if visitor returns false
|
|
86368
|
-
return;
|
|
86369
|
-
}
|
|
86370
|
-
} else if (second === node) {
|
|
86371
|
-
if (visitor(first, edge) === false) {
|
|
86372
|
-
//terminate traversal if visitor returns false
|
|
86373
|
-
return;
|
|
86374
|
-
}
|
|
86375
|
-
}
|
|
86376
|
-
}
|
|
86377
|
-
}
|
|
86378
|
-
|
|
86379
|
-
/**
|
|
86380
|
-
*
|
|
86381
|
-
* @param {N} source
|
|
86382
|
-
* @param {N} target
|
|
86383
|
-
* @return {Edge<N>|null}
|
|
86384
|
-
*/
|
|
86385
|
-
findTraversableEdge(source, target) {
|
|
86386
|
-
|
|
86387
|
-
const edges = this.__edges;
|
|
86388
|
-
|
|
86389
|
-
const numEdges = edges.length;
|
|
86390
|
-
|
|
86391
|
-
for (let i = 0; i < numEdges; i++) {
|
|
86392
|
-
|
|
86393
|
-
/**
|
|
86394
|
-
*
|
|
86395
|
-
* @type {Edge<N>}
|
|
86396
|
-
*/
|
|
86397
|
-
const edge = edges[i];
|
|
86398
|
-
|
|
86399
|
-
if (
|
|
86400
|
-
(edge.first === source && edge.second === target && edge.direction !== EdgeDirectionType.Backward)
|
|
86401
|
-
|| (edge.second === source && edge.first === target && edge.direction !== EdgeDirectionType.Forward)
|
|
86402
|
-
) {
|
|
86403
|
-
return edge;
|
|
86404
|
-
}
|
|
86405
|
-
}
|
|
86406
|
-
|
|
86407
|
-
return null;
|
|
86408
|
-
}
|
|
86409
|
-
|
|
86410
|
-
/**
|
|
86411
|
-
*
|
|
86412
|
-
* @param {N} node1
|
|
86413
|
-
* @param {N} node2
|
|
86414
|
-
* @returns {Edge<N>|null}
|
|
86415
|
-
*/
|
|
86416
|
-
findConnectingEdge(node1, node2) {
|
|
86417
|
-
const edges = this.__edges;
|
|
86418
|
-
|
|
86419
|
-
const numEdges = edges.length;
|
|
86420
|
-
|
|
86421
|
-
for (let i = 0; i < numEdges; i++) {
|
|
86422
|
-
|
|
86423
|
-
const edge = edges[i];
|
|
86424
|
-
|
|
86425
|
-
if (edge.contains(node1) && edge.contains(node2)) {
|
|
86426
|
-
return edge;
|
|
86427
|
-
}
|
|
86428
|
-
|
|
86429
|
-
}
|
|
86430
|
-
|
|
86431
|
-
return null;
|
|
86432
|
-
}
|
|
86433
|
-
|
|
86434
|
-
/**
|
|
86435
|
-
*
|
|
86436
|
-
* @param {N} source
|
|
86437
|
-
* @param {N} target
|
|
86438
|
-
* @param {function(Edge<N>):boolean} visitor
|
|
86439
|
-
*/
|
|
86440
|
-
findTraversableEdges(source, target, visitor) {
|
|
86441
|
-
const edges = this.__edges;
|
|
86442
|
-
for (let i = 0; i < edges.length; i++) {
|
|
86443
|
-
const edge = edges[i];
|
|
86444
|
-
if (edge.validateTransition(source, target)) {
|
|
86445
|
-
|
|
86446
|
-
if (visitor(edge) === false) {
|
|
86447
|
-
return;
|
|
86448
|
-
}
|
|
86449
|
-
}
|
|
86450
|
-
}
|
|
86451
|
-
}
|
|
86452
|
-
|
|
86453
|
-
/**
|
|
86454
|
-
*
|
|
86455
|
-
* @param {N} node
|
|
86456
|
-
* @returns {Edge<N>[]}
|
|
86457
|
-
*/
|
|
86458
|
-
getAttachedEdges(node) {
|
|
86459
|
-
let i = 0;
|
|
86460
|
-
|
|
86461
|
-
const result = [];
|
|
86462
|
-
|
|
86463
|
-
const edges = this.__edges;
|
|
86464
|
-
const l = edges.length;
|
|
86465
|
-
|
|
86466
|
-
for (; i < l; i++) {
|
|
86467
|
-
const edge = edges[i];
|
|
86468
|
-
|
|
86469
|
-
if (edge.contains(node)) {
|
|
86470
|
-
result.push(edge);
|
|
86471
|
-
}
|
|
86472
|
-
}
|
|
86473
|
-
|
|
86474
|
-
return result;
|
|
86475
|
-
}
|
|
86476
|
-
|
|
86477
|
-
/**
|
|
86478
|
-
*
|
|
86479
|
-
* @param {N} node
|
|
86480
|
-
* @returns {N[]}
|
|
86481
|
-
*/
|
|
86482
|
-
getNeighbours(node) {
|
|
86483
|
-
const result = [];
|
|
86484
|
-
|
|
86485
|
-
const edges = this.edges;
|
|
86486
|
-
const nEdges = edges.length;
|
|
86487
|
-
|
|
86488
|
-
for (let i = 0; i < nEdges; i++) {
|
|
86489
|
-
const edge = edges[i];
|
|
86490
|
-
|
|
86491
|
-
const first = edge.first;
|
|
86492
|
-
const second = edge.second;
|
|
86493
|
-
|
|
86494
|
-
if (first === node && (edge.direction === EdgeDirectionType.Forward || edge.direction === EdgeDirectionType.Undirected)) {
|
|
86495
|
-
if (result.indexOf(second) === -1) {
|
|
86496
|
-
result.push(second);
|
|
86497
|
-
}
|
|
86498
|
-
} else if (second === node && (edge.direction === EdgeDirectionType.Backward || edge.direction === EdgeDirectionType.Undirected)) {
|
|
86499
|
-
if (result.indexOf(first) === -1) {
|
|
86500
|
-
result.push(first);
|
|
86501
|
-
}
|
|
86502
|
-
}
|
|
86503
|
-
|
|
86504
|
-
}
|
|
86505
|
-
|
|
86506
|
-
return result;
|
|
86507
|
-
}
|
|
86508
|
-
|
|
86509
|
-
/**
|
|
86510
|
-
*
|
|
86511
|
-
* @param {N} node
|
|
86512
|
-
* @returns {boolean}
|
|
86513
|
-
*/
|
|
86514
|
-
containsNode(node) {
|
|
86515
|
-
return this.__nodes_set.has(node);
|
|
86516
|
-
}
|
|
86517
|
-
|
|
86518
|
-
/**
|
|
86519
|
-
* @deprecated
|
|
86520
|
-
* @returns {number}
|
|
86521
|
-
*/
|
|
86522
|
-
length() {
|
|
86523
|
-
const edges = this.__edges;
|
|
86524
|
-
let result = 0;
|
|
86525
|
-
for (let i = 0; i < edges.length; i++) {
|
|
86526
|
-
const edge = edges[i];
|
|
86527
|
-
result += edge.length;
|
|
86528
|
-
}
|
|
86529
|
-
return result;
|
|
86530
|
-
}
|
|
86531
|
-
|
|
86532
|
-
/**
|
|
86533
|
-
*
|
|
86534
|
-
* @param {N} node
|
|
86535
|
-
*/
|
|
86536
|
-
addNode(node) {
|
|
86537
|
-
|
|
86538
|
-
this.__nodes_set.add(node);
|
|
86539
|
-
|
|
86540
|
-
this.__nodes.push(node);
|
|
86541
|
-
}
|
|
86542
|
-
|
|
86543
|
-
/**
|
|
86544
|
-
*
|
|
86545
|
-
* @param {N} node
|
|
86546
|
-
* @returns {boolean}
|
|
86547
|
-
*/
|
|
86548
|
-
removeNode(node) {
|
|
86549
|
-
if (!this.containsNode(node)) {
|
|
86550
|
-
return false;
|
|
86551
|
-
}
|
|
86552
|
-
|
|
86553
|
-
const i = this.__nodes.indexOf(node);
|
|
86554
|
-
|
|
86555
|
-
if (i === -1) {
|
|
86556
|
-
// this should never happen
|
|
86557
|
-
return false;
|
|
86558
|
-
} else {
|
|
86559
|
-
//remove attached connections
|
|
86560
|
-
const attachedEdges = this.getAttachedEdges(node);
|
|
86561
|
-
|
|
86562
|
-
const n = attachedEdges.length;
|
|
86563
|
-
|
|
86564
|
-
for (let j = 0; j < n; j++) {
|
|
86565
|
-
const edge = attachedEdges[j];
|
|
86566
|
-
|
|
86567
|
-
this.removeEdge(edge);
|
|
86568
|
-
}
|
|
86569
|
-
|
|
86570
|
-
this.__nodes.splice(i, 1);
|
|
86571
|
-
this.__nodes_set.delete(node);
|
|
86572
|
-
|
|
86573
|
-
return true;
|
|
86574
|
-
}
|
|
86575
|
-
}
|
|
86576
|
-
|
|
86577
|
-
/**
|
|
86578
|
-
* Whether or not the graph contains given node
|
|
86579
|
-
* NOTE: same as {@link #containsNode}
|
|
86580
|
-
* @param {N} node
|
|
86581
|
-
* @returns {boolean}
|
|
86582
|
-
*/
|
|
86583
|
-
hasNode(node) {
|
|
86584
|
-
return this.containsNode(node);
|
|
86585
|
-
}
|
|
86586
|
-
|
|
86587
|
-
/**
|
|
86588
|
-
*
|
|
86589
|
-
* @param {Edge<N>} edge
|
|
86590
|
-
*/
|
|
86591
|
-
addEdge(edge) {
|
|
86592
|
-
//assert.ok(this.containsNode(edge.first), `Node Edge.first(=${edge.first}) is not present in the graph`);
|
|
86593
|
-
//assert.ok(this.containsNode(edge.second), `Node Edge.second(=${edge.second}) is not present in the graph`);
|
|
86594
|
-
|
|
86595
|
-
this.__edges.push(edge);
|
|
86596
|
-
this.onChange.send1(edge);
|
|
86597
|
-
}
|
|
86598
|
-
|
|
86599
|
-
/**
|
|
86600
|
-
*
|
|
86601
|
-
* @param {N} source
|
|
86602
|
-
* @param {N} target
|
|
86603
|
-
* @param {EdgeDirectionType} [direction]
|
|
86604
|
-
* @returns {Edge<N>}
|
|
86605
|
-
*/
|
|
86606
|
-
createEdge(source, target, direction = EdgeDirectionType.Undirected) {
|
|
86607
|
-
const edge = new Edge(source, target);
|
|
86608
|
-
|
|
86609
|
-
edge.direction = direction;
|
|
86610
|
-
|
|
86611
|
-
this.addEdge(edge);
|
|
86612
|
-
|
|
86613
|
-
return edge;
|
|
86614
|
-
}
|
|
86615
|
-
|
|
86616
|
-
/**
|
|
86617
|
-
*
|
|
86618
|
-
* @param {Edge<N>} edge
|
|
86619
|
-
* @returns {boolean}
|
|
86620
|
-
*/
|
|
86621
|
-
removeEdge(edge) {
|
|
86622
|
-
const edges = this.__edges;
|
|
86623
|
-
const indexOf = edges.indexOf(edge);
|
|
86624
|
-
if (indexOf >= 0) {
|
|
86625
|
-
edges.splice(indexOf, 1);
|
|
86626
|
-
this.onChange.send1(edge);
|
|
86627
|
-
|
|
86628
|
-
return true;
|
|
86629
|
-
} else {
|
|
86630
|
-
|
|
86631
|
-
return false;
|
|
86632
|
-
}
|
|
86633
|
-
}
|
|
86634
|
-
|
|
86635
|
-
clear() {
|
|
86636
|
-
this.__edges = [];
|
|
86637
|
-
this.__nodes = [];
|
|
86638
|
-
this.__nodes_set.clear();
|
|
86639
|
-
|
|
86640
|
-
this.onChange.send0();
|
|
86641
|
-
}
|
|
86642
|
-
|
|
86643
|
-
/**
|
|
86644
|
-
*
|
|
86645
|
-
* @returns {Graph<N>}
|
|
86646
|
-
*/
|
|
86647
|
-
clone() {
|
|
86648
|
-
const graph = new Graph();
|
|
86649
|
-
|
|
86650
|
-
graph.copy(this);
|
|
86651
|
-
|
|
86652
|
-
return graph;
|
|
86653
|
-
}
|
|
86654
|
-
}
|
|
86655
|
-
|
|
86656
86262
|
/**
|
|
86657
86263
|
* Contains serializers for various data types as well as data upgraders which enable support for serialization format changes
|
|
86658
86264
|
*/
|
|
@@ -86689,23 +86295,25 @@ class BinarySerializationRegistry {
|
|
|
86689
86295
|
*/
|
|
86690
86296
|
registerAdapter(adapter, className) {
|
|
86691
86297
|
|
|
86692
|
-
|
|
86298
|
+
let _className = className;
|
|
86299
|
+
|
|
86300
|
+
if (_className === undefined) {
|
|
86693
86301
|
const klass = adapter.getClass();
|
|
86694
86302
|
|
|
86695
86303
|
if (typeof klass.typeName === "string") {
|
|
86696
|
-
|
|
86304
|
+
_className = klass.typeName;
|
|
86697
86305
|
} else {
|
|
86698
86306
|
throw new Error(`className not specified, could not infer class name from the class itself`);
|
|
86699
86307
|
}
|
|
86700
86308
|
}
|
|
86701
86309
|
|
|
86702
|
-
if (this.serializers.has(
|
|
86310
|
+
if (this.serializers.has(_className)) {
|
|
86703
86311
|
//a serializer already exists
|
|
86704
86312
|
|
|
86705
86313
|
return false;
|
|
86706
86314
|
}
|
|
86707
86315
|
|
|
86708
|
-
this.serializers.set(
|
|
86316
|
+
this.serializers.set(_className, adapter);
|
|
86709
86317
|
|
|
86710
86318
|
return true;
|
|
86711
86319
|
}
|
|
@@ -116360,7 +115968,7 @@ class Uint32Heap {
|
|
|
116360
115968
|
const size = this.__size;
|
|
116361
115969
|
|
|
116362
115970
|
while (true) {
|
|
116363
|
-
const l = (
|
|
115971
|
+
const l = (i << 1) + 1;
|
|
116364
115972
|
const r = l + 1;
|
|
116365
115973
|
|
|
116366
115974
|
let smallest = i;
|
|
@@ -116482,6 +116090,15 @@ class Uint32Heap {
|
|
|
116482
116090
|
return -1;
|
|
116483
116091
|
}
|
|
116484
116092
|
|
|
116093
|
+
/**
|
|
116094
|
+
*
|
|
116095
|
+
* @param {number} id
|
|
116096
|
+
* @returns {boolean}
|
|
116097
|
+
*/
|
|
116098
|
+
contains(id){
|
|
116099
|
+
return this.find_index_by_id(id) !== -1;
|
|
116100
|
+
}
|
|
116101
|
+
|
|
116485
116102
|
/**
|
|
116486
116103
|
* Clear out all the data, heap will be made empty
|
|
116487
116104
|
*/
|
|
@@ -116647,7 +116264,7 @@ function index2point(result, index, width) {
|
|
|
116647
116264
|
* @param {number} height
|
|
116648
116265
|
* @returns {number}
|
|
116649
116266
|
*/
|
|
116650
|
-
function
|
|
116267
|
+
function compute_neighbors(result, index, width, height) {
|
|
116651
116268
|
const x = index % width;
|
|
116652
116269
|
const y = (index / width) | 0;
|
|
116653
116270
|
|
|
@@ -116657,14 +116274,17 @@ function computeNeighbors(result, index, width, height) {
|
|
|
116657
116274
|
result[neighbour_count] = index - width;
|
|
116658
116275
|
neighbour_count++;
|
|
116659
116276
|
}
|
|
116277
|
+
|
|
116660
116278
|
if (x > 0) {
|
|
116661
116279
|
result[neighbour_count] = index - 1;
|
|
116662
116280
|
neighbour_count++;
|
|
116663
116281
|
}
|
|
116282
|
+
|
|
116664
116283
|
if (x < width - 1) {
|
|
116665
116284
|
result[neighbour_count] = index + 1;
|
|
116666
116285
|
neighbour_count++;
|
|
116667
116286
|
}
|
|
116287
|
+
|
|
116668
116288
|
if (y < height - 1) {
|
|
116669
116289
|
result[neighbour_count] = index + width;
|
|
116670
116290
|
neighbour_count++;
|
|
@@ -116681,7 +116301,7 @@ function computeNeighbors(result, index, width, height) {
|
|
|
116681
116301
|
* @param {number} height
|
|
116682
116302
|
* @returns {number[]}
|
|
116683
116303
|
*/
|
|
116684
|
-
function
|
|
116304
|
+
function compute_path(node, g_score, width, height) {
|
|
116685
116305
|
let v_previous = new Vector2(-1, -1);
|
|
116686
116306
|
let v_current = new Vector2();
|
|
116687
116307
|
|
|
@@ -116732,7 +116352,7 @@ function pathTo(node, g_score, width, height) {
|
|
|
116732
116352
|
v_current = t;
|
|
116733
116353
|
|
|
116734
116354
|
// find next point
|
|
116735
|
-
const neighbour_count =
|
|
116355
|
+
const neighbour_count = compute_neighbors(neighbors, current, width, height);
|
|
116736
116356
|
|
|
116737
116357
|
current = -1;
|
|
116738
116358
|
|
|
@@ -116811,16 +116431,16 @@ closed.preventShrink();
|
|
|
116811
116431
|
* @param {number} height
|
|
116812
116432
|
* @param {number} start
|
|
116813
116433
|
* @param {number} goal
|
|
116814
|
-
* @param {number}
|
|
116815
|
-
* @param {number}
|
|
116434
|
+
* @param {number} crossing_penalty
|
|
116435
|
+
* @param {number} block_value value in the field that signifies impassible obstacle
|
|
116816
116436
|
* @returns {Array.<number>} array of indices representing path from start to end
|
|
116817
116437
|
*/
|
|
116818
116438
|
function find_path_on_grid_astar(
|
|
116819
116439
|
field,
|
|
116820
116440
|
width, height,
|
|
116821
116441
|
start, goal,
|
|
116822
|
-
|
|
116823
|
-
|
|
116442
|
+
crossing_penalty,
|
|
116443
|
+
block_value
|
|
116824
116444
|
) {
|
|
116825
116445
|
|
|
116826
116446
|
// prepare sets
|
|
@@ -116844,15 +116464,15 @@ function find_path_on_grid_astar(
|
|
|
116844
116464
|
const currentNode = open.pop_min();
|
|
116845
116465
|
|
|
116846
116466
|
if (currentNode === goal) {
|
|
116847
|
-
// End case
|
|
116848
|
-
return
|
|
116467
|
+
// End case - result has been found, return the traced path.
|
|
116468
|
+
return compute_path(currentNode, g_score, width, height);
|
|
116849
116469
|
}
|
|
116850
116470
|
|
|
116851
116471
|
// Normal case -- move currentNode from open to closed, process each of its neighbors.
|
|
116852
116472
|
closed.set(currentNode, true);
|
|
116853
116473
|
|
|
116854
116474
|
// Find all neighbors for the current node.
|
|
116855
|
-
const neighbour_count =
|
|
116475
|
+
const neighbour_count = compute_neighbors(neighbors, currentNode, width, height);
|
|
116856
116476
|
|
|
116857
116477
|
for (let i = 0; i < neighbour_count; ++i) {
|
|
116858
116478
|
const neighbor = neighbors[i];
|
|
@@ -116864,39 +116484,39 @@ function find_path_on_grid_astar(
|
|
|
116864
116484
|
|
|
116865
116485
|
// The g score is the shortest distance from start to current node.
|
|
116866
116486
|
// We need to check if the path we have arrived at this neighbor is the shortest one we have seen yet.
|
|
116867
|
-
const
|
|
116487
|
+
const neighbor_value = field[neighbor];
|
|
116868
116488
|
|
|
116869
|
-
if (
|
|
116489
|
+
if (neighbor_value === block_value) {
|
|
116870
116490
|
//cell is blocked, close and continue
|
|
116871
116491
|
closed.set(neighbor, true);
|
|
116872
116492
|
continue;
|
|
116873
116493
|
}
|
|
116874
116494
|
|
|
116875
116495
|
// Cost of traversing to this neighbour
|
|
116876
|
-
const transition_cost =
|
|
116496
|
+
const transition_cost = neighbor_value * crossing_penalty + 1;
|
|
116877
116497
|
|
|
116878
116498
|
// updated path cost
|
|
116879
|
-
const
|
|
116499
|
+
const cost_so_far = g_score[currentNode] + transition_cost;
|
|
116880
116500
|
|
|
116881
116501
|
const index_in_open_set = open.find_index_by_id(neighbor);
|
|
116882
116502
|
|
|
116883
116503
|
const not_in_open_set = index_in_open_set === -1;
|
|
116884
116504
|
|
|
116885
|
-
if (not_in_open_set ||
|
|
116505
|
+
if (not_in_open_set || cost_so_far < g_score[neighbor]) {
|
|
116886
116506
|
|
|
116887
116507
|
// update refined score
|
|
116888
|
-
g_score[neighbor] =
|
|
116508
|
+
g_score[neighbor] = cost_so_far;
|
|
116889
116509
|
|
|
116890
|
-
const
|
|
116510
|
+
const remaining_heuristic = heuristic(neighbor, goal, width);
|
|
116891
116511
|
|
|
116892
|
-
const
|
|
116512
|
+
const refined_heuristic = cost_so_far + remaining_heuristic;
|
|
116893
116513
|
|
|
116894
116514
|
if (not_in_open_set) {
|
|
116895
116515
|
// Pushing to heap will put it in proper place based on the 'f' value.
|
|
116896
|
-
open.insert(neighbor,
|
|
116516
|
+
open.insert(neighbor, refined_heuristic);
|
|
116897
116517
|
} else {
|
|
116898
116518
|
// Already seen the node, but since it has been re-scored we need to reorder it in the heap
|
|
116899
|
-
open.__update_score_by_index(index_in_open_set,
|
|
116519
|
+
open.__update_score_by_index(index_in_open_set, refined_heuristic);
|
|
116900
116520
|
}
|
|
116901
116521
|
}
|
|
116902
116522
|
}
|