@woosh/meep-engine 2.48.23 → 2.49.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/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/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/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/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
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { max2 } from "../../../math/max2.js";
|
|
2
|
+
import { min2 } from "../../../math/min2.js";
|
|
3
|
+
import { QuadTreeDatum } from "../../2d/quad-tree/QuadTreeDatum.js";
|
|
4
|
+
import { removeRedundantBoxesArray } from "./removeRedundantBoxesArray.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Cut out a region from given set of boxes
|
|
8
|
+
* @param {AABB2} scissor area to be cut out
|
|
9
|
+
* @param {QuadTreeNode} boxes
|
|
10
|
+
*/
|
|
11
|
+
export function cutArea(scissor, boxes) {
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @type {QuadTreeDatum[]}
|
|
16
|
+
*/
|
|
17
|
+
const additions = [];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @type {QuadTreeDatum[]}
|
|
22
|
+
*/
|
|
23
|
+
const removals = [];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* @param {QuadTreeDatum} box
|
|
28
|
+
*/
|
|
29
|
+
function visitOverlap(box) {
|
|
30
|
+
removals.push(box);
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
//compute overlap region
|
|
34
|
+
const x0 = max2(scissor.x0, box.x0);
|
|
35
|
+
const x1 = min2(scissor.x1, box.x1);
|
|
36
|
+
|
|
37
|
+
const y0 = max2(scissor.y0, box.y0);
|
|
38
|
+
const y1 = min2(scissor.y1, box.y1);
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
//create 4 boxes around overlap
|
|
42
|
+
if (x0 > box.x0) {
|
|
43
|
+
//add left box
|
|
44
|
+
additions.push(new QuadTreeDatum(box.x0, box.y0, x0, box.y1));
|
|
45
|
+
}
|
|
46
|
+
if (x1 < box.x1) {
|
|
47
|
+
//add right box
|
|
48
|
+
additions.push(new QuadTreeDatum(x1, box.y0, box.x1, box.y1));
|
|
49
|
+
}
|
|
50
|
+
if (y0 > box.y0) {
|
|
51
|
+
//add top box
|
|
52
|
+
additions.push(new QuadTreeDatum(box.x0, box.y0, box.x1, y0));
|
|
53
|
+
}
|
|
54
|
+
if (y1 < box.y1) {
|
|
55
|
+
//add bottom box
|
|
56
|
+
additions.push(new QuadTreeDatum(box.x0, y1, box.x1, box.y1));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
boxes.traverseRectangleIntersections(scissor.x0, scissor.y0, scissor.x1, scissor.y1, visitOverlap);
|
|
62
|
+
|
|
63
|
+
let i, l;
|
|
64
|
+
//perform removals
|
|
65
|
+
for (i = 0, l = removals.length; i < l; i++) {
|
|
66
|
+
const removal = removals[i];
|
|
67
|
+
removal.disconnect();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//drop potential overlaps between additions
|
|
71
|
+
removeRedundantBoxesArray(additions);
|
|
72
|
+
|
|
73
|
+
//perform additions
|
|
74
|
+
for (i = 0, l = additions.length; i < l; i++) {
|
|
75
|
+
const addition = additions[i];
|
|
76
|
+
|
|
77
|
+
boxes.insertDatum(addition);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {number} width
|
|
4
|
+
* @param {number} height
|
|
5
|
+
* @param {QuadTreeNode} boxes
|
|
6
|
+
* @param {function(containerWidth:number, containerHeight:number, childWidth:number, childHeight:number):number} costFunction
|
|
7
|
+
* @returns {QuadTreeDatum} suitable container box
|
|
8
|
+
*/
|
|
9
|
+
export function findBestContainer(width, height, boxes, costFunction) {
|
|
10
|
+
let best = null;
|
|
11
|
+
let bestScore = Number.POSITIVE_INFINITY;
|
|
12
|
+
|
|
13
|
+
const visitor = (node) => {
|
|
14
|
+
|
|
15
|
+
if (node.getWidth() < width) {
|
|
16
|
+
//too small, don't traverse deeper
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (node.getHeight() < height) {
|
|
21
|
+
//too small, don't traverse deeper
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const data = node.data;
|
|
26
|
+
const numBoxes = data.length;
|
|
27
|
+
|
|
28
|
+
for (let i = 0; i < numBoxes; i++) {
|
|
29
|
+
const box = data[i];
|
|
30
|
+
|
|
31
|
+
const bW = box.getWidth();
|
|
32
|
+
|
|
33
|
+
if (bW < width) {
|
|
34
|
+
//too small
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const bH = box.getHeight();
|
|
39
|
+
|
|
40
|
+
if (bH < height) {
|
|
41
|
+
//too small
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const cost = costFunction(bW, bH, width, height);
|
|
46
|
+
if (cost < bestScore) {
|
|
47
|
+
bestScore = cost;
|
|
48
|
+
best = box;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return true;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
boxes.traversePreOrder(visitor);
|
|
56
|
+
|
|
57
|
+
return best;
|
|
58
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { findBestContainer } from "./findBestContainer.js";
|
|
2
|
+
import { costByRemainingArea } from "./cost/costByRemainingArea.js";
|
|
3
|
+
import { cutArea } from "./cutArea.js";
|
|
4
|
+
import { QuadTreeDatum } from "../../2d/quad-tree/QuadTreeDatum.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param {AABB2} box
|
|
9
|
+
* @param {QuadTreeNode} free
|
|
10
|
+
* @returns {boolean}
|
|
11
|
+
*/
|
|
12
|
+
export function packOneBox(box, free) {
|
|
13
|
+
const w = box.getWidth();
|
|
14
|
+
const h = box.getHeight();
|
|
15
|
+
|
|
16
|
+
const container = findBestContainer(w, h, free, costByRemainingArea);
|
|
17
|
+
|
|
18
|
+
if (container === null) {
|
|
19
|
+
//couldn't find a place for box
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//remove container from free set
|
|
24
|
+
container.disconnect();
|
|
25
|
+
|
|
26
|
+
//place box at bottom left of the container
|
|
27
|
+
const y0 = container.y0;
|
|
28
|
+
const x0 = container.x0;
|
|
29
|
+
|
|
30
|
+
box.set(x0, y0, x0 + w, y0 + h);
|
|
31
|
+
|
|
32
|
+
//update remaining set by removing this box area from free set
|
|
33
|
+
cutArea(box, free);
|
|
34
|
+
|
|
35
|
+
//split remaining space
|
|
36
|
+
if (box.y1 !== container.y1) {
|
|
37
|
+
const splitA = new QuadTreeDatum(container.x0, box.y1, container.x1, container.y1);
|
|
38
|
+
|
|
39
|
+
free.insertDatum(splitA);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (box.x1 !== container.x1) {
|
|
43
|
+
const splitB = new QuadTreeDatum(box.x1, container.y0, container.x1, container.y1);
|
|
44
|
+
free.insertDatum(splitB);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
return true;
|
|
49
|
+
}
|
package/src/core/geom/v3_dot.js
CHANGED
|
@@ -10,10 +10,10 @@ import { line2SegmentsIntersect } from "../../geom/2d/LineSegment2.js";
|
|
|
10
10
|
import Vector2, { v2_distance } from "../../geom/Vector2.js";
|
|
11
11
|
import { max2 } from "../../math/max2.js";
|
|
12
12
|
import { min2 } from "../../math/min2.js";
|
|
13
|
-
import { applyCentralGravityAABB2 } from "./BoxLayouter.js";
|
|
14
13
|
import { computeDisconnectedSubGraphs } from "./computeDisconnectedSubGraphs.js";
|
|
15
14
|
import { Connection } from "./Connection.js";
|
|
16
15
|
import { resolveAABB2Overlap } from "./box/resolveAABB2Overlap.js";
|
|
16
|
+
import { applyCentralGravityAABB2 } from "./box/applyCentralGravityAABB2.js";
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
import AABB2 from "
|
|
8
|
-
import Vector2 from "
|
|
9
|
-
import { computeDisconnectedSubGraphs } from "
|
|
10
|
-
import { Connection } from "
|
|
11
|
-
import { resolveAABB2Overlap } from "./
|
|
7
|
+
import AABB2 from "../../../geom/2d/aabb/AABB2.js";
|
|
8
|
+
import Vector2 from "../../../geom/Vector2.js";
|
|
9
|
+
import { computeDisconnectedSubGraphs } from "../computeDisconnectedSubGraphs.js";
|
|
10
|
+
import { Connection } from "../Connection.js";
|
|
11
|
+
import { resolveAABB2Overlap } from "./resolveAABB2Overlap.js";
|
|
12
|
+
import { applyCentralGravityAABB2 } from "./applyCentralGravityAABB2.js";
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -181,51 +182,6 @@ function applyPull(edges, strength) {
|
|
|
181
182
|
}
|
|
182
183
|
}
|
|
183
184
|
|
|
184
|
-
/**
|
|
185
|
-
*
|
|
186
|
-
* @param {Array.<AABB2>} boxes
|
|
187
|
-
* @returns {Vector2}
|
|
188
|
-
*/
|
|
189
|
-
function computeCenter(boxes) {
|
|
190
|
-
const numBoxes = boxes.length;
|
|
191
|
-
|
|
192
|
-
const center = new Vector2();
|
|
193
|
-
for (let i = 0; i < numBoxes; i++) {
|
|
194
|
-
const box = boxes[i];
|
|
195
|
-
center._add(box.midX(), box.midY());
|
|
196
|
-
}
|
|
197
|
-
center.multiplyScalar(1 / numBoxes);
|
|
198
|
-
|
|
199
|
-
return center;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
*
|
|
204
|
-
* @param {Array.<AABB2>} boxes
|
|
205
|
-
* @param {number} strength
|
|
206
|
-
*/
|
|
207
|
-
export function applyCentralGravityAABB2(boxes, strength) {
|
|
208
|
-
const numBoxes = boxes.length;
|
|
209
|
-
|
|
210
|
-
const center = computeCenter(boxes);
|
|
211
|
-
|
|
212
|
-
const delta = new Vector2();
|
|
213
|
-
for (let i = 0; i < numBoxes; i++) {
|
|
214
|
-
const box = boxes[i];
|
|
215
|
-
|
|
216
|
-
if (box.locked === true) {
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
delta.copy(center);
|
|
221
|
-
delta._sub(box.midX(), box.midY());
|
|
222
|
-
|
|
223
|
-
delta.multiplyScalar(strength);
|
|
224
|
-
|
|
225
|
-
box.move(delta.x, delta.y);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
185
|
|
|
230
186
|
function resolveBoxConnectionOverlaps(boxes, connections, maxSteps) {
|
|
231
187
|
for (let i = 0; i < maxSteps; i++) {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { aabb2_compute_center_from_multiple } from "../../../geom/2d/aabb/aabb2_compute_center_from_multiple.js";
|
|
2
|
+
import Vector2 from "../../../geom/Vector2.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {(AABB2|{locked:boolean})[]} boxes
|
|
7
|
+
* @param {number} strength
|
|
8
|
+
*/
|
|
9
|
+
export function applyCentralGravityAABB2(boxes, strength) {
|
|
10
|
+
const numBoxes = boxes.length;
|
|
11
|
+
|
|
12
|
+
const center = aabb2_compute_center_from_multiple(boxes);
|
|
13
|
+
|
|
14
|
+
const delta = new Vector2();
|
|
15
|
+
for (let i = 0; i < numBoxes; i++) {
|
|
16
|
+
const box = boxes[i];
|
|
17
|
+
|
|
18
|
+
if (box.locked === true) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
delta.copy(center);
|
|
23
|
+
delta._sub(box.midX(), box.midY());
|
|
24
|
+
|
|
25
|
+
delta.multiplyScalar(strength);
|
|
26
|
+
|
|
27
|
+
box.move(delta.x, delta.y);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { resolvePath } from "./resolvePath.js";
|
|
2
|
+
|
|
3
|
+
test("resolve global path", () => {
|
|
4
|
+
const root = {};
|
|
5
|
+
expect(resolvePath(root, '')).toBe(root);
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
test("resolve nested path", () => {
|
|
9
|
+
const nested_child = {};
|
|
10
|
+
|
|
11
|
+
const root = { a: { b: nested_child } };
|
|
12
|
+
|
|
13
|
+
expect(resolvePath(root, '/a/b')).toBe(nested_child);
|
|
14
|
+
});
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { ReactiveAdd } from "
|
|
2
|
-
import { ReactiveDivide } from "
|
|
3
|
-
import { ReactiveMultiply } from "
|
|
4
|
-
import { ReactiveNegate } from "
|
|
5
|
-
import { ReactiveSubtract } from "
|
|
6
|
-
import { ReactiveEquals } from "
|
|
7
|
-
import { ReactiveGreaterThan } from "
|
|
8
|
-
import { ReactiveGreaterThanOrEqual } from "
|
|
9
|
-
import { ReactiveLessThan } from "
|
|
10
|
-
import { ReactiveLessThanOrEqual } from "
|
|
11
|
-
import { ReactiveNotEquals } from "
|
|
12
|
-
import { ReactiveAnd } from "
|
|
13
|
-
import { ReactiveNot } from "
|
|
14
|
-
import { ReactiveOr } from "
|
|
15
|
-
import { ReactiveLiteralNumber } from "
|
|
16
|
-
import { ReactiveReference } from "
|
|
17
|
-
import { compileReactiveExpression } from "
|
|
1
|
+
import { ReactiveAdd } from "../../model/reactive/model/arithmetic/ReactiveAdd.js";
|
|
2
|
+
import { ReactiveDivide } from "../../model/reactive/model/arithmetic/ReactiveDivide.js";
|
|
3
|
+
import { ReactiveMultiply } from "../../model/reactive/model/arithmetic/ReactiveMultiply.js";
|
|
4
|
+
import { ReactiveNegate } from "../../model/reactive/model/arithmetic/ReactiveNegate.js";
|
|
5
|
+
import { ReactiveSubtract } from "../../model/reactive/model/arithmetic/ReactiveSubtract.js";
|
|
6
|
+
import { ReactiveEquals } from "../../model/reactive/model/comparative/ReactiveEquals.js";
|
|
7
|
+
import { ReactiveGreaterThan } from "../../model/reactive/model/comparative/ReactiveGreaterThan.js";
|
|
8
|
+
import { ReactiveGreaterThanOrEqual } from "../../model/reactive/model/comparative/ReactiveGreaterThanOrEqual.js";
|
|
9
|
+
import { ReactiveLessThan } from "../../model/reactive/model/comparative/ReactiveLessThan.js";
|
|
10
|
+
import { ReactiveLessThanOrEqual } from "../../model/reactive/model/comparative/ReactiveLessThanOrEqual.js";
|
|
11
|
+
import { ReactiveNotEquals } from "../../model/reactive/model/comparative/ReactiveNotEquals.js";
|
|
12
|
+
import { ReactiveAnd } from "../../model/reactive/model/logic/ReactiveAnd.d.ts";
|
|
13
|
+
import { ReactiveNot } from "../../model/reactive/model/logic/ReactiveNot.js";
|
|
14
|
+
import { ReactiveOr } from "../../model/reactive/model/logic/ReactiveOr.js";
|
|
15
|
+
import { ReactiveLiteralNumber } from "../../model/reactive/model/terminal/ReactiveLiteralNumber.js";
|
|
16
|
+
import { ReactiveReference } from "../../model/reactive/model/terminal/ReactiveReference.d.ts";
|
|
17
|
+
import { compileReactiveExpression } from "./compileReactiveExpression.js";
|
|
18
18
|
|
|
19
19
|
test('compile: REFERENCE', () => {
|
|
20
20
|
const expression = compileReactiveExpression('a');
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { MersenneTwister } from "./MersenneTwister.js";
|
|
2
|
+
|
|
3
|
+
test("constructor does not throw", () => {
|
|
4
|
+
expect(() => new MersenneTwister(0)).not.toThrow();
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
test("from seed of 0, first 3 values are within 0..1 range", () => {
|
|
8
|
+
const rng = new MersenneTwister(0);
|
|
9
|
+
|
|
10
|
+
for (let i = 0; i < 3; i++) {
|
|
11
|
+
|
|
12
|
+
const value = rng.random();
|
|
13
|
+
|
|
14
|
+
expect(value).toBeLessThanOrEqual(1)
|
|
15
|
+
expect(value).toBeGreaterThanOrEqual(0)
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { makeSequenceLoop } from "../makeSequenceLoop.js";
|
|
2
|
+
import { randomGaussian } from "./randomGaussian.js";
|
|
3
|
+
|
|
4
|
+
test("sample is average of rolls", () => {
|
|
5
|
+
|
|
6
|
+
const random = makeSequenceLoop([0, 1, 2, 11]);
|
|
7
|
+
|
|
8
|
+
expect(randomGaussian(random, 4)).toBe(3.5);
|
|
9
|
+
});
|
|
@@ -12,7 +12,7 @@ export function computeStatisticalMean(values, start = 0, end = values.length) {
|
|
|
12
12
|
|
|
13
13
|
let total = 0;
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const sample_count = end - start;
|
|
16
16
|
|
|
17
17
|
for (let i = 0; i < end; i++) {
|
|
18
18
|
const value = values[i];
|
|
@@ -20,5 +20,5 @@ export function computeStatisticalMean(values, start = 0, end = values.length) {
|
|
|
20
20
|
total += value;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
return total /
|
|
23
|
+
return total / sample_count;
|
|
24
24
|
}
|
|
@@ -23,9 +23,11 @@ export class ReactiveDivide extends ReactiveBinaryExpression {
|
|
|
23
23
|
|
|
24
24
|
return r;
|
|
25
25
|
}
|
|
26
|
+
|
|
26
27
|
equals(other) {
|
|
27
|
-
return other.isReactiveDivide && super.equals(other);
|
|
28
|
+
return (other.isReactiveDivide === true) && super.equals(other);
|
|
28
29
|
}
|
|
30
|
+
|
|
29
31
|
toCode() {
|
|
30
32
|
return `( ${this.left.toCode()} / ${this.right.toCode()} )`
|
|
31
33
|
}
|
|
@@ -22,9 +22,11 @@ export class ReactiveNegate extends ReactiveUnaryExpression {
|
|
|
22
22
|
|
|
23
23
|
return r;
|
|
24
24
|
}
|
|
25
|
+
|
|
25
26
|
equals(other) {
|
|
26
|
-
return other.isReactiveNegate && super.equals(other);
|
|
27
|
+
return (other.isReactiveNegate === true) && super.equals(other);
|
|
27
28
|
}
|
|
29
|
+
|
|
28
30
|
toCode() {
|
|
29
31
|
return `-${this.source.toCode()}`
|
|
30
32
|
}
|
|
@@ -23,9 +23,11 @@ export class ReactiveGreaterThan extends ReactiveBinaryExpression {
|
|
|
23
23
|
|
|
24
24
|
return r;
|
|
25
25
|
}
|
|
26
|
+
|
|
26
27
|
equals(other) {
|
|
27
|
-
return other.isReactiveGreaterThan && super.equals(other);
|
|
28
|
+
return (other.isReactiveGreaterThan === true) && super.equals(other);
|
|
28
29
|
}
|
|
30
|
+
|
|
29
31
|
toCode() {
|
|
30
32
|
return `( ${this.left.toCode()} > ${this.right.toCode()} )`
|
|
31
33
|
}
|
|
@@ -23,9 +23,11 @@ export class ReactiveGreaterThanOrEqual extends ReactiveBinaryExpression {
|
|
|
23
23
|
|
|
24
24
|
return r;
|
|
25
25
|
}
|
|
26
|
+
|
|
26
27
|
equals(other) {
|
|
27
|
-
return other.isReactiveGreaterThanOrEqual && super.equals(other);
|
|
28
|
+
return (other.isReactiveGreaterThanOrEqual === true) && super.equals(other);
|
|
28
29
|
}
|
|
30
|
+
|
|
29
31
|
toCode() {
|
|
30
32
|
return `( ${this.left.toCode()} >= ${this.right.toCode()} )`
|
|
31
33
|
}
|
|
@@ -23,9 +23,11 @@ export class ReactiveLessThan extends ReactiveBinaryExpression {
|
|
|
23
23
|
|
|
24
24
|
return r;
|
|
25
25
|
}
|
|
26
|
+
|
|
26
27
|
equals(other) {
|
|
27
|
-
return other.isReactiveLessThan && super.equals(other);
|
|
28
|
+
return (other.isReactiveLessThan === true) && super.equals(other);
|
|
28
29
|
}
|
|
30
|
+
|
|
29
31
|
toCode() {
|
|
30
32
|
return `( ${this.left.toCode()} < ${this.right.toCode()} )`
|
|
31
33
|
}
|
|
@@ -23,9 +23,11 @@ export class ReactiveLessThanOrEqual extends ReactiveBinaryExpression {
|
|
|
23
23
|
|
|
24
24
|
return r;
|
|
25
25
|
}
|
|
26
|
+
|
|
26
27
|
equals(other) {
|
|
27
|
-
return other.isReactiveLessThanOrEqual && super.equals(other);
|
|
28
|
+
return (other.isReactiveLessThanOrEqual === true) && super.equals(other);
|
|
28
29
|
}
|
|
30
|
+
|
|
29
31
|
toCode() {
|
|
30
32
|
return `( ${this.left.toCode()} <= ${this.right.toCode()} )`
|
|
31
33
|
}
|
|
@@ -22,9 +22,11 @@ export class ReactiveNot extends ReactiveUnaryExpression {
|
|
|
22
22
|
|
|
23
23
|
return r;
|
|
24
24
|
}
|
|
25
|
+
|
|
25
26
|
equals(other) {
|
|
26
|
-
return other.isReactiveNot && super.equals(other);
|
|
27
|
+
return (other.isReactiveNot === true) && super.equals(other);
|
|
27
28
|
}
|
|
29
|
+
|
|
28
30
|
toCode() {
|
|
29
31
|
return `!${this.source.toCode()}`
|
|
30
32
|
}
|
|
@@ -5,3 +5,10 @@ test("computeHashFloat", () => {
|
|
|
5
5
|
|
|
6
6
|
expect(computeHashFloat(500)).not.toEqual(computeHashFloat(400))
|
|
7
7
|
});
|
|
8
|
+
|
|
9
|
+
test("hash is an integer", () => {
|
|
10
|
+
const hash = computeHashFloat(1.237);
|
|
11
|
+
|
|
12
|
+
expect(typeof hash).toBe("number");
|
|
13
|
+
expect(Number.isInteger(hash)).toBe(true);
|
|
14
|
+
});
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import Task from "../Task.js";
|
|
2
2
|
import { TaskSignal } from "../TaskSignal.js";
|
|
3
3
|
import { assert } from "../../../assert.js";
|
|
4
|
+
import { anyOf, equalTo } from "../../../debug/matchers/matchers.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
*
|
|
7
8
|
* @param {string} name
|
|
8
9
|
* @param {Iterator} iterator
|
|
9
|
-
* @param {TaskSignal.Continue|TaskSignal.Yield} [cycle_signal] what to signal at the end of each iteration, Continue will provide better throughput, whereas Yield will produce very low load on the CPU
|
|
10
|
+
* @param {(TaskSignal.Continue)|(TaskSignal.Yield)} [cycle_signal] what to signal at the end of each iteration, Continue will provide better throughput, whereas Yield will produce very low load on the CPU
|
|
10
11
|
* @returns {Task}
|
|
11
12
|
*/
|
|
12
13
|
export function iteratorTask(name, iterator, cycle_signal = TaskSignal.Continue) {
|
|
13
14
|
assert.defined(iterator, 'iterator');
|
|
14
15
|
assert.notNull(iterator, 'iterator');
|
|
15
16
|
assert.isFunction(iterator.next, 'iterator.next');
|
|
17
|
+
assert.that(cycle_signal, 'cycle_signal', anyOf(equalTo(TaskSignal.Continue), equalTo(TaskSignal.Yield)));
|
|
16
18
|
|
|
17
19
|
return new Task({
|
|
18
20
|
name,
|