@woosh/meep-engine 2.100.1 → 2.100.3

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 (55) hide show
  1. package/build/meep.cjs +109 -78
  2. package/build/meep.min.js +1 -1
  3. package/build/meep.module.js +109 -78
  4. package/package.json +1 -1
  5. package/src/core/binary/downloadUrlAsFile.d.ts.map +1 -1
  6. package/src/core/binary/downloadUrlAsFile.js +3 -1
  7. package/src/core/color/oklab/Okhsv.spec.d.ts +2 -0
  8. package/src/core/color/oklab/Okhsv.spec.d.ts.map +1 -0
  9. package/src/core/color/oklab/Okhsv.spec.js +17 -0
  10. package/src/core/color/oklab/XYZ.spec.js +2 -2
  11. package/src/core/color/oklab/compute_max_saturation.d.ts +11 -0
  12. package/src/core/color/oklab/compute_max_saturation.d.ts.map +1 -0
  13. package/src/core/color/oklab/compute_max_saturation.js +84 -0
  14. package/src/core/color/oklab/find_cusp.d.ts +10 -0
  15. package/src/core/color/oklab/find_cusp.d.ts.map +1 -0
  16. package/src/core/color/oklab/find_cusp.js +27 -0
  17. package/src/core/color/oklab/find_gamut_intersection.d.ts +15 -0
  18. package/src/core/color/oklab/find_gamut_intersection.d.ts.map +1 -0
  19. package/src/core/color/oklab/find_gamut_intersection.js +101 -0
  20. package/src/core/color/oklab/linear_srgb_to_okhsv.d.ts +9 -0
  21. package/src/core/color/oklab/linear_srgb_to_okhsv.d.ts.map +1 -0
  22. package/src/core/color/oklab/linear_srgb_to_okhsv.js +74 -0
  23. package/src/core/color/oklab/linear_srgb_to_oklab.d.ts +9 -0
  24. package/src/core/color/oklab/linear_srgb_to_oklab.d.ts.map +1 -0
  25. package/src/core/color/oklab/linear_srgb_to_oklab.js +20 -0
  26. package/src/core/color/oklab/okhsv_to_linear_srgb.d.ts +9 -0
  27. package/src/core/color/oklab/okhsv_to_linear_srgb.d.ts.map +1 -0
  28. package/src/core/color/oklab/okhsv_to_linear_srgb.js +59 -0
  29. package/src/core/color/oklab/oklab_to_linear_srgb.d.ts +10 -0
  30. package/src/core/color/oklab/oklab_to_linear_srgb.d.ts.map +1 -0
  31. package/src/core/color/oklab/oklab_to_linear_srgb.js +21 -0
  32. package/src/core/color/oklab/oklab_to_xyz.d.ts +5 -2
  33. package/src/core/color/oklab/oklab_to_xyz.d.ts.map +1 -1
  34. package/src/core/color/oklab/oklab_to_xyz.js +5 -5
  35. package/src/core/color/oklab/oklab_to_xyz.spec.js +4 -4
  36. package/src/core/color/oklab/toe.d.ts +13 -0
  37. package/src/core/color/oklab/toe.d.ts.map +1 -0
  38. package/src/core/color/oklab/toe.js +22 -0
  39. package/src/core/color/oklab/xyz_to_oklab.d.ts +5 -2
  40. package/src/core/color/oklab/xyz_to_oklab.d.ts.map +1 -1
  41. package/src/core/color/oklab/xyz_to_oklab.js +5 -5
  42. package/src/core/color/oklab/xyz_to_oklab.spec.js +4 -4
  43. package/src/engine/asset/AssetManager.d.ts.map +1 -1
  44. package/src/engine/asset/AssetManager.js +6 -1
  45. package/src/engine/asset/loaders/ArrayBufferLoader.d.ts +2 -1
  46. package/src/engine/asset/loaders/ArrayBufferLoader.d.ts.map +1 -1
  47. package/src/engine/asset/loaders/ArrayBufferLoader.js +107 -79
  48. package/src/engine/graphics/texture/sampler/HarmonicDiffusionGrid.d.ts +1 -1
  49. package/src/engine/graphics/texture/sampler/HarmonicDiffusionGrid.d.ts.map +1 -1
  50. package/src/engine/graphics/texture/sampler/HarmonicDiffusionGrid.js +4 -4
  51. package/src/engine/graphics/texture/sampler/Sampler2D2Canvas.d.ts +1 -2
  52. package/src/engine/graphics/texture/sampler/Sampler2D2Canvas.d.ts.map +1 -1
  53. package/src/engine/graphics/texture/sampler/Sampler2D2Canvas.js +1 -2
  54. package/src/engine/graphics/texture/sampler/sampler2d_to_uint8_RGBA.d.ts.map +1 -1
  55. package/src/engine/graphics/texture/sampler/sampler2d_to_uint8_RGBA.js +8 -0
