@woosh/meep-engine 2.76.3 → 2.77.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 +202 -621
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +202 -621
- 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/Graph.js +1 -0
- package/src/core/graph/SquareMatrix.js +4 -2
- package/src/core/graph/WeightedEdge.js +5 -9
- 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/v2/Graph.js +16 -9
- package/src/core/graph/v2/NodeContainer.js +120 -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 +30 -27
- 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/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,46 +70671,142 @@ 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
|
|
|
70686
|
+
/**
|
|
70687
|
+
* Attached edges
|
|
70688
|
+
* @type {Edge<N>[]}
|
|
70689
|
+
* @private
|
|
70690
|
+
*/
|
|
70691
|
+
__edges = [];
|
|
70692
|
+
|
|
70693
|
+
/**
|
|
70694
|
+
*
|
|
70695
|
+
* @type {Map<N,number>}
|
|
70696
|
+
* @private
|
|
70697
|
+
*/
|
|
70698
|
+
__neighbors = new Map();
|
|
70699
|
+
|
|
70700
|
+
/**
|
|
70701
|
+
*
|
|
70702
|
+
* @return {number}
|
|
70703
|
+
*/
|
|
70704
|
+
getEdgeCount() {
|
|
70705
|
+
return this.__edges.length;
|
|
70706
|
+
}
|
|
70707
|
+
|
|
70708
|
+
/**
|
|
70709
|
+
* Do not modify the returned value
|
|
70710
|
+
* @return {Edge<N>[]}
|
|
70711
|
+
*/
|
|
70712
|
+
getEdges() {
|
|
70713
|
+
return this.__edges;
|
|
70714
|
+
}
|
|
70715
|
+
|
|
70716
|
+
/**
|
|
70717
|
+
*
|
|
70718
|
+
* @returns {N[]}
|
|
70719
|
+
*/
|
|
70720
|
+
get inNodes() {
|
|
70721
|
+
return this.inEdges.map(e => e.other(this.node));
|
|
70722
|
+
}
|
|
70723
|
+
|
|
70724
|
+
/**
|
|
70725
|
+
*
|
|
70726
|
+
* @returns {N[]}
|
|
70727
|
+
*/
|
|
70728
|
+
get outNodes() {
|
|
70729
|
+
return this.outEdges.map(e => e.other(this.node));
|
|
70730
|
+
}
|
|
70731
|
+
|
|
70732
|
+
|
|
70733
|
+
get outEdges() {
|
|
70665
70734
|
/**
|
|
70666
70735
|
*
|
|
70667
70736
|
* @type {Edge<N>[]}
|
|
70668
|
-
* @private
|
|
70669
70737
|
*/
|
|
70670
|
-
|
|
70738
|
+
const result = [];
|
|
70739
|
+
|
|
70740
|
+
this.getOutgoingEdges(result);
|
|
70741
|
+
|
|
70742
|
+
return result;
|
|
70743
|
+
}
|
|
70671
70744
|
|
|
70745
|
+
get inEdges() {
|
|
70672
70746
|
/**
|
|
70673
70747
|
*
|
|
70674
|
-
* @type {
|
|
70675
|
-
* @private
|
|
70748
|
+
* @type {Edge<N>[]}
|
|
70676
70749
|
*/
|
|
70677
|
-
|
|
70750
|
+
const result = [];
|
|
70751
|
+
|
|
70752
|
+
this.getIncomingEdges(result);
|
|
70753
|
+
|
|
70754
|
+
return result;
|
|
70678
70755
|
}
|
|
70679
70756
|
|
|
70757
|
+
|
|
70680
70758
|
/**
|
|
70681
70759
|
*
|
|
70682
|
-
* @
|
|
70760
|
+
* @param {Edge<N>[]} result
|
|
70761
|
+
* @returns {number}
|
|
70683
70762
|
*/
|
|
70684
|
-
|
|
70685
|
-
|
|
70763
|
+
getIncomingEdges(result) {
|
|
70764
|
+
const edges = this.__edges;
|
|
70765
|
+
|
|
70766
|
+
const edge_count = edges.length;
|
|
70767
|
+
|
|
70768
|
+
let result_count = 0;
|
|
70769
|
+
|
|
70770
|
+
for (let i = 0; i < edge_count; i++) {
|
|
70771
|
+
const edge = edges[i];
|
|
70772
|
+
|
|
70773
|
+
if (edge.isDirectedTowards(this.node)) {
|
|
70774
|
+
|
|
70775
|
+
result.push(edge);
|
|
70776
|
+
result_count++;
|
|
70777
|
+
|
|
70778
|
+
}
|
|
70779
|
+
|
|
70780
|
+
}
|
|
70781
|
+
|
|
70782
|
+
return result_count;
|
|
70686
70783
|
}
|
|
70687
70784
|
|
|
70688
70785
|
/**
|
|
70689
|
-
*
|
|
70690
|
-
* @
|
|
70786
|
+
*
|
|
70787
|
+
* @param {Edge<N>[]} result
|
|
70788
|
+
* @returns {number}
|
|
70691
70789
|
*/
|
|
70692
|
-
|
|
70693
|
-
|
|
70790
|
+
getOutgoingEdges(result) {
|
|
70791
|
+
const edges = this.__edges;
|
|
70792
|
+
|
|
70793
|
+
const edge_count = edges.length;
|
|
70794
|
+
|
|
70795
|
+
let result_count = 0;
|
|
70796
|
+
|
|
70797
|
+
for (let i = 0; i < edge_count; i++) {
|
|
70798
|
+
const edge = edges[i];
|
|
70799
|
+
|
|
70800
|
+
if (edge.isDirectedAwayFrom(this.node)) {
|
|
70801
|
+
|
|
70802
|
+
result.push(edge);
|
|
70803
|
+
result_count++;
|
|
70804
|
+
|
|
70805
|
+
}
|
|
70806
|
+
|
|
70807
|
+
}
|
|
70808
|
+
|
|
70809
|
+
return result_count;
|
|
70694
70810
|
}
|
|
70695
70811
|
|
|
70696
70812
|
/**
|
|
@@ -70703,12 +70819,14 @@ class NodeContainer {
|
|
|
70703
70819
|
const edges = this.__edges;
|
|
70704
70820
|
const edge_count = edges.length;
|
|
70705
70821
|
|
|
70822
|
+
const current_node = this.node;
|
|
70823
|
+
|
|
70706
70824
|
for (let i = 0; i < edge_count; i++) {
|
|
70707
70825
|
const edge = edges[i];
|
|
70708
70826
|
|
|
70709
70827
|
if (
|
|
70710
|
-
(edge.first ===
|
|
70711
|
-
|| (edge.second ===
|
|
70828
|
+
(edge.first === current_node && edge.direction === EdgeDirectionType.Forward)
|
|
70829
|
+
|| (edge.second === current_node && edge.direction === EdgeDirectionType.Backward)
|
|
70712
70830
|
|
|
70713
70831
|
) {
|
|
70714
70832
|
r++;
|
|
@@ -70732,7 +70850,7 @@ class NodeContainer {
|
|
|
70732
70850
|
|
|
70733
70851
|
/**
|
|
70734
70852
|
*
|
|
70735
|
-
* @param {function(Edge)} visitor
|
|
70853
|
+
* @param {function(Edge<N>)} visitor
|
|
70736
70854
|
* @param {*} [thisArg]
|
|
70737
70855
|
* @returns {number}
|
|
70738
70856
|
*/
|
|
@@ -70864,17 +70982,20 @@ class NodeContainer {
|
|
|
70864
70982
|
}
|
|
70865
70983
|
|
|
70866
70984
|
/**
|
|
70985
|
+
* Reconstruct path from search metadata
|
|
70867
70986
|
* @template T
|
|
70868
70987
|
* @param {NodeContainer<T>} goal_node_container
|
|
70869
|
-
* @param {Map<NodeContainer<T>,NodeContainer<T>>}
|
|
70870
|
-
* @returns {T[]}
|
|
70988
|
+
* @param {Map<NodeContainer<T>,NodeContainer<T>>} came_from
|
|
70989
|
+
* @returns {T[]} Nodes comprising the path from start to goal
|
|
70871
70990
|
*/
|
|
70872
|
-
function construct_path(goal_node_container,
|
|
70991
|
+
function construct_path(goal_node_container, came_from) {
|
|
70873
70992
|
const result = [];
|
|
70993
|
+
|
|
70874
70994
|
let c = goal_node_container;
|
|
70995
|
+
|
|
70875
70996
|
do {
|
|
70876
70997
|
result.unshift(c.node);
|
|
70877
|
-
c =
|
|
70998
|
+
c = came_from.get(c);
|
|
70878
70999
|
} while (c !== undefined);
|
|
70879
71000
|
|
|
70880
71001
|
return result;
|
|
@@ -70883,21 +71004,26 @@ function construct_path(goal_node_container, cameFrom) {
|
|
|
70883
71004
|
/**
|
|
70884
71005
|
* @template N
|
|
70885
71006
|
*/
|
|
70886
|
-
|
|
71007
|
+
class Graph {
|
|
70887
71008
|
|
|
70888
71009
|
/**
|
|
70889
71010
|
*
|
|
70890
71011
|
* @type {Map<N, NodeContainer<N>>}
|
|
71012
|
+
* @readonly
|
|
70891
71013
|
* @private
|
|
70892
71014
|
*/
|
|
70893
71015
|
__nodes = new Map();
|
|
70894
71016
|
/**
|
|
70895
71017
|
*
|
|
70896
71018
|
* @type {Set<Edge<N>>}
|
|
71019
|
+
* @readonly
|
|
70897
71020
|
* @private
|
|
70898
71021
|
*/
|
|
70899
71022
|
__edges = new Set();
|
|
70900
71023
|
|
|
71024
|
+
/**
|
|
71025
|
+
* @readonly
|
|
71026
|
+
*/
|
|
70901
71027
|
on = {
|
|
70902
71028
|
/**
|
|
70903
71029
|
* @type {Signal<N,this>}
|
|
@@ -71051,10 +71177,10 @@ let Graph$1 = class Graph {
|
|
|
71051
71177
|
*
|
|
71052
71178
|
* @param {N} source
|
|
71053
71179
|
* @param {N} target
|
|
71054
|
-
* @param {EdgeDirectionType} type
|
|
71180
|
+
* @param {EdgeDirectionType} [type] Undirected by default
|
|
71055
71181
|
* @returns {Edge<N>}
|
|
71056
71182
|
*/
|
|
71057
|
-
createEdge(source, target, type) {
|
|
71183
|
+
createEdge(source, target, type = EdgeDirectionType.Undirected) {
|
|
71058
71184
|
const edge = new Edge(source, target);
|
|
71059
71185
|
|
|
71060
71186
|
edge.direction = type;
|
|
@@ -71230,8 +71356,7 @@ let Graph$1 = class Graph {
|
|
|
71230
71356
|
const edge_count = edges.length;
|
|
71231
71357
|
|
|
71232
71358
|
for (let i = 0; i < edge_count; i++) {
|
|
71233
|
-
|
|
71234
|
-
result[i] = edge;
|
|
71359
|
+
result[i] = edges[i];
|
|
71235
71360
|
}
|
|
71236
71361
|
|
|
71237
71362
|
return edge_count;
|
|
@@ -71352,7 +71477,7 @@ let Graph$1 = class Graph {
|
|
|
71352
71477
|
|
|
71353
71478
|
return r;
|
|
71354
71479
|
}
|
|
71355
|
-
}
|
|
71480
|
+
}
|
|
71356
71481
|
|
|
71357
71482
|
/**
|
|
71358
71483
|
*
|
|
@@ -71361,7 +71486,7 @@ let Graph$1 = class Graph {
|
|
|
71361
71486
|
* @return {Graph}
|
|
71362
71487
|
*/
|
|
71363
71488
|
function computeSystemComponentDependencyGraph(system_count, systems) {
|
|
71364
|
-
const dependency_graph = new Graph
|
|
71489
|
+
const dependency_graph = new Graph();
|
|
71365
71490
|
|
|
71366
71491
|
for (let i = 0; i < system_count; i++) {
|
|
71367
71492
|
const system = systems[i];
|
|
@@ -86097,564 +86222,6 @@ class PeriodicConsolePrinter {
|
|
|
86097
86222
|
}
|
|
86098
86223
|
}
|
|
86099
86224
|
|
|
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
86225
|
/**
|
|
86659
86226
|
* Contains serializers for various data types as well as data upgraders which enable support for serialization format changes
|
|
86660
86227
|
*/
|
|
@@ -86691,23 +86258,25 @@ class BinarySerializationRegistry {
|
|
|
86691
86258
|
*/
|
|
86692
86259
|
registerAdapter(adapter, className) {
|
|
86693
86260
|
|
|
86694
|
-
|
|
86261
|
+
let _className = className;
|
|
86262
|
+
|
|
86263
|
+
if (_className === undefined) {
|
|
86695
86264
|
const klass = adapter.getClass();
|
|
86696
86265
|
|
|
86697
86266
|
if (typeof klass.typeName === "string") {
|
|
86698
|
-
|
|
86267
|
+
_className = klass.typeName;
|
|
86699
86268
|
} else {
|
|
86700
86269
|
throw new Error(`className not specified, could not infer class name from the class itself`);
|
|
86701
86270
|
}
|
|
86702
86271
|
}
|
|
86703
86272
|
|
|
86704
|
-
if (this.serializers.has(
|
|
86273
|
+
if (this.serializers.has(_className)) {
|
|
86705
86274
|
//a serializer already exists
|
|
86706
86275
|
|
|
86707
86276
|
return false;
|
|
86708
86277
|
}
|
|
86709
86278
|
|
|
86710
|
-
this.serializers.set(
|
|
86279
|
+
this.serializers.set(_className, adapter);
|
|
86711
86280
|
|
|
86712
86281
|
return true;
|
|
86713
86282
|
}
|
|
@@ -116362,7 +115931,7 @@ class Uint32Heap {
|
|
|
116362
115931
|
const size = this.__size;
|
|
116363
115932
|
|
|
116364
115933
|
while (true) {
|
|
116365
|
-
const l = (
|
|
115934
|
+
const l = (i << 1) + 1;
|
|
116366
115935
|
const r = l + 1;
|
|
116367
115936
|
|
|
116368
115937
|
let smallest = i;
|
|
@@ -116484,6 +116053,15 @@ class Uint32Heap {
|
|
|
116484
116053
|
return -1;
|
|
116485
116054
|
}
|
|
116486
116055
|
|
|
116056
|
+
/**
|
|
116057
|
+
*
|
|
116058
|
+
* @param {number} id
|
|
116059
|
+
* @returns {boolean}
|
|
116060
|
+
*/
|
|
116061
|
+
contains(id){
|
|
116062
|
+
return this.find_index_by_id(id) !== -1;
|
|
116063
|
+
}
|
|
116064
|
+
|
|
116487
116065
|
/**
|
|
116488
116066
|
* Clear out all the data, heap will be made empty
|
|
116489
116067
|
*/
|
|
@@ -116649,7 +116227,7 @@ function index2point(result, index, width) {
|
|
|
116649
116227
|
* @param {number} height
|
|
116650
116228
|
* @returns {number}
|
|
116651
116229
|
*/
|
|
116652
|
-
function
|
|
116230
|
+
function compute_neighbors(result, index, width, height) {
|
|
116653
116231
|
const x = index % width;
|
|
116654
116232
|
const y = (index / width) | 0;
|
|
116655
116233
|
|
|
@@ -116659,14 +116237,17 @@ function computeNeighbors(result, index, width, height) {
|
|
|
116659
116237
|
result[neighbour_count] = index - width;
|
|
116660
116238
|
neighbour_count++;
|
|
116661
116239
|
}
|
|
116240
|
+
|
|
116662
116241
|
if (x > 0) {
|
|
116663
116242
|
result[neighbour_count] = index - 1;
|
|
116664
116243
|
neighbour_count++;
|
|
116665
116244
|
}
|
|
116245
|
+
|
|
116666
116246
|
if (x < width - 1) {
|
|
116667
116247
|
result[neighbour_count] = index + 1;
|
|
116668
116248
|
neighbour_count++;
|
|
116669
116249
|
}
|
|
116250
|
+
|
|
116670
116251
|
if (y < height - 1) {
|
|
116671
116252
|
result[neighbour_count] = index + width;
|
|
116672
116253
|
neighbour_count++;
|
|
@@ -116683,7 +116264,7 @@ function computeNeighbors(result, index, width, height) {
|
|
|
116683
116264
|
* @param {number} height
|
|
116684
116265
|
* @returns {number[]}
|
|
116685
116266
|
*/
|
|
116686
|
-
function
|
|
116267
|
+
function compute_path(node, g_score, width, height) {
|
|
116687
116268
|
let v_previous = new Vector2(-1, -1);
|
|
116688
116269
|
let v_current = new Vector2();
|
|
116689
116270
|
|
|
@@ -116734,7 +116315,7 @@ function pathTo(node, g_score, width, height) {
|
|
|
116734
116315
|
v_current = t;
|
|
116735
116316
|
|
|
116736
116317
|
// find next point
|
|
116737
|
-
const neighbour_count =
|
|
116318
|
+
const neighbour_count = compute_neighbors(neighbors, current, width, height);
|
|
116738
116319
|
|
|
116739
116320
|
current = -1;
|
|
116740
116321
|
|
|
@@ -116789,15 +116370,15 @@ function heuristic(index0, index1, width) {
|
|
|
116789
116370
|
const x1 = index0 % width;
|
|
116790
116371
|
const y1 = (index0 / width) | 0;
|
|
116791
116372
|
|
|
116792
|
-
//
|
|
116793
116373
|
const x2 = index1 % width;
|
|
116794
116374
|
const y2 = (index1 / width) | 0;
|
|
116795
116375
|
|
|
116796
|
-
//
|
|
116797
|
-
const dx =
|
|
116798
|
-
const dy =
|
|
116376
|
+
// deltas
|
|
116377
|
+
const dx = x2 - x1;
|
|
116378
|
+
const dy = y2 - y1;
|
|
116799
116379
|
|
|
116800
|
-
|
|
116380
|
+
// we skip expensive SQRT, but still get a good guiding heuristic which has the same monotonic order
|
|
116381
|
+
return dx * dx + dy * dy;
|
|
116801
116382
|
}
|
|
116802
116383
|
|
|
116803
116384
|
|
|
@@ -116813,16 +116394,16 @@ closed.preventShrink();
|
|
|
116813
116394
|
* @param {number} height
|
|
116814
116395
|
* @param {number} start
|
|
116815
116396
|
* @param {number} goal
|
|
116816
|
-
* @param {number}
|
|
116817
|
-
* @param {number}
|
|
116397
|
+
* @param {number} crossing_penalty
|
|
116398
|
+
* @param {number} block_value value in the field that signifies impassible obstacle
|
|
116818
116399
|
* @returns {Array.<number>} array of indices representing path from start to end
|
|
116819
116400
|
*/
|
|
116820
116401
|
function find_path_on_grid_astar(
|
|
116821
116402
|
field,
|
|
116822
116403
|
width, height,
|
|
116823
116404
|
start, goal,
|
|
116824
|
-
|
|
116825
|
-
|
|
116405
|
+
crossing_penalty,
|
|
116406
|
+
block_value
|
|
116826
116407
|
) {
|
|
116827
116408
|
|
|
116828
116409
|
// prepare sets
|
|
@@ -116846,15 +116427,15 @@ function find_path_on_grid_astar(
|
|
|
116846
116427
|
const currentNode = open.pop_min();
|
|
116847
116428
|
|
|
116848
116429
|
if (currentNode === goal) {
|
|
116849
|
-
// End case
|
|
116850
|
-
return
|
|
116430
|
+
// End case - result has been found, return the traced path.
|
|
116431
|
+
return compute_path(currentNode, g_score, width, height);
|
|
116851
116432
|
}
|
|
116852
116433
|
|
|
116853
116434
|
// Normal case -- move currentNode from open to closed, process each of its neighbors.
|
|
116854
116435
|
closed.set(currentNode, true);
|
|
116855
116436
|
|
|
116856
116437
|
// Find all neighbors for the current node.
|
|
116857
|
-
const neighbour_count =
|
|
116438
|
+
const neighbour_count = compute_neighbors(neighbors, currentNode, width, height);
|
|
116858
116439
|
|
|
116859
116440
|
for (let i = 0; i < neighbour_count; ++i) {
|
|
116860
116441
|
const neighbor = neighbors[i];
|
|
@@ -116866,39 +116447,39 @@ function find_path_on_grid_astar(
|
|
|
116866
116447
|
|
|
116867
116448
|
// The g score is the shortest distance from start to current node.
|
|
116868
116449
|
// We need to check if the path we have arrived at this neighbor is the shortest one we have seen yet.
|
|
116869
|
-
const
|
|
116450
|
+
const neighbor_value = field[neighbor];
|
|
116870
116451
|
|
|
116871
|
-
if (
|
|
116452
|
+
if (neighbor_value === block_value) {
|
|
116872
116453
|
//cell is blocked, close and continue
|
|
116873
116454
|
closed.set(neighbor, true);
|
|
116874
116455
|
continue;
|
|
116875
116456
|
}
|
|
116876
116457
|
|
|
116877
116458
|
// Cost of traversing to this neighbour
|
|
116878
|
-
const transition_cost =
|
|
116459
|
+
const transition_cost = neighbor_value * crossing_penalty + 1;
|
|
116879
116460
|
|
|
116880
116461
|
// updated path cost
|
|
116881
|
-
const
|
|
116462
|
+
const cost_so_far = g_score[currentNode] + transition_cost;
|
|
116882
116463
|
|
|
116883
116464
|
const index_in_open_set = open.find_index_by_id(neighbor);
|
|
116884
116465
|
|
|
116885
116466
|
const not_in_open_set = index_in_open_set === -1;
|
|
116886
116467
|
|
|
116887
|
-
if (not_in_open_set ||
|
|
116468
|
+
if (not_in_open_set || cost_so_far < g_score[neighbor]) {
|
|
116888
116469
|
|
|
116889
116470
|
// update refined score
|
|
116890
|
-
g_score[neighbor] =
|
|
116471
|
+
g_score[neighbor] = cost_so_far;
|
|
116891
116472
|
|
|
116892
|
-
const
|
|
116473
|
+
const remaining_heuristic = heuristic(neighbor, goal, width);
|
|
116893
116474
|
|
|
116894
|
-
const
|
|
116475
|
+
const refined_heuristic = cost_so_far + remaining_heuristic;
|
|
116895
116476
|
|
|
116896
116477
|
if (not_in_open_set) {
|
|
116897
116478
|
// Pushing to heap will put it in proper place based on the 'f' value.
|
|
116898
|
-
open.insert(neighbor,
|
|
116479
|
+
open.insert(neighbor, refined_heuristic);
|
|
116899
116480
|
} else {
|
|
116900
116481
|
// 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,
|
|
116482
|
+
open.__update_score_by_index(index_in_open_set, refined_heuristic);
|
|
116902
116483
|
}
|
|
116903
116484
|
}
|
|
116904
116485
|
}
|