@ar-js-org/artoolkit5-ts 0.1.0 → 0.2.1

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.
@@ -17,86 +17,168 @@ async function a(e, r, i, a) {
17
17
  core: s,
18
18
  width: e,
19
19
  height: r,
20
- markers: {},
20
+ patternMarkers: {},
21
+ barcodeMarkers: {},
22
+ minConfidence: {
23
+ pattern: 0,
24
+ barcode: 0
25
+ },
21
26
  disposed: !1
22
27
  };
23
28
  }
24
29
  function o(e) {
25
- e.disposed ||= (e.core.teardown(), e.core.delete(), e.markers = {}, !0);
30
+ e.disposed ||= (e.core.teardown(), e.core.delete(), e.patternMarkers = {}, e.barcodeMarkers = {}, !0);
31
+ }
32
+ //#endregion
33
+ //#region node_modules/@ar-js-org/artoolkit5-constants/dist/generated/artoolkit_constants.js
34
+ var s = 1028, c = 1029, l = 1285, u = {
35
+ color: 0,
36
+ mono: 1,
37
+ matrix: 2,
38
+ color_and_matrix: 3,
39
+ mono_and_matrix: 4
40
+ }, d = {
41
+ "3x3": 3,
42
+ "3x3_PARITY65": 259,
43
+ "3x3_HAMMING63": 515,
44
+ "4x4": 4,
45
+ "4x4_BCH_13_9_3": 772,
46
+ "4x4_BCH_13_5_5": s,
47
+ "5x5": 5,
48
+ "5x5_BCH_22_7_7": l,
49
+ "5x5_BCH_22_12_5": c,
50
+ "6x6": 6
51
+ }, f = {
52
+ manual: 0,
53
+ auto_median: 1,
54
+ auto_otsu: 2,
55
+ auto_bracketing: 4
56
+ }, p = {
57
+ frame: 0,
58
+ field: 1
59
+ }, m = {
60
+ white_region: 0,
61
+ black_region: 1
62
+ };
63
+ function h(e, t, n) {
64
+ let i = Object.prototype.hasOwnProperty.call(e, t) ? e[t] : void 0;
65
+ if (i === void 0) {
66
+ let i = Object.keys(e).join(", ");
67
+ throw new r(`Invalid value ${JSON.stringify(t)} for '${n}'. Valid values are: ${i}.`);
68
+ }
69
+ return i;
70
+ }
71
+ //#endregion
72
+ //#region src/detector.ts
73
+ function g(e, t) {
74
+ if (i(e, "configureDetector"), t.detectionMode !== void 0 && e.core.setPatternDetectionMode(h(u, t.detectionMode, "detectionMode")), t.matrixCodeType !== void 0 && e.core.setMatrixCodeType(h(d, t.matrixCodeType, "matrixCodeType")), t.threshold !== void 0 && e.core.setThreshold(_(t.threshold)), t.thresholdMode !== void 0 && e.core.setThresholdMode(h(f, t.thresholdMode, "thresholdMode")), t.labelingMode !== void 0 && e.core.setLabelingMode(h(m, t.labelingMode, "labelingMode")), t.imageProcMode !== void 0 && e.core.setImageProcMode(h(p, t.imageProcMode, "imageProcMode")), t.patternRatio !== void 0 && e.core.setPattRatio(v(t.patternRatio)), t.minConfidence !== void 0) {
75
+ let { pattern: n, barcode: r } = t.minConfidence;
76
+ n !== void 0 && (e.minConfidence.pattern = y(n, "minConfidence.pattern")), r !== void 0 && (e.minConfidence.barcode = y(r, "minConfidence.barcode"));
77
+ }
78
+ t.nearPlane !== void 0 && e.core.setProjectionNearPlane(t.nearPlane), t.farPlane !== void 0 && e.core.setProjectionFarPlane(t.farPlane), (t.nearPlane !== void 0 || t.farPlane !== void 0) && e.core.recalculateCameraLens();
79
+ }
80
+ function _(e) {
81
+ if (!Number.isInteger(e) || e < 0 || e > 255) throw new r(`Invalid value ${e} for 'threshold'. Must be an integer between 0 and 255 inclusive.`);
82
+ return e;
83
+ }
84
+ function v(e) {
85
+ if (!Number.isFinite(e) || e <= 0 || e >= 1) throw new r(`Invalid value ${e} for 'patternRatio'. Must be a finite number greater than 0 and less than 1.`);
86
+ return e;
87
+ }
88
+ function y(e, t) {
89
+ if (!Number.isFinite(e) || e < 0 || e > 1) throw new r(`Invalid value ${e} for '${t}'. Must be a finite number between 0 and 1 inclusive.`);
90
+ return e;
26
91
  }
27
92
  //#endregion
28
93
  //#region src/markers.ts