@@ -67746,6 +67746,83 @@ class AssetLoader {
67746
67746
  }
67747
67747
  }
67748
67748
 
67749
+ /**
67750
+ *
67751
+ * @param {Response} input
67752
+ * @param {function} progress
67753
+ * @return {Response}
67754
+ */
67755
+ function observeResponseProgress(input, progress) {
67756
+ let response = input;
67757
+
67758
+
67759
+ if (typeof ReadableStream === 'undefined' || response.body.getReader === undefined) {
67760
+
67761
+ return response;
67762
+
67763
+ }
67764
+
67765
+ /**
67766
+ * @type {ReadableStreamDefaultReader<Uint8Array>}
67767
+ */
67768
+ const reader = response.body.getReader();
67769
+
67770
+ const contentLength = response.headers.get('Content-Length');
67771
+ const total = contentLength ? parseInt(contentLength) : 0;
67772
+ let loaded = 0;
67773
+
67774
+ // periodically read data into the new stream tracking while download progress
67775
+ const stream_prototype = {
67776
+ type: "bytes",
67777
+ start(controller) {
67778
+
67779
+ pump();
67780
+
67781
+ function pump() {
67782
+
67783
+ reader.read().then(({ done, value }) => {
67784
+
67785
+ if (done) {
67786
+ // no more data, we're done
67787
+ controller.close();
67788
+ return;
67789
+ }
67790
+
67791
+ loaded += value.byteLength;
67792
+
67793
+ progress(loaded, total);
67794
+
67795
+ controller.enqueue(value);
67796
+ pump();
67797
+
67798
+ });
67799
+
67800
+ }
67801
+
67802
+ }
67803
+
67804
+ };
67805
+
67806
+ /**
67807
+ * @type {ReadableStream}
67808
+ */
67809
+ let stream;
67810
+
67811
+ try {
67812
+ stream = new ReadableStream(stream_prototype);
67813
+
67814
+ response = new Response(stream);
67815
+ } catch (e) {
67816
+ /*
67817
+ Workaround for Safari bug: "TypeError: ReadableByteStreamController is not implemented"
67818
+ By not wrapping the response we lose the ability to track progress, but that's not a critical issue in most cases
67819
+ */
67820
+ }
67821
+
67822
+ return response;
67823
+
67824
+ }
67825
+
67749
67826
  class ArrayBufferLoader extends AssetLoader {
67750
67827
  /**
67751
67828
  *
@@ -67764,7 +67841,13 @@ class ArrayBufferLoader extends AssetLoader {
67764
67841
  this.__fetch_priority = fetch_priority;
67765
67842
  }
67766
67843
 
67767
- load(scope, path, success, failure = console.error, progress = noop) {
67844
+ async load(
67845
+ scope,
67846
+ path,
67847
+ success,
67848
+ failure = console.error,
67849
+ progress = noop
67850
+ ) {
67768
67851
  const coc = this.assetManager !== null ? this.assetManager.crossOriginConfig : CrossOriginConfig.default;
67769
67852
 
67770
67853
  const headers = new Headers();
@@ -67779,93 +67862,36 @@ class ArrayBufferLoader extends AssetLoader {
67779
67862
  request.priority = this.__fetch_priority;
67780
67863
  }
67781
67864
 
67782
- fetch(request)
67783
- .then(handle_response)
67784
- .then(response_to_asset)
67785
- .catch(failure);
67865
+ let response = await fetch(request);
67786
67866
 
67787
- /**
67788
- *
67789
- * @param {Response} response
67790
- * @return {Promise<void>}
67791
- */
67792
- async function response_to_asset(response) {
67793
- const arrayBuffer = await response.arrayBuffer();
67867
+ if (!(response.status === 200 || response.status === 0)) {
67794
67868
 
67795
- const asset = new Asset(
67796
- function () {
67797
- return arrayBuffer;
67798
- },
67799
- arrayBuffer.byteSize
67800
- );
67869
+ throw Error(`fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`);
67801
67870
 
67802
- success(asset);
67803
67871
  }
67804
67872
 
67805
- /**
67806
- *
67807
- * @param {Response} response
67808
- * @return {Response}
67809
- */
67810
- function handle_response(response) {
67811
- if (!(response.status === 200 || response.status === 0)) {
67812
-
67813
- throw Error(`fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`);
67814
-
67815
- }
67816
-
67817
- // Some browsers return HTTP Status 0 when using non-http protocol
67818
- // e.g. 'file://' or 'data://'. Handle as success.
67819
-
67820
- if (response.status === 0) ;
67821
-
67822
- if (typeof ReadableStream === 'undefined' || response.body.getReader === undefined) {
67823
-
67824
- return response;
67825
-
67826
- }
67827
-
67828
- const reader = response.body.getReader();
67829
- const contentLength = response.headers.get('Content-Length');
67830
- const total = contentLength ? parseInt(contentLength) : 0;
67831
- let loaded = 0;
67832
-
67833
- // periodically read data into the new stream tracking while download progress
67834
- const stream = new ReadableStream({
67835
- type: "bytes",
67836
- start(controller) {
67837
-
67838
- pump();
67839
-
67840
- function pump() {
67841
-
67842
- reader.read().then(({ done, value }) => {
67843
-
67844
- if (done) {
67845
- // no more data, we're done
67846
- controller.close();
67847
- return;
67848
- }
67849
-
67850
- loaded += value.byteLength;
67873
+ // Some browsers return HTTP Status 0 when using non-http protocol
67874
+ // e.g. 'file://' or 'data://'. Handle as success.
67851
67875
 
67852
- progress(loaded, total);
67876
+ if (response.status === 0) ;
67853
67877
 
67854
- controller.enqueue(value);
67855
- pump();
67856
-
67857
- });
67858
-
67859
- }
67860
-
67861
- }
67878
+ try {
67879
+ response = observeResponseProgress(response, progress);
67880
+ } catch (e) {
67881
+ }
67862
67882
 
67863
- });
67883
+ const arrayBuffer = await response.arrayBuffer();
67864
67884
 
67865
- return new Response(stream);
67866
- }
67885
+ const asset = new Asset(
67886
+ function () {
67887
+ return arrayBuffer;
67888
+ },
67889
+ arrayBuffer.byteSize
67890
+ );
67867
67891
 
67892
+ success(asset);
67868
67893
 
67894
+ return asset;
67869
67895
  }
67870
67896
  }
