@woosh/meep-engine 2.36.28 → 2.37.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.
Files changed (125) hide show
  1. package/core/bvh2/bvh3/{bvh_query_user_data_by_frustum.js → bvh_query_user_data_overlaps_frustum.js} +4 -5
  2. package/core/bvh2/traversal/ThreeClippingPlaneComputingBVHVisitor.js +1 -1
  3. package/core/color/Color.js +54 -3
  4. package/core/color/hsv2rgb.js +3 -3
  5. package/core/color/kelvin_to_rgb.js +51 -0
  6. package/core/color/kelvin_to_rgb.spec.js +61 -0
  7. package/core/color/linear_to_sRGB.js +17 -0
  8. package/core/color/prototype_kelvin_to_rgb.js +44 -0
  9. package/core/color/rgb_to_kelvin.js +34 -0
  10. package/core/color/rgb_to_kelvin.spec.js +15 -0
  11. package/core/color/sRGB_to_linear.js +16 -0
  12. package/core/geom/3d/frustum/read_frustum_planes_to_array.d.ts +3 -0
  13. package/{engine/graphics/render/forward_plus/cluster → core/geom/3d/frustum}/read_frustum_planes_to_array.js +1 -1
  14. package/core/geom/3d/line/line3_computeSegmentPointDistance_sqr.js +2 -2
  15. package/core/geom/LineSegment.js +2 -2
  16. package/core/geom/Vector3.js +14 -0
  17. package/core/math/DEG_TO_RAD.js +1 -0
  18. package/core/math/MathUtils.spec.js +0 -13
  19. package/core/math/RAD_TO_DEG.js +1 -0
  20. package/core/math/clamp01.js +15 -0
  21. package/core/math/fract.js +10 -0
  22. package/core/math/newton_solver_1d.js +21 -0
  23. package/core/math/smoothStep.js +3 -3
  24. package/core/math/solveQuadratic.js +32 -12
  25. package/core/math/solveQuadratic.spec.js +18 -0
  26. package/core/primitives/strings/StringUtils.js +10 -0
  27. package/core/process/task/TaskUtils.js +2 -2
  28. package/core/process/undo/Action.d.ts +2 -2
  29. package/core/process/undo/Action.js +4 -4
  30. package/core/process/undo/ActionGroup.js +4 -4
  31. package/core/process/undo/ActionProcessor.d.ts +6 -6
  32. package/core/process/undo/ActionProcessor.js +106 -16
  33. package/core/process/undo/ActionProcessor.spec.js +20 -15
  34. package/editor/actions/concrete/ComponentAddAction.js +2 -2
  35. package/editor/actions/concrete/ComponentRemoveAction.js +2 -2
  36. package/editor/actions/concrete/EntityCreateAction.js +2 -2
  37. package/editor/actions/concrete/EntityRemoveAction.js +2 -2
  38. package/editor/actions/concrete/PaintTerrainOverlayAction.js +2 -2
  39. package/editor/actions/concrete/PatchTerrainHeightAction.js +2 -2
  40. package/editor/actions/concrete/PatchTerrainTextureAction.js +2 -2
  41. package/editor/actions/concrete/SelectionAddAction.js +2 -2
  42. package/editor/actions/concrete/SelectionClearAction.js +2 -2
  43. package/editor/actions/concrete/SelectionRemoveAction.js +2 -2
  44. package/editor/actions/concrete/TransformModifyAction.js +2 -2
  45. package/editor/actions/concrete/WriteGridValueAction.js +2 -2
  46. package/editor/view/EditorView.js +11 -9
  47. package/editor/view/ecs/components/color/GaugeView.js +2 -2
  48. package/editor/view/ecs/components/particles/ColorParameterLUTController.js +5 -4
  49. package/editor/view/ecs/components/particles/ScalarParameterLUTController.js +5 -3
  50. package/engine/Clock.js +4 -0
  51. package/engine/UserController.js +2 -1
  52. package/engine/animation/behavior/animateProperty.js +6 -1
  53. package/engine/animation/keyed2/behavior/AnimationBehavior.js +0 -1
  54. package/engine/ecs/EntityBuilder.js +12 -1
  55. package/engine/ecs/animation/OneBoneSurfaceAlignmentSolver.js +2 -1
  56. package/engine/ecs/animation/TwoBoneInverseKinematicsSolver.js +2 -1
  57. package/engine/ecs/fow/shader/screenSpaceFogOfWarShader.js +14 -11
  58. package/engine/ecs/systems/AimControllerSystem.js +3 -2
  59. package/engine/ecs/systems/RangedAttackSystem.js +3 -2
  60. package/engine/ecs/systems/SteeringSystem.js +3 -3
  61. package/engine/ecs/terrain/ecs/ClingToTerrainSystem.js +2 -2
  62. package/engine/ecs/terrain/util/paintTerrainOverlayViaLookupTable.js +2 -2
  63. package/engine/graphics/GraphicsEngine.js +2 -1
  64. package/engine/graphics/camera/CameraShake.js +4 -4
  65. package/engine/graphics/ecs/animation/animator/graph/AnimationTransition.js +2 -2
  66. package/engine/graphics/ecs/camera/TiltCameraController.js +3 -2
  67. package/engine/graphics/ecs/compileAllMaterials.js +2 -2
  68. package/engine/graphics/ecs/highlight/renderer/OutlineRenderer.js +10 -11
  69. package/engine/graphics/ecs/mesh/createTaskWaitForMeshesToLoad.js +2 -2
  70. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.d.ts +6 -0
  71. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +19 -0
  72. package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +4 -2
  73. package/engine/graphics/ecs/mesh-v2/render/optimization/RuntimeDrawMethodOptimizer.js +6 -0
  74. package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +31 -0
  75. package/engine/graphics/micron/build/fill_patch_geometry_data.js +2 -2
  76. package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +5 -3
  77. package/engine/graphics/render/forward_plus/LightManager.js +1 -1
  78. package/engine/graphics/render/gizmo/Gizmo.js +3 -0
  79. package/engine/graphics/render/gizmo/GizmoRenderingPlugin.js +5 -0
  80. package/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +91 -0
  81. package/engine/graphics/render/view/CameraView.js +1 -1
  82. package/engine/graphics/texture/sampler/Sampler2D.js +110 -18
  83. package/engine/graphics/three/OrbitControls.js +3 -2
  84. package/engine/graphics/trail/x/simulator/RibbonXFixedPhysicsSimulator.js +2 -2
  85. package/engine/graphics/util/makeMeshPreviewScene.js +11 -3
  86. package/engine/intelligence/behavior/Behavior.js +36 -17
  87. package/engine/intelligence/behavior/SelectorBehavior.js +6 -5
  88. package/engine/intelligence/behavior/composite/ParallelBehavior.js +0 -66
  89. package/engine/intelligence/behavior/composite/ParallelBehaviorSerializationAdapter.js +63 -0
  90. package/engine/intelligence/behavior/composite/SequenceBehavior.js +36 -11
  91. package/engine/intelligence/behavior/decorator/AbstractDecoratorBehavior.js +0 -2
  92. package/engine/intelligence/behavior/decorator/IgnoreFailureBehavior.js +2 -4
  93. package/engine/intelligence/behavior/decorator/InverterBehavior.js +3 -3
  94. package/engine/intelligence/behavior/decorator/RepeatBehavior.js +0 -35
  95. package/engine/intelligence/behavior/decorator/RepeatBehavior.spec.js +0 -10
  96. package/engine/intelligence/behavior/decorator/RepeatBehaviorSerializationAdapter.js +37 -0
  97. package/engine/intelligence/behavior/decorator/RepeatUntilFailureBehavior.js +0 -3
  98. package/engine/intelligence/behavior/decorator/RepeatUntilSuccessBehavior.js +5 -10
  99. package/engine/intelligence/behavior/ecs/BehaviorComponent.js +95 -7
  100. package/engine/intelligence/behavior/ecs/BehaviorComponentSerializationAdapter.js +15 -8
  101. package/engine/intelligence/behavior/ecs/BehaviorSystem.js +28 -37
  102. package/engine/intelligence/behavior/ecs/DieBehavior.js +2 -7
  103. package/engine/intelligence/behavior/ecs/WaitForEventBehavior.js +2 -29
  104. package/engine/intelligence/behavior/ecs/WaitForEventBehaviorSerializationAdapter.js +29 -0
  105. package/engine/intelligence/behavior/primitive/ActionBehavior.js +6 -13
  106. package/engine/intelligence/behavior/primitive/FailingBehavior.js +1 -29
  107. package/engine/intelligence/behavior/primitive/FailingBehaviorSerializationAdapter.js +29 -0
  108. package/engine/intelligence/behavior/primitive/PromiseBehavior.js +15 -3
  109. package/engine/intelligence/behavior/selector/WeightedRandomBehavior.js +1 -5
  110. package/engine/intelligence/behavior/util/ConditionBehavior.js +1 -3
  111. package/engine/intelligence/behavior/util/ConditionBehavior.spec.js +1 -7
  112. package/engine/intelligence/behavior/util/ConditionalBehavior.js +3 -6
  113. package/engine/intelligence/behavior/util/DelayBehavior.js +2 -4
  114. package/engine/intelligence/behavior/util/SelectorBehavior.js +13 -12
  115. package/engine/intelligence/blackboard/AbstractBlackboard.js +16 -2
  116. package/engine/plugin/EnginePluginManager.js +4 -14
  117. package/engine/sound/ecs/emitter/SoundEmitter.js +3 -0
  118. package/generation/filtering/numeric/math/CellFilterSaturate.js +2 -2
  119. package/generation/grid/generation/GridTaskDensityMarkerDistribution.js +3 -2
  120. package/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.spec.js +1 -1
  121. package/generation/rules/CellMatcherLayerBitMaskTest.js +3 -3
  122. package/package.json +1 -1
  123. package/view/elements/progress/SmoothProgressBar.js +2 -2
  124. package/view/elements/progress/segmented/SegmentedResourceBarView.js +3 -3
  125. package/view/elements/radial/RadialProgressView.js +2 -2
