@woosh/meep-engine 2.134.5 → 2.135.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/bundle-worker-image-decoder.js +1 -1
- package/build/bundle-worker-terrain.js +1 -1
- package/editor/tools/v2/TransformControlsGizmo.js +1 -1
- package/editor/view/node-graph/NodeGraphEditorView.js +2 -2
- package/package.json +1 -1
- package/src/core/assert.d.ts +0 -2
- package/src/core/assert.d.ts.map +1 -1
- package/src/core/assert.js +0 -6
- package/src/core/color/Color.d.ts +0 -5
- package/src/core/color/Color.d.ts.map +1 -1
- package/src/core/color/Color.js +1 -7
- package/src/core/geom/2d/hash-grid/SpatialHashGrid.js +386 -386
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_2d.js +1 -1
- package/src/core/geom/2d/quad-tree-binary/QuadTree.js +714 -714
- package/src/core/geom/3d/triangle/computeTriangleRayIntersection.js +160 -160
- package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js +96 -96
- package/src/core/geom/packing/max-rect/MaxRectanglesPacker.js +1 -1
- package/src/core/geom/packing/max-rect/findBestContainer.js +4 -4
- package/src/core/geom/packing/max-rect/packOneBox.js +2 -2
- package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.js +1 -1
- package/src/core/graph/layout/box/BoxLayouter.js +7 -7
- package/src/core/graph/layout/box/position_box_next_to_box.js +6 -6
- package/src/core/math/computeWholeDivisorLow.js +33 -33
- package/src/core/math/linalg/eigen/eigen_values_find_spectral_gap.d.ts.map +1 -0
- package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts +10 -0
- package/src/core/math/linalg/eigen/matrix_eigenvalues_in_place.d.ts.map +1 -0
- package/src/core/{graph → math/linalg}/eigen/matrix_eigenvalues_in_place.js +8 -7
- package/src/core/math/linalg/eigen/matrix_householder_in_place.d.ts.map +1 -0
- package/src/core/{graph → math/linalg}/eigen/matrix_householder_in_place.js +11 -5
- package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts +15 -0
- package/src/core/math/linalg/eigen/matrix_qr_in_place.d.ts.map +1 -0
- package/src/core/{graph → math/linalg}/eigen/matrix_qr_in_place.js +8 -2
- package/src/core/{graph → math/linalg}/eigen/matrix_top_eigenvector_power_iteration.d.ts +0 -3
- package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +1 -0
- package/src/core/{graph → math/linalg}/eigen/matrix_top_eigenvector_power_iteration.js +0 -3
- package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts +19 -0
- package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.d.ts.map +1 -0
- package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.js +161 -0
- package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts +15 -0
- package/src/core/math/linalg/polynomial_real_roots_in_interval.d.ts.map +1 -0
- package/src/core/math/linalg/polynomial_real_roots_in_interval.js +200 -0
- package/src/core/math/solveCubic.d.ts +15 -0
- package/src/core/math/solveCubic.d.ts.map +1 -0
- package/src/core/math/solveCubic.js +82 -0
- package/src/core/math/spline/spline3_hermite_bounds_t.d.ts +23 -0
- package/src/core/math/spline/spline3_hermite_bounds_t.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_bounds_t.js +109 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts +25 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite.js +44 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts +16 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.js +120 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts +11 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_2d.js +451 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts +12 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_nd.js +339 -0
- package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts +15 -0
- package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.js +21 -0
- package/src/core/math/spline/spline3_hermite_to_monomial.d.ts +24 -0
- package/src/core/math/spline/spline3_hermite_to_monomial.d.ts.map +1 -0
- package/src/core/math/spline/spline3_hermite_to_monomial.js +37 -0
- package/src/core/math/spline/v3_computeCatmullRomSplineUniformDistance.js +1 -1
- package/src/core/model/node-graph/visual/NodeGraphVisualData.js +1 -1
- package/src/core/model/reactive/model/util/createRandomReactiveExpression.js +185 -185
- package/src/core/process/delay.js +16 -16
- package/src/engine/animation/async/TimeSeries.js +300 -300
- package/src/engine/animation/curve/AnimationCurve.d.ts +0 -4
- package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
- package/src/engine/animation/curve/AnimationCurve.js +1 -6
- package/src/engine/animation/curve/draw/position_canvas_to_curve.js +2 -2
- package/src/engine/animation/curve/draw/position_curve_to_canvas.js +2 -2
- package/src/engine/ecs/fow/shader/FogOfWarRenderer.js +145 -145
- package/src/engine/ecs/gui/position/ViewportPositionSystem.js +2 -2
- package/src/engine/ecs/parent/entity_node_compute_bounding_box.js +1 -1
- package/src/engine/ecs/transform/Transform.d.ts +0 -10
- package/src/engine/ecs/transform/Transform.d.ts.map +1 -1
- package/src/engine/ecs/transform/Transform.js +0 -12
- package/src/engine/graphics/composit/CompositLayer.js +254 -254
- package/src/engine/graphics/ecs/mesh-v2/sg_hierarchy_compute_bounding_box_via_parent_entity.js +1 -1
- package/src/engine/graphics/ecs/path/tube/build/build_geometry_linear.js +2 -2
- package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +3 -3
- package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +201 -201
- package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -1
- package/src/engine/graphics/render/buffer/slot/parameter/ProgramValueSlotParameterSet.js +2 -2
- package/src/engine/graphics/render/forward_plus/LightManager.js +1226 -1226
- package/src/engine/graphics/render/forward_plus/model/PointLight.js +1 -1
- package/src/engine/graphics/sh3/lpv/lpv_obtain_storage_cached_volume.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +2 -2
- package/src/engine/graphics/texture/atlas/TextureAtlasDebugger.js +1 -1
- package/src/engine/graphics/texture/sampler/HarmonicDiffusionGrid.js +145 -145
- package/src/engine/graphics/texture/sampler/serialization/TextureBinaryBufferSerializer.js +2 -2
- package/src/engine/intelligence/behavior/ecs/BehaviorComponent.d.ts +2 -6
- package/src/engine/intelligence/behavior/ecs/BehaviorComponent.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/ecs/BehaviorComponent.js +0 -10
- package/src/engine/intelligence/mcts/MonteCarlo.js +275 -275
- package/src/engine/navigation/ecs/path_following/PathFollower.js +222 -222
- package/src/generation/grid/GridData.js +220 -220
- package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +385 -385
- package/src/view/elements/image/SvgImageView.js +1 -1
- package/src/view/elements/windrose/WindRoseDiagram.js +369 -369
- package/src/view/minimap/gl/MinimapFogOfWar.js +3 -3
- package/src/view/util/DomSizeObserver.js +1 -1
- package/src/core/binary/clz32.d.ts +0 -6
- package/src/core/binary/clz32.d.ts.map +0 -1
- package/src/core/binary/clz32.js +0 -5
- package/src/core/binary/type/dataTypeFromTypedArray.d.ts +0 -8
- package/src/core/binary/type/dataTypeFromTypedArray.d.ts.map +0 -1
- package/src/core/binary/type/dataTypeFromTypedArray.js +0 -11
- package/src/core/collection/array/computeHashIntegerArray.d.ts +0 -1
- package/src/core/collection/array/computeHashIntegerArray.d.ts.map +0 -1
- package/src/core/collection/array/computeHashIntegerArray.js +0 -7
- package/src/core/collection/array/typed/typedArrayToDataType.d.ts +0 -6
- package/src/core/collection/array/typed/typedArrayToDataType.d.ts.map +0 -1
- package/src/core/collection/array/typed/typedArrayToDataType.js +0 -6
- package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.d.ts +0 -6
- package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.d.ts.map +0 -1
- package/src/core/geom/3d/mat4/MATRIX_4_IDENTITY.js +0 -7
- package/src/core/graph/eigen/eigen_values_find_spectral_gap.d.ts.map +0 -1
- package/src/core/graph/eigen/matrix_eigenvalues_in_place.d.ts +0 -8
- package/src/core/graph/eigen/matrix_eigenvalues_in_place.d.ts.map +0 -1
- package/src/core/graph/eigen/matrix_householder_in_place.d.ts.map +0 -1
- package/src/core/graph/eigen/matrix_qr_in_place.d.ts +0 -9
- package/src/core/graph/eigen/matrix_qr_in_place.d.ts.map +0 -1
- package/src/core/graph/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +0 -1
- package/src/core/math/spline/cubicCurve.d.ts +0 -6
- package/src/core/math/spline/cubicCurve.d.ts.map +0 -1
- package/src/core/math/spline/cubicCurve.js +0 -6
- package/src/core/math/spline/spline_bezier2.d.ts +0 -6
- package/src/core/math/spline/spline_bezier2.d.ts.map +0 -1
- package/src/core/math/spline/spline_bezier2.js +0 -6
- package/src/core/math/spline/spline_bezier3.d.ts +0 -6
- package/src/core/math/spline/spline_bezier3.d.ts.map +0 -1
- package/src/core/math/spline/spline_bezier3.js +0 -6
- package/src/core/math/spline/spline_bezier3_bounds.d.ts +0 -6
- package/src/core/math/spline/spline_bezier3_bounds.d.ts.map +0 -1
- package/src/core/math/spline/spline_bezier3_bounds.js +0 -6
- package/src/core/math/spline/spline_hermite3.d.ts +0 -6
- package/src/core/math/spline/spline_hermite3.d.ts.map +0 -1
- package/src/core/math/spline/spline_hermite3.js +0 -6
- package/src/core/math/spline/spline_hermite3_bounds.d.ts +0 -6
- package/src/core/math/spline/spline_hermite3_bounds.d.ts.map +0 -1
- package/src/core/math/spline/spline_hermite3_bounds.js +0 -6
- package/src/core/math/spline/spline_hermite3_to_bezier.d.ts +0 -2
- package/src/core/math/spline/spline_hermite3_to_bezier.d.ts.map +0 -1
- package/src/core/math/spline/spline_hermite3_to_bezier.js +0 -6
- package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.d.ts +0 -37
- package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.d.ts.map +0 -1
- package/src/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.js +0 -70
- /package/src/core/{graph → math/linalg}/eigen/eigen_values_find_spectral_gap.d.ts +0 -0
- /package/src/core/{graph → math/linalg}/eigen/eigen_values_find_spectral_gap.js +0 -0
- /package/src/core/{graph → math/linalg}/eigen/matrix_householder_in_place.d.ts +0 -0
|
@@ -1,387 +1,387 @@
|
|
|
1
|
-
import { assert } from "../../../assert.js";
|
|
2
|
-
import { UINT32_MAX } from "../../../binary/UINT32_MAX.js";
|
|
3
|
-
import { clamp } from "../../../math/clamp.js";
|
|
4
|
-
import { BinaryElementPool } from "../../3d/topology/struct/binary/BinaryElementPool.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export const NULL_POINTER = UINT32_MAX;
|
|
8
|
-
/**
|
|
9
|
-
* Single-linked list
|
|
10
|
-
* Pointer to next NODE in the same grid cell
|
|
11
|
-
* @type {number}
|
|
12
|
-
*/
|
|
13
|
-
const COLUMN_NODE_SAME_NODE_NEXT = 0;
|
|
14
|
-
/**
|
|
15
|
-
* Single-linked list
|
|
16
|
-
* Pointer to next NODE containing the same element
|
|
17
|
-
* @type {number}
|
|
18
|
-
*/
|
|
19
|
-
const COLUMN_NODE_SAME_ELEMENT_NEXT = 1;
|
|
20
|
-
/**
|
|
21
|
-
* Pointer to ELEMENT
|
|
22
|
-
* @type {number}
|
|
23
|
-
*/
|
|
24
|
-
const COLUMN_NODE_ELEMENT = 2;
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Points to grid cell that stores this node
|
|
28
|
-
* @type {number}
|
|
29
|
-
*/
|
|
30
|
-
const COLUMN_NODE_GRID_INDEX = 3;
|
|
31
|
-
|
|
32
|
-
const COLUMN_ELEMENT_DATA = 0;
|
|
33
|
-
const COLUMN_ELEMENT_NODE_FIRST = 1;
|
|
34
|
-
export const COLUMN_ELEMENT_X0 = 2;
|
|
35
|
-
export const COLUMN_ELEMENT_Y0 = 3;
|
|
36
|
-
export const COLUMN_ELEMENT_X1 = 4;
|
|
37
|
-
export const COLUMN_ELEMENT_Y1 = 5;
|
|
38
|
-
|
|
39
|
-
export class SpatialHashGrid {
|
|
40
|
-
#element_pool = new BinaryElementPool(24)
|
|
41
|
-
#node_pool = new BinaryElementPool(16);
|
|
42
|
-
#grid_data = new Uint32Array(0);
|
|
43
|
-
|
|
44
|
-
#size_x = 0;
|
|
45
|
-
#size_y = 0;
|
|
46
|
-
|
|
47
|
-
#scale = 1;
|
|
48
|
-
#scale_inverse = 1;
|
|
49
|
-
|
|
50
|
-
get size_x() {
|
|
51
|
-
return this.#size_x;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
get size_y() {
|
|
55
|
-
return this.#size_y;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
get node_pool() {
|
|
59
|
-
return this.#node_pool;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
*
|
|
64
|
-
* @return {BinaryElementPool}
|
|
65
|
-
*/
|
|
66
|
-
get element_pool() {
|
|
67
|
-
return this.#element_pool;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
get scale() {
|
|
71
|
-
return this.#scale;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
get scale_inverse() {
|
|
75
|
-
return this.#scale_inverse;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
constructor(size_x = 1, size_y = 1, scale = 8) {
|
|
79
|
-
|
|
80
|
-
assert.notNaN(scale, "scale");
|
|
81
|
-
assert.
|
|
82
|
-
assert.greaterThan(scale, 0, 'scale must be greater than 0');
|
|
83
|
-
|
|
84
|
-
this.#size_x = size_x;
|
|
85
|
-
this.#size_y = size_y;
|
|
86
|
-
this.#scale = scale;
|
|
87
|
-
this.#scale_inverse = 1 / scale;
|
|
88
|
-
|
|
89
|
-
this.#build();
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
#build() {
|
|
93
|
-
this.#grid_data = new Uint32Array(this.#size_x * this.#size_y);
|
|
94
|
-
|
|
95
|
-
this.#grid_data.fill(NULL_POINTER);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
element_allocate() {
|
|
99
|
-
const element = this.#element_pool.allocate();
|
|
100
|
-
|
|
101
|
-
return element;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
element_set_user_data(element, user_data) {
|
|
105
|
-
const pool = this.#element_pool;
|
|
106
|
-
const address = pool.element_word(element);
|
|
107
|
-
|
|
108
|
-
pool.data_uint32[address + COLUMN_ELEMENT_DATA] = user_data;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
element_get_user_data(element) {
|
|
112
|
-
const pool = this.#element_pool;
|
|
113
|
-
const address = pool.element_word(element);
|
|
114
|
-
|
|
115
|
-
return pool.data_uint32[address + COLUMN_ELEMENT_DATA];
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* You have to remove the element from the grid before changing its bounds
|
|
120
|
-
* @param {number} element
|
|
121
|
-
* @param {number} x0
|
|
122
|
-
* @param {number} y0
|
|
123
|
-
* @param {number} x1
|
|
124
|
-
* @param {number} y1
|
|
125
|
-
*/
|
|
126
|
-
element_set_bounds_primitive(element, x0, y0, x1, y1) {
|
|
127
|
-
const pool = this.#element_pool;
|
|
128
|
-
const address = pool.element_word(element);
|
|
129
|
-
|
|
130
|
-
const float32 = pool.data_float32;
|
|
131
|
-
|
|
132
|
-
float32[address + COLUMN_ELEMENT_X0] = x0;
|
|
133
|
-
float32[address + COLUMN_ELEMENT_Y0] = y0;
|
|
134
|
-
float32[address + COLUMN_ELEMENT_X1] = x1;
|
|
135
|
-
float32[address + COLUMN_ELEMENT_Y1] = y1;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
*
|
|
140
|
-
* @param {number} element
|
|
141
|
-
*/
|
|
142
|
-
element_release(element) {
|
|
143
|
-
this.#element_pool.release(element);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
*
|
|
148
|
-
* @param {number} element
|
|
149
|
-
*/
|
|
150
|
-
element_insert(element) {
|
|
151
|
-
const pool = this.#element_pool;
|
|
152
|
-
const address = pool.element_word(element);
|
|
153
|
-
|
|
154
|
-
const uint32 = pool.data_uint32;
|
|
155
|
-
|
|
156
|
-
// make sure that we don't point at anything yet
|
|
157
|
-
uint32[address + COLUMN_ELEMENT_NODE_FIRST] = NULL_POINTER;
|
|
158
|
-
|
|
159
|
-
const float32 = pool.data_float32;
|
|
160
|
-
|
|
161
|
-
const x0 = float32[address + COLUMN_ELEMENT_X0];
|
|
162
|
-
const y0 = float32[address + COLUMN_ELEMENT_Y0];
|
|
163
|
-
const x1 = float32[address + COLUMN_ELEMENT_X1];
|
|
164
|
-
const y1 = float32[address + COLUMN_ELEMENT_Y1];
|
|
165
|
-
|
|
166
|
-
// convert to grid coordinates
|
|
167
|
-
const grid_x0 = Math.floor(x0 * this.#scale_inverse);
|
|
168
|
-
const grid_y0 = Math.floor(y0 * this.#scale_inverse);
|
|
169
|
-
|
|
170
|
-
const grid_x1 = Math.floor(x1 * this.#scale_inverse);
|
|
171
|
-
const grid_y1 = Math.floor(y1 * this.#scale_inverse);
|
|
172
|
-
|
|
173
|
-
for (let y = grid_y0; y <= grid_y1; y++) {
|
|
174
|
-
for (let x = grid_x0; x <= grid_x1; x++) {
|
|
175
|
-
this.#element_insert_into_cell(element, x, y);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
*
|
|
182
|
-
* @param {number} node
|
|
183
|
-
* @return {number}
|
|
184
|
-
*/
|
|
185
|
-
node_get_element(node) {
|
|
186
|
-
const address = this.#node_pool.element_word(node);
|
|
187
|
-
return this.#node_pool.data_uint32[address + COLUMN_NODE_ELEMENT];
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Next element in the linked list of cell's nodes
|
|
192
|
-
* @param {number} node
|
|
193
|
-
* @return {number}
|
|
194
|
-
*/
|
|
195
|
-
node_get_same_cell_next_node(node) {
|
|
196
|
-
const address = this.#node_pool.element_word(node);
|
|
197
|
-
|
|
198
|
-
return this.#node_pool.data_uint32[address + COLUMN_NODE_SAME_NODE_NEXT];
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
*
|
|
203
|
-
* @param {number} cell_index
|
|
204
|
-
* @return {number}
|
|
205
|
-
*/
|
|
206
|
-
cell_get_first_node(cell_index) {
|
|
207
|
-
assert.lessThan(cell_index, this.#size_x * this.#size_y);
|
|
208
|
-
|
|
209
|
-
return this.#grid_data[cell_index]
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
*
|
|
214
|
-
* @param {number} x
|
|
215
|
-
* @param {number} y
|
|
216
|
-
* @return {number}
|
|
217
|
-
*/
|
|
218
|
-
world_position_to_cell_index(x, y) {
|
|
219
|
-
const grid_x = clamp(Math.floor(x * this.#scale_inverse), 0, this.#size_x - 1);
|
|
220
|
-
const grid_y = clamp(Math.floor(y * this.#scale_inverse), 0, this.#size_y - 1);
|
|
221
|
-
|
|
222
|
-
return this.cell_position_to_index(grid_x, grid_y);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
*
|
|
227
|
-
* @param {number} x
|
|
228
|
-
* @param {number} y
|
|
229
|
-
* @returns {number}
|
|
230
|
-
*/
|
|
231
|
-
cell_position_to_index(x, y) {
|
|
232
|
-
assert.isNonNegativeInteger(x, 'x');
|
|
233
|
-
assert.isNonNegativeInteger(y, 'y');
|
|
234
|
-
|
|
235
|
-
return y * this.#size_x + x;
|
|
236
|
-
|
|
237
|
-
// const cell_count = this.#size_x * this.#size_y;
|
|
238
|
-
//
|
|
239
|
-
// const _x = split_by_2(x);
|
|
240
|
-
// const _y = split_by_2(y);
|
|
241
|
-
//
|
|
242
|
-
// const hash = _x | (_y << 1);
|
|
243
|
-
//
|
|
244
|
-
// return hash % cell_count;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
*
|
|
249
|
-
* @param {number} cell_x
|
|
250
|
-
* @param {number} cell_y
|
|
251
|
-
* @return {boolean}
|
|
252
|
-
*/
|
|
253
|
-
is_cell_empty(cell_x, cell_y) {
|
|
254
|
-
assert.isNonNegativeInteger(cell_x, 'cell_x');
|
|
255
|
-
assert.lessThan(cell_x, this.#size_x, 'cell_x overflow');
|
|
256
|
-
|
|
257
|
-
assert.isNonNegativeInteger(cell_y, 'cell_y');
|
|
258
|
-
assert.lessThan(cell_y, this.#size_y, 'cell_y overflow');
|
|
259
|
-
|
|
260
|
-
const index = this.cell_position_to_index(cell_x, cell_y);
|
|
261
|
-
|
|
262
|
-
const grid = this.#grid_data;
|
|
263
|
-
|
|
264
|
-
return grid[index] === NULL_POINTER;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
*
|
|
269
|
-
* @param {number} element
|
|
270
|
-
* @param {number} grid_x
|
|
271
|
-
* @param {number} grid_y
|
|
272
|
-
*/
|
|
273
|
-
#element_insert_into_cell(element, grid_x, grid_y) {
|
|
274
|
-
|
|
275
|
-
// create a node
|
|
276
|
-
const node_pool = this.#node_pool;
|
|
277
|
-
const node = node_pool.allocate();
|
|
278
|
-
|
|
279
|
-
const node_address = node_pool.element_word(node);
|
|
280
|
-
const node_data_uint32 = node_pool.data_uint32;
|
|
281
|
-
|
|
282
|
-
node_data_uint32[node_address + COLUMN_NODE_ELEMENT] = element;
|
|
283
|
-
|
|
284
|
-
// link node to the element
|
|
285
|
-
const element_pool = this.#element_pool;
|
|
286
|
-
const element_address = element_pool.element_word(element);
|
|
287
|
-
|
|
288
|
-
const element_data_uint32 = element_pool.data_uint32;
|
|
289
|
-
|
|
290
|
-
const element_first_node = element_data_uint32[element_address + COLUMN_ELEMENT_NODE_FIRST];
|
|
291
|
-
|
|
292
|
-
// point to previous first
|
|
293
|
-
node_data_uint32[node_address + COLUMN_NODE_SAME_ELEMENT_NEXT] = element_first_node;
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
element_data_uint32[element_address + COLUMN_ELEMENT_NODE_FIRST] = node;
|
|
297
|
-
|
|
298
|
-
// link node to the cell
|
|
299
|
-
const cell_index = this.cell_position_to_index(grid_x, grid_y);
|
|
300
|
-
|
|
301
|
-
node_data_uint32[node_address + COLUMN_NODE_GRID_INDEX] = cell_index;
|
|
302
|
-
|
|
303
|
-
const grid_data = this.#grid_data;
|
|
304
|
-
|
|
305
|
-
const cell_first_node = grid_data[cell_index];
|
|
306
|
-
|
|
307
|
-
node_data_uint32[node_address + COLUMN_NODE_SAME_NODE_NEXT] = cell_first_node;
|
|
308
|
-
|
|
309
|
-
grid_data[cell_index] = node;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
*
|
|
314
|
-
* @param {number} cell_index
|
|
315
|
-
* @param {number} node
|
|
316
|
-
* @returns {boolean}
|
|
317
|
-
*/
|
|
318
|
-
#grid_cell_remove_node(cell_index, node) {
|
|
319
|
-
assert.isNonNegativeInteger(cell_index, 'cell_index');
|
|
320
|
-
assert.isNonNegativeInteger(node, 'node');
|
|
321
|
-
|
|
322
|
-
const pool = this.#node_pool;
|
|
323
|
-
const node_data_uint32 = pool.data_uint32;
|
|
324
|
-
|
|
325
|
-
const grid_data = this.#grid_data;
|
|
326
|
-
let n = grid_data[cell_index]
|
|
327
|
-
let previous = NULL_POINTER;
|
|
328
|
-
|
|
329
|
-
while (n !== NULL_POINTER) {
|
|
330
|
-
const address = pool.element_word(n);
|
|
331
|
-
const next = node_data_uint32[address + COLUMN_NODE_SAME_NODE_NEXT];
|
|
332
|
-
|
|
333
|
-
if (n === node) {
|
|
334
|
-
// found the node to cut
|
|
335
|
-
|
|
336
|
-
if (previous === NULL_POINTER) {
|
|
337
|
-
// first element in the list
|
|
338
|
-
grid_data[cell_index] = next;
|
|
339
|
-
} else {
|
|
340
|
-
const previous_address = pool.element_word(previous);
|
|
341
|
-
|
|
342
|
-
node_data_uint32[previous_address + COLUMN_NODE_SAME_NODE_NEXT] = next;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
return true;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
previous = n;
|
|
349
|
-
n = next;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
return false;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
*
|
|
357
|
-
* @param {number} element
|
|
358
|
-
*/
|
|
359
|
-
element_remove(element) {
|
|
360
|
-
assert.isNonNegativeInteger(element, 'element');
|
|
361
|
-
|
|
362
|
-
const element_pool = this.#element_pool;
|
|
363
|
-
const address = element_pool.element_word(element);
|
|
364
|
-
|
|
365
|
-
let node = element_pool.data_uint32[address + COLUMN_ELEMENT_NODE_FIRST];
|
|
366
|
-
|
|
367
|
-
const node_pool = this.#node_pool;
|
|
368
|
-
const node_data_uint32 = node_pool.data_uint32;
|
|
369
|
-
|
|
370
|
-
do {
|
|
371
|
-
|
|
372
|
-
const node_address = node_pool.element_word(node);
|
|
373
|
-
|
|
374
|
-
const next = node_data_uint32[node_address + COLUMN_NODE_SAME_ELEMENT_NEXT];
|
|
375
|
-
|
|
376
|
-
const grid_index = node_data_uint32[node_address + COLUMN_NODE_GRID_INDEX];
|
|
377
|
-
|
|
378
|
-
// cut this node from CELL list
|
|
379
|
-
this.#grid_cell_remove_node(grid_index, node);
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
// advance onto next
|
|
383
|
-
node = next;
|
|
384
|
-
} while (node !== NULL_POINTER)
|
|
385
|
-
|
|
386
|
-
}
|
|
1
|
+
import { assert } from "../../../assert.js";
|
|
2
|
+
import { UINT32_MAX } from "../../../binary/UINT32_MAX.js";
|
|
3
|
+
import { clamp } from "../../../math/clamp.js";
|
|
4
|
+
import { BinaryElementPool } from "../../3d/topology/struct/binary/BinaryElementPool.js";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export const NULL_POINTER = UINT32_MAX;
|
|
8
|
+
/**
|
|
9
|
+
* Single-linked list
|
|
10
|
+
* Pointer to next NODE in the same grid cell
|
|
11
|
+
* @type {number}
|
|
12
|
+
*/
|
|
13
|
+
const COLUMN_NODE_SAME_NODE_NEXT = 0;
|
|
14
|
+
/**
|
|
15
|
+
* Single-linked list
|
|
16
|
+
* Pointer to next NODE containing the same element
|
|
17
|
+
* @type {number}
|
|
18
|
+
*/
|
|
19
|
+
const COLUMN_NODE_SAME_ELEMENT_NEXT = 1;
|
|
20
|
+
/**
|
|
21
|
+
* Pointer to ELEMENT
|
|
22
|
+
* @type {number}
|
|
23
|
+
*/
|
|
24
|
+
const COLUMN_NODE_ELEMENT = 2;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Points to grid cell that stores this node
|
|
28
|
+
* @type {number}
|
|
29
|
+
*/
|
|
30
|
+
const COLUMN_NODE_GRID_INDEX = 3;
|
|
31
|
+
|
|
32
|
+
const COLUMN_ELEMENT_DATA = 0;
|
|
33
|
+
const COLUMN_ELEMENT_NODE_FIRST = 1;
|
|
34
|
+
export const COLUMN_ELEMENT_X0 = 2;
|
|
35
|
+
export const COLUMN_ELEMENT_Y0 = 3;
|
|
36
|
+
export const COLUMN_ELEMENT_X1 = 4;
|
|
37
|
+
export const COLUMN_ELEMENT_Y1 = 5;
|
|
38
|
+
|
|
39
|
+
export class SpatialHashGrid {
|
|
40
|
+
#element_pool = new BinaryElementPool(24)
|
|
41
|
+
#node_pool = new BinaryElementPool(16);
|
|
42
|
+
#grid_data = new Uint32Array(0);
|
|
43
|
+
|
|
44
|
+
#size_x = 0;
|
|
45
|
+
#size_y = 0;
|
|
46
|
+
|
|
47
|
+
#scale = 1;
|
|
48
|
+
#scale_inverse = 1;
|
|
49
|
+
|
|
50
|
+
get size_x() {
|
|
51
|
+
return this.#size_x;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get size_y() {
|
|
55
|
+
return this.#size_y;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get node_pool() {
|
|
59
|
+
return this.#node_pool;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @return {BinaryElementPool}
|
|
65
|
+
*/
|
|
66
|
+
get element_pool() {
|
|
67
|
+
return this.#element_pool;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
get scale() {
|
|
71
|
+
return this.#scale;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
get scale_inverse() {
|
|
75
|
+
return this.#scale_inverse;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
constructor(size_x = 1, size_y = 1, scale = 8) {
|
|
79
|
+
|
|
80
|
+
assert.notNaN(scale, "scale");
|
|
81
|
+
assert.isFinite(scale, 'scale');
|
|
82
|
+
assert.greaterThan(scale, 0, 'scale must be greater than 0');
|
|
83
|
+
|
|
84
|
+
this.#size_x = size_x;
|
|
85
|
+
this.#size_y = size_y;
|
|
86
|
+
this.#scale = scale;
|
|
87
|
+
this.#scale_inverse = 1 / scale;
|
|
88
|
+
|
|
89
|
+
this.#build();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
#build() {
|
|
93
|
+
this.#grid_data = new Uint32Array(this.#size_x * this.#size_y);
|
|
94
|
+
|
|
95
|
+
this.#grid_data.fill(NULL_POINTER);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
element_allocate() {
|
|
99
|
+
const element = this.#element_pool.allocate();
|
|
100
|
+
|
|
101
|
+
return element;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
element_set_user_data(element, user_data) {
|
|
105
|
+
const pool = this.#element_pool;
|
|
106
|
+
const address = pool.element_word(element);
|
|
107
|
+
|
|
108
|
+
pool.data_uint32[address + COLUMN_ELEMENT_DATA] = user_data;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
element_get_user_data(element) {
|
|
112
|
+
const pool = this.#element_pool;
|
|
113
|
+
const address = pool.element_word(element);
|
|
114
|
+
|
|
115
|
+
return pool.data_uint32[address + COLUMN_ELEMENT_DATA];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* You have to remove the element from the grid before changing its bounds
|
|
120
|
+
* @param {number} element
|
|
121
|
+
* @param {number} x0
|
|
122
|
+
* @param {number} y0
|
|
123
|
+
* @param {number} x1
|
|
124
|
+
* @param {number} y1
|
|
125
|
+
*/
|
|
126
|
+
element_set_bounds_primitive(element, x0, y0, x1, y1) {
|
|
127
|
+
const pool = this.#element_pool;
|
|
128
|
+
const address = pool.element_word(element);
|
|
129
|
+
|
|
130
|
+
const float32 = pool.data_float32;
|
|
131
|
+
|
|
132
|
+
float32[address + COLUMN_ELEMENT_X0] = x0;
|
|
133
|
+
float32[address + COLUMN_ELEMENT_Y0] = y0;
|
|
134
|
+
float32[address + COLUMN_ELEMENT_X1] = x1;
|
|
135
|
+
float32[address + COLUMN_ELEMENT_Y1] = y1;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
*
|
|
140
|
+
* @param {number} element
|
|
141
|
+
*/
|
|
142
|
+
element_release(element) {
|
|
143
|
+
this.#element_pool.release(element);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
*
|
|
148
|
+
* @param {number} element
|
|
149
|
+
*/
|
|
150
|
+
element_insert(element) {
|
|
151
|
+
const pool = this.#element_pool;
|
|
152
|
+
const address = pool.element_word(element);
|
|
153
|
+
|
|
154
|
+
const uint32 = pool.data_uint32;
|
|
155
|
+
|
|
156
|
+
// make sure that we don't point at anything yet
|
|
157
|
+
uint32[address + COLUMN_ELEMENT_NODE_FIRST] = NULL_POINTER;
|
|
158
|
+
|
|
159
|
+
const float32 = pool.data_float32;
|
|
160
|
+
|
|
161
|
+
const x0 = float32[address + COLUMN_ELEMENT_X0];
|
|
162
|
+
const y0 = float32[address + COLUMN_ELEMENT_Y0];
|
|
163
|
+
const x1 = float32[address + COLUMN_ELEMENT_X1];
|
|
164
|
+
const y1 = float32[address + COLUMN_ELEMENT_Y1];
|
|
165
|
+
|
|
166
|
+
// convert to grid coordinates
|
|
167
|
+
const grid_x0 = Math.floor(x0 * this.#scale_inverse);
|
|
168
|
+
const grid_y0 = Math.floor(y0 * this.#scale_inverse);
|
|
169
|
+
|
|
170
|
+
const grid_x1 = Math.floor(x1 * this.#scale_inverse);
|
|
171
|
+
const grid_y1 = Math.floor(y1 * this.#scale_inverse);
|
|
172
|
+
|
|
173
|
+
for (let y = grid_y0; y <= grid_y1; y++) {
|
|
174
|
+
for (let x = grid_x0; x <= grid_x1; x++) {
|
|
175
|
+
this.#element_insert_into_cell(element, x, y);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
*
|
|
182
|
+
* @param {number} node
|
|
183
|
+
* @return {number}
|
|
184
|
+
*/
|
|
185
|
+
node_get_element(node) {
|
|
186
|
+
const address = this.#node_pool.element_word(node);
|
|
187
|
+
return this.#node_pool.data_uint32[address + COLUMN_NODE_ELEMENT];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Next element in the linked list of cell's nodes
|
|
192
|
+
* @param {number} node
|
|
193
|
+
* @return {number}
|
|
194
|
+
*/
|
|
195
|
+
node_get_same_cell_next_node(node) {
|
|
196
|
+
const address = this.#node_pool.element_word(node);
|
|
197
|
+
|
|
198
|
+
return this.#node_pool.data_uint32[address + COLUMN_NODE_SAME_NODE_NEXT];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
*
|
|
203
|
+
* @param {number} cell_index
|
|
204
|
+
* @return {number}
|
|
205
|
+
*/
|
|
206
|
+
cell_get_first_node(cell_index) {
|
|
207
|
+
assert.lessThan(cell_index, this.#size_x * this.#size_y);
|
|
208
|
+
|
|
209
|
+
return this.#grid_data[cell_index]
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
*
|
|
214
|
+
* @param {number} x
|
|
215
|
+
* @param {number} y
|
|
216
|
+
* @return {number}
|
|
217
|
+
*/
|
|
218
|
+
world_position_to_cell_index(x, y) {
|
|
219
|
+
const grid_x = clamp(Math.floor(x * this.#scale_inverse), 0, this.#size_x - 1);
|
|
220
|
+
const grid_y = clamp(Math.floor(y * this.#scale_inverse), 0, this.#size_y - 1);
|
|
221
|
+
|
|
222
|
+
return this.cell_position_to_index(grid_x, grid_y);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
*
|
|
227
|
+
* @param {number} x
|
|
228
|
+
* @param {number} y
|
|
229
|
+
* @returns {number}
|
|
230
|
+
*/
|
|
231
|
+
cell_position_to_index(x, y) {
|
|
232
|
+
assert.isNonNegativeInteger(x, 'x');
|
|
233
|
+
assert.isNonNegativeInteger(y, 'y');
|
|
234
|
+
|
|
235
|
+
return y * this.#size_x + x;
|
|
236
|
+
|
|
237
|
+
// const cell_count = this.#size_x * this.#size_y;
|
|
238
|
+
//
|
|
239
|
+
// const _x = split_by_2(x);
|
|
240
|
+
// const _y = split_by_2(y);
|
|
241
|
+
//
|
|
242
|
+
// const hash = _x | (_y << 1);
|
|
243
|
+
//
|
|
244
|
+
// return hash % cell_count;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
*
|
|
249
|
+
* @param {number} cell_x
|
|
250
|
+
* @param {number} cell_y
|
|
251
|
+
* @return {boolean}
|
|
252
|
+
*/
|
|
253
|
+
is_cell_empty(cell_x, cell_y) {
|
|
254
|
+
assert.isNonNegativeInteger(cell_x, 'cell_x');
|
|
255
|
+
assert.lessThan(cell_x, this.#size_x, 'cell_x overflow');
|
|
256
|
+
|
|
257
|
+
assert.isNonNegativeInteger(cell_y, 'cell_y');
|
|
258
|
+
assert.lessThan(cell_y, this.#size_y, 'cell_y overflow');
|
|
259
|
+
|
|
260
|
+
const index = this.cell_position_to_index(cell_x, cell_y);
|
|
261
|
+
|
|
262
|
+
const grid = this.#grid_data;
|
|
263
|
+
|
|
264
|
+
return grid[index] === NULL_POINTER;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
*
|
|
269
|
+
* @param {number} element
|
|
270
|
+
* @param {number} grid_x
|
|
271
|
+
* @param {number} grid_y
|
|
272
|
+
*/
|
|
273
|
+
#element_insert_into_cell(element, grid_x, grid_y) {
|
|
274
|
+
|
|
275
|
+
// create a node
|
|
276
|
+
const node_pool = this.#node_pool;
|
|
277
|
+
const node = node_pool.allocate();
|
|
278
|
+
|
|
279
|
+
const node_address = node_pool.element_word(node);
|
|
280
|
+
const node_data_uint32 = node_pool.data_uint32;
|
|
281
|
+
|
|
282
|
+
node_data_uint32[node_address + COLUMN_NODE_ELEMENT] = element;
|
|
283
|
+
|
|
284
|
+
// link node to the element
|
|
285
|
+
const element_pool = this.#element_pool;
|
|
286
|
+
const element_address = element_pool.element_word(element);
|
|
287
|
+
|
|
288
|
+
const element_data_uint32 = element_pool.data_uint32;
|
|
289
|
+
|
|
290
|
+
const element_first_node = element_data_uint32[element_address + COLUMN_ELEMENT_NODE_FIRST];
|
|
291
|
+
|
|
292
|
+
// point to previous first
|
|
293
|
+
node_data_uint32[node_address + COLUMN_NODE_SAME_ELEMENT_NEXT] = element_first_node;
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
element_data_uint32[element_address + COLUMN_ELEMENT_NODE_FIRST] = node;
|
|
297
|
+
|
|
298
|
+
// link node to the cell
|
|
299
|
+
const cell_index = this.cell_position_to_index(grid_x, grid_y);
|
|
300
|
+
|
|
301
|
+
node_data_uint32[node_address + COLUMN_NODE_GRID_INDEX] = cell_index;
|
|
302
|
+
|
|
303
|
+
const grid_data = this.#grid_data;
|
|
304
|
+
|
|
305
|
+
const cell_first_node = grid_data[cell_index];
|
|
306
|
+
|
|
307
|
+
node_data_uint32[node_address + COLUMN_NODE_SAME_NODE_NEXT] = cell_first_node;
|
|
308
|
+
|
|
309
|
+
grid_data[cell_index] = node;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
*
|
|
314
|
+
* @param {number} cell_index
|
|
315
|
+
* @param {number} node
|
|
316
|
+
* @returns {boolean}
|
|
317
|
+
*/
|
|
318
|
+
#grid_cell_remove_node(cell_index, node) {
|
|
319
|
+
assert.isNonNegativeInteger(cell_index, 'cell_index');
|
|
320
|
+
assert.isNonNegativeInteger(node, 'node');
|
|
321
|
+
|
|
322
|
+
const pool = this.#node_pool;
|
|
323
|
+
const node_data_uint32 = pool.data_uint32;
|
|
324
|
+
|
|
325
|
+
const grid_data = this.#grid_data;
|
|
326
|
+
let n = grid_data[cell_index]
|
|
327
|
+
let previous = NULL_POINTER;
|
|
328
|
+
|
|
329
|
+
while (n !== NULL_POINTER) {
|
|
330
|
+
const address = pool.element_word(n);
|
|
331
|
+
const next = node_data_uint32[address + COLUMN_NODE_SAME_NODE_NEXT];
|
|
332
|
+
|
|
333
|
+
if (n === node) {
|
|
334
|
+
// found the node to cut
|
|
335
|
+
|
|
336
|
+
if (previous === NULL_POINTER) {
|
|
337
|
+
// first element in the list
|
|
338
|
+
grid_data[cell_index] = next;
|
|
339
|
+
} else {
|
|
340
|
+
const previous_address = pool.element_word(previous);
|
|
341
|
+
|
|
342
|
+
node_data_uint32[previous_address + COLUMN_NODE_SAME_NODE_NEXT] = next;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
previous = n;
|
|
349
|
+
n = next;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
*
|
|
357
|
+
* @param {number} element
|
|
358
|
+
*/
|
|
359
|
+
element_remove(element) {
|
|
360
|
+
assert.isNonNegativeInteger(element, 'element');
|
|
361
|
+
|
|
362
|
+
const element_pool = this.#element_pool;
|
|
363
|
+
const address = element_pool.element_word(element);
|
|
364
|
+
|
|
365
|
+
let node = element_pool.data_uint32[address + COLUMN_ELEMENT_NODE_FIRST];
|
|
366
|
+
|
|
367
|
+
const node_pool = this.#node_pool;
|
|
368
|
+
const node_data_uint32 = node_pool.data_uint32;
|
|
369
|
+
|
|
370
|
+
do {
|
|
371
|
+
|
|
372
|
+
const node_address = node_pool.element_word(node);
|
|
373
|
+
|
|
374
|
+
const next = node_data_uint32[node_address + COLUMN_NODE_SAME_ELEMENT_NEXT];
|
|
375
|
+
|
|
376
|
+
const grid_index = node_data_uint32[node_address + COLUMN_NODE_GRID_INDEX];
|
|
377
|
+
|
|
378
|
+
// cut this node from CELL list
|
|
379
|
+
this.#grid_cell_remove_node(grid_index, node);
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
// advance onto next
|
|
383
|
+
node = next;
|
|
384
|
+
} while (node !== NULL_POINTER)
|
|
385
|
+
|
|
386
|
+
}
|
|
387
387
|
}
|