@woosh/meep-engine 2.49.8 → 2.50.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/actions/concrete/ArrayCopyAction.js +1 -1
- package/package.json +1 -1
- package/src/core/binary/BinaryBuffer.js +1 -1
- package/src/core/binary/BinaryBuffer.spec.js +128 -0
- package/src/core/binary/int32_to_binary_string.js +4 -1
- package/src/core/binary/int32_to_binary_string.spec.js +9 -0
- package/src/core/bvh2/BinaryNode.js +0 -30
- package/src/core/bvh2/binary/2/BinaryUint32BVH.js +1 -1
- package/src/core/bvh2/binary/IndexedBinaryBVH.js +1 -1
- package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +1 -1
- package/src/core/bvh2/bvh3/query/compute_tight_near_far_clipping_planes.js +1 -1
- package/src/core/cache/Cache.js +31 -29
- package/src/core/cache/Cache.spec.js +4 -1
- package/src/core/collection/HashMap.js +1 -1
- package/src/core/collection/array/{copyArray.js → array_copy.js} +1 -24
- package/src/core/collection/array/array_copy_entire.js +21 -0
- package/src/core/collection/array/typed/typed_array_copy.js +1 -1
- package/src/core/collection/queue/Deque.d.ts +4 -0
- package/src/core/collection/queue/Deque.js +5 -7
- package/src/core/collection/queue/Deque.spec.js +107 -0
- package/src/core/collection/table/RowFirstTable.js +1 -1
- package/src/core/geom/2d/aabb/AABB2.d.ts +14 -0
- package/src/core/geom/2d/aabb/AABB2.js +9 -7
- package/src/core/geom/2d/aabb/AABB2.spec.js +100 -0
- package/src/core/geom/2d/aabb/aabb2_compute_center_from_multiple.spec.js +11 -0
- package/src/core/geom/2d/aabb/aabb2_compute_overlap.spec.js +56 -0
- package/src/core/geom/2d/aabb/aabb2_contains.spec.js +40 -0
- package/src/core/geom/2d/bvh/Node2.js +1 -1
- package/src/core/geom/2d/convex-hull/fixed_convex_hull_humus.js +1 -1
- package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js +1 -1
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_2d.js +35 -0
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_array_2d.js +51 -0
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_2d.js +15 -0
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_array_2d.js +30 -0
- package/src/core/geom/2d/line/line_segment_line_segment_intersection_exists_2d.js +29 -0
- package/src/core/geom/3d/aabb/AABB3.d.ts +4 -0
- package/src/core/geom/3d/aabb/AABB3.spec.js +30 -0
- package/src/core/geom/3d/matrix/m4_make_translation.js +1 -1
- package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +1 -1
- package/src/core/geom/3d/tetrahedra/TetrahedralMesh.js +1 -1
- package/src/core/geom/3d/tetrahedra/compute_circumsphere.js +1 -1
- package/src/core/geom/3d/tetrahedra/delaunay/fill_in_a_cavity.js +1 -1
- package/src/core/geom/3d/topology/bounds/computeTriangleClusterNormalBoundingCone.js +1 -1
- package/src/core/geom/3d/topology/expandConnectivityByLocality.js +1 -1
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +1 -1
- package/src/core/geom/Quaternion.d.ts +11 -0
- package/src/core/geom/Quaternion.js +36 -27
- package/src/core/geom/Quaternion.spec.js +141 -0
- package/src/core/geom/Vector2.d.ts +5 -1
- package/src/core/geom/Vector2.js +24 -0
- package/src/core/geom/Vector3.d.ts +4 -0
- package/src/core/geom/Vector3.spec.js +60 -0
- package/src/core/graph/GraphUtils.js +4 -2
- package/src/core/graph/layout/CircleLayout.js +4 -2
- package/src/core/math/bessel_i0.spec.js +43 -0
- package/src/core/math/bessel_j0.js +30 -0
- package/src/core/math/hash/murmur3_32.spec.js +8 -0
- package/src/core/math/hash/squirrel3.spec.js +16 -0
- package/src/core/math/interval/NumericInterval.js +1 -0
- package/src/core/math/{bessel_i0.js → modified_bessel_i0.js} +5 -2
- package/src/core/math/noise/{create_noise_2d.js → create_simplex_noise_2d.js} +2 -2
- package/src/core/math/noise/create_simplex_noise_2d.spec.js +21 -0
- package/src/core/math/physics/irradiance/interpolate_irradiance_linear.spec.js +20 -0
- package/src/core/math/physics/irradiance/interpolate_irradiance_lograrithmic.js +4 -4
- package/src/core/math/physics/irradiance/interpolate_irradiance_lograrithmic.spec.js +18 -0
- package/src/core/math/physics/irradiance/interpolate_irradiance_smith.js +1 -1
- package/src/core/math/physics/irradiance/interpolate_irradiance_smith.spec.js +20 -0
- package/src/core/math/random/seededRandomMersenneTwister.spec.js +10 -0
- package/src/core/math/spline/spline_bezier3.js +1 -1
- package/src/core/math/spline/spline_bezier3_bounds.js +2 -1
- package/src/core/math/spline/spline_bezier3_bounds.spec.js +37 -0
- package/src/core/math/statistics/computeSampleSize_Cochran.spec.js +12 -0
- package/src/core/math/statistics/computeStatisticalPartialMedian.js +4 -0
- package/src/core/math/statistics/computeStatisticalPartialMedian.spec.js +13 -0
- package/src/core/math/vector_nd_dot.js +16 -0
- package/src/core/math/{normalizeArrayVector.js → vector_nd_normalize.js} +3 -3
- package/src/core/math/vector_nd_normalize.spec.js +15 -0
- package/src/core/process/PromiseWatcher.spec.js +1 -1
- package/src/engine/achievements/Achievement.spec.js +21 -0
- package/src/engine/animation/curve/compression/downsample_float_array_curve_by_error.js +1 -1
- package/src/engine/animation/curve/compression/prototypeCurveCompression.js +2 -2
- package/src/engine/animation/curve/compression/{animation_curve_to_float_array.js → sample_animation_curve_to_float_array.js} +10 -3
- package/src/engine/animation/curve/compression/sample_animation_curve_to_float_array.spec.js +29 -0
- package/src/engine/animation/curve/draw/build_curve_editor.js +3 -3
- package/src/engine/development/performance/RingBufferMetric.js +1 -1
- package/src/engine/ecs/EntityManager.js +1 -205
- package/src/engine/ecs/animation/Animation.js +2 -180
- package/src/engine/ecs/animation/AnimationClip.js +132 -0
- package/src/engine/ecs/animation/AnimationClip.spec.js +5 -0
- package/src/engine/ecs/animation/AnimationClipFlag.js +7 -0
- package/src/engine/ecs/animation/AnimationFlags.js +8 -0
- package/src/engine/ecs/animation/AnimationSerializationAdapter.js +32 -0
- package/src/engine/ecs/fow/FogOfWar.js +1 -1
- package/src/engine/ecs/guid/GUID.js +1 -1
- package/src/engine/ecs/systems/AnimationSystem.js +3 -1
- package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +1 -1
- package/src/engine/ecs/terrain/overlay/TerrainOverlay.js +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +1 -1
- package/src/engine/ecs/transform/Transform.d.ts +2 -0
- package/src/engine/ecs/transform/Transform.spec.js +63 -0
- package/src/engine/ecs/transform-attachment/TransformAttachment.d.ts +17 -1
- package/src/engine/ecs/transform-attachment/TransformAttachment.js +12 -2
- package/src/engine/ecs/transform-attachment/TransformAttachment.spec.js +103 -0
- package/src/engine/graphics/camera/testClippingPlaneComputation.js +1 -1
- package/src/engine/graphics/ecs/animation/AnimationControllerSystem.js +2 -1
- package/src/engine/graphics/ecs/path/testPathDisplaySystem.js +1 -1
- package/src/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +1 -1
- package/src/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +1 -1
- package/src/engine/graphics/geometry/MikkT/GenerateTSpaces.js +1 -1
- package/src/engine/graphics/geometry/MikkT/m_getNormal.js +1 -1
- package/src/engine/graphics/geometry/MikkT/m_getTexCoord.js +1 -1
- package/src/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +1 -1
- package/src/engine/graphics/geometry/instancing/InstancedMeshGroup.js +1 -1
- package/src/engine/graphics/geometry/optimization/merge/merge_geometry_hierarchy.js +1 -1
- package/src/engine/graphics/impostors/octahedral/util/build_cutout_from_atlas_by_alpha.js +1 -1
- package/src/engine/graphics/load_and_set_cubemap_v0.js +1 -1
- package/src/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +1 -1
- package/src/engine/graphics/render/Lines.js +1 -1
- package/src/engine/graphics/render/buffer/buffers/prototypeNormalFrameBuffer.js +1 -1
- package/src/engine/graphics/render/buffer/simple-fx/taa/TemporalSupersamplingRenderPlugin.js +1 -1
- package/src/engine/graphics/render/forward_plus/LightManager.js +1 -1
- package/src/engine/graphics/render/forward_plus/model/Decal.js +1 -1
- package/src/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +1 -1
- package/src/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +1 -1
- package/src/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +1 -1
- package/src/engine/graphics/render/view/CameraView.js +1 -1
- package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +1 -1
- package/src/engine/graphics/render/visibility/hiz/query/BatchOcclusionQuery.js +1 -1
- package/src/engine/graphics/render/webgpu/sample/MeshInstance.js +1 -1
- package/src/engine/graphics/sh3/LightProbeVolume.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/PathTracer.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/make_sky_hosek.js +1 -1
- package/src/engine/graphics/sh3/prototypeSH3Probe.js +1 -1
- package/src/engine/graphics/texture/3d/scs3d_read_2d_slice.js +1 -1
- package/src/engine/graphics/texture/CanvasClone.js +5 -1
- package/src/engine/graphics/texture/sampler/Sampler2D.js +14 -75
- package/src/engine/graphics/texture/sampler/bicubic.js +19 -19
- package/src/engine/graphics/texture/sampler/convertSampler2D2DataURL.spec.js +10 -0
- package/src/engine/graphics/texture/sampler/copy_Sampler2D_channel_data.spec.js +90 -0
- package/src/engine/graphics/texture/sampler/differenceSampler.js +13 -8
- package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_Chamfer.js +140 -0
- package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_NaiveFlood.js +130 -0
- package/src/engine/graphics/texture/sampler/distance/computeUnsignedDistanceField.js +10 -0
- package/src/engine/graphics/texture/sampler/distance/computeUnsignedDistanceField.spec.js +183 -0
- package/src/engine/graphics/texture/sampler/distance/computeUnsignedDistanceField_Chamfer.js +133 -0
- package/src/engine/graphics/texture/sampler/filter/kaiser_1.js +8 -4
- package/src/engine/graphics/texture/sampler/filter/kaiser_bessel_window.js +2 -0
- package/src/engine/graphics/texture/sampler/filter/mitchell.js +4 -0
- package/src/engine/graphics/texture/sampler/loadSampler2D.js +5 -2
- package/src/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.js +8 -3
- package/src/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.spec.js +13 -0
- package/src/engine/graphics/texture/sampler/sampler2d_channel_compute_min_indices.js +58 -0
- package/src/engine/graphics/trail/TemporalPath.js +0 -36
- package/src/engine/intelligence/behavior/composite/ParallelBehavior.spec.js +12 -12
- package/src/engine/intelligence/behavior/composite/SequenceBehavior.spec.js +17 -0
- package/src/engine/intelligence/behavior/primitive/SucceedingBehavior.js +2 -0
- package/src/engine/knowledge/database/StaticKnowledgeDataTable.d.ts +7 -1
- package/src/engine/knowledge/database/StaticKnowledgeDataTable.spec.js +21 -0
- package/src/engine/knowledge/database/StaticKnowledgeDataTableDescriptor.d.ts +2 -2
- package/src/engine/logging/ConsoleLoggerBackend.js +4 -0
- package/src/engine/logging/VoidLoggerBackend.js +12 -0
- package/src/engine/navigation/ecs/components/computeCatmullRomSpline.js +1 -1
- package/src/engine/navigation/ecs/components/computeCatmullRomSplineUniformDistance.js +1 -1
- package/src/engine/physics/cannon/CannonJSPhysicsSystem.js +1 -1
- package/src/engine/save/GameStateLoader.js +1 -1
- package/src/engine/scene/Scene.d.ts +2 -0
- package/src/engine/scene/Scene.js +2 -2
- package/src/engine/scene/Scene.spec.js +20 -0
- package/src/engine/scene/SceneManager.d.ts +4 -0
- package/src/engine/scene/SceneManager.js +46 -23
- package/src/engine/scene/SceneManager.spec.js +107 -0
- package/src/engine/sound/material/detector/terrain/TerrainSoundMaterialSurfaceDetector.js +2 -2
- package/src/engine/ui/GUIEngine.js +1 -1
- package/src/generation/filtering/numeric/complex/CellFilterAngleToNormal.js +11 -4
- package/src/generation/filtering/numeric/complex/CellFilterAngleToNormal.spec.js +30 -0
- package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +18 -2
- package/src/generation/filtering/numeric/complex/CellFilterGaussianBlur.spec.js +17 -0
- package/src/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +2 -2
- package/src/generation/grid/GridData.js +0 -60
- package/src/generation/grid/generation/util/buildUnsignedDistanceField.js +3 -1
- package/src/generation/markers/MarkerNode.js +2 -2
- package/src/generation/theme/AreaMask.js +3 -1
- package/src/view/elements/progress/RectangularPieProgressView.js +8 -6
- package/src/core/geom/2d/LineSegment2.js +0 -175
- package/src/core/geom/Matrix4.js +0 -275
- package/src/engine/graphics/texture/sampler/distanceField.js +0 -411
- package/src/engine/graphics/texture/sampler/distanceField.spec.js +0 -184
- package/src/engine/physics/cannon/cannon.min.js +0 -27
- /package/src/engine/ecs/{animation → ik}/IKMath.js +0 -0
- /package/src/engine/ecs/{animation → ik}/IKProblem.js +0 -0
- /package/src/engine/ecs/{animation → ik}/IKSolver.js +0 -0
- /package/src/engine/ecs/{animation → ik}/InverseKinematics.js +0 -0
- /package/src/engine/ecs/{animation → ik}/InverseKinematicsSystem.js +0 -0
- /package/src/engine/ecs/{animation → ik}/OneBoneSurfaceAlignmentSolver.js +0 -0
- /package/src/engine/ecs/{animation → ik}/TwoBoneInverseKinematicsSolver.js +0 -0
- /package/src/engine/physics/spring/{Spring.js → computeHookeForce.js} +0 -0
|
@@ -136,15 +136,16 @@ class Quaternion {
|
|
|
136
136
|
|
|
137
137
|
up.crossVectors(forward, right);
|
|
138
138
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
139
|
+
// construct partial transform matrix
|
|
140
|
+
const m00 = right.x;
|
|
141
|
+
const m01 = right.y;
|
|
142
|
+
const m02 = right.z;
|
|
143
|
+
const m10 = up.x;
|
|
144
|
+
const m11 = up.y;
|
|
145
|
+
const m12 = up.z;
|
|
146
|
+
const m20 = forward.x;
|
|
147
|
+
const m21 = forward.y;
|
|
148
|
+
const m22 = forward.z;
|
|
148
149
|
|
|
149
150
|
|
|
150
151
|
const num8 = (m00 + m11) + m22;
|
|
@@ -159,22 +160,29 @@ class Quaternion {
|
|
|
159
160
|
_y = (m20 - m02) * num;
|
|
160
161
|
_z = (m01 - m10) * num;
|
|
161
162
|
} else if ((m00 >= m11) && (m00 >= m22)) {
|
|
162
|
-
|
|
163
|
-
|
|
163
|
+
|
|
164
|
+
const num7 = Math.sqrt(((1 + m00) - m11) - m22);
|
|
165
|
+
const num4 = 0.5 / num7;
|
|
166
|
+
|
|
164
167
|
_x = 0.5 * num7;
|
|
165
168
|
_y = (m01 + m10) * num4;
|
|
166
169
|
_z = (m02 + m20) * num4;
|
|
167
170
|
_w = (m12 - m21) * num4;
|
|
171
|
+
|
|
168
172
|
} else if (m11 > m22) {
|
|
169
|
-
|
|
170
|
-
|
|
173
|
+
|
|
174
|
+
const num6 = Math.sqrt(((1 + m11) - m00) - m22);
|
|
175
|
+
const num3 = 0.5 / num6;
|
|
176
|
+
|
|
171
177
|
_x = (m10 + m01) * num3;
|
|
172
178
|
_y = 0.5 * num6;
|
|
173
179
|
_z = (m21 + m12) * num3;
|
|
174
180
|
_w = (m20 - m02) * num3;
|
|
175
181
|
} else {
|
|
176
|
-
|
|
177
|
-
|
|
182
|
+
|
|
183
|
+
const num5 = Math.sqrt(((1 + m22) - m00) - m11);
|
|
184
|
+
const num2 = 0.5 / num5;
|
|
185
|
+
|
|
178
186
|
_x = (m20 + m02) * num2;
|
|
179
187
|
_y = (m21 + m12) * num2;
|
|
180
188
|
_z = 0.5 * num5;
|
|
@@ -359,9 +367,9 @@ class Quaternion {
|
|
|
359
367
|
toAxisAngle(axis) {
|
|
360
368
|
const rad = Math.acos(this.w) * 2.0;
|
|
361
369
|
|
|
362
|
-
const s = Math.sin(rad
|
|
370
|
+
const s = Math.sin(rad * 0.5);
|
|
363
371
|
|
|
364
|
-
if (s > EPSILON) {
|
|
372
|
+
if (Math.abs(s) > EPSILON) {
|
|
365
373
|
axis.set(
|
|
366
374
|
this.x / s,
|
|
367
375
|
this.y / s,
|
|
@@ -378,7 +386,8 @@ class Quaternion {
|
|
|
378
386
|
let l = this.length();
|
|
379
387
|
|
|
380
388
|
if (l < EPSILON) {
|
|
381
|
-
//
|
|
389
|
+
// Quaternion has close to 0 length
|
|
390
|
+
// use identity, avoid division by 0
|
|
382
391
|
this.set(0, 0, 0, 1);
|
|
383
392
|
} else {
|
|
384
393
|
const m = 1 / l;
|
|
@@ -1131,17 +1140,17 @@ class Quaternion {
|
|
|
1131
1140
|
m31, m32, m33
|
|
1132
1141
|
) {
|
|
1133
1142
|
|
|
1134
|
-
assert.notNaN(m11,'m11');
|
|
1135
|
-
assert.notNaN(m12,'m12');
|
|
1136
|
-
assert.notNaN(m13,'m13');
|
|
1143
|
+
assert.notNaN(m11, 'm11');
|
|
1144
|
+
assert.notNaN(m12, 'm12');
|
|
1145
|
+
assert.notNaN(m13, 'm13');
|
|
1137
1146
|
|
|
1138
|
-
assert.notNaN(m21,'m21');
|
|
1139
|
-
assert.notNaN(m22,'m22');
|
|
1140
|
-
assert.notNaN(m23,'m23');
|
|
1147
|
+
assert.notNaN(m21, 'm21');
|
|
1148
|
+
assert.notNaN(m22, 'm22');
|
|
1149
|
+
assert.notNaN(m23, 'm23');
|
|
1141
1150
|
|
|
1142
|
-
assert.notNaN(m31,'m31');
|
|
1143
|
-
assert.notNaN(m32,'m32');
|
|
1144
|
-
assert.notNaN(m33,'m33');
|
|
1151
|
+
assert.notNaN(m31, 'm31');
|
|
1152
|
+
assert.notNaN(m32, 'm32');
|
|
1153
|
+
assert.notNaN(m33, 'm33');
|
|
1145
1154
|
|
|
1146
1155
|
|
|
1147
1156
|
const trace = m11 + m22 + m33;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Quaternion from "./Quaternion.js";
|
|
2
2
|
import Vector3 from "./Vector3.js";
|
|
3
|
+
import { decode_octahedron_to_unit } from "./3d/normal/octahedron/decode_octahedron_to_unit.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
*
|
|
@@ -260,3 +261,143 @@ test('computeTwistAngle', () => {
|
|
|
260
261
|
expect(q.computeTwistAngle(Vector3.up)).toBeCloseTo(hp * 3);
|
|
261
262
|
|
|
262
263
|
});
|
|
264
|
+
|
|
265
|
+
test("numeric(array) accessors", () => {
|
|
266
|
+
|
|
267
|
+
const q = new Quaternion();
|
|
268
|
+
|
|
269
|
+
q[0] = 3;
|
|
270
|
+
q[1] = -7;
|
|
271
|
+
q[2] = 11;
|
|
272
|
+
q[3] = -13;
|
|
273
|
+
|
|
274
|
+
expect(q[0]).toEqual(3);
|
|
275
|
+
expect(q.x).toEqual(3);
|
|
276
|
+
|
|
277
|
+
expect(q[1]).toEqual(-7);
|
|
278
|
+
expect(q.y).toEqual(-7);
|
|
279
|
+
|
|
280
|
+
expect(q[2]).toEqual(11);
|
|
281
|
+
expect(q.z).toEqual(11);
|
|
282
|
+
|
|
283
|
+
expect(q[3]).toEqual(-13);
|
|
284
|
+
expect(q.w).toEqual(-13);
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
test("forward lookRotation produces identity quaternion ", () => {
|
|
288
|
+
|
|
289
|
+
const q = new Quaternion(1, 3, 4, -7);
|
|
290
|
+
|
|
291
|
+
q.lookRotation(Vector3.forward, Vector3.up);
|
|
292
|
+
|
|
293
|
+
expect(q.roughlyEquals(Quaternion.identity)).toBe(true);
|
|
294
|
+
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
test("lookRotation when FORWARD and UP are the same vectors ", () => {
|
|
298
|
+
|
|
299
|
+
const q = new Quaternion(1, 3, 4, -7);
|
|
300
|
+
|
|
301
|
+
q.lookRotation(Vector3.forward, Vector3.forward);
|
|
302
|
+
|
|
303
|
+
const vec = Vector3.forward.clone();
|
|
304
|
+
|
|
305
|
+
vec.applyQuaternion(q);
|
|
306
|
+
|
|
307
|
+
expect(vec.roughlyEquals(Vector3.forward, 0.001)).toBe(true);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
test("check lookRotation rotations on octahedron points", () => {
|
|
311
|
+
|
|
312
|
+
const q = new Quaternion(1, 3, 4, -7);
|
|
313
|
+
|
|
314
|
+
const direction_vector_forward_array = [];
|
|
315
|
+
|
|
316
|
+
const direction_vector_forward = new Vector3();
|
|
317
|
+
|
|
318
|
+
const direction_vector_up_array = [];
|
|
319
|
+
|
|
320
|
+
const direction_vector_up = new Vector3();
|
|
321
|
+
|
|
322
|
+
const rotation_vector = new Vector3();
|
|
323
|
+
|
|
324
|
+
const GRID_SIZE = 9;
|
|
325
|
+
|
|
326
|
+
for (let i0 = 0; i0 < GRID_SIZE; i0++) {
|
|
327
|
+
for (let j0 = 0; j0 < GRID_SIZE; j0++) {
|
|
328
|
+
|
|
329
|
+
const u0 = i0 / (GRID_SIZE - 1);
|
|
330
|
+
const v0 = j0 / (GRID_SIZE - 1);
|
|
331
|
+
|
|
332
|
+
// sample direction for FORWARD vector
|
|
333
|
+
decode_octahedron_to_unit(direction_vector_forward_array, 0, u0, v0);
|
|
334
|
+
direction_vector_forward.readFromArray(direction_vector_forward_array);
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
for (let i1 = 0; i1 < GRID_SIZE; i1++) {
|
|
338
|
+
for (let j1 = 0; j1 < GRID_SIZE; j1++) {
|
|
339
|
+
|
|
340
|
+
const u1 = i1 / (GRID_SIZE - 1);
|
|
341
|
+
const v1 = j1 / (GRID_SIZE - 1);
|
|
342
|
+
|
|
343
|
+
// sample direction for UP vector
|
|
344
|
+
decode_octahedron_to_unit(direction_vector_up_array, 0, u1, v1);
|
|
345
|
+
direction_vector_up.readFromArray(direction_vector_up_array);
|
|
346
|
+
|
|
347
|
+
// obtain quaternion
|
|
348
|
+
q.lookRotation(direction_vector_forward, direction_vector_up);
|
|
349
|
+
|
|
350
|
+
// verify that a vector transformed via this quaternion would produce the same direction as the look direciton
|
|
351
|
+
rotation_vector.copy(Vector3.forward);
|
|
352
|
+
|
|
353
|
+
rotation_vector.applyQuaternion(q);
|
|
354
|
+
|
|
355
|
+
expect(rotation_vector.roughlyEquals(direction_vector_forward, 0.001)).toBe(true);
|
|
356
|
+
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
test("random produces valid normalized quaternion", () => {
|
|
365
|
+
|
|
366
|
+
const q = new Quaternion();
|
|
367
|
+
|
|
368
|
+
q.random(() => 0);
|
|
369
|
+
|
|
370
|
+
expect(q.length()).toBeCloseTo(1);
|
|
371
|
+
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
test("toAxisAngle on identity", () => {
|
|
375
|
+
const q = new Quaternion();
|
|
376
|
+
|
|
377
|
+
const axis = new Vector3();
|
|
378
|
+
|
|
379
|
+
const angle = q.toAxisAngle(axis);
|
|
380
|
+
|
|
381
|
+
expect(angle).toBeCloseTo(0)
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
test("normalizing quaternion of 0 length produces non-NaN result", () => {
|
|
385
|
+
const q = new Quaternion(0, 0, 0, 0);
|
|
386
|
+
|
|
387
|
+
q.normalize();
|
|
388
|
+
|
|
389
|
+
expect(q.x).not.toBeNaN();
|
|
390
|
+
expect(q.y).not.toBeNaN();
|
|
391
|
+
expect(q.z).not.toBeNaN();
|
|
392
|
+
expect(q.w).not.toBeNaN();
|
|
393
|
+
|
|
394
|
+
expect(q.length()).toBeCloseTo(1);
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
test("angleTo between identical quaternions should be 0", () => {
|
|
398
|
+
|
|
399
|
+
const a = new Quaternion();
|
|
400
|
+
const b = new Quaternion();
|
|
401
|
+
|
|
402
|
+
expect(a.angleTo(b)).toBeCloseTo(0);
|
|
403
|
+
});
|
|
@@ -35,6 +35,10 @@ export default class Vector2 {
|
|
|
35
35
|
|
|
36
36
|
clone(): Vector2
|
|
37
37
|
|
|
38
|
+
equals(other: Vector2): boolean
|
|
39
|
+
|
|
40
|
+
roughlyEquals(other: Vector2, tolerance?: number): boolean
|
|
41
|
+
|
|
38
42
|
distanceTo(other: Vector2): number
|
|
39
43
|
|
|
40
44
|
isZero(): boolean
|
|
@@ -43,5 +47,5 @@ export default class Vector2 {
|
|
|
43
47
|
|
|
44
48
|
writeToArray(array: ArrayLike<number>, offset?: number): void
|
|
45
49
|
|
|
46
|
-
asArray():number[]
|
|
50
|
+
asArray(): number[]
|
|
47
51
|
}
|
package/src/core/geom/Vector2.js
CHANGED
|
@@ -9,6 +9,8 @@ import { clamp } from "../math/clamp.js";
|
|
|
9
9
|
import { lerp } from "../math/lerp.js";
|
|
10
10
|
import { max2 } from "../math/max2.js";
|
|
11
11
|
import { min2 } from "../math/min2.js";
|
|
12
|
+
import { EPSILON } from "../math/EPSILON.js";
|
|
13
|
+
import { epsilonEquals } from "../math/epsilonEquals.js";
|
|
12
14
|
|
|
13
15
|
class Vector2 {
|
|
14
16
|
/**
|
|
@@ -588,6 +590,28 @@ class Vector2 {
|
|
|
588
590
|
return this.x === other.x && this.y === other.y;
|
|
589
591
|
}
|
|
590
592
|
|
|
593
|
+
/**
|
|
594
|
+
*
|
|
595
|
+
* @param {Vector2} other
|
|
596
|
+
* @param {number} [tolerance]
|
|
597
|
+
* @return {boolean}
|
|
598
|
+
*/
|
|
599
|
+
roughlyEquals(other, tolerance) {
|
|
600
|
+
return this._roughlyEquals(other.x, other.y, tolerance);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
*
|
|
605
|
+
* @param {number} x
|
|
606
|
+
* @param {number} y
|
|
607
|
+
* @param {number} [tolerance] acceptable deviation
|
|
608
|
+
* @return {boolean}
|
|
609
|
+
*/
|
|
610
|
+
_roughlyEquals(x, y, tolerance = EPSILON) {
|
|
611
|
+
return epsilonEquals(this.x, x, tolerance)
|
|
612
|
+
&& epsilonEquals(this.y, y, tolerance);
|
|
613
|
+
}
|
|
614
|
+
|
|
591
615
|
get 0() {
|
|
592
616
|
return this.x;
|
|
593
617
|
}
|
|
@@ -45,3 +45,63 @@ test('addVectors', () => {
|
|
|
45
45
|
expect(ut.y).toBe(14);
|
|
46
46
|
expect(ut.z).toBe(18);
|
|
47
47
|
});
|
|
48
|
+
|
|
49
|
+
test("equals", () => {
|
|
50
|
+
expect(new Vector3(1, -2, 3).equals(new Vector3(1, -2, 3)))
|
|
51
|
+
.toBe(true);
|
|
52
|
+
|
|
53
|
+
expect(new Vector3(1, -2, 3).equals(new Vector3(5, -2, 3)))
|
|
54
|
+
.toBe(false);
|
|
55
|
+
|
|
56
|
+
expect(new Vector3(1, -2, 3).equals(new Vector3(1, 5, 3)))
|
|
57
|
+
.toBe(false);
|
|
58
|
+
|
|
59
|
+
expect(new Vector3(1, -2, 3).equals(new Vector3(1, -2, 5)))
|
|
60
|
+
.toBe(false);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("roughlyEquals", () => {
|
|
64
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2, 3), 0))
|
|
65
|
+
.toBe(true);
|
|
66
|
+
|
|
67
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2, 3), 0.1))
|
|
68
|
+
.toBe(true);
|
|
69
|
+
|
|
70
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1.01, -2, 3), 0.1))
|
|
71
|
+
.toBe(true);
|
|
72
|
+
|
|
73
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(0.99, -2, 3), 0.1))
|
|
74
|
+
.toBe(true);
|
|
75
|
+
|
|
76
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(0.89, -2, 3), 0.1))
|
|
77
|
+
.toBe(false);
|
|
78
|
+
|
|
79
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1.11, -2, 3), 0.1))
|
|
80
|
+
.toBe(false);
|
|
81
|
+
|
|
82
|
+
// Y
|
|
83
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2.01, 3), 0.1))
|
|
84
|
+
.toBe(true);
|
|
85
|
+
|
|
86
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -1.99, 3), 0.1))
|
|
87
|
+
.toBe(true);
|
|
88
|
+
|
|
89
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2.11, 3), 0.1))
|
|
90
|
+
.toBe(false);
|
|
91
|
+
|
|
92
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -1.89, 3), 0.1))
|
|
93
|
+
.toBe(false);
|
|
94
|
+
|
|
95
|
+
// Z
|
|
96
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2, 3.01), 0.1))
|
|
97
|
+
.toBe(true);
|
|
98
|
+
|
|
99
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2, 2.99), 0.1))
|
|
100
|
+
.toBe(true);
|
|
101
|
+
|
|
102
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2, 2.89), 0.1))
|
|
103
|
+
.toBe(false);
|
|
104
|
+
|
|
105
|
+
expect(new Vector3(1, -2, 3).roughlyEquals(new Vector3(1, -2, 3.11), 0.1))
|
|
106
|
+
.toBe(false);
|
|
107
|
+
});
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
line_segment_compute_line_segment_intersection_vectors_array_2d
|
|
8
|
+
} from "../geom/2d/line/line_segment_compute_line_segment_intersection_vectors_array_2d.js";
|
|
7
9
|
|
|
8
10
|
const Utils = {};
|
|
9
11
|
|
|
@@ -155,7 +157,7 @@ function graph2paths(graph, thickness) {
|
|
|
155
157
|
const l = edges.length;
|
|
156
158
|
for (; i < l; i++) {
|
|
157
159
|
const edge = edges[i];
|
|
158
|
-
if (
|
|
160
|
+
if (line_segment_compute_line_segment_intersection_vectors_array_2d(from, to, edge.first, edge.second)) {
|
|
159
161
|
return true;
|
|
160
162
|
}
|
|
161
163
|
}
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
import { assert } from "../../assert.js";
|
|
7
7
|
import Circle from "../../geom/2d/circle/Circle.js";
|
|
8
8
|
import AABB2 from "../../geom/2d/aabb/AABB2.js";
|
|
9
|
-
import { line2SegmentsIntersect } from "../../geom/2d/LineSegment2.js";
|
|
10
9
|
import Vector2, { v2_distance } from "../../geom/Vector2.js";
|
|
11
10
|
import { max2 } from "../../math/max2.js";
|
|
12
11
|
import { min2 } from "../../math/min2.js";
|
|
@@ -14,6 +13,9 @@ import { computeDisconnectedSubGraphs } from "./computeDisconnectedSubGraphs.js"
|
|
|
14
13
|
import { Connection } from "./Connection.js";
|
|
15
14
|
import { resolveAABB2Overlap } from "./box/resolveAABB2Overlap.js";
|
|
16
15
|
import { applyCentralGravityAABB2 } from "./box/applyCentralGravityAABB2.js";
|
|
16
|
+
import {
|
|
17
|
+
line_segment_line_segment_intersection_exists_2d
|
|
18
|
+
} from "../../geom/2d/line/line_segment_line_segment_intersection_exists_2d.js";
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
/**
|
|
@@ -364,7 +366,7 @@ function computeNumberOfCrossOvers(edges, numEdges) {
|
|
|
364
366
|
const b0 = e1.source;
|
|
365
367
|
const b1 = e1.target;
|
|
366
368
|
|
|
367
|
-
if (
|
|
369
|
+
if (line_segment_line_segment_intersection_exists_2d(
|
|
368
370
|
a0.x, a0.y,
|
|
369
371
|
a1.x, a1.y,
|
|
370
372
|
b0.x, b0.y,
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { bessel_j0 } from "./bessel_j0.js";
|
|
2
|
+
|
|
3
|
+
test("sanity", () => {
|
|
4
|
+
const v = bessel_j0(0);
|
|
5
|
+
|
|
6
|
+
expect(typeof v).toBe("number");
|
|
7
|
+
expect(v).not.toBeNaN();
|
|
8
|
+
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test("sweep through low positive values", () => {
|
|
12
|
+
// https://www.wolframalpha.com/input?i=besselj%5B0%2Cx%5D
|
|
13
|
+
|
|
14
|
+
expect(bessel_j0(0)).toBeCloseTo(1, 1);
|
|
15
|
+
expect(bessel_j0(0.1)).toBeCloseTo(0.997, 1);
|
|
16
|
+
expect(bessel_j0(0.2)).toBeCloseTo(0.990, 1);
|
|
17
|
+
expect(bessel_j0(0.3)).toBeCloseTo(0.977, 1);
|
|
18
|
+
expect(bessel_j0(0.4)).toBeCloseTo(0.960, 1);
|
|
19
|
+
expect(bessel_j0(0.5)).toBeCloseTo(0.938, 1);
|
|
20
|
+
expect(bessel_j0(0.6)).toBeCloseTo(0.912, 1);
|
|
21
|
+
expect(bessel_j0(0.7)).toBeCloseTo(0.881, 1);
|
|
22
|
+
expect(bessel_j0(0.8)).toBeCloseTo(0.846, 1);
|
|
23
|
+
expect(bessel_j0(0.9)).toBeCloseTo(0.807, 1);
|
|
24
|
+
expect(bessel_j0(1)).toBeCloseTo(0.765, 1);
|
|
25
|
+
expect(bessel_j0(2)).toBeCloseTo(0.223, 1);
|
|
26
|
+
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("roots", () => {
|
|
30
|
+
|
|
31
|
+
expect(bessel_j0(2.40482555769577)).toBeCloseTo(0, 1);
|
|
32
|
+
expect(bessel_j0(-2.40482555769577)).toBeCloseTo(0, 1);
|
|
33
|
+
|
|
34
|
+
expect(bessel_j0(5.52007811028631)).toBeCloseTo(0, 1);
|
|
35
|
+
expect(bessel_j0(-5.52007811028631)).toBeCloseTo(0, 1);
|
|
36
|
+
|
|
37
|
+
expect(bessel_j0(8.65372791291101)).toBeCloseTo(0, 1);
|
|
38
|
+
expect(bessel_j0(-8.65372791291101)).toBeCloseTo(0, 1);
|
|
39
|
+
|
|
40
|
+
expect(bessel_j0(11.7915344390143)).toBeCloseTo(0, 1);
|
|
41
|
+
expect(bessel_j0(-11.7915344390143)).toBeCloseTo(0, 1);
|
|
42
|
+
|
|
43
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { assert } from "../assert.js";
|
|
2
|
+
|
|
3
|
+
const q = 0.7172491568;
|
|
4
|
+
const p0 = 0.6312725339;
|
|
5
|
+
const ps0 = 0.4308049446;
|
|
6
|
+
const p1 = 0.3500347951;
|
|
7
|
+
const ps1 = 0.4678202347;
|
|
8
|
+
const p2 = -0.06207747907;
|
|
9
|
+
const ps2 = 0.04253832927;
|
|
10
|
+
// const lamb4 = (lamb * lamb) * (lamb * lamb);
|
|
11
|
+
const lamb4 = 0.559840650625;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Bessel first order function of zeroth order
|
|
15
|
+
* @see https://link.springer.com/article/10.1007/s40314-020-01238-z
|
|
16
|
+
* @see https://www.shadertoy.com/view/Wt3czM
|
|
17
|
+
* @param {number} x
|
|
18
|
+
* @return {number}
|
|
19
|
+
*/
|
|
20
|
+
export function bessel_j0(x) {
|
|
21
|
+
assert.notNaN(x, 'x');
|
|
22
|
+
|
|
23
|
+
const xx = x * x;
|
|
24
|
+
|
|
25
|
+
const t0 = Math.sqrt(1.0 + lamb4 * xx);
|
|
26
|
+
const t1 = Math.sqrt(t0);
|
|
27
|
+
|
|
28
|
+
return xx === 0.0 ? 1.0 : 1.0 / (t1 * (1.0 + q * xx)) * ((p0 + p1 * xx + p2 * t0) * Math.cos(x) + ((ps0 + ps1 * xx) * t0 + ps2 * xx) * (Math.sin(x) / x));
|
|
29
|
+
|
|
30
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { squirrel3 } from "./squirrel3.js";
|
|
2
|
+
|
|
3
|
+
function expect_integer(v) {
|
|
4
|
+
|
|
5
|
+
expect(typeof v).toBe("number");
|
|
6
|
+
expect(Number.isInteger(v)).toBe(true);
|
|
7
|
+
expect(v).not.toBeNaN();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
test("sanity check", () => {
|
|
11
|
+
expect_integer(squirrel3(0));
|
|
12
|
+
expect_integer(squirrel3(1));
|
|
13
|
+
expect_integer(squirrel3(-1));
|
|
14
|
+
|
|
15
|
+
expect(squirrel3(0)).not.toEqual(squirrel3(1));
|
|
16
|
+
});
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { assert } from "../assert.js";
|
|
2
2
|
|
|
3
|
+
// const lamb = 0.865;
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
|
-
* Modified bessel function of the first kind
|
|
6
|
+
* Modified bessel function of the first kind zeroth order
|
|
5
7
|
* @see https://mathworld.wolfram.com/ModifiedBesselFunctionoftheFirstKind.html
|
|
6
8
|
* @see https://computergraphics.stackexchange.com/questions/6393/kaiser-windowed-sinc-filter-for-mip-mapping
|
|
7
9
|
* @see https://github.com/terifan/ImageResampler/blob/dbc212ce6aaa769bf3c9623cb6ead58ffd51d76c/src/org/terifan/image_resampler/FilterFactory.java
|
|
8
10
|
* @param {number} x
|
|
9
11
|
* @returns {number}
|
|
10
12
|
*/
|
|
11
|
-
export function
|
|
13
|
+
export function modified_bessel_i0(x) {
|
|
12
14
|
assert.notNaN(x, 'x');
|
|
13
15
|
|
|
14
16
|
let sum = 1.0;
|
|
@@ -24,3 +26,4 @@ export function bessel_i0(x) {
|
|
|
24
26
|
|
|
25
27
|
return sum;
|
|
26
28
|
}
|
|
29
|
+
|
|
@@ -58,9 +58,9 @@ const grad4 = /*#__PURE__*/ new Float64Array([0, 1, 1, 1, 0, 1, 1, -1, 0, 1, -1,
|
|
|
58
58
|
/**
|
|
59
59
|
* Creates a 2D noise function
|
|
60
60
|
* @param random the random function that will be used to build the permutation table
|
|
61
|
-
* @returns {function(x:number, y:number):number}
|
|
61
|
+
* @returns {function(x:number, y:number):number} producing values in range -1 .. 1
|
|
62
62
|
*/
|
|
63
|
-
export function
|
|
63
|
+
export function create_simplex_noise_2d(random = Math.random) {
|
|
64
64
|
// allocate continuous chunk of memory
|
|
65
65
|
const buffer = new ArrayBuffer(512 * 2);
|
|
66
66
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { create_simplex_noise_2d } from "./create_simplex_noise_2d.js";
|
|
2
|
+
|
|
3
|
+
test("sample 10 points in 0..1 range", () => {
|
|
4
|
+
const noise2d = create_simplex_noise_2d(() => 0);
|
|
5
|
+
|
|
6
|
+
const COUNT = 10;
|
|
7
|
+
for (let i = 0; i < COUNT; i++) {
|
|
8
|
+
const u = i / (COUNT - 1);
|
|
9
|
+
for (let j = 0; j < COUNT; j++) {
|
|
10
|
+
const v = j / (COUNT - 1);
|
|
11
|
+
|
|
12
|
+
const value = noise2d(u, v);
|
|
13
|
+
|
|
14
|
+
expect(typeof value).toBe('number');
|
|
15
|
+
expect(value).not.toBeNaN();
|
|
16
|
+
|
|
17
|
+
expect(value).toBeGreaterThanOrEqual(-1);
|
|
18
|
+
expect(value).toBeLessThanOrEqual(1);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { interpolate_irradiance_linear } from "./interpolate_irradiance_linear.js";
|
|
2
|
+
|
|
3
|
+
test("sanity check", () => {
|
|
4
|
+
|
|
5
|
+
expect(interpolate_irradiance_linear(3, 3, 3)).toBe(1);
|
|
6
|
+
|
|
7
|
+
expect(interpolate_irradiance_linear(3, 3, 7)).toBe(1);
|
|
8
|
+
|
|
9
|
+
expect(interpolate_irradiance_linear(7, 3, 7)).toBe(0);
|
|
10
|
+
|
|
11
|
+
expect(interpolate_irradiance_linear(0, 3, 7)).toBe(1);
|
|
12
|
+
|
|
13
|
+
expect(interpolate_irradiance_linear(11, 3, 7)).toBe(0);
|
|
14
|
+
|
|
15
|
+
const mid = interpolate_irradiance_linear(5, 3, 7);
|
|
16
|
+
|
|
17
|
+
expect(mid).toBeGreaterThan(0);
|
|
18
|
+
expect(mid).toBeLessThan(1);
|
|
19
|
+
|
|
20
|
+
});
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { inverseLerp } from "../../inverseLerp.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Approximates logarithmic decay, except it goes to 0 at max
|
|
5
|
+
* Estimation is done using a 5th degree polynomial
|
|
5
6
|
* @param {number} distance
|
|
6
7
|
* @param {number} min
|
|
7
8
|
* @param {number} max
|
|
8
9
|
* @return {number}
|
|
9
10
|
*/
|
|
10
11
|
export function interpolate_irradiance_lograrithmic(distance, min, max) {
|
|
11
|
-
if (distance >= max) {
|
|
12
|
-
return 0;
|
|
13
|
-
}
|
|
14
12
|
|
|
15
13
|
if (distance <= min) {
|
|
16
14
|
return 1;
|
|
15
|
+
} else if (distance >= max) {
|
|
16
|
+
return 0;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
const x = inverseLerp(min, max, distance);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { interpolate_irradiance_lograrithmic } from "./interpolate_irradiance_lograrithmic.js";
|
|
2
|
+
|
|
3
|
+
test("sanity check", () => {
|
|
4
|
+
expect(interpolate_irradiance_lograrithmic(3, 3, 3)).toBe(1);
|
|
5
|
+
|
|
6
|
+
expect(interpolate_irradiance_lograrithmic(3, 3, 7)).toBe(1);
|
|
7
|
+
|
|
8
|
+
expect(interpolate_irradiance_lograrithmic(7, 3, 7)).toBe(0);
|
|
9
|
+
|
|
10
|
+
expect(interpolate_irradiance_lograrithmic(0, 3, 7)).toBe(1);
|
|
11
|
+
|
|
12
|
+
expect(interpolate_irradiance_lograrithmic(11, 3, 7)).toBe(0);
|
|
13
|
+
|
|
14
|
+
const mid = interpolate_irradiance_lograrithmic(5, 3, 7);
|
|
15
|
+
|
|
16
|
+
expect(mid).toBeGreaterThan(0);
|
|
17
|
+
expect(mid).toBeLessThan(1);
|
|
18
|
+
});
|