@@ -14,12 +14,11 @@ const scratch_aabb = [];
14
14
  * @param {ExplicitBinaryBoundingVolumeHierarchy} bvh
15
15
  * @param {number[]|Float32Array} frustum
16
16
  */
17
- export function bvh_query_user_data_by_frustum(
17
+ export function bvh_query_user_data_overlaps_frustum(
18
18
  result,
19
19
  result_offset,
20
20
  bvh,
21
- frustum
22
- ) {
21
+ frustum) {
23
22
  const root = bvh.root;
24
23
 
25
24
  if (root === NULL_NODE) {
@@ -30,9 +29,9 @@ export function bvh_query_user_data_by_frustum(
30
29
  *
31
30
  * @type {number}
32
31
  */
33
- let traversal_cursor = 0;
32
+ let traversal_cursor = 1;
34
33
 
35
- traversal_stack[traversal_cursor++] = root;
34
+ traversal_stack[0] = root;
36
35
 
37
36
  let result_cursor = result_offset;
38
37
 
@@ -1,6 +1,6 @@
1
1
  import { computePointDistanceToPlane } from "../../geom/Plane.js";
2
2
  import { BVHVisitor } from "./BVHVisitor.js";
3
- import { read_frustum_planes_to_array } from "../../../engine/graphics/render/forward_plus/cluster/read_frustum_planes_to_array.js";
3
+ import { read_frustum_planes_to_array } from "../../geom/3d/frustum/read_frustum_planes_to_array.js";
4
4
  import { __detailed_box_volume_intersection } from "./__detailed_box_volume_intersection.js";
5
5
 
6
6
  export class ThreeClippingPlaneComputingBVHVisitor extends BVHVisitor {
@@ -1,7 +1,6 @@
1
1
  import { assert } from "../assert.js";
2
2
  import Signal from "../events/signal/Signal.js";
3
3
  import { parseColor } from "./ColorUtils.js";
4
- import { clamp } from "../math/clamp.js";
5
4
  import { min2 } from "../math/min2.js";
6
5
  import { max2 } from "../math/max2.js";
7
6
  import { min3 } from "../math/min3.js";
@@ -9,7 +8,11 @@ import { computeHashIntegerArray } from "../collection/array/computeHashIntegerA
9
8
  import { computeHashFloat } from "../math/hash/computeHashFloat.js";
10
9
  import { rgb2hsv } from "./rgb2hsv.js";
11
10
  import { rgb2uint24 } from "./rgb2uint24.js";
11
+ import { clamp01 } from "../math/clamp01.js";
12
12
 
13
+ /**
14
+ * @class
15
+ */
13
16
  export class Color {
14
17
  /**
15
18
  *
@@ -44,6 +47,54 @@ export class Color {
44
47
  this.onChanged = new Signal();
45
48
  }
46
49
 
50
+ /**
51
+ *
52
+ * @returns {number}
53
+ */
54
+ get 0() {
55
+ return this.r;
56
+ }
57
+
58
+ /**
59
+ *
60
+ * @param {number} v
61
+ */
62
+ set 0(v) {
63
+ this.r = v;
64
+ }
65
+
66
+ /**
67
+ *
68
+ * @returns {number}
69
+ */
70
+ get 1() {
71
+ return this.g;
72
+ }
73
+
74
+ /**
75
+ *
76
+ * @param {number} v
77
+ */
78
+ set 1(v) {
79
+ this.g = v;
80
+ }
81
+
82
+ /**
83
+ *
84
+ * @returns {number}
85
+ */
86
+ get 2() {
87
+ return this.b;
88
+ }
89
+
90
+ /**
91
+ *
92
+ * @param {number} v
93
+ */
94
+ set 2(v) {
95
+ this.b = v;
96
+ }
97
+
47
98
  /**
48
99
  *
49
100
  * @param {number} r
@@ -227,8 +278,8 @@ export class Color {
227
278
  _h = h + 1;
228
279
  }
229
280
 
230
- const _s = clamp(s, 0, 1);
231
- const _v = clamp(v, 0, 1);
281
+ const _s = clamp01(s);
282
+ const _v = clamp01(v);
232
283
 
233
284
  let r, g, b;
234
285
 
@@ -1,4 +1,4 @@
1
- import { clamp } from "../math/clamp.js";
1
+ import { clamp01 } from "../math/clamp01.js";
2
2
 
3
3
  /**
4
4
  *
@@ -15,8 +15,8 @@ export function hsv2rgb(h, s, v) {
15
15
  _h = h + 1;
16
16
  }
17
17
 
18
- const _s = clamp(s, 0, 1);
19
- const _v = clamp(v, 0, 1);
18
+ const _s = clamp01(s);
19
+ const _v = clamp01(v);
20
20
 
21
21
  let r, g, b, i, f, p, q, t;
22
22
 
@@ -0,0 +1,51 @@
1
+ import { clamp01 } from "../math/clamp01.js";
2
+
3
+ /**
4
+ * @see https://www.zombieprototypes.com/?p=210
5
+ * @see https://tannerhelland.com/2012/09/18/convert-temperature-rgb-algorithm-code.html
6
+ * TODO: not sure if output is in linear or sRGB space, looking at the way colors look in Unity - it appears that colors are in sRGB and need to be shifted to linear before being used
7
+ * @param {number[]} result RGB output
8
+ * @param {number} result_offset
9
+ * @param {number} temperature in Kelvin
10
+ */
11
+ export function kelvin_to_rgb(result, result_offset, temperature) {
12
+ let r;
13
+ let g;
14
+ let b;
15
+
16
+ // Temperature divided by 100 for calculations
17
+ const t = temperature / 100;
18
+
19
+ if (t <= 66) {
20
+ r = 1;
21
+
22
+ g = clamp01(
23
+ -0.6088425710866344 - 0.001748900018414868 * (t - 2) + 0.4097731842899564 * Math.log(t - 2)
24
+ );
25
+
26
+ if (t <= 20) {
27
+ b = 0;
28
+ } else {
29
+
30
+ b = clamp01(
31
+ -0.9990954974165059 + 0.0032447435545127036 * (t - 10) + 0.453646839257496 * Math.log(t - 10)
32
+ );
33
+
34
+ }
35
+ } else {
36
+
37
+ r = clamp01(
38
+ 1.3803015908551253 + 0.0004478684462124118 * (t - 55) - 0.15785750232675008 * Math.log(t - 55)
39
+ ); // in normalized scale
40
+
41
+ g = clamp01(
42
+ 1.2762722061615583 + 0.0003115080994769546 * (t - 50) - 0.11013841706194392 * Math.log(t - 50)
43
+ );
44
+
45
+ b = 1;
46
+ }
47
+
48
+ result[result_offset + 0] = r;
49
+ result[result_offset + 1] = g;
50
+ result[result_offset + 2] = b;
51
+ }
@@ -0,0 +1,61 @@
1
+ import { kelvin_to_rgb } from "./kelvin_to_rgb.js";
2
+ import { v3_distance } from "../geom/v3_distance.js";
3
+ import { Color } from "./Color.js";
4
+
5
+ function rgb([r255, g255, b255]) {
6
+ return [r255 * 255, g255 * 255, b255 * 255];
7
+ }
8
+
9
+ function closeTo(actual, expected, error = 0.05) {
10
+ const distance = v3_distance(
11
+ actual[0], actual[1], actual[2],
12
+ expected[0], expected[1], expected[2]
13
+ );
14
+
15
+ expect(distance).toBeLessThan(error * 255);
16
+ }
17
+
18
+ /**
19
+ * NOTE: original function is fit from that dataset
20
+ * @see http://www.vendian.org/mncharity/dir3/blackbody/UnstableURLs/bbr_color.html
21
+ * @type {(number|string)[]}
22
+ */
23
+ const bbr_color_table_2deg = [
24
+ 1000, "#ff3300",
25
+ 1100, "#ff4500",
26
+ 2000, "#ff8d0b",
27
+ 3000, "#ffb969",
28
+ 4000, "#ffd5a1",
29
+ 5000, "#ffe7cc",
30
+ 6000, "#fff4ed",
31
+ 7000, "#f7f5ff",
32
+ 8000, "#e5e9ff",
33
+ 9000, "#d9e1ff",
34
+ 10000, "#cfdaff",
35
+ 11000, "#c8d5ff",
36
+ 12000, "#c3d1ff",
37
+ 13000, "#beceff",
38
+ 14000, "#bacbff",
39
+ 15000, "#b7c9ff",
40
+ 15000, "#b7c9ff",
41
+ 16000, "#b5c7ff",
42
+ 20000, "#adc1ff",
43
+ 30000, "#a5baff",
44
+ 40000, "#a1b7ff",
45
+ ];
46
+
47
+ test("table", () => {
48
+ const t = [];
49
+
50
+ for (let i = 0; i < bbr_color_table_2deg.length;) {
51
+ const temp = bbr_color_table_2deg[i++];
52
+ const color = bbr_color_table_2deg[i++];
53
+
54
+ kelvin_to_rgb(t, 0, temp);
55
+
56
+ const color_obj = Color.parse(color);
57
+
58
+ closeTo(rgb(t), [color_obj.r * 255, color_obj.g * 255, color_obj.b * 255]);
59
+
60
+ }
61
+ });
@@ -0,0 +1,17 @@
1
+
2
+ function convert(c){
3
+ return ( c < 0.0031308 ) ? c * 12.92 : 1.055 * ( Math.pow( c, 0.41666 ) ) - 0.055;
4
+ }
5
+
6
+ /**
7
+ *
8
+ * @param {number[]} output
9
+ * @param {number} output_offset
10
+ * @param {number[]} input
11
+ * @param {number} input_offset
12
+ */
13
+ export function linear_to_sRGB(output, output_offset, input, input_offset) {
14
+ output[output_offset] = convert(input[input_offset]);
15
+ output[output_offset + 1] = convert(input[input_offset + 1]);
16
+ output[output_offset + 2] = convert(input[input_offset + 2]);
17
+ }
@@ -0,0 +1,44 @@
1
+ import { CanvasView } from "../../view/elements/CanvasView.js";
2
+ import { kelvin_to_rgb } from "./kelvin_to_rgb.js";
3
+ import { lerp } from "../math/lerp.js";
4
+ import { Sampler2D } from "../../engine/graphics/texture/sampler/Sampler2D.js";
5
+ import sampler2D2Canvas from "../../engine/graphics/texture/sampler/Sampler2D2Canvas.js";
6
+ import { sRGB_to_linear } from "./sRGB_to_linear.js";
7
+
8
+ const view = new CanvasView();
9
+
10
+ view.css({
11
+ position: 'fixed',
12
+ left: '10px',
13
+ top: '10px',
14
+ zIndex: 5
15
+ });
16
+ view.size.set(400, 50);
17
+
18
+ document.body.append(view.el);
19
+
20
+ view.link();
21
+
22
+ const sampler = Sampler2D.float32(4, 400, 50);
23
+
24
+ const color = [1, 1, 1, 1];
25
+ for (let i = 0; i < sampler.width; i++) {
26
+ const f = i / (sampler.width - 1);
27
+ const k = lerp(1500, 20000, f);
28
+ kelvin_to_rgb(color, 0, k);
29
+
30
+ sRGB_to_linear(color, 0, color, 0);
31
+
32
+ for (let j = 0; j < sampler.height; j++) {
33
+ sampler.set(i, j, color);
34
+ // sampler.set(i, j, [f, f, f, 1]);
35
+
36
+ }
37
+ // sampler.set(i, sampler.height - 1, [f, f, f, 1]);
38
+ }
39
+
40
+ console.log(sampler);
41
+
42
+ sampler2D2Canvas(sampler, 255, 0, view.el);
43
+
44
+
@@ -0,0 +1,34 @@
1
+ import { kelvin_to_rgb } from "./kelvin_to_rgb.js";
2
+
3
+ const scratch_rgb = [];
4
+
5
+ /**
6
+ *
7
+ * @see https://www.zombieprototypes.com/?p=210
8
+ * @param {number[]|ArrayLike<number>|{0:number,1:number,2:number}} input input array
9
+ * @param {number} input_offset offset into input array
10
+ */
11
+ export function rgb_to_kelvin(input, input_offset = 0) {
12
+ const r = input[input_offset];
13
+ const g = input[input_offset + 1];
14
+ const b = input[input_offset + 2];
15
+
16
+ // use solver to reverse function, slow but hey - it works
17
+ var temperature;
18
+ var epsilon=0.4;
19
+ var minTemperature = 1000;
20
+ var maxTemperature = 40000;
21
+
22
+ while (maxTemperature - minTemperature > epsilon) {
23
+ temperature = (maxTemperature + minTemperature) / 2;
24
+ kelvin_to_rgb(scratch_rgb,0,temperature);
25
+ if ((scratch_rgb[2] / scratch_rgb[0]) >= (b / r)) {
26
+ maxTemperature = temperature;
27
+ } else {
28
+ minTemperature = temperature;
29
+ }
30
+ }
31
+
32
+ return Math.round(temperature);
33
+
34
+ }
@@ -0,0 +1,15 @@
1
+ import { rgb_to_kelvin } from "./rgb_to_kelvin.js";
2
+ import { Color } from "./Color.js";
3
+
4
+
5
+ test("1000 K", () => {
6
+ const actual = rgb_to_kelvin(Color.parse("#ff3e00"));
7
+
8
+ expect(Math.abs(actual - 1000)).toBeLessThan(100);
9
+ });
10
+
11
+ test("40000 K", () => {
12
+ const actual = rgb_to_kelvin(Color.parse("#8cb4ff"));
13
+
14
+ expect(Math.abs(actual - 40000)).toBeLessThan(100);
15
+ });
@@ -0,0 +1,16 @@
1
+ function convert(c) {
2
+ return (c < 0.04045) ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
3
+ }
4
+
5
+ /**
6
+ *
7
+ * @param {number[]} output
8
+ * @param {number} output_offset
9
+ * @param {number[]} input
10
+ * @param {number} input_offset
11
+ */
12
+ export function sRGB_to_linear(output, output_offset, input, input_offset) {
13
+ output[output_offset] = convert(input[input_offset]);
14
+ output[output_offset + 1] = convert(input[input_offset + 1]);
15
+ output[output_offset + 2] = convert(input[input_offset + 2]);
16
+ }
@@ -0,0 +1,3 @@
1
+ import {Plane} from "three";
2
+
3
+ export function read_frustum_planes_to_array(planes: Plane[], array: ArrayLike<number>);
@@ -1,4 +1,4 @@
1
- import { assert } from "../../../../../core/assert.js";
1
+ import { assert } from "../../../assert.js";
2
2
 
3
3
  /**
4
4
  *
@@ -1,5 +1,5 @@
1
- import { clamp } from "../../../math/clamp.js";
2
1
  import { v3_distance_sqr } from "../../v3_distance_sqr.js";
2
+ import { clamp01 } from "../../../math/clamp01.js";
3
3
 
4
4
  /**
5
5
  * Computes shortest distance between a line segment(defined by 2 points) and a point
@@ -29,7 +29,7 @@ export function line3_computeSegmentPointDistance_sqr(x0, y0, z0, x1, y1, z1, px
29
29
 
30
30
  const d3 = line_delta_x * sp0_x + line_delta_y * sp0_y + line_delta_z * sp0_z;
31
31
 
32
- const t = clamp(d3 / d2, 0, 1);
32
+ const t = clamp01(d3 / d2);
33
33
 
34
34
  // compute point on the line
35
35
  const lp_x = line_delta_x * t + x0;
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Created by Alex on 18/03/14.
3
3
  */
4
- import { clamp } from "../math/clamp.js";
5
4
  import Vector3 from "./Vector3.js";
5
+ import { clamp01 } from "../math/clamp01.js";
6
6
 
7
7
 
8
8
  const SMALL_NUM = 1e-9;
@@ -30,7 +30,7 @@ LineSegment.prototype.closestPointToPointParameter = function (point, clampToLin
30
30
 
31
31
  if (clampToLine) {
32
32
 
33
- t = clamp(t, 0, 1);
33
+ t = clamp01(t);
34
34
 
35
35
  }
36
36
 
@@ -928,6 +928,20 @@ class Vector3 {
928
928
  static distance(a, b) {
929
929
  return v3_length(a.x - b.x, a.y - b.y, a.z - b.z);
930
930
  }
931
+
932
+ /**
933
+ *
934
+ * @param {number[]} input
935
+ * @param {number} [offset]
936
+ * @returns {Vector3}
937
+ */
938
+ static fromArray(input, offset = 0) {
939
+ return new Vector3(
940
+ input[offset],
941
+ input[offset + 1],
942
+ input[offset + 2]
943
+ );
944
+ }
931
945
  }
932
946
 
933
947
  Vector3.prototype.lengthSq = Vector3.prototype.lengthSqr;
@@ -0,0 +1 @@
1
+ export const DEG_TO_RAD = Math.PI / 180;
@@ -10,7 +10,6 @@ import { min3 } from "./min3.js";
10
10
  import { sign } from "./sign.js";
11
11
  import { isValueBetween } from "./isValueBetween.js";
12
12
  import { isValueBetweenInclusive } from "./isValueBetweenInclusive.js";
13
- import { solveQuadratic } from "./solveQuadratic.js";
14
13
  import { overlap1D } from "./overlap1D.js";
15
14
  import { computeHashFloat } from "./hash/computeHashFloat.js";
16
15
 
@@ -223,18 +222,6 @@ test("isValueBetweenInclusive", () => {
223
222
  });
224
223
 
225
224
 
226
- test("solveQuadratic", () => {
227
- expect(solveQuadratic(0, 0, 0)).toStrictEqual([0, 0]);
228
-
229
- expect(solveQuadratic(0, 0, 1)).toStrictEqual(null);
230
-
231
- expect(solveQuadratic(0, 2, 3)).toStrictEqual([-1.5, -1.5]);
232
-
233
- expect(solveQuadratic(1, -2, -3)).toStrictEqual([-1, 3]);
234
-
235
- expect(solveQuadratic(1, -2, 3)).toBe(null);
236
- });
237
-
238
225
  test('overlap1D', () => {
239
226
  expect(overlap1D(0, 0, 0, 0)).toBe(false);
240
227
  expect(overlap1D(-3, -1, -2, -0.5)).toBe(true);
@@ -0,0 +1 @@
1
+ export const RAD_TO_DEG = 180 / Math.PI;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Clamps a value to 0..1 range
3
+ * Same as `clamp(value, 0, 1)`
4
+ * @param {number} value
5
+ * @returns {number}
6
+ */
7
+ export function clamp01(value) {
8
+ if (value < 0) {
9
+ return 0;
10
+ } else if (value > 1) {
11
+ return 1;
12
+ } else {
13
+ return value;
14
+ }
15
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * compute the fractional part of the argument
3
+ * GLSL "fract" function port
4
+ * @see https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/fract.xhtml
5
+ * @param {number} v
6
+ * @returns {number} returns the fractional part of x. This is calculated as x - floor(x).
7
+ */
8
+ export function fract(v) {
9
+ return v % 1;
10
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Newtonian solver, works by moving along the curve in the direction of gradient
3
+ * @template T
4
+ * @param {function(T):number} f
5
+ * @param {T} xStart
6
+ * @param {number} [max_steps]
7
+ * @param {number} [eps]
8
+ * @returns {number}
9
+ */
10
+ export function newton_solver_1d(f, xStart, max_steps = 1000, eps = 0.00000001) {
11
+ let x = xStart, fx;
12
+
13
+ let remaining_steps = max_steps;
14
+
15
+ while ((remaining_steps--) && Math.abs(fx = f(x)) > eps) {
16
+ const dfdx = (f(x + eps) - fx) / eps;
17
+ x = x - fx / dfdx;
18
+ }
19
+
20
+ return x;
21
+ }
@@ -1,4 +1,4 @@
1
- import { clamp } from "./clamp.js";
1
+ import { clamp01 } from "./clamp01.js";
2
2
 
3
3
  /**
4
4
  * Adapted from OpenGL spec
@@ -11,7 +11,7 @@ export function smoothStep(edge0, edge1, x) {
11
11
 
12
12
  const span = edge1 - edge0;
13
13
 
14
- const t = clamp((x - edge0) / span, 0, 1);
14
+ const t = clamp01((x - edge0) / span);
15
15
 
16
16
  return t * t * (3 - 2 * t);
17
- }
17
+ }
@@ -1,25 +1,45 @@
1
1
  /**
2
- * Return solutions for quadratic
2
+ * Return solutions for a quadratic equation
3
3
  * @param {number} a
4
4
  * @param {number} b
5
5
  * @param {number} c
6
- * @returns {number[]|null}
6
+ * @param {number[]} result solutions are written here
7
+ * @param {number} result_offset offset into result array where solutions are written to
8
+ * @returns {number} number of found solutions (roots)
7
9
  */
8
- export function solveQuadratic(a, b, c) {
9
- let sol = null;
10
+ export function solveQuadratic(result, result_offset, a, b, c) {
11
+
10
12
  if (Math.abs(a) < 1e-6) {
11
13
  if (Math.abs(b) < 1e-6) {
12
- sol = Math.abs(c) < 1e-6 ? [0, 0] : null;
14
+ if (Math.abs(c) < 1e-6) {
15
+
16
+ result[result_offset] = 0;
17
+ result[result_offset + 1] = 0;
18
+
19
+ return 2;
20
+
21
+ }
13
22
  } else {
14
- sol = [-c / b, -c / b];
23
+ result[result_offset] = -c / b;
24
+ result[result_offset + 1] = -c / b;
25
+
26
+ return 2;
15
27
  }
16
28
  } else {
17
- let disc = b * b - 4 * a * c;
18
- if (disc >= 0) {
19
- disc = Math.sqrt(disc);
20
- a = 2 * a;
21
- sol = [(-b - disc) / a, (-b + disc) / a];
29
+ const disc_sqr = b * b - 4 * a * c;
30
+
31
+ if (disc_sqr >= 0) {
32
+ const disc = Math.sqrt(disc_sqr);
33
+ const a2 = 2 * a;
34
+
35
+ result[result_offset] = (-b - disc) / a2;
36
+ result[result_offset + 1] = (-b + disc) / a2;
37
+
38
+ return 2;
22
39
  }
40
+
23
41
  }
24
- return sol;
42
+
43
+ // no roots
44
+ return 0;
25
45
  }
@@ -0,0 +1,18 @@
1
+ import { solveQuadratic } from "./solveQuadratic.js";
2
+
3
+ test("solveQuadratic", () => {
4
+ const roots = [];
5
+
6
+ solveQuadratic(roots, 0, 0, 0, 0)
7
+ expect(roots).toStrictEqual([0, 0]);
8
+
9
+ expect(solveQuadratic(roots, 0, 0, 0, 1)).toStrictEqual(0);
10
+
11
+ solveQuadratic(roots, 0, 0, 2, 3);
12
+ expect(roots).toStrictEqual([-1.5, -1.5]);
13
+
14
+ solveQuadratic(roots, 0, 1, -2, -3);
15
+ expect(roots).toStrictEqual([-1, 3]);
16
+
17
+ expect(solveQuadratic(roots, 0, 1, -2, 3)).toBe(0);
18
+ });
@@ -93,3 +93,13 @@ export function computeCommonPrefix(strings) {
93
93
  export function camelToKebab(string) {
94
94
  return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
95
95
  }
96
+
97
+
98
+ /**
99
+ *
100
+ * @param {string} string
101
+ * @returns {string}
102
+ */
103
+ export function kebabToUnderscore(string) {
104
+ return string.replace('-', '_');
105
+ }
@@ -2,10 +2,10 @@
2
2
  * Created by Alex on 22/05/2016.
3
3
  */
4
4
  import { randomizeArrayElementOrder } from "../../collection/ArrayUtils.js";
5
- import { clamp } from "../../math/clamp.js";
6
5
  import { seededRandom } from "../../math/random/seededRandom.js";
7
6
  import Task from "./Task.js";
8
7
  import TaskSignal from "./TaskSignal.js";
8
+ import { clamp01 } from "../../math/clamp01.js";
9
9
 
10
10
  /**
11
11
  *
@@ -180,7 +180,7 @@ export function delayTask(delay, name = "unnamed") {
180
180
  fraction = 0;
181
181
  }
182
182
 
183
- return clamp(fraction, 0, 1);
183
+ return clamp01(fraction);
184
184
  },
185
185
  estimatedDuration
186
186
  });