@woosh/meep-engine 2.37.19 → 2.37.20

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.
Files changed (110) hide show
  1. package/core/binary/float2uint8.js +8 -0
  2. package/core/binary/uint82float.js +8 -0
  3. package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +6 -4
  4. package/core/collection/list/List.d.ts +1 -1
  5. package/core/color/Color.js +69 -1
  6. package/core/color/YCbCr_to_rgb_uint24.js +3 -4
  7. package/core/color/hsv2rgb.js +4 -3
  8. package/core/color/linear_to_sRGB.js +4 -5
  9. package/core/color/rgb2uint24.js +6 -4
  10. package/core/color/rgb_to_YCbCr_uint24.js +11 -13
  11. package/core/events/signal/Signal.d.ts +11 -9
  12. package/core/geom/2d/quad-tree/qt_collect_by_circle.js +67 -0
  13. package/core/geom/Quaternion.d.ts +16 -1
  14. package/core/geom/Quaternion.js +129 -65
  15. package/core/geom/Quaternion.spec.js +24 -0
  16. package/core/geom/Vector2.js +3 -3
  17. package/core/geom/Vector3.d.ts +2 -0
  18. package/core/geom/Vector3.js +31 -7
  19. package/core/geom/Vector4.js +16 -0
  20. package/core/math/bell_membership_function.js +19 -0
  21. package/core/math/exp2.js +8 -0
  22. package/core/math/interval/NumericInterval.js +17 -0
  23. package/core/math/physics/brdf/brdf_burley.js +25 -0
  24. package/core/math/physics/bsdf/bsdf_schlick.js +22 -0
  25. package/core/math/physics/irradiance/interpolate_irradiance_linear.js +18 -0
  26. package/{engine/sound/ecs/emitter/attenuate/attenuateSoundLogarithmic.js → core/math/physics/irradiance/interpolate_irradiance_lograrithmic.js} +2 -2
  27. package/{engine/sound/ecs/emitter/attenuate/attenuateSoundSmith.js → core/math/physics/irradiance/interpolate_irradiance_smith.js} +1 -1
  28. package/editor/actions/concrete/ModifyPatchSampler2DAction.js +118 -0
  29. package/editor/actions/concrete/ModifyPatchSampler2DAction.spec.js +30 -0
  30. package/editor/actions/concrete/PatchTerrainHeightAction.js +12 -104
  31. package/editor/ecs/component/createObjectEditor.js +53 -29
  32. package/editor/ecs/component/editors/Sampler2DEditor.js +71 -24
  33. package/editor/ecs/component/editors/ecs/terrain/TerrainEditor.js +47 -0
  34. package/editor/ecs/component/editors/primitive/FunctionEditor.js +6 -2
  35. package/editor/tools/SelectionTool.js +1 -1
  36. package/editor/tools/paint/TerrainHeightPaintTool.js +88 -68
  37. package/editor/tools/paint/TerrainPaintTool.js +2 -1
  38. package/editor/tools/paint/TerrainTexturePaintTool.js +8 -73
  39. package/engine/asset/AssetManager.d.ts +1 -1
  40. package/engine/asset/AssetManager.js +390 -388
  41. package/engine/asset/loaders/gltf/extensions/MSFT_texture_dds.js +14 -2
  42. package/engine/ecs/fow/FogOfWarEditor.js +13 -0
  43. package/engine/ecs/terrain/ecs/OffsetScaleTransform2D.d.ts +6 -0
  44. package/engine/ecs/terrain/ecs/Terrain.js +21 -1
  45. package/engine/ecs/terrain/ecs/splat/SplatMapping.js +26 -28
  46. package/engine/ecs/terrain/overlay/TerrainOverlay.js +71 -66
  47. package/engine/ecs/terrain/tiles/TerrainTileManager.js +23 -0
  48. package/engine/ecs/terrain/util/paintTerrainOverlayViaLookupTable.js +13 -7
  49. package/engine/ecs/transform/Transform.d.ts +2 -0
  50. package/engine/ecs/transform/Transform.js +3 -0
  51. package/engine/graphics/ecs/light/Light.js +0 -47
  52. package/engine/graphics/ecs/light/LightSerializationAdapter.js +50 -0
  53. package/engine/graphics/ecs/mesh-v2/DrawMode.js +2 -1
  54. package/engine/graphics/ecs/mesh-v2/build_three_object.js +3 -1
  55. package/engine/graphics/ecs/sprite/Sprite.js +11 -0
  56. package/engine/graphics/ecs/sprite/SpriteSystemPE.js +133 -0
  57. package/engine/graphics/ecs/sprite/prototypeSpriteSystem.js +1566 -0
  58. package/engine/graphics/micron/prototypeVirtualGeometry.js +2 -2
  59. package/engine/graphics/particles/particular/engine/emitter/ParticleLayer.js +17 -9
  60. package/engine/graphics/particles/particular/engine/renderers/ParticleRenderer.js +12 -10
  61. package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +7 -2
  62. package/engine/graphics/particles/particular/engine/renderers/billboard/SoftBillboardParticlePool.js +27 -0
  63. package/engine/graphics/particles/particular/engine/renderers/billboard/SoftBillboardParticleRenderer.js +80 -0
  64. package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +16 -4
  65. package/engine/graphics/shaders/TerrainShader.js +8 -8
  66. package/engine/graphics/texture/atlas/TextureAtlasDebugger.js +2 -1
  67. package/engine/graphics/texture/sampler/Sampler2D.js +190 -201
  68. package/engine/graphics/texture/sampler/Sampler2D.spec.js +34 -35
  69. package/engine/graphics/texture/sampler/bicubic.js +59 -0
  70. package/engine/graphics/texture/sampler/downsampleSample2D.spec.js +2 -2
  71. package/engine/graphics/texture/sampler/genericResampleSampler2D.js +0 -2
  72. package/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +146 -0
  73. package/engine/graphics/texture/sampler/{downsampleSampler2D.js → sampler2D_scale_down_linear.js} +8 -4
  74. package/engine/graphics/texture/sampler/sampler2_d_scale_down_lanczos.js +140 -0
  75. package/engine/graphics/texture/sampler/scaleSampler2D.js +3 -3
  76. package/engine/graphics/texture/sampler/writeSampler2DDataToDataTexture.js +1 -1
  77. package/engine/input/ecs/util/TerrainCameraTargetSampler.js +2 -2
  78. package/engine/navigation/ecs/components/computeNonuniformCatmullRomSplineSample.js +117 -0
  79. package/engine/platform/GetURLHash.js +27 -0
  80. package/engine/platform/WebEnginePlatform.js +1 -22
  81. package/engine/sound/ecs/emitter/SoundEmitter.js +10 -6
  82. package/generation/GridGenerator.js +7 -6
  83. package/generation/example/SampleGenerator0.js +6 -6
  84. package/generation/example/filters/SampleGroundMoistureFilter.js +58 -17
  85. package/generation/example/themes/SampleTheme0.js +11 -7
  86. package/generation/filtering/numeric/CellFilterLiteralFloat.js +5 -0
  87. package/generation/filtering/numeric/complex/CellFilterDilate.js +36 -0
  88. package/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +15 -5
  89. package/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +53 -1
  90. package/generation/filtering/numeric/math/CellFilterMax2.js +3 -0
  91. package/generation/filtering/numeric/math/CellFilterMembershipGeneralizedBell.js +55 -0
  92. package/generation/filtering/numeric/sampling/AbstractCellFilterSampleGridLayer.js +42 -0
  93. package/generation/filtering/numeric/sampling/CellFilterSampleLayerCubic.js +36 -0
  94. package/generation/filtering/numeric/sampling/CellFilterSampleLayerLinear.js +41 -0
  95. package/generation/grid/GridData.d.ts +5 -1
  96. package/generation/grid/GridData.js +35 -36
  97. package/generation/grid/MarkerMatchCounter.js +5 -3
  98. package/generation/markers/GridActionRuleSet.js +15 -32
  99. package/generation/markers/GridCellActionPlaceMarker.js +8 -10
  100. package/generation/markers/debug/visualizeMarkers.js +56 -36
  101. package/generation/markers/emitter/MarkerNodeEmitterFromAction.js +8 -8
  102. package/generation/markers/prototypeGridCellActionPlaceMarker.js +209 -0
  103. package/generation/markers/transform/MarkerNodeTransformerOffsetPosition.js +1 -5
  104. package/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.spec.js +2 -2
  105. package/generation/placement/GridCellPlacementRule.js +10 -3
  106. package/package.json +1 -1
  107. package/samples/terrain/from_image.js +7 -3
  108. package/engine/graphics/particles/particular/engine/renderers/SoftBillboardParticleRenderer.js +0 -7
  109. package/engine/sound/ecs/emitter/attenuate/attenuateSoundLinear.js +0 -11
  110. package/generation/filtering/numeric/CellFilterReadGridLayer.js +0 -73
