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