67871
67897
 
@@ -86223,7 +86249,12 @@ class AssetManager {
86223
86249
  try {
86224
86250
 
86225
86251
 
86226
- loader.load(scope, full_path, success, failure, progress);
86252
+ const result = loader.load(scope, full_path, success, failure, progress);
86253
+
86254
+ if (result instanceof Promise) {
86255
+ // allow promise responses
86256
+ result.catch(failure);
86257
+ }
86227
86258
 
86228
86259
  } catch (e) {
86229
86260
  failure(e);
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "description": "Fully featured ECS game engine written in JavaScript",
6
6
  "type": "module",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.100.1",
8
+ "version": "2.100.3",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -1 +1 @@
1
- {"version":3,"file":"downloadUrlAsFile.d.ts","sourceRoot":"","sources":["../../../../src/core/binary/downloadUrlAsFile.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,uCAHW,MAAM,YACN,MAAM,QAShB"}
1
+ {"version":3,"file":"downloadUrlAsFile.d.ts","sourceRoot":"","sources":["../../../../src/core/binary/downloadUrlAsFile.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,uCAHW,MAAM,YACN,MAAM,QAWhB"}
@@ -4,9 +4,11 @@
4
4
  * @param {string} filename
5
5
  */
6
6
  export function downloadUrlAsFile(url, filename) {
7
- const elem = window.document.createElement('a');
7
+ const elem = document.createElement('a');
8
8
  elem.href = url;
9
9
  elem.download = filename;
10
+
11
+ // only elements on the dom are clickable, so we add it
10
12
  document.body.appendChild(elem);
11
13
  elem.click();
12
14
  document.body.removeChild(elem);
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Okhsv.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Okhsv.spec.d.ts","sourceRoot":"","sources":["../../../../../src/core/color/oklab/Okhsv.spec.js"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ import { linear_srgb_to_okhsv } from "./linear_srgb_to_okhsv.js";
2
+ import { okhsv_to_linear_srgb } from "./okhsv_to_linear_srgb.js";
3
+
4
+ test("to/from consistency", () => {
5
+
6
+ const out = [];
7
+
8
+ const sample = [0.123, 0.345, 0.457];
9
+
10
+ okhsv_to_linear_srgb(out, ...sample);
11
+
12
+ linear_srgb_to_okhsv(out, ...out);
13
+
14
+ expect(out[0]).toBeCloseTo(sample[0]);
15
+ expect(out[1]).toBeCloseTo(sample[1]);
16
+ expect(out[2]).toBeCloseTo(sample[2]);
17
+ });
@@ -7,9 +7,9 @@ test("to/from consistency", () => {
7
7
 
8
8
  const sample = [0.123, 0.345, 0.457];
9
9
 
10
- oklab_to_xyz(sample, out);
10
+ oklab_to_xyz(out, ...sample);
11
11
 
12
- xyz_to_oklab(out, out);
12
+ xyz_to_oklab(out, ...out);
13
13
 
14
14
  expect(out[0]).toBeCloseTo(sample[0]);
15
15
  expect(out[1]).toBeCloseTo(sample[1]);
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Finds the maximum saturation possible for a given hue that fits in sRGB
3
+ * Saturation here is defined as S = C/L
4
+ * a and b must be normalized so a^2 + b^2 == 1
5
+ * @copyright "Company Named Limited" 2023
6
+ * @param {number} a
7
+ * @param {number} b
8
+ * @returns {number}
9
+ */
10
+ export function compute_max_saturation(a: number, b: number): number;
11
+ //# sourceMappingURL=compute_max_saturation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute_max_saturation.d.ts","sourceRoot":"","sources":["../../../../../src/core/color/oklab/compute_max_saturation.js"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,0CAJW,MAAM,KACN,MAAM,GACJ,MAAM,CA4ElB"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Finds the maximum saturation possible for a given hue that fits in sRGB
3
+ * Saturation here is defined as S = C/L
4
+ * a and b must be normalized so a^2 + b^2 == 1
5
+ * @copyright "Company Named Limited" 2023
6
+ * @param {number} a
7
+ * @param {number} b
8
+ * @returns {number}
9
+ */
10
+ export function compute_max_saturation(a, b) {
11
+ // Max saturation will be when one of r, g or b goes below zero.
12
+
13
+ // Select different coefficients depending on which component goes below zero first
14
+ let k0, k1, k2, k3, k4, wl, wm, ws;
15
+
16
+ if (-1.88170328 * a - 0.80936493 * b > 1) {
17
+ // Red component
18
+ k0 = +1.19086277;
19
+ k1 = +1.76576728;
20
+ k2 = +0.59662641;
21
+ k3 = +0.75515197;
22
+ k4 = +0.56771245;
23
+ wl = +4.0767416621;
24
+ wm = -3.3077115913;
25
+ ws = +0.2309699292;
26
+ } else if (1.81444104 * a - 1.19445276 * b > 1) {
27
+ // Green component
28
+ k0 = +0.73956515;
29
+ k1 = -0.45954404;
30
+ k2 = +0.08285427;
31
+ k3 = +0.12541070;
32
+ k4 = +0.14503204;
33
+ wl = -1.2684380046;
34
+ wm = +2.6097574011;
35
+ ws = -0.3413193965;
36
+ } else {
37
+ // Blue component
38
+ k0 = +1.35733652;
39
+ k1 = -0.00915799;
40
+ k2 = -1.15130210;
41
+ k3 = -0.50559606;
42
+ k4 = +0.00692167;
43
+ wl = -0.0041960863;
44
+ wm = -0.7034186147;
45
+ ws = +1.7076147010;
46
+ }
47
+
48
+ // Approximate max saturation using a polynomial:
49
+ let S = k0 + k1 * a + k2 * b + k3 * a * a + k4 * a * b;
50
+
51
+ // Do one step of Halley's method to get closer
52
+ // this gives an error less than 10e6, except for some blue hues where the dS/dh is close to infinite
53
+ // this should be sufficient for most applications, otherwise do two/three steps
54
+
55
+ const k_l = +0.3963377774 * a + 0.2158037573 * b;
56
+ const k_m = -0.1055613458 * a - 0.0638541728 * b;
57
+ const k_s = -0.0894841775 * a - 1.2914855480 * b;
58
+
59
+ {
60
+ const l_ = 1. + S * k_l;
61
+ const m_ = 1. + S * k_m;
62
+ const s_ = 1. + S * k_s;
63
+
64
+ const l = l_ * l_ * l_;
65
+ const m = m_ * m_ * m_;
66
+ const s = s_ * s_ * s_;
67
+
68
+ const l_dS = 3. * k_l * l_ * l_;
69
+ const m_dS = 3. * k_m * m_ * m_;
70
+ const s_dS = 3. * k_s * s_ * s_;
71
+
72
+ const l_dS2 = 6. * k_l * k_l * l_;
73
+ const m_dS2 = 6. * k_m * k_m * m_;
74
+ const s_dS2 = 6. * k_s * k_s * s_;
75
+
76
+ const f = wl * l + wm * m + ws * s;
77
+ const f1 = wl * l_dS + wm * m_dS + ws * s_dS;
78
+ const f2 = wl * l_dS2 + wm * m_dS2 + ws * s_dS2;
79
+
80
+ S = S - f * f1 / (f1 * f1 - 0.5 * f * f2);
81
+ }
82
+
83
+ return S;
84
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * finds L_cusp and C_cusp for a given hue
3
+ * a and b must be normalized so a^2 + b^2 == 1
4
+ * @copyright "Company Named Limited" 2023
5
+ * @param {number[]} output [L, C]
6
+ * @param {number} a
7
+ * @param {number} b
8
+ */
9
+ export function find_cusp(output: number[], a: number, b: number): void;
10
+ //# sourceMappingURL=find_cusp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find_cusp.d.ts","sourceRoot":"","sources":["../../../../../src/core/color/oklab/find_cusp.js"],"names":[],"mappings":"AAOA;;;;;;;GAOG;AACH,kCAJW,MAAM,EAAE,KACR,MAAM,KACN,MAAM,QAahB"}
@@ -0,0 +1,27 @@
1
+ import { max3 } from "../../math/max3.js";
2
+ import { compute_max_saturation } from "./compute_max_saturation.js";
3
+ import { oklab_to_linear_srgb } from "./oklab_to_linear_srgb.js";
4
+
5
+ const rgb_at_max = [0, 0, 0];
6
+
7
+
8
+ /**
9
+ * finds L_cusp and C_cusp for a given hue
10
+ * a and b must be normalized so a^2 + b^2 == 1
11
+ * @copyright "Company Named Limited" 2023
12
+ * @param {number[]} output [L, C]
13
+ * @param {number} a
14
+ * @param {number} b
15
+ */
16
+ export function find_cusp(output, a, b) {
17
+ // First, find the maximum saturation (saturation S = C/L)
18
+ const S_cusp = compute_max_saturation(a, b);
19
+
20
+ // Convert to linear sRGB to find the first point where at least one of r,g or b >= 1:
21
+ oklab_to_linear_srgb(rgb_at_max, 1, S_cusp * a, S_cusp * b);
22
+ const L_cusp = Math.cbrt(1. / max3(rgb_at_max[0], rgb_at_max[1], rgb_at_max[2]));
23
+ const C_cusp = L_cusp * S_cusp;
24
+
25
+ output[0] = L_cusp;
26
+ output[1] = C_cusp;
27
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Finds intersection of the line defined by
3
+ * L = L0 * (1 - t) + t * L1;
4
+ * C = t * C1;
5
+ * a and b must be normalized so a^2 + b^2 == 1
6
+ * @copyright "Company Named Limited" 2023
7
+ * @param {number} a
8
+ * @param {number} b
9
+ * @param {number} L1
10
+ * @param {number} C1
11
+ * @param {number} L0
12
+ * @returns {number}
13
+ */
14
+ export function find_gamut_intersection(a: number, b: number, L1: number, C1: number, L0: number): number;
15
+ //# sourceMappingURL=find_gamut_intersection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find_gamut_intersection.d.ts","sourceRoot":"","sources":["../../../../../src/core/color/oklab/find_gamut_intersection.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,2CAPW,MAAM,KACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,GACJ,MAAM,CAoFlB"}
@@ -0,0 +1,101 @@
1
+ import { min3 } from "../../math/min3.js";
2
+ import { find_cusp } from "./find_cusp.js";
3
+
4
+ const cusp = [0, 0];
5
+
6
+ /**
7
+ * Finds intersection of the line defined by
8
+ * L = L0 * (1 - t) + t * L1;
9
+ * C = t * C1;
10
+ * a and b must be normalized so a^2 + b^2 == 1
11
+ * @copyright "Company Named Limited" 2023
12
+ * @param {number} a
13
+ * @param {number} b
14
+ * @param {number} L1
15
+ * @param {number} C1
16
+ * @param {number} L0
17
+ * @returns {number}
18
+ */
19
+ export function find_gamut_intersection(a, b, L1, C1, L0) {
20
+ // Find the cusp of the gamut triangle
21
+ find_cusp(cusp, a, b);
22
+
23
+ // Find the intersection for upper and lower half seprately
24
+ let t;
25
+ if (((L1 - L0) * cusp[1] - (cusp[0] - L0) * C1) <= 0.) {
26
+ // Lower half
27
+
28
+ t = cusp[1] * L0 / (C1 * cusp[0] + cusp[1] * (L0 - L1));
29
+ } else {
30
+ // Upper half
31
+
32
+ // First intersect with triangle
33
+ t = cusp[1] * (L0 - 1.) / (C1 * (cusp[0] - 1.) + cusp[1] * (L0 - L1));
34
+
35
+ // Then one step of Halley's method
36
+ {
37
+ const dL = L1 - L0;
38
+ const dC = C1;
39
+
40
+ const k_l = +0.3963377774 * a + 0.2158037573 * b;
41
+ const k_m = -0.1055613458 * a - 0.0638541728 * b;
42
+ const k_s = -0.0894841775 * a - 1.2914855480 * b;
43
+
44
+ const l_dt = dL + dC * k_l;
45
+ const m_dt = dL + dC * k_m;
46
+ const s_dt = dL + dC * k_s;
47
+
48
+
49
+ // If higher accuracy is required, 2 or 3 iterations of the following block can be used:
50
+ {
51
+ const L = L0 * (1 - t) + t * L1;
52
+ const C = t * C1;
53
+
54
+ const l_ = L + C * k_l;
55
+ const m_ = L + C * k_m;
56
+ const s_ = L + C * k_s;
57
+
58
+ const l = l_ * l_ * l_;
59
+ const m = m_ * m_ * m_;
60
+ const s = s_ * s_ * s_;
61
+
62
+ const ldt = 3 * l_dt * l_ * l_;
63
+ const mdt = 3 * m_dt * m_ * m_;
64
+ const sdt = 3 * s_dt * s_ * s_;
65
+
66
+ const ldt2 = 6 * l_dt * l_dt * l_;
67
+ const mdt2 = 6 * m_dt * m_dt * m_;
68
+ const sdt2 = 6 * s_dt * s_dt * s_;
69
+
70
+ const r = 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s - 1;
71
+ const r1 = 4.0767416621 * ldt - 3.3077115913 * mdt + 0.2309699292 * sdt;
72
+ const r2 = 4.0767416621 * ldt2 - 3.3077115913 * mdt2 + 0.2309699292 * sdt2;
73
+
74
+ const u_r = r1 / (r1 * r1 - 0.5 * r * r2);
75
+ let t_r = -r * u_r;
76
+
77
+ const g = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s - 1;
78
+ const g1 = -1.2684380046 * ldt + 2.6097574011 * mdt - 0.3413193965 * sdt;
79
+ const g2 = -1.2684380046 * ldt2 + 2.6097574011 * mdt2 - 0.3413193965 * sdt2;
80
+
81
+ const u_g = g1 / (g1 * g1 - 0.5 * g * g2);
82
+ let t_g = -g * u_g;
83
+
84
+ const b = -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s - 1;
85
+ const b1 = -0.0041960863 * ldt - 0.7034186147 * mdt + 1.7076147010 * sdt;
86
+ const b2 = -0.0041960863 * ldt2 - 0.7034186147 * mdt2 + 1.7076147010 * sdt2;
87
+
88
+ const u_b = b1 / (b1 * b1 - 0.5 * b * b2);
89
+ let t_b = -b * u_b;
90
+
91
+ t_r = u_r >= 0 ? t_r : Number.MAX_VALUE;
92
+ t_g = u_g >= 0 ? t_g : Number.MAX_VALUE;
93
+ t_b = u_b >= 0 ? t_b : Number.MAX_VALUE;
94
+
95
+ t += min3(t_r, t_g, t_b);
96
+ }
97
+ }
98
+ }
99
+
100
+ return t;
101
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ *
3
+ * @param {number[]} output
4
+ * @param {number} r
5
+ * @param {number} g
6
+ * @param {number} b
7
+ */
8
+ export function linear_srgb_to_okhsv(output: number[], r: number, g: number, b: number): void;
9
+ //# sourceMappingURL=linear_srgb_to_okhsv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear_srgb_to_okhsv.d.ts","sourceRoot":"","sources":["../../../../../src/core/color/oklab/linear_srgb_to_okhsv.js"],"names":[],"mappings":"AAkBA;;;;;;GAMG;AACH,6CALW,MAAM,EAAE,KACR,MAAM,KACN,MAAM,KACN,MAAM,QAkDhB"}
@@ -0,0 +1,74 @@
1
+ import { find_cusp } from "./find_cusp.js";
2
+ import { linear_srgb_to_oklab } from "./linear_srgb_to_oklab.js";
3
+ import { oklab_to_linear_srgb } from "./oklab_to_linear_srgb.js";
4
+ import { toe, toe_inv } from "./toe.js";
5
+
6
+ const Lab = [0, 0, 0];
7
+
8
+ /**
9
+ *
10
+ * @type {number[]}
11
+ */
12
+ const cusp = [0, 0];
13
+ /**
14
+ *
15
+ * @type {number[]}
16
+ */
17
+ const rgb_scale = [0, 0, 0];
18
+
19
+ /**
20
+ *
21
+ * @param {number[]} output
22
+ * @param {number} r
23
+ * @param {number} g
24
+ * @param {number} b
25
+ */
26
+ export function linear_srgb_to_okhsv(output, r, g, b) {
27
+
28
+ linear_srgb_to_oklab(Lab, r, g, b)
29
+
30
+ let C = Math.sqrt(Lab[1] * Lab[1] + Lab[2] * Lab[2]);
31
+ const a_ = Lab[1] / C;
32
+ const b_ = Lab[2] / C;
33
+
34
+ let L = Lab[0];
35
+ const h = 0.5 + 0.5 * Math.atan2(-Lab[2], -Lab[1]) / Math.PI;
36
+
37
+ find_cusp(cusp, a_, b_);
38
+
39
+ const S_max = cusp[1] / cusp[0];
40
+ const T_max = cusp[1] / (1 - cusp[0]);
41
+
42
+ const S_0 = 0.5;
43
+ const k = 1 - S_0 / S_max;
44
+
45
+ // first we find L_v, C_v, L_vt and C_vt
46
+
47
+ const t = T_max / (C + L * T_max);
48
+ const L_v = t * L;
49
+ const C_v = t * C;
50
+
51
+ const L_vt = toe_inv(L_v);
52
+ const C_vt = C_v * L_vt / L_v;
53
+
54
+ // we can then use these to invert the step that compensates for the toe and the curved top part of the triangle:
55
+
56
+ oklab_to_linear_srgb(rgb_scale, L_vt, a_ * C_vt, b_ * C_vt);
57
+
58
+ const scale_L = Math.cbrt(1. / Math.max(rgb_scale[0], rgb_scale[1], rgb_scale[2], 0));
59
+
60
+ L = L / scale_L;
61
+ C = C / scale_L;
62
+
63
+ C = C * toe(L) / L;
64
+ L = toe(L);
65
+
66
+ // we can now compute v and s:
67
+
68
+ const v = L / L_v;
69
+ const s = (S_0 + T_max) * C_v / ((T_max * S_0) + T_max * k * C_v);
70
+
71
+ output[0] = h;
72
+ output[1] = s;
73
+ output[2] = v;
74
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ *
3
+ * @param {number[]} output
4
+ * @param {number} r
5
+ * @param {number} g
6
+ * @param {number} b
7
+ */
8
+ export function linear_srgb_to_oklab(output: number[], r: number, g: number, b: number): void;
9
+ //# sourceMappingURL=linear_srgb_to_oklab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linear_srgb_to_oklab.d.ts","sourceRoot":"","sources":["../../../../../src/core/color/oklab/linear_srgb_to_oklab.js"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,6CALW,MAAM,EAAE,KACR,MAAM,KACN,MAAM,KACN,MAAM,QAchB"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ *
3
+ * @param {number[]} output
4
+ * @param {number} r
5
+ * @param {number} g
6
+ * @param {number} b
7
+ */
8
+ export function linear_srgb_to_oklab(output, r, g, b) {
9
+ const l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;
10
+ const m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;
11
+ const s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;
12
+
13
+ const l_ = Math.cbrt(l);
14
+ const m_ = Math.cbrt(m);
15
+ const s_ = Math.cbrt(s);
16
+
17
+ output[0] = 0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_;
18
+ output[1] = 1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_;
19
+ output[2] = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_;
20
+ }