@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
|
@@ -7,194 +7,202 @@ import { EPSILON } from "../math/EPSILON.js";
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* Represents a direction vector+angle
|
|
11
|
+
* Mainly used inside particle systems for pick a motion direction at spawn
|
|
12
12
|
*/
|
|
13
|
-
export
|
|
13
|
+
export class ConicRay {
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
* @
|
|
15
|
+
*
|
|
16
|
+
* @constructor
|
|
17
17
|
*/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
constructor() {
|
|
19
|
+
/**
|
|
20
|
+
* Must be normalized
|
|
21
|
+
* @type {Vector3}
|
|
22
|
+
*/
|
|
23
|
+
this.direction = new Vector3(0, 1, 0);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Semi-angle of the cone, that is the angle between the center axis and the edge of the cone
|
|
27
|
+
* In radians
|
|
28
|
+
* @type {number}
|
|
29
|
+
*/
|
|
30
|
+
this.angle = 0;
|
|
31
|
+
}
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
33
|
+
toJSON() {
|
|
34
|
+
return {
|
|
35
|
+
direction: this.direction.toJSON(),
|
|
36
|
+
angle: this.angle
|
|
37
|
+
};
|
|
38
|
+
}
|
|
34
39
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
40
|
+
fromJSON(json) {
|
|
41
|
+
this.direction.fromJSON(json.direction);
|
|
42
|
+
this.angle = json.angle;
|
|
43
|
+
}
|
|
39
44
|
|
|
40
|
-
/**
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @param {BinaryBuffer} buffer
|
|
48
|
+
*/
|
|
49
|
+
toBinaryBuffer(buffer) {
|
|
50
|
+
buffer.writeFloat64(this.angle);
|
|
51
|
+
this.direction.toBinaryBufferFloat32(buffer);
|
|
52
|
+
}
|
|
48
53
|
|
|
49
|
-
/**
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
/**
|
|
55
|
+
*
|
|
56
|
+
* @param {BinaryBuffer} buffer
|
|
57
|
+
*/
|
|
58
|
+
fromBinaryBuffer(buffer) {
|
|
59
|
+
this.angle = buffer.readFloat64();
|
|
60
|
+
this.direction.fromBinaryBufferFloat32(buffer);
|
|
56
61
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
62
|
+
//normalize direction
|
|
63
|
+
this.direction.normalize();
|
|
64
|
+
}
|
|
60
65
|
|
|
61
|
-
/**
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
66
|
+
/**
|
|
67
|
+
*
|
|
68
|
+
* @param {ConicRay} other
|
|
69
|
+
* @returns {boolean}
|
|
70
|
+
*/
|
|
71
|
+
equals(other) {
|
|
72
|
+
return this.angle === other.angle && this.direction.equals(other.direction);
|
|
73
|
+
}
|
|
69
74
|
|
|
70
|
-
/**
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
/**
|
|
76
|
+
*
|
|
77
|
+
* @param {ConicRay} other
|
|
78
|
+
* @param {number} tolerance
|
|
79
|
+
* @returns {boolean}
|
|
80
|
+
*/
|
|
81
|
+
roughlyEquals(other, tolerance = EPSILON) {
|
|
82
|
+
return epsilonEquals(this.angle, other.angle, tolerance)
|
|
83
|
+
&& this.direction.roughlyEquals(other.direction, tolerance);
|
|
84
|
+
}
|
|
79
85
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
+
hash() {
|
|
87
|
+
return computeHashIntegerArray(
|
|
88
|
+
computeHashFloat(this.angle),
|
|
89
|
+
this.direction.hash()
|
|
90
|
+
);
|
|
91
|
+
}
|
|
86
92
|
|
|
87
|
-
/**
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
93
|
+
/**
|
|
94
|
+
*
|
|
95
|
+
* @param {ConicRay} other
|
|
96
|
+
*/
|
|
97
|
+
copy(other) {
|
|
98
|
+
this.direction.copy(other.direction);
|
|
99
|
+
this.angle = other.angle;
|
|
100
|
+
}
|
|
95
101
|
|
|
96
|
-
/**
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
/**
|
|
103
|
+
* Includes boundary matches
|
|
104
|
+
* @param {Vector3} v3
|
|
105
|
+
* @returns {boolean}
|
|
106
|
+
*/
|
|
107
|
+
containsDirectionVector(v3) {
|
|
108
|
+
const angular_distance = this.direction.angleTo(v3);
|
|
103
109
|
|
|
104
|
-
|
|
105
|
-
}
|
|
110
|
+
return angular_distance <= this.angle;
|
|
111
|
+
}
|
|
106
112
|
|
|
107
|
-
/**
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
/**
|
|
114
|
+
* NOTE: Heavily based on a stackoverflow answer
|
|
115
|
+
* @see https://stackoverflow.com/questions/38997302/create-random-unit-vector-inside-a-defined-conical-region/39003745#39003745
|
|
116
|
+
* @param {function} random
|
|
117
|
+
* @param {Vector3} result
|
|
118
|
+
*/
|
|
119
|
+
sampleRandomDirection(random, result) {
|
|
120
|
+
const coneAngle = this.angle;
|
|
115
121
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
if (coneAngle === 0) {
|
|
123
|
+
//fast path, just copy ray direction
|
|
124
|
+
result.copy(this.direction);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
121
127
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
// Generate points on the spherical cap around the north pole [1].
|
|
129
|
+
// [1] See https://math.stackexchange.com/a/205589/81266
|
|
130
|
+
const angleCosine = Math.cos(coneAngle);
|
|
125
131
|
|
|
126
|
-
|
|
132
|
+
const z = random() * (1 - angleCosine) + angleCosine;
|
|
127
133
|
|
|
128
|
-
|
|
134
|
+
const phi = random() * 6.28318530718; //2*pi
|
|
129
135
|
|
|
130
|
-
|
|
136
|
+
const zSqr = z * z;
|
|
131
137
|
|
|
132
|
-
|
|
138
|
+
const zSqrtNeg = Math.sqrt(1 - zSqr);
|
|
133
139
|
|
|
134
|
-
|
|
135
|
-
|
|
140
|
+
const x = zSqrtNeg * Math.cos(phi);
|
|
141
|
+
const y = zSqrtNeg * Math.sin(phi);
|
|
136
142
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
+
// If the spherical cap is centered around the north pole, we're done.
|
|
144
|
+
const direction = this.direction;
|
|
145
|
+
if (direction._equals(0, 0, 1)) {
|
|
146
|
+
result.set(x, y, z);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
143
149
|
|
|
144
|
-
|
|
150
|
+
assert.ok(direction.isNormalized(), 'direction vector must be normalized');
|
|
145
151
|
|
|
146
|
-
|
|
152
|
+
// Find the rotation axis `u` and rotation angle `rot` [1]
|
|
147
153
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
const dX = direction.x;
|
|
155
|
+
const dY = direction.y;
|
|
156
|
+
const dZ = direction.z;
|
|
151
157
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
158
|
+
//compute u
|
|
159
|
+
//compute rotation angle
|
|
160
|
+
const rot = Math.acos(dZ);
|
|
155
161
|
|
|
156
162
|
|
|
157
|
-
|
|
158
|
-
|
|
163
|
+
// Convert rotation axis and angle to 3x3 rotation matrix [2]
|
|
164
|
+
// [2] See https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle
|
|
159
165
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
+
//write matrix
|
|
167
|
+
const c = dZ;
|
|
168
|
+
const s = Math.sin(rot);
|
|
169
|
+
const t = 1 - c;
|
|
170
|
+
const tx = -t * dY;
|
|
171
|
+
const ty = t * dX;
|
|
166
172
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
+
//build relevant terms of the matrix
|
|
174
|
+
const n11 = c - tx * dY;
|
|
175
|
+
const n12 = tx * dX;
|
|
176
|
+
const n22 = ty * dX + c;
|
|
177
|
+
const n13 = s * dX;
|
|
178
|
+
const n32 = -s * dY;
|
|
173
179
|
|
|
174
180
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
181
|
+
// Rotate [x; y; z] from north pole to `coneDir`.
|
|
182
|
+
const _x = n11 * x + n12 * y + n13 * z;
|
|
183
|
+
const _y = n12 * x + n22 * y + -n32 * z;
|
|
184
|
+
const _z = -n13 * x + n32 * y + c * z;
|
|
179
185
|
|
|
180
|
-
|
|
181
|
-
}
|
|
186
|
+
result.set(_x, _y, _z);
|
|
187
|
+
}
|
|
182
188
|
|
|
183
|
-
/**
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
189
|
+
/**
|
|
190
|
+
*
|
|
191
|
+
* @param {number} x
|
|
192
|
+
* @param {number} y
|
|
193
|
+
* @param {number} z
|
|
194
|
+
* @param {number} angle
|
|
195
|
+
* @returns {ConicRay}
|
|
196
|
+
*/
|
|
197
|
+
static fromScalars(x, y, z, angle) {
|
|
198
|
+
assert.greaterThanOrEqual(angle, 0, 'angle must be non-negative');
|
|
193
199
|
|
|
194
|
-
|
|
200
|
+
const r = new ConicRay();
|
|
195
201
|
|
|
196
|
-
|
|
197
|
-
|
|
202
|
+
r.angle = angle;
|
|
203
|
+
r.direction.set(x, y, z);
|
|
198
204
|
|
|
199
|
-
|
|
205
|
+
return r;
|
|
206
|
+
}
|
|
200
207
|
}
|
|
208
|
+
|
package/src/core/geom/Matrix4.js
CHANGED
|
@@ -1125,7 +1125,25 @@ class Quaternion {
|
|
|
1125
1125
|
* @param {number} m33
|
|
1126
1126
|
* @returns {Quaternion}
|
|
1127
1127
|
*/
|
|
1128
|
-
__setFromRotationMatrix(
|
|
1128
|
+
__setFromRotationMatrix(
|
|
1129
|
+
m11, m12, m13,
|
|
1130
|
+
m21, m22, m23,
|
|
1131
|
+
m31, m32, m33
|
|
1132
|
+
) {
|
|
1133
|
+
|
|
1134
|
+
assert.notNaN(m11,'m11');
|
|
1135
|
+
assert.notNaN(m12,'m12');
|
|
1136
|
+
assert.notNaN(m13,'m13');
|
|
1137
|
+
|
|
1138
|
+
assert.notNaN(m21,'m21');
|
|
1139
|
+
assert.notNaN(m22,'m22');
|
|
1140
|
+
assert.notNaN(m23,'m23');
|
|
1141
|
+
|
|
1142
|
+
assert.notNaN(m31,'m31');
|
|
1143
|
+
assert.notNaN(m32,'m32');
|
|
1144
|
+
assert.notNaN(m33,'m33');
|
|
1145
|
+
|
|
1146
|
+
|
|
1129
1147
|
const trace = m11 + m22 + m33;
|
|
1130
1148
|
|
|
1131
1149
|
let x, y, z, w, s;
|
|
@@ -1,221 +1,15 @@
|
|
|
1
1
|
import BinaryHeap from "../../../collection/heap/FastBinaryHeap.js";
|
|
2
2
|
import { assert } from "../../../assert.js";
|
|
3
|
-
import { max2 } from "../../../math/max2.js";
|
|
4
|
-
import { min2 } from "../../../math/min2.js";
|
|
5
3
|
import { QuadTreeDatum } from "../../2d/quad-tree/QuadTreeDatum.js";
|
|
6
4
|
import { QuadTreeNode } from "../../2d/quad-tree/QuadTreeNode.js";
|
|
7
5
|
import AABB2 from "../../2d/aabb/AABB2.js";
|
|
8
6
|
import Vector2 from "../../Vector2.js";
|
|
9
|
-
import { removeRedundantBoxesArray } from "./removeRedundantBoxesArray.js";
|
|
10
7
|
import { removeRedundantBoxes } from "./removeRedundantBoxes.js";
|
|
8
|
+
import { costByRemainingArea } from "./cost/costByRemainingArea.js";
|
|
9
|
+
import { findBestContainer } from "./findBestContainer.js";
|
|
10
|
+
import { packOneBox } from "./packOneBox.js";
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
/**
|
|
14
|
-
*
|
|
15
|
-
* @param {number} containerWidth
|
|
16
|
-
* @param {number} containerHeight
|
|
17
|
-
* @param {number} childWidth
|
|
18
|
-
* @param {number} childHeight
|
|
19
|
-
* @returns {number}
|
|
20
|
-
*/
|
|
21
|
-
function costByRemainingArea(containerWidth, containerHeight, childWidth, childHeight) {
|
|
22
|
-
const dW = containerWidth - childWidth;
|
|
23
|
-
const dH = containerHeight - childHeight;
|
|
24
|
-
|
|
25
|
-
return dW * containerHeight + dH * childWidth;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
*
|
|
30
|
-
* @param {number} containerWidth
|
|
31
|
-
* @param {number} containerHeight
|
|
32
|
-
* @param {number} childWidth
|
|
33
|
-
* @param {number} childHeight
|
|
34
|
-
* @returns {number}
|
|
35
|
-
*/
|
|
36
|
-
function costByBestShortSide(containerWidth, containerHeight, childWidth, childHeight) {
|
|
37
|
-
return Math.min(containerWidth - childWidth, containerHeight - childHeight);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
*
|
|
42
|
-
* @param {number} width
|
|
43
|
-
* @param {number} height
|
|
44
|
-
* @param {QuadTreeNode} boxes
|
|
45
|
-
* @param {function(containerWidth:number, containerHeight:number, childWidth:number, childHeight:number):number} costFunction
|
|
46
|
-
* @returns {QuadTreeDatum} suitable container box
|
|
47
|
-
*/
|
|
48
|
-
function findBestContainer(width, height, boxes, costFunction) {
|
|
49
|
-
let best = null;
|
|
50
|
-
let bestScore = Number.POSITIVE_INFINITY;
|
|
51
|
-
|
|
52
|
-
const visitor = (node) => {
|
|
53
|
-
|
|
54
|
-
if (node.getWidth() < width) {
|
|
55
|
-
//too small, don't traverse deeper
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (node.getHeight() < height) {
|
|
60
|
-
//too small, don't traverse deeper
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const data = node.data;
|
|
65
|
-
const numBoxes = data.length;
|
|
66
|
-
|
|
67
|
-
for (let i = 0; i < numBoxes; i++) {
|
|
68
|
-
const box = data[i];
|
|
69
|
-
|
|
70
|
-
const bW = box.getWidth();
|
|
71
|
-
|
|
72
|
-
if (bW < width) {
|
|
73
|
-
//too small
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const bH = box.getHeight();
|
|
78
|
-
|
|
79
|
-
if (bH < height) {
|
|
80
|
-
//too small
|
|
81
|
-
continue;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const cost = costFunction(bW, bH, width, height);
|
|
85
|
-
if (cost < bestScore) {
|
|
86
|
-
bestScore = cost;
|
|
87
|
-
best = box;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return true;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
boxes.traversePreOrder(visitor);
|
|
95
|
-
|
|
96
|
-
return best;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Cut out a region from given set of boxes
|
|
101
|
-
* @param {AABB2} scissor area to be cut out
|
|
102
|
-
* @param {QuadTreeNode} boxes
|
|
103
|
-
*/
|
|
104
|
-
function cutArea(scissor, boxes) {
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
*
|
|
108
|
-
* @type {QuadTreeDatum[]}
|
|
109
|
-
*/
|
|
110
|
-
const additions = [];
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
*
|
|
114
|
-
* @type {QuadTreeDatum[]}
|
|
115
|
-
*/
|
|
116
|
-
const removals = [];
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
*
|
|
120
|
-
* @param {QuadTreeDatum} box
|
|
121
|
-
*/
|
|
122
|
-
function visitOverlap(box) {
|
|
123
|
-
removals.push(box);
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
//compute overlap region
|
|
127
|
-
const x0 = max2(scissor.x0, box.x0);
|
|
128
|
-
const x1 = min2(scissor.x1, box.x1);
|
|
129
|
-
|
|
130
|
-
const y0 = max2(scissor.y0, box.y0);
|
|
131
|
-
const y1 = min2(scissor.y1, box.y1);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
//create 4 boxes around overlap
|
|
135
|
-
if (x0 > box.x0) {
|
|
136
|
-
//add left box
|
|
137
|
-
additions.push(new QuadTreeDatum(box.x0, box.y0, x0, box.y1));
|
|
138
|
-
}
|
|
139
|
-
if (x1 < box.x1) {
|
|
140
|
-
//add right box
|
|
141
|
-
additions.push(new QuadTreeDatum(x1, box.y0, box.x1, box.y1));
|
|
142
|
-
}
|
|
143
|
-
if (y0 > box.y0) {
|
|
144
|
-
//add top box
|
|
145
|
-
additions.push(new QuadTreeDatum(box.x0, box.y0, box.x1, y0));
|
|
146
|
-
}
|
|
147
|
-
if (y1 < box.y1) {
|
|
148
|
-
//add bottom box
|
|
149
|
-
additions.push(new QuadTreeDatum(box.x0, y1, box.x1, box.y1));
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
boxes.traverseRectangleIntersections(scissor.x0, scissor.y0, scissor.x1, scissor.y1, visitOverlap);
|
|
155
|
-
|
|
156
|
-
let i, l;
|
|
157
|
-
//perform removals
|
|
158
|
-
for (i = 0, l = removals.length; i < l; i++) {
|
|
159
|
-
const removal = removals[i];
|
|
160
|
-
removal.disconnect();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
//drop potential overlaps between additions
|
|
164
|
-
removeRedundantBoxesArray(additions);
|
|
165
|
-
|
|
166
|
-
//perform additions
|
|
167
|
-
for (i = 0, l = additions.length; i < l; i++) {
|
|
168
|
-
const addition = additions[i];
|
|
169
|
-
|
|
170
|
-
boxes.insertDatum(addition);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
*
|
|
176
|
-
* @param {AABB2} box
|
|
177
|
-
* @param {QuadTreeNode} free
|
|
178
|
-
* @returns {boolean}
|
|
179
|
-
*/
|
|
180
|
-
function packOneBox(box, free) {
|
|
181
|
-
const w = box.getWidth();
|
|
182
|
-
const h = box.getHeight();
|
|
183
|
-
|
|
184
|
-
const container = findBestContainer(w, h, free, costByRemainingArea);
|
|
185
|
-
|
|
186
|
-
if (container === null) {
|
|
187
|
-
//couldn't find a place for box
|
|
188
|
-
return false;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
//remove container from free set
|
|
192
|
-
container.disconnect();
|
|
193
|
-
|
|
194
|
-
//place box at bottom left of the container
|
|
195
|
-
const y0 = container.y0;
|
|
196
|
-
const x0 = container.x0;
|
|
197
|
-
|
|
198
|
-
box.set(x0, y0, x0 + w, y0 + h);
|
|
199
|
-
|
|
200
|
-
//update remaining set by removing this box area from free set
|
|
201
|
-
cutArea(box, free);
|
|
202
|
-
|
|
203
|
-
//split remaining space
|
|
204
|
-
if (box.y1 !== container.y1) {
|
|
205
|
-
const splitA = new QuadTreeDatum(container.x0, box.y1, container.x1, container.y1);
|
|
206
|
-
|
|
207
|
-
free.insertDatum(splitA);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (box.x1 !== container.x1) {
|
|
211
|
-
const splitB = new QuadTreeDatum(box.x1, container.y0, container.x1, container.y1);
|
|
212
|
-
free.insertDatum(splitB);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return true;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
13
|
export class MaxRectanglesPacker {
|
|
220
14
|
/**
|
|
221
15
|
*
|
|
@@ -456,13 +250,9 @@ export class MaxRectanglesPacker {
|
|
|
456
250
|
* @param {AABB2[]} boxes
|
|
457
251
|
* @returns {boolean} true if packing was successful, false otherwise
|
|
458
252
|
*/
|
|
459
|
-
function packMaxRectangles(width, height, boxes) {
|
|
253
|
+
export function packMaxRectangles(width, height, boxes) {
|
|
460
254
|
|
|
461
255
|
const packer = new MaxRectanglesPacker(width, height);
|
|
462
256
|
|
|
463
257
|
return packer.addMany(boxes);
|
|
464
258
|
}
|
|
465
|
-
|
|
466
|
-
export {
|
|
467
|
-
packMaxRectangles
|
|
468
|
-
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {number} containerWidth
|
|
4
|
+
* @param {number} containerHeight
|
|
5
|
+
* @param {number} childWidth
|
|
6
|
+
* @param {number} childHeight
|
|
7
|
+
* @returns {number}
|
|
8
|
+
*/
|
|
9
|
+
export function costByBestShortSide(containerWidth, containerHeight, childWidth, childHeight) {
|
|
10
|
+
return Math.min(containerWidth - childWidth, containerHeight - childHeight);
|
|
11
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {number} containerWidth
|
|
4
|
+
* @param {number} containerHeight
|
|
5
|
+
* @param {number} childWidth
|
|
6
|
+
* @param {number} childHeight
|
|
7
|
+
* @returns {number}
|
|
8
|
+
*/
|
|
9
|
+
export function costByRemainingArea(containerWidth, containerHeight, childWidth, childHeight) {
|
|
10
|
+
const dW = containerWidth - childWidth;
|
|
11
|
+
const dH = containerHeight - childHeight;
|
|
12
|
+
|
|
13
|
+
return dW * containerHeight + dH * childWidth;
|
|
14
|
+
}
|