29
- async function s(t, n) {
94
+ async function b(t, n) {
30
95
  return i(t, "loadPatternMarker"), e(t.mod, t.core, n);
31
96
  }
32
97
  //#endregion
33
98
  //#region src/math.ts
34
- var c = 16;
35
- function l(e) {
99
+ var x = 16;
100
+ function S(e) {
36
101
  return i(e, "getCameraProjectionMatrix"), e.core.getCameraLens();
37
102
  }
38
- function u(e, t = new Float32Array(c)) {
103
+ function C(e, t = new Float32Array(x)) {
39
104
  return t[0] = e[0], t[1] = e[4], t[2] = e[8], t[3] = 0, t[4] = e[1], t[5] = e[5], t[6] = e[9], t[7] = 0, t[8] = e[2], t[9] = e[6], t[10] = e[10], t[11] = 0, t[12] = e[3], t[13] = e[7], t[14] = e[11], t[15] = 1, t;
40
105
  }
41
- function d(e, t = new Float32Array(c), n) {
106
+ function w(e, t = new Float32Array(x), n) {
42
107
  return t[0] = e[0], t[4] = e[4], t[8] = e[8], t[12] = e[12], t[1] = -e[1], t[5] = -e[5], t[9] = -e[9], t[13] = -e[13], t[2] = -e[2], t[6] = -e[6], t[10] = -e[10], t[14] = -e[14], t[3] = 0, t[7] = 0, t[11] = 0, t[15] = 1, n !== void 0 && n !== 0 && (t[12] *= n, t[13] *= n, t[14] *= n), t;
43
108
  }
44
109
  //#endregion
45
110
  //#region src/tracking.ts
46
- var f = 12, p = 3, m = -1, h = [], g = !0, _ = /* @__PURE__ */ new Float32Array(16);
47
- function v(e, t, n = 1) {
48
- i(e, "trackMarker"), e.markers[t] = {
49
- id: t,
50
- markerWidth: n,
111
+ var T = 12, E = 3, D = -1, O = [], k = !0, A = /* @__PURE__ */ new Float32Array(16);
112
+ function j(e, t, n = 1) {
113
+ i(e, "trackMarker"), e.patternMarkers[t] = N(t, n);
114
+ }
115
+ function M(e, t, n = 1) {
116
+ i(e, "trackBarcodeMarker"), e.barcodeMarkers[t] = N(t, n);
117
+ }
118
+ function N(e, t) {
119
+ return {
120
+ id: e,
121
+ markerWidth: t,
51
122
  inPrevious: !1,
52
123
  inCurrent: !1,
53
- matrix: new Float64Array(f),
124
+ matrix: new Float64Array(T),
54
125
  matrixGL: /* @__PURE__ */ new Float32Array(16)
55
126
  };
56
127
  }
57
- function y(e, t) {
58
- return i(e, "processFrame"), b(e, t), x(e), {
59
- detected: S(e),
60
- lost: C(e)
128
+ function P(e, t) {
129
+ return i(e, "processFrame"), F(e, t), I(e), {
130
+ detected: L(e),
131
+ lost: z(e)
61
132
  };
62
133
  }
63
- function b(e, t) {
64
- e.core.passVideoData(t, h, g), e.core.detectMarker();
134
+ function F(e, t) {
135
+ e.core.passVideoData(t, O, k), e.core.detectMarker();
65
136
  }
66
- function x(e) {
67
- for (let t in e.markers) {
68
- let n = e.markers[t];
137
+ function I(e) {
138
+ for (let t of [e.patternMarkers, e.barcodeMarkers]) for (let e in t) {
139
+ let n = t[e];
69
140
  n.inPrevious = n.inCurrent, n.inCurrent = !1;
70
141
  }
71
142
  }
72
- function S(e) {
143
+ function L(e) {
73
144
  let t = [], n = e.core.getMarkerNum();
74
145
  for (let r = 0; r < n; r++) {
75
- let { id: n } = e.core.getMarkerInfo(r);
76
- if (n === m) continue;
77
- let i = e.markers[n];
78
- i && (i.inCurrent = !0, w(e, r, i), t.push({
79
- id: i.id,
80
- matrix: i.matrix,
81
- matrixGL: i.matrixGL
82
- }));
146
+ let n = e.core.getMarkerInfo(r), i = R(e.patternMarkers, e, r, n.idPatt, n.cfPatt, "pattern", e.minConfidence.pattern, n.vertex);
147
+ i && t.push(i);
148
+ let a = R(e.barcodeMarkers, e, r, n.idMatrix, n.cfMatrix, "barcode", e.minConfidence.barcode, n.vertex);
149
+ a && t.push(a);
83
150
  }
84
151
  return t;
85
152
  }
86
- function C(e) {
87
- let t = [];
88
- for (let n in e.markers) {
89
- let r = e.markers[n];
90
- r.inPrevious && !r.inCurrent && t.push(r.id);
153
+ function R(e, t, n, r, i, a, o, s) {
154
+ if (r === D) return;
155
+ let c = e[r];
156
+ if (c && !(i < o)) return c.inCurrent = !0, B(t, n, c), {
157
+ id: c.id,
158
+ type: a,
159
+ confidence: i,
160
+ matrix: c.matrix,
161
+ matrixGL: c.matrixGL,
162
+ vertex: s
163
+ };
164
+ }
165
+ function z(e) {
166
+ let t = [], n = [[e.patternMarkers, "pattern"], [e.barcodeMarkers, "barcode"]];
167
+ for (let [e, r] of n) for (let n in e) {
168
+ let i = e[n];
169
+ i.inPrevious && !i.inCurrent && t.push({
170
+ id: i.id,
171
+ type: r
172
+ });
91
173
  }
92
174
  return t;
93
175
  }
94
- function w(e, t, n) {
95
- n.inPrevious ? e.core.getTransMatSquareCont(t, n.markerWidth) : e.core.getTransMatSquare(t, n.markerWidth), T(e, n.matrix), u(n.matrix, _), d(_, n.matrixGL);
176
+ function B(e, t, n) {
177
+ n.inPrevious ? e.core.getTransMatSquareCont(t, n.markerWidth) : e.core.getTransMatSquare(t, n.markerWidth), V(e, n.matrix), C(n.matrix, A), w(A, n.matrixGL);
96
178
  }
97
- function T(e, t) {
98
- let n = e.core.getTransform() >> p;
99
- t.set(e.mod.HEAPF64.subarray(n, n + f));
179
+ function V(e, t) {
180
+ let n = e.core.getTransform() >> E;
181
+ t.set(e.mod.HEAPF64.subarray(n, n + T));
100
182
  }
101
183
  //#endregion
102
- export { r as ARToolKitError, d as arglCameraViewRHf, a as createARToolKitState, o as disposeARToolKitState, l as getCameraProjectionMatrix, s as loadPatternMarker, y as processFrame, v as trackMarker, u as transMatToGLMat };
184
+ export { r as ARToolKitError, w as arglCameraViewRHf, g as configureDetector, a as createARToolKitState, o as disposeARToolKitState, S as getCameraProjectionMatrix, b as loadPatternMarker, P as processFrame, M as trackBarcodeMarker, j as trackMarker, C as transMatToGLMat };
@@ -1 +1 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("@ar-js-org/artoolkit5-wasm")):typeof define==`function`&&define.amd?define([`exports`,`@ar-js-org/artoolkit5-wasm`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ARToolkit5TS={},e.ARToolkit5Wasm))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=class e extends Error{constructor(t){super(t),this.name=`ARToolKitError`,Object.setPrototypeOf(this,e.prototype)}};function r(e,t){if(e.disposed)throw new n(`${t} was called on a disposed ARToolKitState. Create a new one with createARToolKitState().`)}async function i(e,n,r,i){let a=(await(0,t.createARToolKit)({locateFile:e=>i&&e.endsWith(`.wasm`)?i:e})).mod,o=new a.ARToolKitCore,s=await(0,t.loadCameraFromUrl)(a,o,r);return await o.setup(e,n,s),{mod:a,core:o,width:e,height:n,markers:{},disposed:!1}}function a(e){e.disposed||=(e.core.teardown(),e.core.delete(),e.markers={},!0)}async function o(e,n){return r(e,`loadPatternMarker`),(0,t.addMarkerFromUrl)(e.mod,e.core,n)}var s=16;function c(e){return r(e,`getCameraProjectionMatrix`),e.core.getCameraLens()}function l(e,t=new Float32Array(s)){return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=0,t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=0,t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=0,t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=1,t}function u(e,t=new Float32Array(s),n){return t[0]=e[0],t[4]=e[4],t[8]=e[8],t[12]=e[12],t[1]=-e[1],t[5]=-e[5],t[9]=-e[9],t[13]=-e[13],t[2]=-e[2],t[6]=-e[6],t[10]=-e[10],t[14]=-e[14],t[3]=0,t[7]=0,t[11]=0,t[15]=1,n!==void 0&&n!==0&&(t[12]*=n,t[13]*=n,t[14]*=n),t}var d=12,f=3,p=-1,m=[],h=!0,g=new Float32Array(16);function _(e,t,n=1){r(e,`trackMarker`),e.markers[t]={id:t,markerWidth:n,inPrevious:!1,inCurrent:!1,matrix:new Float64Array(d),matrixGL:new Float32Array(16)}}function v(e,t){return r(e,`processFrame`),y(e,t),b(e),{detected:x(e),lost:S(e)}}function y(e,t){e.core.passVideoData(t,m,h),e.core.detectMarker()}function b(e){for(let t in e.markers){let n=e.markers[t];n.inPrevious=n.inCurrent,n.inCurrent=!1}}function x(e){let t=[],n=e.core.getMarkerNum();for(let r=0;r<n;r++){let{id:n}=e.core.getMarkerInfo(r);if(n===p)continue;let i=e.markers[n];i&&(i.inCurrent=!0,C(e,r,i),t.push({id:i.id,matrix:i.matrix,matrixGL:i.matrixGL}))}return t}function S(e){let t=[];for(let n in e.markers){let r=e.markers[n];r.inPrevious&&!r.inCurrent&&t.push(r.id)}return t}function C(e,t,n){n.inPrevious?e.core.getTransMatSquareCont(t,n.markerWidth):e.core.getTransMatSquare(t,n.markerWidth),w(e,n.matrix),l(n.matrix,g),u(g,n.matrixGL)}function w(e,t){let n=e.core.getTransform()>>f;t.set(e.mod.HEAPF64.subarray(n,n+d))}e.ARToolKitError=n,e.arglCameraViewRHf=u,e.createARToolKitState=i,e.disposeARToolKitState=a,e.getCameraProjectionMatrix=c,e.loadPatternMarker=o,e.processFrame=v,e.trackMarker=_,e.transMatToGLMat=l});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("@ar-js-org/artoolkit5-wasm")):typeof define==`function`&&define.amd?define([`exports`,`@ar-js-org/artoolkit5-wasm`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ARToolkit5TS={},e.ARToolkit5Wasm))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=class e extends Error{constructor(t){super(t),this.name=`ARToolKitError`,Object.setPrototypeOf(this,e.prototype)}};function r(e,t){if(e.disposed)throw new n(`${t} was called on a disposed ARToolKitState. Create a new one with createARToolKitState().`)}async function i(e,n,r,i){let a=(await(0,t.createARToolKit)({locateFile:e=>i&&e.endsWith(`.wasm`)?i:e})).mod,o=new a.ARToolKitCore,s=await(0,t.loadCameraFromUrl)(a,o,r);return await o.setup(e,n,s),{mod:a,core:o,width:e,height:n,patternMarkers:{},barcodeMarkers:{},minConfidence:{pattern:0,barcode:0},disposed:!1}}function a(e){e.disposed||=(e.core.teardown(),e.core.delete(),e.patternMarkers={},e.barcodeMarkers={},!0)}var o=1028,s=1029,c=1285,l={color:0,mono:1,matrix:2,color_and_matrix:3,mono_and_matrix:4},u={"3x3":3,"3x3_PARITY65":259,"3x3_HAMMING63":515,"4x4":4,"4x4_BCH_13_9_3":772,"4x4_BCH_13_5_5":o,"5x5":5,"5x5_BCH_22_7_7":c,"5x5_BCH_22_12_5":s,"6x6":6},d={manual:0,auto_median:1,auto_otsu:2,auto_bracketing:4},f={frame:0,field:1},p={white_region:0,black_region:1};function m(e,t,r){let i=Object.prototype.hasOwnProperty.call(e,t)?e[t]:void 0;if(i===void 0){let i=Object.keys(e).join(`, `);throw new n(`Invalid value ${JSON.stringify(t)} for '${r}'. Valid values are: ${i}.`)}return i}function h(e,t){if(r(e,`configureDetector`),t.detectionMode!==void 0&&e.core.setPatternDetectionMode(m(l,t.detectionMode,`detectionMode`)),t.matrixCodeType!==void 0&&e.core.setMatrixCodeType(m(u,t.matrixCodeType,`matrixCodeType`)),t.threshold!==void 0&&e.core.setThreshold(g(t.threshold)),t.thresholdMode!==void 0&&e.core.setThresholdMode(m(d,t.thresholdMode,`thresholdMode`)),t.labelingMode!==void 0&&e.core.setLabelingMode(m(p,t.labelingMode,`labelingMode`)),t.imageProcMode!==void 0&&e.core.setImageProcMode(m(f,t.imageProcMode,`imageProcMode`)),t.patternRatio!==void 0&&e.core.setPattRatio(_(t.patternRatio)),t.minConfidence!==void 0){let{pattern:n,barcode:r}=t.minConfidence;n!==void 0&&(e.minConfidence.pattern=v(n,`minConfidence.pattern`)),r!==void 0&&(e.minConfidence.barcode=v(r,`minConfidence.barcode`))}t.nearPlane!==void 0&&e.core.setProjectionNearPlane(t.nearPlane),t.farPlane!==void 0&&e.core.setProjectionFarPlane(t.farPlane),(t.nearPlane!==void 0||t.farPlane!==void 0)&&e.core.recalculateCameraLens()}function g(e){if(!Number.isInteger(e)||e<0||e>255)throw new n(`Invalid value ${e} for 'threshold'. Must be an integer between 0 and 255 inclusive.`);return e}function _(e){if(!Number.isFinite(e)||e<=0||e>=1)throw new n(`Invalid value ${e} for 'patternRatio'. Must be a finite number greater than 0 and less than 1.`);return e}function v(e,t){if(!Number.isFinite(e)||e<0||e>1)throw new n(`Invalid value ${e} for '${t}'. Must be a finite number between 0 and 1 inclusive.`);return e}async function y(e,n){return r(e,`loadPatternMarker`),(0,t.addMarkerFromUrl)(e.mod,e.core,n)}var b=16;function x(e){return r(e,`getCameraProjectionMatrix`),e.core.getCameraLens()}function S(e,t=new Float32Array(b)){return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=0,t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=0,t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=0,t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=1,t}function C(e,t=new Float32Array(b),n){return t[0]=e[0],t[4]=e[4],t[8]=e[8],t[12]=e[12],t[1]=-e[1],t[5]=-e[5],t[9]=-e[9],t[13]=-e[13],t[2]=-e[2],t[6]=-e[6],t[10]=-e[10],t[14]=-e[14],t[3]=0,t[7]=0,t[11]=0,t[15]=1,n!==void 0&&n!==0&&(t[12]*=n,t[13]*=n,t[14]*=n),t}var w=12,T=3,E=-1,D=[],O=!0,k=new Float32Array(16);function A(e,t,n=1){r(e,`trackMarker`),e.patternMarkers[t]=M(t,n)}function j(e,t,n=1){r(e,`trackBarcodeMarker`),e.barcodeMarkers[t]=M(t,n)}function M(e,t){return{id:e,markerWidth:t,inPrevious:!1,inCurrent:!1,matrix:new Float64Array(w),matrixGL:new Float32Array(16)}}function N(e,t){return r(e,`processFrame`),P(e,t),F(e),{detected:I(e),lost:R(e)}}function P(e,t){e.core.passVideoData(t,D,O),e.core.detectMarker()}function F(e){for(let t of[e.patternMarkers,e.barcodeMarkers])for(let e in t){let n=t[e];n.inPrevious=n.inCurrent,n.inCurrent=!1}}function I(e){let t=[],n=e.core.getMarkerNum();for(let r=0;r<n;r++){let n=e.core.getMarkerInfo(r),i=L(e.patternMarkers,e,r,n.idPatt,n.cfPatt,`pattern`,e.minConfidence.pattern,n.vertex);i&&t.push(i);let a=L(e.barcodeMarkers,e,r,n.idMatrix,n.cfMatrix,`barcode`,e.minConfidence.barcode,n.vertex);a&&t.push(a)}return t}function L(e,t,n,r,i,a,o,s){if(r===E)return;let c=e[r];if(c&&!(i<o))return c.inCurrent=!0,z(t,n,c),{id:c.id,type:a,confidence:i,matrix:c.matrix,matrixGL:c.matrixGL,vertex:s}}function R(e){let t=[],n=[[e.patternMarkers,`pattern`],[e.barcodeMarkers,`barcode`]];for(let[e,r]of n)for(let n in e){let i=e[n];i.inPrevious&&!i.inCurrent&&t.push({id:i.id,type:r})}return t}function z(e,t,n){n.inPrevious?e.core.getTransMatSquareCont(t,n.markerWidth):e.core.getTransMatSquare(t,n.markerWidth),B(e,n.matrix),S(n.matrix,k),C(k,n.matrixGL)}function B(e,t){let n=e.core.getTransform()>>T;t.set(e.mod.HEAPF64.subarray(n,n+w))}e.ARToolKitError=n,e.arglCameraViewRHf=C,e.configureDetector=h,e.createARToolKitState=i,e.disposeARToolKitState=a,e.getCameraProjectionMatrix=x,e.loadPatternMarker=y,e.processFrame=N,e.trackBarcodeMarker=j,e.trackMarker=A,e.transMatToGLMat=S});
@@ -0,0 +1,88 @@
1
+ export type DetectionMode = 'color' | 'mono' | 'matrix' | 'color_and_matrix' | 'mono_and_matrix';
2
+ /**
3
+ * `'global_id'` is deliberately absent. `AR_MATRIX_CODE_GLOBAL_ID` decodes a
4
+ * 64-bit value into `markerInfo->globalID`, and that field is not bound, so
5
+ * nothing here can read what the mode decoded (artoolkit5-wasm#29).
6
+ *
7
+ * Offering it anyway would not leave the mode inert — it would leave it
8
+ * aliasing. The engine still fills `idMatrix`, the field `processFrame` reads:
9
+ * a global ID below 32768 is reported as itself, and **every** larger one is
10
+ * reported as `0` (`arPattGetID.c:213-217`). A barcode registered as `0` would
11
+ * therefore match every large global-ID marker in view, and with none
12
+ * registered those markers would silently never match at all.
13
+ *
14
+ * Re-adding it once the value is bound is a non-breaking addition. Shipping it
15
+ * first would be the expensive order: #29 has still to settle how a 64-bit
16
+ * value crosses into JavaScript, and by then that would be released API.
17
+ */
18
+ export type MatrixCodeType = '3x3' | '3x3_PARITY65' | '3x3_HAMMING63' | '4x4' | '4x4_BCH_13_9_3' | '4x4_BCH_13_5_5' | '5x5' | '5x5_BCH_22_7_7' | '5x5_BCH_22_12_5' | '6x6';
19
+ /**
20
+ * `'auto_adaptive'` is deliberately absent. `AR_LABELING_THRESH_MODE_AUTO_ADAPTIVE`
21
+ * is exported by the constants package, but `AR_DISABLE_THRESH_MODE_AUTO_ADAPTIVE`
22
+ * is set in the WebARKitLib build this module compiles against, which compiles out
23
+ * its `case` in `arCreateHandle.c`. Passing it silently falls through to `manual`.
24
+ * Offering a mode that cannot work would be worse than not offering it; re-adding
25
+ * it if the upstream build flag changes is a non-breaking addition.
26
+ */
27
+ export type ThresholdMode = 'manual' | 'auto_median' | 'auto_otsu' | 'auto_bracketing';
28
+ export type ImageProcMode = 'frame' | 'field';
29
+ /** `'black_region'` — black-bordered markers on a white background — is the engine default. */
30
+ export type LabelingMode = 'white_region' | 'black_region';
31
+ /**
32
+ * Minimum match confidence per marker family, 0.0 to 1.0.
33
+ *
34
+ * The two families are not comparable, so they take separate thresholds.
35
+ *
36
+ * Confidence is a continuous quality score for *both* families, not a verdict:
37
+ * it moves with viewing angle, distance and focus. Measured on real hardware,
38
+ * the genuine and spurious ranges overlap in both directions — a genuine
39
+ * barcode read 0.500 at an awkward angle while a misread of a pattern marker
40
+ * reached 0.867. So no threshold avoids both missed markers and admitted
41
+ * phantoms; see the README for the measurements and the trade-off.
42
+ *
43
+ * Omitted keys are left unchanged. Both default to 0, which filters nothing
44
+ * beyond the engine's own cutoff of 0.5.
45
+ */
46
+ export interface MinConfidence {
47
+ /** Applies to pattern markers, compared against `cfPatt`. */
48
+ pattern?: number;
49
+ /** Applies to barcode markers, compared against `cfMatrix`. */
50
+ barcode?: number;
51
+ }
52
+ export interface DetectorOptions {
53
+ detectionMode?: DetectionMode;
54
+ matrixCodeType?: MatrixCodeType;
55
+ /** Luma threshold, 0-255. Only meaningful when `thresholdMode` is `'manual'`. */
56
+ threshold?: number;
57
+ thresholdMode?: ThresholdMode;
58
+ labelingMode?: LabelingMode;
59
+ imageProcMode?: ImageProcMode;
60
+ /** Proportion of the marker occupied by the pattern. Exclusive of 0 and 1. */
61
+ patternRatio?: number;
62
+ nearPlane?: number;
63
+ farPlane?: number;
64
+ /**
65
+ * Rejects weak matches, per family. Unlike every other option here this
66
+ * is applied by this library rather than passed to the engine — ARToolKit
67
+ * has no setter for it.
68
+ */
69
+ minConfidence?: MinConfidence;
70
+ }
71
+ export declare const DETECTION_MODES: Record<DetectionMode, number>;
72
+ export declare const MATRIX_CODE_TYPES: Record<MatrixCodeType, number>;
73
+ export declare const THRESHOLD_MODES: Record<ThresholdMode, number>;
74
+ export declare const IMAGE_PROC_MODES: Record<ImageProcMode, number>;
75
+ export declare const LABELING_MODES: Record<LabelingMode, number>;
76
+ /**
77
+ * Looks up `value` in `table`, throwing a message that names the option and
78
+ * lists what it does accept — the failure mode a raw `table[value]` cannot
79
+ * give you, since an unknown key there is `undefined`, not an error.
80
+ *
81
+ * `Object.prototype.hasOwnProperty` guards against inherited keys: `table`
82
+ * is a plain object literal, so `value` arriving as e.g. `'toString'` from
83
+ * outside TypeScript's type safety (a plain-JS caller, JSON, a UI control)
84
+ * would otherwise resolve to `Object.prototype.toString` rather than
85
+ * `undefined`, silently passing a function into the setter instead of
86
+ * throwing.
87
+ */
88
+ export declare function lookUp<T extends string>(table: Record<T, number>, value: T, optionName: string): number;
@@ -0,0 +1,22 @@
1
+ import { DetectorOptions } from './config';
2
+ import { ARToolKitState } from './domain';
3
+ /**
4
+ * Applies detector tuning.
5
+ *
6
+ * Only the keys present in `opts` are applied — a partial call mid-session
7
+ * changes just those settings and leaves everything else as it was.
8
+ *
9
+ * Every option but one is handed to the ARToolKit5 engine. `minConfidence`
10
+ * is the exception: the engine's confidence cutoff is a compile-time
11
+ * constant with no setter, so that threshold is recorded on `state` and
12
+ * applied by `processFrame` instead.
13
+ *
14
+ * Setting `nearPlane` or `farPlane` also recomputes the projection matrix
15
+ * `getCameraProjectionMatrix` returns, so a change is visible on the very
16
+ * next call rather than requiring a separate step to take effect.
17
+ *
18
+ * @throws {ARToolKitError} if the state has been disposed, if a string option
19
+ * is not one of its documented values, or if `threshold` or `patternRatio` is
20
+ * outside the range the engine accepts.
21
+ */
22
+ export declare function configureDetector(state: ARToolKitState, opts: DetectorOptions): void;
package/dist/domain.d.ts CHANGED
@@ -3,6 +3,16 @@
3
3
  *
4
4
  * This module contains types only — no logic, no side effects.
5
5
  */
6
+ /**
7
+ * Which family a registered marker belongs to.
8
+ *
9
+ * The engine reports each family through its own field — `idPatt` for
10
+ * pattern markers, `idMatrix` for barcode markers — so a detection is
11
+ * matched against the registry by the field that produced it. This type
12
+ * records which field a given registration answers to. See `trackMarker`
13
+ * and `trackBarcodeMarker`.
14
+ */
15
+ export type MarkerType = 'pattern' | 'barcode';
6
16
  /**
7
17
  * Detection result for a single marker in a single frame.
8
18
  *
@@ -16,6 +26,20 @@
16
26
  */
17
27
  export interface MarkerPose {
18
28
  id: number;
29
+ type: MarkerType;
30
+ /**
31
+ * How strongly the engine matched this marker, 0.0 to 1.0.
32
+ *
33
+ * Read from the field belonging to this marker's family — `cfPatt` for a
34
+ * pattern marker, `cfMatrix` for a barcode — so the two are directly
35
+ * comparable only within a family, not across them.
36
+ *
37
+ * A continuous quality score for both families, not a verdict: the same
38
+ * marker moves across a wide range with viewing angle, distance and focus.
39
+ * A high value is not proof of a genuine match, nor a low one proof of a
40
+ * false one — the ranges overlap. See `MinConfidence`.
41
+ */
42
+ confidence: number;
19
43
  /**
20
44
  * 3x4 row-major pose, exactly as ARToolKit produces it.
21
45
  *
@@ -33,6 +57,20 @@ export interface MarkerPose {
33
57
  * camera noise and calibration in the millimetre range.
34
58
  */
35
59
  matrixGL: Float32Array;
60
+ /**
61
+ * The four corners of the detected square, in camera image coordinates
62
+ * with the origin at top-left.
63
+ *
64
+ * Unlike `matrix` and `matrixGL`, this is **not** a view onto a reused
65
+ * buffer — the engine builds a fresh array each frame, so it is safe to
66
+ * retain without copying.
67
+ *
68
+ * Corner order depends on the marker's rotation: `vertex[(4 - dir) % 4]`
69
+ * is the top-left corner of the marker itself, with the rest proceeding
70
+ * clockwise from there. Anything that merely outlines the square can
71
+ * ignore that; anything orientation-sensitive cannot.
72
+ */
73
+ vertex: [number, number][];
36
74
  }
37
75
  /**
38
76
  * Outcome of a single call to `processFrame`.
@@ -45,13 +83,27 @@ export interface FrameResult {
45
83
  /** Markers visible in this frame, with their poses. */
46
84
  detected: MarkerPose[];
47
85
  /**
48
- * IDs of markers visible in the previous frame but not this one.
86
+ * Markers visible in the previous frame but not this one.
49
87
  *
50
88
  * Reported exactly once, on the frame the marker disappears.
89
+ *
90
+ * Carries `type` as well as `id` because the two families have
91
+ * independent ID spaces: a pattern marker and a barcode marker may both
92
+ * be registered as `5`, and an ID alone could not say which was lost.
51
93
  */
52
- lost: number[];
94
+ lost: LostMarker[];
95
+ }
96
+ /** A marker that was visible in the previous frame and is not in this one. */
97
+ export interface LostMarker {
98
+ id: number;
99
+ type: MarkerType;
53
100
  }
54
- /** Per-marker tracking state, owned by {@link ARToolKitState}. */
101
+ /**
102
+ * Per-marker tracking state, owned by {@link ARToolKitState}.
103
+ *
104
+ * Carries no `type`: which registry a marker lives in already determines its
105
+ * family, so storing it again would allow the two to disagree.
106
+ */
55
107
  export interface TrackedMarkerState {
56
108
  id: number;
57
109
  markerWidth: number;
@@ -77,10 +129,40 @@ export interface ARToolKitModule {
77
129
  loadCameraFromPath(path: string): number;
78
130
  addMarker(path: string): number;
79
131
  }
80
- /** Marker metadata returned by the detector for one candidate square. */
132
+ /**
133
+ * Marker metadata returned by the detector for one candidate square.
134
+ *
135
+ * ARToolKit reports results in three families, and each is only valid in the
136
+ * detection modes that populate it — a field the active mode did not write
137
+ * would otherwise expose uninitialised engine memory. The binding reports
138
+ * `-1` for any family the mode does not populate, so every field here is
139
+ * always safe to read; `-1` uniformly means "no match".
140
+ *
141
+ * Requires `@ar-js-org/artoolkit5-wasm` >= 0.3.0, which is where the
142
+ * per-mode fields were first bound.
143
+ */
81
144
  export interface MarkerInfo {
82
- /** Engine-assigned marker ID, or -1 when unrecognised. */
145
+ /**
146
+ * Marker ID, or -1. Only meaningful when `detectionMode` is pattern-only
147
+ * *or* matrix-only — never both. Reported as -1 in the combined modes,
148
+ * where a single unified ID would be ambiguous. Prefer `idPatt` and
149
+ * `idMatrix`, which are valid in every mode that can produce them.
150
+ */
83
151
  id: number;
152
+ /** Pattern-marker ID, or -1. Valid when the mode includes template matching. */
153
+ idPatt: number;
154
+ /** Barcode (matrix code) ID, or -1. Valid when the mode includes matrix detection. */
155
+ idMatrix: number;
156
+ /** Template-match confidence, 0.0-1.0, or -1.0 when there was no match. */
157
+ cfPatt: number;
158
+ /** Matrix-code confidence, 0.0-1.0, or -1.0 when there was no match. */
159
+ cfMatrix: number;
160
+ /**
161
+ * 2D positions of the square's four corners, in camera image coordinates
162
+ * with the origin at top-left. Populated in every detection mode, unlike
163
+ * the id and confidence fields above.
164
+ */
165
+ vertex: [number, number][];
84
166
  }
85
167
  /**
86
168
  * The C++ `ARToolKitCore` instance, narrowed to the methods this library calls.
@@ -99,6 +181,22 @@ export interface ARToolKitCore {
99
181
  /** Byte offset into `HEAPF64` holding the most recent 3x4 pose. */
100
182
  getTransform(): number;
101
183
  getCameraLens(): Float64Array;
184
+ /**
185
+ * Recomputes the cached projection matrix `getCameraLens` returns, from
186
+ * whatever `nearPlane`/`farPlane` currently hold. `setProjectionNearPlane`
187
+ * and `setProjectionFarPlane` only assign those fields — the matrix stays
188
+ * stale until this is called.
189
+ */
190
+ recalculateCameraLens(): void;
191
+ setPatternDetectionMode(mode: number): void;
192
+ setMatrixCodeType(type: number): void;
193
+ setThreshold(threshold: number): void;
194
+ setThresholdMode(mode: number): void;
195
+ setLabelingMode(mode: number): void;
196
+ setImageProcMode(mode: number): void;
197
+ setPattRatio(ratio: number): void;
198
+ setProjectionNearPlane(nearPlane: number): void;
199
+ setProjectionFarPlane(farPlane: number): void;
102
200
  /** Releases the ARToolKit handles held by the C++ instance. */
103
201
  teardown(): number;
104
202
  /** Frees the C++ instance itself. Generated by Embind, not declared in C++. */
@@ -115,8 +213,34 @@ export interface ARToolKitState {
115
213
  readonly core: ARToolKitCore;
116
214
  readonly width: number;
117
215
  readonly height: number;
118
- /** Registered markers, keyed by engine-assigned ID. */
119
- markers: Record<number, TrackedMarkerState>;
216
+ /**
217
+ * Pattern markers, keyed by the engine-assigned ID `loadPatternMarker`
218
+ * returned — matched against `getMarkerInfo`'s `idPatt`.
219
+ */
220
+ patternMarkers: Record<number, TrackedMarkerState>;
221
+ /**
222
+ * Barcode markers, keyed by the ID encoded in the marker's own geometry —
223
+ * matched against `getMarkerInfo`'s `idMatrix`.
224
+ *
225
+ * Separate from {@link ARToolKitState.patternMarkers} because the two
226
+ * families occupy independent ID spaces: pattern IDs are assigned by the
227
+ * engine starting at 0, barcode IDs are chosen by whoever printed the
228
+ * marker, and `5` in one is unrelated to `5` in the other.
229
+ */
230
+ barcodeMarkers: Record<number, TrackedMarkerState>;
231
+ /**
232
+ * Confidence below which a detection is discarded, per family.
233
+ *
234
+ * Enforced here rather than in the engine: ARToolKit's own cutoff
235
+ * (`AR_CONFIDENCE_CUTOFF_DEFAULT`, 0.5) is a compile-time constant with no
236
+ * setter, so this filters on top of it and can only ever be stricter.
237
+ * Both default to 0, meaning no filtering beyond the engine's own.
238
+ * Set through `configureDetector`.
239
+ */
240
+ minConfidence: {
241
+ pattern: number;
242
+ barcode: number;
243
+ };
120
244
  /**
121
245
  * Set by `disposeARToolKitState`. Once true the C++ instance is gone and
122
246
  * every operation on this state throws rather than reaching freed memory.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
- export type { ARToolKitCore, ARToolKitModule, ARToolKitState, FrameResult, MarkerInfo, MarkerPose, TrackedMarkerState, } from './domain';
1
+ export type { ARToolKitCore, ARToolKitModule, ARToolKitState, FrameResult, LostMarker, MarkerInfo, MarkerPose, MarkerType, TrackedMarkerState, } from './domain';
2
+ export type { DetectionMode, DetectorOptions, MinConfidence, ImageProcMode, LabelingMode, MatrixCodeType, ThresholdMode, } from './config';
2
3
  export { ARToolKitError } from './errors';
3
4
  export { createARToolKitState, disposeARToolKitState } from './init';
5
+ export { configureDetector } from './detector';
4
6
  export { loadPatternMarker } from './markers';
5
- export { processFrame, trackMarker } from './tracking';
7
+ export { processFrame, trackBarcodeMarker, trackMarker } from './tracking';
6
8
  export { arglCameraViewRHf, getCameraProjectionMatrix, transMatToGLMat } from './math';
@@ -8,6 +8,30 @@ import { ARToolKitState, FrameResult } from './domain';
8
8
  * @throws {ARToolKitError} if the state has been disposed.
9
9
  */
10
10
  export declare function trackMarker(state: ARToolKitState, pattId: number, markerWidth?: number): void;
11
+ /**
12
+ * Registers a barcode (matrix code) marker for tracking.
13
+ *
14
+ * Unlike a pattern marker, this involves no loading: the engine reads the ID
15
+ * directly off the marker's geometry, so there is no file to fetch and
16
+ * nothing to register with the C++ core first. Registering it here is all
17
+ * that is needed — which is why this is `trackBarcodeMarker`, not
18
+ * `loadBarcodeMarker`.
19
+ *
20
+ * Detecting a barcode marker also requires `configureDetector` to have put
21
+ * the engine into a matrix-capable `detectionMode` (`'matrix'`,
22
+ * `'color_and_matrix'`, or `'mono_and_matrix'`); this function only registers the ID.
23
+ *
24
+ * The two families have independent ID spaces, so a barcode may share an ID
25
+ * with an already-registered pattern marker: the engine reports each through
26
+ * its own field, and they are kept in separate registries.
27
+ *
28
+ * @param barcodeId The ID encoded in the marker itself — this is not
29
+ * assigned by the engine, unlike a pattern marker's ID.
30
+ * @param markerWidth Physical marker width; the unit chosen here is the unit
31
+ * all returned translations are expressed in.
32
+ * @throws {ARToolKitError} if the state has been disposed.
33
+ */
34
+ export declare function trackBarcodeMarker(state: ARToolKitState, barcodeId: number, markerWidth?: number): void;
11
35
  /**
12
36
  * Detects registered markers in a single frame.
13
37
  *
@@ -15,9 +39,11 @@ export declare function trackMarker(state: ARToolKitState, pattId: number, marke
15
39
  * so a consumer emitting found/updated/lost events does not have to diff
16
40
  * successive results to recover information tracking already had.
17
41
  *
18
- * Called once per animation frame, so it allocates no typed arrays: every pose
19
- * is written into buffers owned by the marker's tracking state. Those buffers
20
- * are reused next frame — copy them if you need to retain values.
42
+ * Called once per animation frame, so it allocates no typed arrays: `matrix`
43
+ * and `matrixGL` are written into buffers owned by the marker's tracking
44
+ * state, and those buffers are reused next frame — copy them if you need to
45
+ * retain values. `vertex` is the exception; it is a fresh array every frame
46
+ * and can be retained as it is.
21
47
  *
22
48
  * @param videoFrame RGBA pixels matching the width and height the state was
23
49
  * created with.