@woosh/meep-engine 2.48.23 → 2.49.1
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/editor/tools/GridPaintTool.js +1 -1
- package/editor/tools/paint/TerrainPaintTool.js +1 -1
- package/editor/view/GridPickCoordinateView.js +1 -1
- package/package.json +1 -1
- package/src/core/UUID.js +2 -0
- package/src/core/assert.js +4 -1
- package/src/core/binary/ctz32.js +1 -1
- package/src/core/binary/operations/bitCount.spec.js +19 -0
- package/src/core/binary/uint82float.spec.js +7 -0
- package/src/core/bvh2/binary/IndexedBinaryBVH.spec.js +7 -0
- package/src/core/bvh2/bvh3/EBBVHLeafProxy.js +3 -0
- package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +5 -4
- package/src/core/bvh2/transform/RotationOptimizer.spec.js +161 -155
- package/src/core/codegen/LineBuilder.js +12 -3
- package/src/core/codegen/LineBuilder.spec.js +7 -0
- package/src/core/collection/CuckooFilter.js +12 -12
- package/src/core/collection/HashMap.js +486 -237
- package/src/core/collection/HashMap.spec.js +110 -1
- package/src/core/collection/array/{typedArrayToDataType.js → typed/typedArrayToDataType.js} +1 -1
- package/src/core/collection/array/weightedRandomFromArray.spec.js +20 -0
- package/src/core/debug/matchers/AnyOf.js +1 -2
- package/src/core/geom/2d/aabb/AABB2.spec.js +1 -1
- package/src/core/geom/2d/aabb/aabb2_compute_center_from_multiple.js +19 -0
- package/src/core/geom/2d/quad-tree/qt_collect_by_circle.js +3 -3
- package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.js +7 -9
- package/src/core/geom/3d/aabb/aabb3_compute_plane_side.js +17 -15
- package/src/core/geom/3d/aabb/aabb3_compute_plane_side.spec.js +25 -0
- package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.js +1 -1
- package/src/core/geom/3d/aabb/aabb3_from_v3_array.js +3 -0
- package/src/core/geom/3d/aabb/aabb3_from_v3_array.spec.js +32 -0
- package/src/core/geom/3d/aabb/aabb3_intersects_aabb3.spec.js +115 -0
- package/src/core/geom/3d/aabb/aabb3_raycast.js +6 -1
- package/src/core/geom/3d/aabb/serializeAABB3Encoded_v0.js +6 -6
- package/src/core/geom/3d/{CircleMath.js → compute_circle_bounding_box.js} +1 -1
- package/src/core/geom/3d/decompose_matrix_4_array.js +18 -19
- package/src/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +1 -1
- package/src/{engine/graphics/ecs/mesh-v2 → core/geom/3d/matrix}/allocate_transform_m4.js +1 -1
- package/src/core/geom/3d/normal/hemioct/decode_hemioct_to_unit.js +26 -0
- package/src/core/geom/3d/normal/hemioct/encode_unit3_hemioct.js +0 -26
- package/src/core/geom/3d/normal/hemioct/unit_hemioct.spec.js +2 -1
- package/src/core/geom/3d/plane/computePlaneLineIntersection.js +51 -0
- package/src/core/geom/3d/plane/computePlanePlaneIntersection.js +77 -0
- package/src/core/geom/3d/plane/computePlaneRayIntersection.js +55 -0
- package/src/core/geom/3d/plane/plane3_computeLineSegmentIntersection.js +50 -0
- package/src/core/geom/3d/plane/planeRayIntersection.js +14 -0
- package/src/core/geom/3d/{tetrahedra/in_sphere_fast.js → sphere/in_sphere3d_fast.js} +1 -1
- package/src/core/geom/3d/{tetrahedra/in_sphere_robust.js → sphere/in_sphere3d_robust.js} +1 -1
- package/src/core/geom/3d/sphere/sphere_array_intersects_point.js +2 -2
- package/src/core/geom/3d/sphere/{sphereIntersectsPoint.js → sphere_intersects_point.js} +7 -4
- package/src/core/geom/3d/sphere/sphere_intersects_point.spec.js +134 -0
- package/src/core/geom/3d/sphere/sphere_intersects_ray.spec.js +49 -0
- package/src/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.js +11 -7
- package/src/core/geom/3d/tetrahedra/delaunay/{debug_validate_mesh.js → debug/debug_validate_mesh.js} +1 -1
- package/src/core/geom/3d/tetrahedra/delaunay/{push_boundary_with_validation.js → debug/push_boundary_with_validation.js} +1 -1
- package/src/core/geom/3d/tetrahedra/delaunay/{validate_cavity_boundary.js → debug/validate_cavity_boundary.js} +2 -2
- package/src/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_compute_cavity.js +2 -2
- package/src/core/geom/3d/triangle/computeTriangleRayIntersection.js +0 -164
- package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js +87 -0
- package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentricEdge.js +81 -0
- package/src/core/geom/{rayTriangleIntersection.js → 3d/triangle/rayTriangleIntersection.js} +2 -2
- package/src/core/geom/ConicRay.js +160 -152
- package/src/core/geom/Matrix4.js +2 -0
- package/src/core/geom/Quaternion.js +19 -1
- package/src/core/geom/packing/max-rect/MaxRectangles.js +4 -214
- package/src/core/geom/packing/max-rect/cost/costByBestShortSide.js +11 -0
- package/src/core/geom/packing/max-rect/cost/costByRemainingArea.js +14 -0
- package/src/core/geom/packing/max-rect/cutArea.js +79 -0
- package/src/core/geom/packing/max-rect/findBestContainer.js +58 -0
- package/src/core/geom/packing/max-rect/packOneBox.js +49 -0
- package/src/core/geom/packing/miniball/Miniball.js +12 -12
- package/src/core/geom/packing/miniball/Quality.js +2 -2
- package/src/core/geom/packing/miniball/Subspan.js +13 -13
- package/src/core/geom/v3_dot.js +1 -1
- package/src/core/graph/layout/CircleLayout.js +1 -1
- package/src/core/graph/layout/{BoxLayouter.js → box/BoxLayouter.js} +6 -50
- package/src/core/graph/layout/box/applyCentralGravityAABB2.js +29 -0
- package/src/core/json/resolvePath.spec.js +14 -0
- package/src/core/land/reactive/{compiler/ReactiveCompiler.spec.js → compileReactiveExpression.spec.js} +17 -17
- package/src/core/math/random/MersenneTwister.spec.js +19 -0
- package/src/core/math/random/randomGaussian.spec.js +9 -0
- package/src/core/math/statistics/computeStatisticalMean.js +2 -2
- package/src/core/model/reactive/model/arithmetic/ReactiveAdd.js +1 -1
- package/src/core/model/reactive/model/arithmetic/ReactiveDivide.js +3 -1
- package/src/core/model/reactive/model/arithmetic/ReactiveMultiply.js +1 -1
- package/src/core/model/reactive/model/arithmetic/ReactiveNegate.js +3 -1
- package/src/core/model/reactive/model/arithmetic/ReactiveSubtract.js +1 -1
- package/src/core/model/reactive/model/comparative/ReactiveEquals.js +1 -1
- package/src/core/model/reactive/model/comparative/ReactiveGreaterThan.js +3 -1
- package/src/core/model/reactive/model/comparative/ReactiveGreaterThanOrEqual.js +3 -1
- package/src/core/model/reactive/model/comparative/ReactiveLessThan.js +3 -1
- package/src/core/model/reactive/model/comparative/ReactiveLessThanOrEqual.js +3 -1
- package/src/core/model/reactive/model/comparative/ReactiveNotEquals.js +1 -1
- package/src/core/model/reactive/model/logic/ReactiveAnd.js +1 -1
- package/src/core/model/reactive/model/logic/ReactiveNot.js +3 -1
- package/src/core/model/reactive/model/logic/ReactiveOr.js +1 -1
- package/src/core/primitives/numbers/computeHashFloat.spec.js +7 -0
- package/src/core/process/task/util/iteratorTask.js +3 -1
- package/src/engine/animation/curve/AnimationCurve.js +34 -5
- package/src/engine/animation/curve/AnimationCurve.spec.js +100 -0
- package/src/engine/asset/AssetTransformer.js +1 -0
- package/src/engine/computeStridedIntegerArrayHash.js +4 -2
- package/src/engine/ecs/components/Renderable.d.ts +1 -1
- package/src/{ecs → engine/ecs}/grid/pick.js +4 -4
- package/src/engine/ecs/parent/entity_node_compute_bounding_box.js +1 -1
- package/src/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.js +1 -18
- package/src/engine/ecs/systems/MotionSystem.js +7 -1
- package/src/engine/ecs/systems/SynchronizePositionSystem.js +8 -2
- package/src/engine/ecs/transform/Transform.js +1 -1
- package/src/engine/graphics/camera/makeScreenScissorFrustum.js +3 -3
- package/src/engine/graphics/camera/testClippingPlaneComputation.js +13 -13
- package/src/engine/graphics/ecs/camera/Camera.js +1 -1
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMesh.js +1 -1
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshSystem.js +9 -0
- package/src/engine/graphics/geometry/MikkT/MikkTSpace.js +1 -1
- package/src/engine/graphics/geometry/MikkT/STSpace.js +1 -1
- package/src/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +1 -1
- package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +1 -1
- package/src/engine/graphics/particles/particular/engine/MovingBoundingBox.js +1 -1
- package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js +1 -0
- package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -1
- package/src/engine/graphics/postprocess/threejs/postprocessing/TexturePass.js +2 -2
- package/src/engine/graphics/sh3/path_tracer/GeometryBVHBatched.js +2 -2
- package/src/engine/graphics/texture/sampler/Sampler2D.js +1 -1
- package/src/engine/graphics/texture/sampler/sampler2d_compute_texel_value_conversion_scale_to_uint8.js +1 -1
- package/src/engine/intelligence/behavior/Behavior.spec.js +15 -0
- package/src/engine/intelligence/mcts/MoveEdge.js +1 -1
- package/src/engine/reference/v1/ReferenceManager.js +3 -0
- package/src/engine/reference/v2/Reference.js +33 -37
- package/src/engine/sound/sopra/README.md +6 -0
- package/src/generation/automata/CaveGeneratorCellularAutomata.js +10 -7
- package/src/generation/automata/CaveGeneratorCellularAutomata.spec.js +12 -0
- package/src/generation/automata/CellularAutomata.js +5 -4
- package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +25 -9
- package/src/view/minimap/dom/MinimapCameraView.js +1 -1
- package/src/core/geom/Plane.js +0 -250
- package/src/core/land/reactive/ReactiveLexer.js +0 -158
- package/src/core/land/reactive/ReactiveLexer.ts +0 -181
- package/src/core/land/reactive/ReactiveListener.ts +0 -323
- package/src/core/land/reactive/ReactiveParser.js +0 -1573
- package/src/core/land/reactive/ReactiveParser.ts +0 -1776
- package/src/core/land/reactive/ReactiveVisitor.js +0 -1
- package/src/core/land/reactive/ReactiveVisitor.ts +0 -218
- package/src/core/land/reactive/compiler/ReactiveCompiler.js +0 -350
- package/src/core/land/reactive/compiler/ReactiveNearlyCompiler.js +0 -166
- package/src/core/land/reactive/compiler/ReactiveParser.js +0 -34
- package/src/core/land/reactive/nearley/ReactiveNearley.js +0 -187
- /package/src/{engine/graphics/ecs/mesh-v2 → core/geom/3d/vector}/allocate_v3.js +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HashMap } from "./HashMap.js";
|
|
1
|
+
import { generate_next_linear_congruential_index, HashMap } from "./HashMap.js";
|
|
2
2
|
import { passThrough, returnOne, strictEquals } from "../function/Functions.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -16,6 +16,7 @@ function makeSample() {
|
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
|
|
19
20
|
test('put and get same value', () => {
|
|
20
21
|
const m = makeSample();
|
|
21
22
|
|
|
@@ -107,6 +108,44 @@ test("retrieval works as intended after hash map grows", () => {
|
|
|
107
108
|
|
|
108
109
|
});
|
|
109
110
|
|
|
111
|
+
test("after deletion element is not found", () => {
|
|
112
|
+
const map = new HashMap({
|
|
113
|
+
keyHashFunction: passThrough,
|
|
114
|
+
keyEqualityFunction: strictEquals,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
map.set(1, "a");
|
|
118
|
+
|
|
119
|
+
map.delete(1);
|
|
120
|
+
|
|
121
|
+
expect(map.size).toBe(0);
|
|
122
|
+
expect(map.get(1)).toBeUndefined();
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("deleting an element then inserting another one all with hash collisions", () => {
|
|
126
|
+
const map = new HashMap({
|
|
127
|
+
keyHashFunction: returnOne,
|
|
128
|
+
keyEqualityFunction: strictEquals,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
map.set(1, "a");
|
|
132
|
+
map.set(7, "b");
|
|
133
|
+
|
|
134
|
+
map.delete(1);
|
|
135
|
+
|
|
136
|
+
expect(map.get(7)).toBe("b");
|
|
137
|
+
expect(map.get(1)).toBeUndefined();
|
|
138
|
+
|
|
139
|
+
map.set(13, "c");
|
|
140
|
+
|
|
141
|
+
expect(map.get(13)).toBe("c");
|
|
142
|
+
|
|
143
|
+
map.delete(13);
|
|
144
|
+
|
|
145
|
+
expect(map.get(7)).toBe("b");
|
|
146
|
+
expect(map.get(13)).toBeUndefined();
|
|
147
|
+
});
|
|
148
|
+
|
|
110
149
|
|
|
111
150
|
test("key iterator", () => {
|
|
112
151
|
const map = new HashMap({
|
|
@@ -129,3 +168,73 @@ test("value iterator", () => {
|
|
|
129
168
|
|
|
130
169
|
expect(map.values().next().value).toBe("hello");
|
|
131
170
|
});
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
test("clear works as expected", () => {
|
|
174
|
+
const map = new HashMap({
|
|
175
|
+
keyHashFunction: passThrough,
|
|
176
|
+
keyEqualityFunction: strictEquals
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
map.set(7, "hello");
|
|
180
|
+
|
|
181
|
+
map.clear();
|
|
182
|
+
|
|
183
|
+
expect(map.get(7)).toBe(undefined);
|
|
184
|
+
expect(map.size).toBe(0);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test("lcg 32", () => {
|
|
188
|
+
const generated = new Uint32Array(32);
|
|
189
|
+
|
|
190
|
+
let next = 0;
|
|
191
|
+
for (let i = 0; i < 32; i++) {
|
|
192
|
+
|
|
193
|
+
generated[i] = next;
|
|
194
|
+
|
|
195
|
+
next = generate_next_linear_congruential_index(next, 31);
|
|
196
|
+
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
generated.sort();
|
|
200
|
+
|
|
201
|
+
for (let i = 0; i < 32; i++) {
|
|
202
|
+
expect(generated[i]).toBe(i);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
test.skip("performance - random fill 100,000", () => {
|
|
208
|
+
const map = new HashMap({
|
|
209
|
+
keyHashFunction: passThrough,
|
|
210
|
+
keyEqualityFunction: strictEquals
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
const map_warmup = new HashMap({
|
|
214
|
+
keyHashFunction: passThrough,
|
|
215
|
+
keyEqualityFunction: strictEquals
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// warm up
|
|
219
|
+
for (let i = 0; i < 10000; i++) {
|
|
220
|
+
map_warmup.set(i, i);
|
|
221
|
+
map_warmup.get(i);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const t0 = performance.now();
|
|
225
|
+
|
|
226
|
+
for (let i = 0; i < 100000; i++) {
|
|
227
|
+
map.set(i, i);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const t1 = performance.now();
|
|
231
|
+
|
|
232
|
+
for (let i = 0; i < 100000; i++) {
|
|
233
|
+
map.get(i);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const t2 = performance.now();
|
|
237
|
+
|
|
238
|
+
console.log(`Fill: ${t1 - t0}ms`)
|
|
239
|
+
console.log(`Drain: ${t2 - t1}ms`)
|
|
240
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { weightedRandomFromArray } from "./weightedRandomFromArray.js";
|
|
2
|
+
import { passThrough, returnOne, returnZero } from "../../function/Functions.js";
|
|
3
|
+
|
|
4
|
+
test("empty array", () => {
|
|
5
|
+
expect(weightedRandomFromArray([], returnZero, passThrough, null, 0))
|
|
6
|
+
.toBeUndefined();
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test("single element array", () => {
|
|
10
|
+
expect(weightedRandomFromArray([1], returnZero, passThrough, null, 1))
|
|
11
|
+
.toBe(1);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test("two elements", () => {
|
|
15
|
+
expect(weightedRandomFromArray([1,3], returnZero, passThrough, null, 2))
|
|
16
|
+
.toBe(1);
|
|
17
|
+
|
|
18
|
+
expect(weightedRandomFromArray([1,3], returnOne, passThrough, null, 2))
|
|
19
|
+
.toBe(3);
|
|
20
|
+
});
|
|
@@ -20,8 +20,7 @@ export class AnyOf extends BaseMatcher {
|
|
|
20
20
|
|
|
21
21
|
matches(item, mismatch_description) {
|
|
22
22
|
for (const matcher of this.#matchers) {
|
|
23
|
-
if (
|
|
24
|
-
|
|
23
|
+
if (matcher.matches(item, NullDescription.INSTANCE)) {
|
|
25
24
|
return true;
|
|
26
25
|
}
|
|
27
26
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Vector2 from "../../Vector2.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {Array.<AABB2>} boxes
|
|
6
|
+
* @returns {Vector2}
|
|
7
|
+
*/
|
|
8
|
+
export function aabb2_compute_center_from_multiple(boxes) {
|
|
9
|
+
const numBoxes = boxes.length;
|
|
10
|
+
|
|
11
|
+
const center = new Vector2();
|
|
12
|
+
for (let i = 0; i < numBoxes; i++) {
|
|
13
|
+
const box = boxes[i];
|
|
14
|
+
center._add(box.midX(), box.midY());
|
|
15
|
+
}
|
|
16
|
+
center.multiplyScalar(1 / numBoxes);
|
|
17
|
+
|
|
18
|
+
return center;
|
|
19
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { aabb2_distance_sqr_to_point } from "../aabb/aabb2_distance_sqr_to_point.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
*
|
|
@@ -33,7 +33,7 @@ export function qt_collect_by_circle(
|
|
|
33
33
|
|
|
34
34
|
const node = node_stack[stack_pointer];
|
|
35
35
|
|
|
36
|
-
const d2 =
|
|
36
|
+
const d2 = aabb2_distance_sqr_to_point(node.x0, node.y0, node.x1, node.y1, x, y);
|
|
37
37
|
|
|
38
38
|
if (d2 > r2) {
|
|
39
39
|
// not a match
|
|
@@ -46,7 +46,7 @@ export function qt_collect_by_circle(
|
|
|
46
46
|
for (let i = 0; i < data_count; i++) {
|
|
47
47
|
const datum = data[i];
|
|
48
48
|
|
|
49
|
-
const d2_to_datum =
|
|
49
|
+
const d2_to_datum = aabb2_distance_sqr_to_point(datum.x0, datum.y0, datum.x1, datum.y1, x, y);
|
|
50
50
|
|
|
51
51
|
if (d2_to_datum <= r2) {
|
|
52
52
|
result[result_cursor++] = datum;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { max2 } from "../../../math/max2.js";
|
|
2
1
|
import { aabb2_distance_sqr_to_point } from "../aabb/aabb2_distance_sqr_to_point.js";
|
|
3
2
|
|
|
4
3
|
/**
|
|
@@ -17,20 +16,18 @@ const node_stack = [];
|
|
|
17
16
|
*/
|
|
18
17
|
export function qt_query_data_nearest_to_point(tree, x, y, max_distance = Infinity) {
|
|
19
18
|
|
|
20
|
-
let stack_pointer =
|
|
19
|
+
let stack_pointer = 1;
|
|
21
20
|
|
|
22
|
-
node_stack[
|
|
23
|
-
stack_pointer++;
|
|
21
|
+
node_stack[0] = tree;
|
|
24
22
|
|
|
25
23
|
let best_leaf_data = undefined;
|
|
26
24
|
let best_distance_sqr = max_distance * max_distance;
|
|
27
25
|
|
|
28
|
-
while (stack_pointer > 0) {
|
|
26
|
+
while (stack_pointer-- > 0) {
|
|
29
27
|
|
|
30
|
-
--stack_pointer;
|
|
31
28
|
const node = node_stack[stack_pointer];
|
|
32
29
|
|
|
33
|
-
const distance_sqr =
|
|
30
|
+
const distance_sqr = aabb2_distance_sqr_to_point(node.x0, node.y0, node.x1, node.y1, x, y);
|
|
34
31
|
|
|
35
32
|
if (distance_sqr >= best_distance_sqr) {
|
|
36
33
|
// too far
|
|
@@ -38,11 +35,12 @@ export function qt_query_data_nearest_to_point(tree, x, y, max_distance = Infini
|
|
|
38
35
|
}
|
|
39
36
|
|
|
40
37
|
const data = node.data;
|
|
38
|
+
const data_count = data.length;
|
|
41
39
|
|
|
42
|
-
for (let i = 0; i <
|
|
40
|
+
for (let i = 0; i < data_count; i++) {
|
|
43
41
|
const datum = data[i];
|
|
44
42
|
|
|
45
|
-
const distance_sqr =
|
|
43
|
+
const distance_sqr = aabb2_distance_sqr_to_point(datum.x0, datum.y0, datum.x1, datum.y1, x, y);
|
|
46
44
|
|
|
47
45
|
if (distance_sqr < best_distance_sqr) {
|
|
48
46
|
best_leaf_data = datum;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { v3_dot } from "../../v3_dot.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 2,0,or -2; 2: above, -2 : below, 0 : intersects plane
|
|
@@ -26,7 +26,6 @@ export function aabb3_compute_plane_side(
|
|
|
26
26
|
_y1,
|
|
27
27
|
_z1
|
|
28
28
|
) {
|
|
29
|
-
let result = 0;
|
|
30
29
|
|
|
31
30
|
let x0,
|
|
32
31
|
y0,
|
|
@@ -60,23 +59,26 @@ export function aabb3_compute_plane_side(
|
|
|
60
59
|
z1 = _z0;
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
|
|
62
|
+
/*
|
|
63
|
+
planar tests are inlined for performance and to save on a few operation,
|
|
64
|
+
if you write it out fully it would be vec4 dot product and comparison to 0,
|
|
65
|
+
since we don't have 4th component for AABB corners,
|
|
66
|
+
we can use vec3 and just move planar offset to the right-hand side of the comparison operation
|
|
67
|
+
*/
|
|
64
68
|
|
|
65
|
-
|
|
66
|
-
// above the plane
|
|
67
|
-
result += 1;
|
|
68
|
-
} else {
|
|
69
|
-
result -= 1;
|
|
70
|
-
}
|
|
69
|
+
const neg_plane_constant = -plane_constant;
|
|
71
70
|
|
|
72
71
|
// check the farthest corner
|
|
72
|
+
if (v3_dot(x1, y1, z1, plane_normal_x, plane_normal_y, plane_normal_z) < neg_plane_constant) {
|
|
73
|
+
// if furthest corner is below plane, the nearest one will be as well, no need to continue
|
|
74
|
+
return -2;
|
|
75
|
+
}
|
|
73
76
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
result -= 1;
|
|
77
|
+
// check the nearest corner
|
|
78
|
+
if (v3_dot(plane_normal_x, plane_normal_y, plane_normal_z, x0, y0, z0) >= neg_plane_constant) {
|
|
79
|
+
// above the plane, both corners are above the plane
|
|
80
|
+
return 2;
|
|
79
81
|
}
|
|
80
82
|
|
|
81
|
-
return
|
|
83
|
+
return 0;
|
|
82
84
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { aabb3_compute_plane_side } from "./aabb3_compute_plane_side.js";
|
|
2
|
+
|
|
3
|
+
test("fully above plane", () => {
|
|
4
|
+
expect(aabb3_compute_plane_side(
|
|
5
|
+
0, 1, 0, 0,
|
|
6
|
+
-1, 0.1, -1,
|
|
7
|
+
1, 1, 1
|
|
8
|
+
)).toBe(2);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test("fully below plane", () => {
|
|
12
|
+
expect(aabb3_compute_plane_side(
|
|
13
|
+
0, 1, 0, 0,
|
|
14
|
+
-1, -1, -1,
|
|
15
|
+
1, -0.1, 1
|
|
16
|
+
)).toBe(-2);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("intersects plane", () => {
|
|
20
|
+
expect(aabb3_compute_plane_side(
|
|
21
|
+
0, 1, 0, 0,
|
|
22
|
+
-1, -1, -1,
|
|
23
|
+
1, 1, 1
|
|
24
|
+
)).toBe(0);
|
|
25
|
+
});
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { aabb3_build_corners } from "./aabb3_build_corners.js";
|
|
2
2
|
import { aabb_build_frustum } from "./aabb3_build_frustum.js";
|
|
3
|
-
import { plane3_computeLineSegmentIntersection } from "../../Plane.js";
|
|
4
3
|
import { aabb3_corner_edge_mapping } from "./aabb3_corner_edge_mapping.js";
|
|
5
4
|
import { aabb3_edge_corner_mapping } from "./aabb3_edge_corner_mapping.js";
|
|
6
5
|
import { plane_computeConvex3PlaneIntersection } from "../plane/plane_computeConvex3PlaneIntersection.js";
|
|
7
6
|
import { is_point_within_planes } from "../plane/is_point_within_planes.js";
|
|
8
7
|
import { v3_distance_above_plane } from "../../v3_distance_above_plane.js";
|
|
9
8
|
import { EPSILON } from "../../../math/EPSILON.js";
|
|
9
|
+
import { plane3_computeLineSegmentIntersection } from "../plane/plane3_computeLineSegmentIntersection.js";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Common piece of continuous memory for better cache coherence
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { min2 } from "../../../math/min2.js";
|
|
2
2
|
import { max2 } from "../../../math/max2.js";
|
|
3
|
+
import { assert } from "../../../assert.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
*
|
|
@@ -8,6 +9,8 @@ import { max2 } from "../../../math/max2.js";
|
|
|
8
9
|
* @param {number} input_length length of the input array
|
|
9
10
|
*/
|
|
10
11
|
export function aabb3_from_v3_array(result, input, input_length) {
|
|
12
|
+
assert.equal(input_length % 3, 0, `Input must be divisible by 3, instead was ${input_length}`)
|
|
13
|
+
|
|
11
14
|
let x0 = Infinity;
|
|
12
15
|
let y0 = Infinity;
|
|
13
16
|
let z0 = Infinity;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { aabb3_from_v3_array } from "./aabb3_from_v3_array.js";
|
|
2
|
+
import { AABB3 } from "./AABB3.js";
|
|
3
|
+
|
|
4
|
+
test("empty list", () => {
|
|
5
|
+
const box = new AABB3();
|
|
6
|
+
|
|
7
|
+
aabb3_from_v3_array(box, [], 0);
|
|
8
|
+
|
|
9
|
+
expect(box.x0).toEqual(Infinity);
|
|
10
|
+
expect(box.x1).toEqual(-Infinity);
|
|
11
|
+
|
|
12
|
+
expect(box.y0).toEqual(Infinity);
|
|
13
|
+
expect(box.y1).toEqual(-Infinity);
|
|
14
|
+
|
|
15
|
+
expect(box.z0).toEqual(Infinity);
|
|
16
|
+
expect(box.z1).toEqual(-Infinity);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test("1 point", () => {
|
|
20
|
+
const box = new AABB3();
|
|
21
|
+
|
|
22
|
+
aabb3_from_v3_array(box, [1, 3, -5], 3);
|
|
23
|
+
|
|
24
|
+
expect(box.x0).toEqual(1);
|
|
25
|
+
expect(box.x1).toEqual(1);
|
|
26
|
+
|
|
27
|
+
expect(box.y0).toEqual(3);
|
|
28
|
+
expect(box.y1).toEqual(3);
|
|
29
|
+
|
|
30
|
+
expect(box.z0).toEqual(-5);
|
|
31
|
+
expect(box.z1).toEqual(-5);
|
|
32
|
+
});
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { aabb3_intersects_aabb3 } from "./aabb3_intersects_aabb3.js";
|
|
2
|
+
|
|
3
|
+
test("full containment", () => {
|
|
4
|
+
|
|
5
|
+
expect(aabb3_intersects_aabb3(
|
|
6
|
+
0, 0, 0, 3, 3, 3,
|
|
7
|
+
1, 1, 1, 2, 2, 2
|
|
8
|
+
)).toBe(true);
|
|
9
|
+
|
|
10
|
+
expect(aabb3_intersects_aabb3(
|
|
11
|
+
-3, -3, -3, 0, 0, 0,
|
|
12
|
+
-2, -2, -2, -1, -1, -1
|
|
13
|
+
)).toBe(true);
|
|
14
|
+
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("complete separation", () => {
|
|
18
|
+
|
|
19
|
+
// X
|
|
20
|
+
expect(aabb3_intersects_aabb3(
|
|
21
|
+
-1, -1, -1, 1, 1, 1,
|
|
22
|
+
2, 1, 1, 3, 2, 2
|
|
23
|
+
)).toBe(false);
|
|
24
|
+
|
|
25
|
+
expect(aabb3_intersects_aabb3(
|
|
26
|
+
-1, -1, -1, 1, 1, 1,
|
|
27
|
+
-3, 1, 1, -2, 2, 2
|
|
28
|
+
)).toBe(false);
|
|
29
|
+
|
|
30
|
+
// Y
|
|
31
|
+
expect(aabb3_intersects_aabb3(
|
|
32
|
+
-1, -1, -1, 1, 1, 1,
|
|
33
|
+
1, 2, 1, 2, 3, 2
|
|
34
|
+
)).toBe(false);
|
|
35
|
+
|
|
36
|
+
expect(aabb3_intersects_aabb3(
|
|
37
|
+
-1, -1, -1, 1, 1, 1,
|
|
38
|
+
1, -3, 1, 2, -2, 2
|
|
39
|
+
)).toBe(false);
|
|
40
|
+
|
|
41
|
+
// Z
|
|
42
|
+
expect(aabb3_intersects_aabb3(
|
|
43
|
+
-1, -1, -1, 1, 1, 1,
|
|
44
|
+
1, 1, 2, 2, 2, 3
|
|
45
|
+
)).toBe(false);
|
|
46
|
+
|
|
47
|
+
expect(aabb3_intersects_aabb3(
|
|
48
|
+
-1, -1, -1, 1, 1, 1,
|
|
49
|
+
1, 1, -3, 2, 2, -2
|
|
50
|
+
)).toBe(false);
|
|
51
|
+
|
|
52
|
+
// XY
|
|
53
|
+
expect(aabb3_intersects_aabb3(
|
|
54
|
+
-1, -1, -1, 1, 1, 1,
|
|
55
|
+
2, 2, 1, 3, 3, 2
|
|
56
|
+
)).toBe(false);
|
|
57
|
+
|
|
58
|
+
expect(aabb3_intersects_aabb3(
|
|
59
|
+
-1, -1, -1, 1, 1, 1,
|
|
60
|
+
-3, 2, 1, -2, 3, 2
|
|
61
|
+
)).toBe(false);
|
|
62
|
+
|
|
63
|
+
expect(aabb3_intersects_aabb3(
|
|
64
|
+
-1, -1, -1, 1, 1, 1,
|
|
65
|
+
2, -3, 1, 3, -2, 2
|
|
66
|
+
)).toBe(false);
|
|
67
|
+
|
|
68
|
+
expect(aabb3_intersects_aabb3(
|
|
69
|
+
-1, -1, -1, 1, 1, 1,
|
|
70
|
+
-3, -3, 1, -2, -2, 2
|
|
71
|
+
)).toBe(false);
|
|
72
|
+
|
|
73
|
+
// YZ
|
|
74
|
+
expect(aabb3_intersects_aabb3(
|
|
75
|
+
-1, -1, -1, 1, 1, 1,
|
|
76
|
+
1, 2, 2, 2, 3, 3
|
|
77
|
+
)).toBe(false);
|
|
78
|
+
|
|
79
|
+
expect(aabb3_intersects_aabb3(
|
|
80
|
+
-1, -1, -1, 1, 1, 1,
|
|
81
|
+
1, -3, 2, 2, -2, 3
|
|
82
|
+
)).toBe(false);
|
|
83
|
+
|
|
84
|
+
expect(aabb3_intersects_aabb3(
|
|
85
|
+
-1, -1, -1, 1, 1, 1,
|
|
86
|
+
1, 2, -3, 2, 3, 2
|
|
87
|
+
)).toBe(false);
|
|
88
|
+
|
|
89
|
+
expect(aabb3_intersects_aabb3(
|
|
90
|
+
-1, -1, -1, 1, 1, 1,
|
|
91
|
+
1, -3, -3, 2, -2, 2
|
|
92
|
+
)).toBe(false);
|
|
93
|
+
|
|
94
|
+
// ZX
|
|
95
|
+
expect(aabb3_intersects_aabb3(
|
|
96
|
+
-1, -1, -1, 1, 1, 1,
|
|
97
|
+
2, 2, 1, 3, 3, 2
|
|
98
|
+
)).toBe(false);
|
|
99
|
+
|
|
100
|
+
expect(aabb3_intersects_aabb3(
|
|
101
|
+
-1, -1, -1, 1, 1, 1,
|
|
102
|
+
2, -3, 2, 3, -2, 2
|
|
103
|
+
)).toBe(false);
|
|
104
|
+
|
|
105
|
+
expect(aabb3_intersects_aabb3(
|
|
106
|
+
-1, -1, -1, 1, 1, 1,
|
|
107
|
+
-3, 2, 1, -2, 3, 2
|
|
108
|
+
)).toBe(false);
|
|
109
|
+
|
|
110
|
+
expect(aabb3_intersects_aabb3(
|
|
111
|
+
-1, -1, -1, 1, 1, 1,
|
|
112
|
+
-3, -3, 2, -2, -2, 2
|
|
113
|
+
)).toBe(false);
|
|
114
|
+
|
|
115
|
+
});
|
|
@@ -27,7 +27,12 @@ import { max2 } from "../../../math/max2.js";
|
|
|
27
27
|
* @see https://gdbooks.gitbooks.io/3dcollisions/content/Chapter3/raycast_aabb.html
|
|
28
28
|
* @see https://blog.johnnovak.net/2016/10/22/the-nim-ray-tracer-project-part-4-calculating-box-normals/
|
|
29
29
|
*/
|
|
30
|
-
export function aabb3_raycast(
|
|
30
|
+
export function aabb3_raycast(
|
|
31
|
+
result, result_offset,
|
|
32
|
+
x0, y0, z0, x1, y1, z1,
|
|
33
|
+
origin_x, origin_y, origin_z,
|
|
34
|
+
direction_x, direction_y, direction_z
|
|
35
|
+
) {
|
|
31
36
|
|
|
32
37
|
// first find intersection
|
|
33
38
|
const dir_inv_x = 1 / direction_x;
|
|
@@ -44,32 +44,32 @@ export function serializeAABB3Encoded_v0(buffer, box, x0, y0, z0, x1, y1, z1) {
|
|
|
44
44
|
const zD = z1 - z0;
|
|
45
45
|
|
|
46
46
|
if ((header & 1) === 0) {
|
|
47
|
-
const _x0 = (((box.x0 - x0) / xD) * 65535)
|
|
47
|
+
const _x0 = Math.floor(((box.x0 - x0) / xD) * 65535);
|
|
48
48
|
buffer.writeUint16(_x0);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
if ((header & 2) === 0) {
|
|
52
|
-
const _x1 = (((box.x1 - x0) / xD) * 65535)
|
|
52
|
+
const _x1 = Math.ceil(((box.x1 - x0) / xD) * 65535);
|
|
53
53
|
buffer.writeUint16(_x1);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
if ((header & 4) === 0) {
|
|
57
|
-
const _y0 = (((box.y0 - y0) / yD) * 65535)
|
|
57
|
+
const _y0 = Math.floor(((box.y0 - y0) / yD) * 65535);
|
|
58
58
|
buffer.writeUint16(_y0);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
if ((header & 8) === 0) {
|
|
62
|
-
const _y1 = (((box.y1 - y0) / yD) * 65535)
|
|
62
|
+
const _y1 = Math.ceil(((box.y1 - y0) / yD) * 65535);
|
|
63
63
|
buffer.writeUint16(_y1);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
if ((header & 16) === 0) {
|
|
67
|
-
const _z0 = (((box.z0 - z0) / zD) * 65535)
|
|
67
|
+
const _z0 = Math.floor(((box.z0 - z0) / zD) * 65535);
|
|
68
68
|
buffer.writeUint16(_z0);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
if ((header & 32) === 0) {
|
|
72
|
-
const _z1 = (((box.z1 - z0) / zD) * 65535)
|
|
72
|
+
const _z1 = Math.ceil(((box.z1 - z0) / zD) * 65535);
|
|
73
73
|
buffer.writeUint16(_z1);
|
|
74
74
|
}
|
|
75
75
|
}
|
|
@@ -12,7 +12,7 @@ import { v3_angle_between } from "../v3_angle_between.js";
|
|
|
12
12
|
* @param {number} normalZ orientation of the circle
|
|
13
13
|
* @param {number} radius
|
|
14
14
|
*/
|
|
15
|
-
export function
|
|
15
|
+
export function compute_circle_bounding_box(
|
|
16
16
|
result,
|
|
17
17
|
centerX, centerY, centerZ,
|
|
18
18
|
normalX, normalY, normalZ,
|
|
@@ -2,34 +2,35 @@ const hypot = Math.hypot;
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
*
|
|
5
|
-
* @param {number[]}
|
|
5
|
+
* @param {number[]} mat4
|
|
6
6
|
* @param {Vector3} position
|
|
7
7
|
* @param {Quaternion} rotation
|
|
8
8
|
* @param {Vector3} scale
|
|
9
9
|
*/
|
|
10
|
-
export function decompose_matrix_4_array(
|
|
11
|
-
const m11 =
|
|
12
|
-
const m12 =
|
|
13
|
-
const m13 =
|
|
10
|
+
export function decompose_matrix_4_array(mat4, position, rotation, scale) {
|
|
11
|
+
const m11 = mat4[0];
|
|
12
|
+
const m12 = mat4[1];
|
|
13
|
+
const m13 = mat4[2];
|
|
14
14
|
|
|
15
15
|
const scale_x = hypot(m11, m12, m13);
|
|
16
16
|
|
|
17
|
-
const m21 =
|
|
18
|
-
const m22 =
|
|
19
|
-
const m23 =
|
|
17
|
+
const m21 = mat4[4];
|
|
18
|
+
const m22 = mat4[5];
|
|
19
|
+
const m23 = mat4[6];
|
|
20
20
|
|
|
21
21
|
const scale_y = hypot(m21, m22, m23);
|
|
22
22
|
|
|
23
|
-
const m31 =
|
|
24
|
-
const m32 =
|
|
25
|
-
const m33 =
|
|
23
|
+
const m31 = mat4[8];
|
|
24
|
+
const m32 = mat4[9];
|
|
25
|
+
const m33 = mat4[10];
|
|
26
26
|
|
|
27
27
|
const scale_z = hypot(m31, m32, m33);
|
|
28
28
|
|
|
29
29
|
// extract rotation matrix
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
const
|
|
30
|
+
// take care of potential division by 0 when scale is 0. Result is inexact, but we get don't break the system at least
|
|
31
|
+
const is1 = scale_x !== 0 ? 1 / scale_x : 1e7;
|
|
32
|
+
const is2 = scale_y !== 0 ? 1 / scale_y : 1e7;
|
|
33
|
+
const is3 = scale_z !== 0 ? 1 / scale_z : 1e7;
|
|
33
34
|
|
|
34
35
|
const sm11 = m11 * is1;
|
|
35
36
|
const sm12 = m12 * is1;
|
|
@@ -43,14 +44,12 @@ export function decompose_matrix_4_array(m, position, rotation, scale) {
|
|
|
43
44
|
const sm32 = m32 * is3;
|
|
44
45
|
const sm33 = m33 * is3;
|
|
45
46
|
|
|
46
|
-
// TODO take care of cases where scale is 0
|
|
47
|
-
|
|
48
47
|
// write out results
|
|
49
48
|
|
|
50
49
|
position.set(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
mat4[12],
|
|
51
|
+
mat4[13],
|
|
52
|
+
mat4[14]
|
|
54
53
|
);
|
|
55
54
|
|
|
56
55
|
scale.set(
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { computePlanePlaneIntersection } from "../../Plane.js";
|
|
2
1
|
import Vector3 from "../../Vector3.js";
|
|
3
2
|
import { plane3_projectPoint } from "../plane/plane3_projectPoint.js";
|
|
4
3
|
import { ray_computeNearestPointToPoint } from "../ray/ray_computeNearestPointToPoint.js";
|
|
@@ -6,6 +5,7 @@ import { v3_distance_above_plane } from "../../v3_distance_above_plane.js";
|
|
|
6
5
|
import {
|
|
7
6
|
plane_three_computeConvex3PlaneIntersection
|
|
8
7
|
} from "../plane/plane_three_compute_convex3_plane_intersection.js";
|
|
8
|
+
import { computePlanePlaneIntersection } from "../plane/computePlanePlaneIntersection.js";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
*
|