@@ -11,6 +11,8 @@ import { lerp } from "../math/lerp.js";
11
11
  import { EPSILON, epsilonEquals, PI2 } from "../math/MathUtils.js";
12
12
  import Vector3 from "./Vector3.js";
13
13
  import { v3_dot } from "./v3_dot.js";
14
+ import { min2 } from "../math/min2.js";
15
+ import { computeHashFloat } from "../math/hash/computeHashFloat.js";
14
16
 
15
17
  const matrix = new ThreeMatrix4();
16
18
 
@@ -45,39 +47,46 @@ class Quaternion {
45
47
  * @param {Number} [w=1]
46
48
  * @constructor
47
49
  */
48
- constructor(x, y, z, w) {
49
- this.x = (typeof x === "number") ? x : 0;
50
- this.y = (typeof x === "number") ? y : 0;
51
- this.z = (typeof z === "number") ? z : 0;
52
- this.w = (typeof w === "number") ? w : 1;
50
+ constructor(x = 0, y = 0, z = 0, w = 1) {
51
+
52
+ /**
53
+ *
54
+ * @type {Number}
55
+ */
56
+ this.x = x;
57
+ /**
58
+ *
59
+ * @type {Number}
60
+ */
61
+ this.y = y;
62
+ /**
63
+ *
64
+ * @type {Number}
65
+ */
66
+ this.z = z;
67
+ /**
68
+ *
69
+ * @type {Number}
70
+ */
71
+ this.w = w;
53
72
 
54
73
  this.onChanged = new Signal();
55
74
  }
56
75
 
57
- /**
58
- *
59
- * @param {Vector3} forwardVector
60
- * @return {Quaternion}
61
- */
62
- lookRotation_2(forwardVector) {
63
-
64
-
65
- const dot = Vector3.forward.dot(forwardVector);
66
- if (Math.abs(dot - (-1.0)) < 0.000001) {
67
- return this.set(Vector3.up.x, Vector3.up.y, Vector3.up.z, 3.1415926535897932);
68
- }
69
- if (Math.abs(dot - (1.0)) < 0.000001) {
70
- return this.set(0, 0, 0, 1);
71
- }
76
+ get 0() {
77
+ return this.x;
78
+ }
72
79
 
73
- const rotAngle = Math.acos(dot);
74
- rotAxis.copy(Vector3.forward);
75
- rotAxis.cross(forwardVector);
76
- rotAxis.normalize();
80
+ get 1() {
81
+ return this.y;
82
+ }
77
83
 
78
- quat3_createFromAxisAngle(rotAxis, rotAngle, this);
84
+ get 2() {
85
+ return this.z;
86
+ }
79
87
 
80
- return this;
88
+ get 3() {
89
+ return this.w;
81
90
  }
82
91
 
83
92
  /**
@@ -171,30 +180,6 @@ class Quaternion {
171
180
  return euler.setFromRotationMatrix(matrix);
172
181
  }
173
182
 
174
- /**
175
- *
176
- * @param {Vector3} direction
177
- * @param {Vector3} reference Reference direction, for example if you want to align Up direction or Forward, supply those here
178
- * @param {number} limit
179
- */
180
- lookRotation_3(direction, reference, limit) {
181
- const q = new Quaternion();
182
-
183
- const f = new Vector3();
184
-
185
- f.copy(reference);
186
-
187
- f.applyQuaternion(this);
188
-
189
- f.normalize();
190
-
191
- //
192
- q.fromUnitVectors2(f, direction);
193
-
194
- console.log(f.toJSON(), q.toJSON(), direction.toJSON(), reference.toJSON());
195
-
196
- this.multiply(q);
197
- }
198
183
 
199
184
  /**
200
185
  *
@@ -317,11 +302,10 @@ class Quaternion {
317
302
  }
318
303
 
319
304
  /**
320
- *
305
+ * @see https://stackoverflow.com/questions/3684269/component-of-a-quaternion-rotation-around-an-axis
321
306
  * @param {Vector3} axis
322
307
  * @param {Quaternion} swing
323
308
  * @param {Quaternion} twist
324
- * @returns {number}
325
309
  */
326
310
  computeSwingAndTwist(axis, swing, twist) {
327
311
  const x = this.x;
@@ -329,17 +313,48 @@ class Quaternion {
329
313
  const z = this.z;
330
314
  const w = this.w;
331
315
 
332
- const p = new Vector3();
316
+ // perform projection of rotation onto axis
317
+ const d = v3_dot(x, y, z, axis.x, axis.y, axis.z);
318
+
319
+ const mag2 = (axis.x * axis.x + axis.y * axis.y + axis.z * axis.z);
333
320
 
334
- p._projectVectors(x, y, z, axis.x, axis.y, axis.z);
321
+ const m = d / mag2;
322
+
323
+ const px = axis.x * m;
324
+ const py = axis.y * m;
325
+ const pz = axis.z * m;
326
+
327
+ if (d < 0) {
328
+ // axis points in the opposite direction from calculated twist, invert all components
329
+ twist.set(-px, -py, -pz, -w);
330
+ } else {
331
+ twist.set(px, py, pz, w);
332
+
333
+ }
335
334
 
336
- twist.set(p.x, p.y, p.z, w);
337
335
  twist.normalize();
338
336
 
339
337
  // rotation * twist.conjugated()
340
338
  swing._multiplyQuaternions(x, y, z, w, -twist.x, -twist.y, -twist.z, twist.w);
341
339
  }
342
340
 
341
+ /**
342
+ * Compute rotation (twist) around input axis
343
+ * @param {Vector3} axis
344
+ * @returns {number} in radians
345
+ */
346
+ computeTwistAngle(axis) {
347
+ assert.defined(axis, "axis");
348
+
349
+ const swing = new Quaternion();
350
+ const twist = new Quaternion();
351
+
352
+ this.computeSwingAndTwist(axis, swing, twist);
353
+
354
+ // extract twist angle from quaternion, see {@link #toAxisAngle}
355
+ return Math.acos(twist.w) * 2;
356
+ }
357
+
343
358
  /**
344
359
  *
345
360
  * @param {Vector3} axis
@@ -366,7 +381,8 @@ class Quaternion {
366
381
  normalize() {
367
382
  let l = this.length();
368
383
 
369
- if (l === 0) {
384
+ if (l < EPSILON) {
385
+ // use identity
370
386
  this.set(0, 0, 0, 1);
371
387
  } else {
372
388
  const m = 1 / l;
@@ -472,10 +488,9 @@ class Quaternion {
472
488
  lookAt(source, target) {
473
489
  const forward = new Vector3();
474
490
 
475
- forward
476
- .copy(target)
477
- .sub(source)
478
- .normalize();
491
+ forward.subVectors(target, source);
492
+
493
+ forward.normalize();
479
494
 
480
495
  this.alignToDirection(forward);
481
496
  }
@@ -532,11 +547,11 @@ class Quaternion {
532
547
  }
533
548
 
534
549
  /**
535
- *
550
+ * @see https://localcoder.org/euler-angle-to-quaternion-then-quaternion-to-euler-angle
551
+ * @see https://discourse.mcneel.com/t/what-is-the-right-method-to-convert-quaternion-to-plane-using-rhinocommon/92411/21?page=2
536
552
  * @param {Vector3} result
537
553
  */
538
554
  toEulerAnglesXYZ(result) {
539
-
540
555
  const x = this.x;
541
556
  const y = this.y;
542
557
  const z = this.z;
@@ -547,9 +562,19 @@ class Quaternion {
547
562
  const y2 = y * y;
548
563
  const z2 = z * z;
549
564
 
550
- const psi = Math.atan2(2 * (x * w - y * z), (w2 - x2 - y2 + z2));
551
- const theta = Math.asin(2 * (x * z + y * w));
552
- const phi = Math.atan2(2 * (z * w - x * y), (w2 + x2 - y2 - z2));
565
+ const r31 = 2 * (x * w - y * z);
566
+ const r32 = w2 - x2 - y2 + z2;
567
+
568
+ const psi = Math.atan2(r31, r32);
569
+
570
+ const r21 = 2 * (x * z + y * w);
571
+
572
+ const theta = Math.asin(r21);
573
+
574
+ const r11 = 2 * (z * w - x * y);
575
+ const r12 = w2 + x2 - y2 - z2;
576
+
577
+ const phi = Math.atan2(r11, r12);
553
578
 
554
579
  result.set(psi, theta, phi);
555
580
  }
@@ -1156,6 +1181,7 @@ class Quaternion {
1156
1181
  this.set(x, y, z, w);
1157
1182
  }
1158
1183
 
1184
+
1159
1185
  /**
1160
1186
  * @see https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/quat.js
1161
1187
  * @param {Quaternion} other
@@ -1511,6 +1537,18 @@ class Quaternion {
1511
1537
  ;
1512
1538
  }
1513
1539
 
1540
+ /**
1541
+ *
1542
+ * @returns {number}
1543
+ */
1544
+ hash() {
1545
+ // fast and dumb hash, just spread bits a bit and XOR them
1546
+ return computeHashFloat(this.x)
1547
+ ^ (computeHashFloat(this.y) >> 2)
1548
+ ^ (computeHashFloat(this.z) >> 1)
1549
+ ^ (computeHashFloat(this.w) << 2);
1550
+ }
1551
+
1514
1552
  /**
1515
1553
  *
1516
1554
  * @param {Quaternion} other
@@ -1582,6 +1620,28 @@ class Quaternion {
1582
1620
 
1583
1621
  return result;
1584
1622
  }
1623
+
1624
+
1625
+ /**
1626
+ * Behaves similarly to Unity's Quaternion `RotateToward` method
1627
+ * @param {Quaternion} result
1628
+ * @param {Quaternion} from
1629
+ * @param {Quaternion} to
1630
+ * @param {number} max_delta
1631
+ */
1632
+ static rotateTowards(result, from, to, max_delta) {
1633
+ const angle = from.angleTo(to);
1634
+
1635
+ if (angle === 0) {
1636
+ result.copy(to);
1637
+ } else {
1638
+ // clamp to 1, to make sure we don't overshoot
1639
+ const t = min2(1, max_delta / angle);
1640
+
1641
+ from.slerp(to, t);
1642
+ }
1643
+
1644
+ }
1585
1645
  }
1586
1646
 
1587
1647
  /**
@@ -1600,6 +1660,10 @@ const axis = new Vector3();
1600
1660
 
1601
1661
  const tempvec3 = new Vector3();
1602
1662
 
1663
+ /**
1664
+ * Used in UINT32 packing
1665
+ * @type {number}
1666
+ */
1603
1667
  const K_CONST = 0.70710678118; // 1/sqrt(2)
1604
1668
 
1605
1669
  export default Quaternion;
@@ -206,6 +206,8 @@ test('toEulerAnglesXYZ', () => {
206
206
  }
207
207
 
208
208
 
209
+ check([0, 0, 0, 1], [0, 0, 0]);
210
+
209
211
  check([0.4794255, 0, 0, 0.8775826], [1, 0, 0]);
210
212
  check([0, 0.4794255, 0, 0.8775826], [0, 1, 0]);
211
213
  check([0, 0, 0.4794255, 0.8775826], [0, 0, 1]);
@@ -221,5 +223,27 @@ test('toEulerAnglesXYZ', () => {
221
223
  check([0, -0.4794255, 0, 0.8775826], [0, -1, 0]);
222
224
  check([0, 0, -0.4794255, 0.8775826], [0, 0, -1]);
223
225
 
226
+ });
227
+
228
+ test('computeTwistAngle', () => {
229
+ const q = new Quaternion();
230
+
231
+ q.fromAxisAngle(Vector3.up, 0);
232
+
233
+ expect(q.computeTwistAngle(Vector3.up)).toBeCloseTo(0);
234
+
235
+ const hp = Math.PI * 0.5;
236
+
237
+ q.fromAxisAngle(Vector3.up, hp);
238
+
239
+ expect(q.computeTwistAngle(Vector3.up)).toBeCloseTo(hp);
240
+
241
+ q.fromAxisAngle(Vector3.up, hp * 2);
242
+
243
+ expect(q.computeTwistAngle(Vector3.up)).toBeCloseTo(hp * 2);
244
+
245
+ q.fromAxisAngle(Vector3.up, hp * 3);
246
+
247
+ expect(q.computeTwistAngle(Vector3.up)).toBeCloseTo(hp * 3);
224
248
 
225
249
  });
@@ -475,7 +475,7 @@ class Vector2 {
475
475
  _distanceSqrTo(x, y) {
476
476
  const dx = this.x - x;
477
477
  const dy = this.y - y;
478
- return magnitudeSqr(dx, dy);
478
+ return v2_length_sqr(dx, dy);
479
479
  }
480
480
 
481
481
  /**
@@ -685,7 +685,7 @@ export function v2_dot(x0, y0, x1, y1) {
685
685
  * @param {number} y
686
686
  * @returns {number}
687
687
  */
688
- function magnitudeSqr(x, y) {
688
+ export function v2_length_sqr(x, y) {
689
689
  return x * x + y * y;
690
690
  }
691
691
 
@@ -696,7 +696,7 @@ function magnitudeSqr(x, y) {
696
696
  * @returns {number}
697
697
  */
698
698
  export function v2_magnitude(x, y) {
699
- return Math.sqrt(magnitudeSqr(x, y));
699
+ return Math.sqrt(v2_length_sqr(x, y));
700
700
  }
701
701
 
702
702
  /**
@@ -51,6 +51,8 @@ export default class Vector3 implements Vector3Like {
51
51
 
52
52
  _crossVectors(ax: number, ay: number, az: number, bx: number, by: number, bz: number): void
53
53
 
54
+ _projectVectors(x0: number, y0: number, z0: number, x1: number, y1: number, z1: number): void
55
+
54
56
  isZero(): boolean
55
57
 
56
58
  copy(other: Vector3Like): void
@@ -688,14 +688,38 @@ class Vector3 {
688
688
  }
689
689
 
690
690
  /**
691
- *
691
+ * Compute orthogonal vectors given a normal
692
+ * Orthogonal vectors are normalized vectors pointing at right angles away from the input normal and to one another
693
+ * @see https://stackoverflow.com/questions/3684269/component-of-a-quaternion-rotation-around-an-axis
694
+ * @param normal
695
+ * @param orthonormal1
696
+ * @param orthonormal2
697
+ */
698
+ static findOrthonormals(normal, orthonormal1, orthonormal2) {
699
+ throw new Error('Not Implemented');
700
+
701
+ // Vector3 w = Vector3.Transform(normal, OrthoX);
702
+ // float dot = Vector3.Dot(normal, w);
703
+ // if (Math.Abs(dot) > 0.6)
704
+ // {
705
+ // w = Vector3.Transform(normal, OrthoY);
706
+ // }
707
+ // w.Normalize();
708
+ //
709
+ // orthonormal1 = Vector3.Cross(normal, w);
710
+ // orthonormal1.Normalize();
711
+ // orthonormal2 = Vector3.Cross(normal, orthonormal1);
712
+ // orthonormal2.Normalize();
713
+ }
714
+
715
+ /**
716
+ * Project first vector onto second one
692
717
  * @param {number} x0
693
- * @param y0
694
- * @param z0
695
- * @param x1
696
- * @param y1
697
- * @param z1
698
- * @private
718
+ * @param {number} y0
719
+ * @param {number} z0
720
+ * @param {number} x1
721
+ * @param {number} y1
722
+ * @param {number} z1
699
723
  */
700
724
  _projectVectors(x0, y0, z0, x1, y1, z1) {
701
725
 
@@ -114,6 +114,22 @@ class Vector4 {
114
114
  this.onChanged = new Signal();
115
115
  }
116
116
 
117
+ get 0() {
118
+ return this.x;
119
+ }
120
+
121
+ get 1() {
122
+ return this.y;
123
+ }
124
+
125
+ get 2() {
126
+ return this.z;
127
+ }
128
+
129
+ get 3() {
130
+ return this.w;
131
+ }
132
+
117
133
  /**
118
134
  *
119
135
  * @param {number[]} array
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Generalized bell function, also known as "Cauchy membership function"
3
+ * @see "dbellmf" function from Matlab
4
+ * @see https://codecrucks.com/what-is-fuzzy-membership-function-complete-guide/
5
+ * @see https://researchhubs.com/post/maths/fundamentals/bell-shaped-function.html
6
+ * @param {number} v
7
+ * @param {number} a Controls window, larger value = larger window. Function will return exactly 0.5 at this distance away from center
8
+ * @param {number} b Slope, larger slope makes function's tails sharper, meaning that values fall off faster away from center
9
+ * @param {number} c Controls center of the bell curve
10
+ * @returns {number}
11
+ */
12
+ export function bell_membership_function(v, a, b, c) {
13
+
14
+ const N = (v - c) / a;
15
+
16
+ const d = 1 + Math.pow(N, b * 2);
17
+
18
+ return 1 / d;
19
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 2 raised to the power of the parameter
3
+ * @param {number} v
4
+ * @returns {number}
5
+ */
6
+ export function exp2(v) {
7
+ return Math.pow(2, v);
8
+ }
@@ -39,6 +39,7 @@ export class NumericInterval {
39
39
  this.onChanged = new Signal();
40
40
  }
41
41
 
42
+
42
43
  /**
43
44
  *
44
45
  * @param {number} min
@@ -108,6 +109,14 @@ export class NumericInterval {
108
109
  return this.min === 0 && this.max === 0;
109
110
  }
110
111
 
112
+ /**
113
+ * Whether min and max are the same
114
+ * @returns {boolean}
115
+ */
116
+ isExact() {
117
+ return this.min === this.max;
118
+ }
119
+
111
120
  /**
112
121
  *
113
122
  * @returns {number}
@@ -176,6 +185,14 @@ export class NumericInterval {
176
185
 
177
186
  return hash;
178
187
  }
188
+
189
+ /**
190
+ * Distance between min and max (= max - min)
191
+ * @returns {number}
192
+ */
193
+ get span() {
194
+ return this.max - this.min;
195
+ }
179
196
  }
180
197
 
181
198
  /**
@@ -0,0 +1,25 @@
1
+ function F_Schlick(u, f0, f90) {
2
+
3
+ return f0 + (f90 - f0) * Math.pow(1.0 - u, 5.0);
4
+ }
5
+
6
+ /**
7
+ * @see https://google.github.io/filament/Filament.md.html#listing_diffusebrdf
8
+ * @see Brent Burley. 2012. Physically Based Shading at Disney. Physically Based Shading in Film and Game Production, ACM SIGGRAPH 2012 Courses.
9
+ * N = surface normal
10
+ * L = light direction
11
+ * V = view direction
12
+ * H = normalize( V + L )
13
+ *
14
+ * @param {number} NoV = abs(dot(n, v)) + 1e-5
15
+ * @param {number} NoL = lamp(dot(n, l), 0.0, 1.0)
16
+ * @param {number} LoH = clamp(dot(l, h), 0.0, 1.0)
17
+ * @param {number} roughness surface roughness coefficient
18
+ * @returns {number}
19
+ */
20
+ export function brdf_burley(NoV, NoL, LoH, roughness) {
21
+ const f90 = 0.5 + 2.0 * roughness * LoH * LoH;
22
+ const lightScatter = F_Schlick(NoL, 1.0, f90);
23
+ const viewScatter = F_Schlick(NoV, 1.0, f90);
24
+ return lightScatter * viewScatter * (1.0 / Math.PI);
25
+ }
@@ -0,0 +1,22 @@
1
+ import { exp2 } from "../../exp2.js";
2
+
3
+
4
+ /**
5
+ *
6
+ * @param {number} f0
7
+ * @param {number} f90
8
+ * @param {number} dotVH
9
+ * @returns {number}
10
+ */
11
+ export function bsdf_schlick(f0, f90, dotVH) {
12
+
13
+ // Original approximation by Christophe Schlick '94
14
+ // float fresnel = pow( 1.0 - dotVH, 5.0 );
15
+
16
+ // Optimized variant (presented by Epic at SIGGRAPH '13)
17
+ // https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf
18
+
19
+ const fresnel = exp2(((-5.55473) * dotVH - 6.98316) * dotVH);
20
+
21
+ return ((f0 * (1.0 - fresnel)) + (f90 * fresnel));
22
+ }
@@ -0,0 +1,18 @@
1
+ import { inverseLerp } from "../../inverseLerp.js";
2
+
3
+ /**
4
+ *
5
+ * @param {number} distance
6
+ * @param {number} min
7
+ * @param {number} max
8
+ * @returns {number}
9
+ */
10
+ export function interpolate_irradiance_linear(distance, min, max) {
11
+ if (distance <= min) {
12
+ return 1;
13
+ } else if (distance >= max) {
14
+ return 0;
15
+ } else {
16
+ return inverseLerp(max, min, distance);
17
+ }
18
+ }
@@ -1,4 +1,4 @@
1
- import { inverseLerp } from "../../../../../core/math/inverseLerp.js";
1
+ import { inverseLerp } from "../../inverseLerp.js";
2
2
 
3
3
  /**
4
4
  *
@@ -7,7 +7,7 @@ import { inverseLerp } from "../../../../../core/math/inverseLerp.js";
7
7
  * @param {number} max
8
8
  * @return {number}
9
9
  */
10
- export function attenuateSoundLogarithmic(distance, min, max) {
10
+ export function interpolate_irradiance_lograrithmic(distance, min, max) {
11
11
  if (distance >= max) {
12
12
  return 0;
13
13
  }
@@ -6,7 +6,7 @@
6
6
  * @param {number} max
7
7
  * @return {number}
8
8
  */
9
- export function attenuateSoundSmith(distance, min, max) {
9
+ export function interpolate_irradiance_smith(distance, min, max) {
10
10
 
11
11
  if (distance < min) {
12
12
  return 1;