@ar-js-org/artoolkit5-ts 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +65 -0
- package/LICENSE +28 -0
- package/README.md +268 -0
- package/dist/artoolkit5-ts.js +102 -0
- package/dist/artoolkit5-ts.umd.cjs +1 -0
- package/dist/domain.d.ts +125 -0
- package/dist/errors.d.ts +20 -0
- package/dist/index.d.ts +6 -0
- package/dist/init.d.ts +27 -0
- package/dist/markers.d.ts +11 -0
- package/dist/math.d.ts +30 -0
- package/dist/tracking.d.ts +26 -0
- package/package.json +68 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] - 2026-08-16
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `createARToolKitState` / `disposeARToolKitState` — lifecycle. Dispose calls
|
|
15
|
+
the core's `teardown()` and then Embind's `delete()`; skipping the first leaks
|
|
16
|
+
the ARToolKit handles the instance owns. Idempotent.
|
|
17
|
+
- `ARToolKitError`, thrown by every operation called on a disposed state, so a
|
|
18
|
+
use-after-dispose names the misused function instead of crashing somewhere
|
|
19
|
+
inside the WASM module.
|
|
20
|
+
- `loadPatternMarker` and `trackMarker` for registering markers.
|
|
21
|
+
- `processFrame`, returning `{ detected, lost }`.
|
|
22
|
+
- `getCameraProjectionMatrix`, `transMatToGLMat` and `arglCameraViewRHf`.
|
|
23
|
+
- Vitest suite covering the matrix maths, the visibility state machine and the
|
|
24
|
+
dispose lifecycle, running without WASM or a browser against a mocked core.
|
|
25
|
+
- CI on Node 22 and 24: typecheck, test, build, and a packaging check.
|
|
26
|
+
- Release workflow, run manually with a version. It runs the checks, sets the
|
|
27
|
+
version, promotes this changelog, derives notes from the commits, tags,
|
|
28
|
+
creates the GitHub Release and publishes to npm with provenance. A `dry_run`
|
|
29
|
+
input rehearses all of it without tagging or publishing.
|
|
30
|
+
- `scripts/release-notes.mjs`, which groups Conventional Commits since the
|
|
31
|
+
previous tag so release notes reflect what actually landed, and
|
|
32
|
+
`scripts/promote-changelog.mjs`, which promotes the Unreleased section.
|
|
33
|
+
- Webcam example: camera to Three.js cube overlay.
|
|
34
|
+
- This changelog.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- `processFrame` returns `{ detected, lost }` rather than `MarkerPose[]`. The
|
|
39
|
+
visibility transition was already computed internally and then discarded,
|
|
40
|
+
forcing consumers to diff successive results to recover it.
|
|
41
|
+
- Named `@ar-js-org/artoolkit5-ts`, matching the rest of the organisation.
|
|
42
|
+
- Depends on `@ar-js-org/artoolkit5-wasm@^0.1.3` from npm rather than a pinned
|
|
43
|
+
git commit. `three` moved to `devDependencies`; only the examples use it.
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- `arglCameraViewRHf` allocated a `Float64Array` while every type declaration
|
|
48
|
+
promised `Float32Array`. Consumers reading `matrixGL` would have received a
|
|
49
|
+
different array type than the published types described, and the AR.js-next
|
|
50
|
+
marker event contract specifies `Float32Array(16)`.
|
|
51
|
+
- `processFrame` allocated roughly three typed arrays per marker per frame. Both
|
|
52
|
+
matrix helpers now write into caller-supplied buffers, with one module-scoped
|
|
53
|
+
scratch array for the intermediate 4×4.
|
|
54
|
+
- Debug logging removed from `src/`, which dumped the entire WASM module to the
|
|
55
|
+
console on every marker load and every `trackMarker` call.
|
|
56
|
+
- `favicon.svg` and orphaned `.d.ts.map` files no longer ship in the package.
|
|
57
|
+
|
|
58
|
+
### Notes
|
|
59
|
+
|
|
60
|
+
Pattern markers only. Barcode support is planned; NFT is out of scope for this
|
|
61
|
+
project. Worker compatibility is untested — nothing in `src/` touches the DOM,
|
|
62
|
+
which is necessary but not proof.
|
|
63
|
+
|
|
64
|
+
[Unreleased]: https://github.com/AR-js-org/artoolkit5-ts/compare/v0.1.0...HEAD
|
|
65
|
+
[0.1.0]: https://github.com/AR-js-org/artoolkit5-ts/releases/tag/v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AR-js-org
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
This library wraps a WebAssembly build of ARToolkit5 (WebARKitLib), which is
|
|
26
|
+
licensed under the GNU Lesser General Public License v3.0. Redistributing a
|
|
27
|
+
build that includes the ARToolkit5 (WebARKitLib) WebAssembly binary carries the
|
|
28
|
+
obligations of that licence in addition to the terms above.
|
package/README.md
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# artoolkit5-ts 🎯
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@ar-js-org/artoolkit5-ts)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](tsconfig.json)
|
|
6
|
+
[](test)
|
|
7
|
+
[](https://github.com/AR-js-org/artoolkit5-wasm)
|
|
8
|
+
[](#-roadmap)
|
|
9
|
+
[](https://github.com/AR-js-org/AR.js-next)
|
|
10
|
+
|
|
11
|
+
TypeScript marker tracking for the browser, built on a WebAssembly build of ARToolkit5 (WebARKitLib).
|
|
12
|
+
|
|
13
|
+
**This is the replacement for [`artoolkit5-js`](https://github.com/AR-js-org/artoolkit5-js)**, which is a fork of [`andypotato/artoolkit5-js`](https://github.com/andypotato/artoolkit5-js) — itself an ES6 module port of artoolkit5.
|
|
14
|
+
|
|
15
|
+
`artoolkit5-ts` is a rewrite rather than another fork in that line. It is written in TypeScript against a maintained WebAssembly build, and it drops the monolithic `ARController` class those ports carried forward in favour of plain data and free functions. Nothing is hidden behind a class, so nothing has to be constructed before it can be used, tested, or tree-shaken.
|
|
16
|
+
|
|
17
|
+
> ⚠️ **Status: alpha.** Pattern markers work end to end, but the API is not stable yet — expect breaking changes before 1.0. See [Roadmap](#-roadmap).
|
|
18
|
+
|
|
19
|
+
## 🧩 Where this fits
|
|
20
|
+
|
|
21
|
+
`artoolkit5-ts` is the detection engine layer of the AR.js-next ecosystem:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
AR.js-next ECS core, event bus, frame pump
|
|
25
|
+
arjs-plugin-artoolkit ECS plugin: Web Worker, ImageBitmap, marker events
|
|
26
|
+
artoolkit5-ts ← this library
|
|
27
|
+
artoolkit5-wasm Emscripten / C++ bindings
|
|
28
|
+
artoolkit5-constants ARToolkit5 constants, extracted from the headers
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
It is renderer-agnostic and DOM-free. It gives you marker poses as matrices; what you draw with them is your business — Three.js, Babylon.js, raw WebGL, or nothing at all.
|
|
32
|
+
|
|
33
|
+
## 📦 Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install @ar-js-org/artoolkit5-ts
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
[`@ar-js-org/artoolkit5-wasm`](https://www.npmjs.com/package/@ar-js-org/artoolkit5-wasm) (`^0.1.3`) provides the WebAssembly engine. It installs automatically as a dependency, and is left external rather than bundled so the `.wasm` binary is fetched once and cached instead of being copied into every bundle that depends on it.
|
|
40
|
+
|
|
41
|
+
`three` is only needed to run the examples, not the library.
|
|
42
|
+
|
|
43
|
+
## 🚀 Quick start
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import {
|
|
47
|
+
createARToolKitState,
|
|
48
|
+
loadPatternMarker,
|
|
49
|
+
trackMarker,
|
|
50
|
+
processFrame,
|
|
51
|
+
} from '@ar-js-org/artoolkit5-ts';
|
|
52
|
+
|
|
53
|
+
// 1. Initialise once — loads the WASM module and camera calibration
|
|
54
|
+
const state = await createARToolKitState(640, 480, './data/camera_para.dat');
|
|
55
|
+
|
|
56
|
+
// 2. Register the markers you care about.
|
|
57
|
+
// The ID is assigned by the engine — never hardcode it.
|
|
58
|
+
const markerId = await loadPatternMarker(state, './data/patt.hiro');
|
|
59
|
+
trackMarker(state, markerId, 1.0);
|
|
60
|
+
|
|
61
|
+
// 3. Per frame: pass RGBA pixels in, get poses out.
|
|
62
|
+
// Draw your video to a canvas and read it back; the library never
|
|
63
|
+
// touches the DOM, so obtaining the pixels is your side of the line.
|
|
64
|
+
const pixels = ctx.getImageData(0, 0, 640, 480).data;
|
|
65
|
+
const { detected, lost } = processFrame(state, pixels);
|
|
66
|
+
|
|
67
|
+
for (const marker of detected) {
|
|
68
|
+
// marker.matrixGL is a 4x4 column-major right-handed matrix,
|
|
69
|
+
// ready to hand to WebGL or Three.js.
|
|
70
|
+
// With Three.js, set mesh.matrixAutoUpdate = false once beforehand,
|
|
71
|
+
// or it recomputes the matrix from position/quaternion/scale and
|
|
72
|
+
// discards the pose you just wrote.
|
|
73
|
+
mesh.matrix.fromArray(marker.matrixGL);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// `lost` holds markers that were visible last frame and are not now —
|
|
77
|
+
// reported once, on the frame they disappear
|
|
78
|
+
for (const id of lost) {
|
|
79
|
+
hideObjectFor(id);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
A complete working example lives in [`examples/webcam`](examples/webcam) — webcam capture, marker tracking and a Three.js cube overlay:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npm run dev
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
You will need the [Hiro marker](https://commons.wikimedia.org/wiki/File:Hiro_marker_wikipedia.png) printed or on a second screen.
|
|
90
|
+
|
|
91
|
+
## 🧠 Why functions instead of a controller class
|
|
92
|
+
|
|
93
|
+
The `ARController` that `artoolkit5-js` inherited from `jsartoolkit5` was a God Object: it owned the WASM module, the canvas, the video element, marker state and the render loop. That made it impossible to tree-shake, awkward to run in a Worker, and hard to test without a browser.
|
|
94
|
+
|
|
95
|
+
Here, `ARToolKitState` is a plain data container with no methods, and every operation takes it as its first argument:
|
|
96
|
+
|
|
97
|
+
- **Tree-shakeable** — you bundle only the functions you import
|
|
98
|
+
- **Testable** — functions take input and return output; no mocking a class hierarchy
|
|
99
|
+
- **Worker-friendly** — no DOM anywhere in `src/`, so state can live off the main thread
|
|
100
|
+
- **Framework-agnostic** — nothing assumes React, Vue, or any renderer
|
|
101
|
+
|
|
102
|
+
The trade-off is deliberate: this library will not open your camera, create a canvas, or run a render loop for you. Those belong to your application.
|
|
103
|
+
|
|
104
|
+
## 📖 API
|
|
105
|
+
|
|
106
|
+
### `createARToolKitState(width, height, cameraUrl, wasmUrl?)`
|
|
107
|
+
|
|
108
|
+
Initialises the WASM module and camera parameters. Returns `Promise<ARToolKitState>`.
|
|
109
|
+
|
|
110
|
+
| Parameter | Type | Description |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| `width` | `number` | Frame width; must match the frames you pass to `processFrame` |
|
|
113
|
+
| `height` | `number` | Frame height |
|
|
114
|
+
| `cameraUrl` | `string` | URL of an ARToolKit `camera_para.dat` calibration file |
|
|
115
|
+
| `wasmUrl` | `string?` | Explicit URL for `artoolkit5.wasm`. Required when your bundler rewrites asset paths, as Vite does |
|
|
116
|
+
|
|
117
|
+
### `loadPatternMarker(state, markerUrl)`
|
|
118
|
+
|
|
119
|
+
Downloads a `.patt` file, writes it to the WASM virtual filesystem and registers it. Returns `Promise<number>` — the engine-assigned marker ID.
|
|
120
|
+
|
|
121
|
+
Loading a marker does not start tracking it; pass the ID to `trackMarker`.
|
|
122
|
+
|
|
123
|
+
### `trackMarker(state, pattId, markerWidth?)`
|
|
124
|
+
|
|
125
|
+
Registers a marker for tracking and allocates its reusable pose buffers.
|
|
126
|
+
|
|
127
|
+
`markerWidth` defaults to `1.0`. Whatever unit you choose here is the unit all returned translations are expressed in — use millimetres if you want millimetres.
|
|
128
|
+
|
|
129
|
+
### `processFrame(state, videoFrame)`
|
|
130
|
+
|
|
131
|
+
Detects registered markers in one frame. Returns a `FrameResult`:
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
interface FrameResult {
|
|
135
|
+
detected: MarkerPose[]; // visible in this frame
|
|
136
|
+
lost: number[]; // IDs visible last frame, gone in this one
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`lost` is reported **exactly once**, on the frame a marker disappears — it does not repeat while the marker stays absent. Tracking already computes this transition internally, so exposing it saves every consumer from diffing successive results to recover it.
|
|
141
|
+
|
|
142
|
+
`videoFrame` is a `Uint8ClampedArray` of RGBA pixels matching the width and height the state was created with — typically `ctx.getImageData(...).data`.
|
|
143
|
+
|
|
144
|
+
This runs on every animation frame and allocates no typed arrays: poses are written into buffers owned by the marker's tracking state, and **those buffers are reused next frame**. Copy the values if you need to retain them.
|
|
145
|
+
|
|
146
|
+
### `disposeARToolKitState(state)`
|
|
147
|
+
|
|
148
|
+
Releases the WASM resources the state holds. Call it when tracking stops — otherwise a page that starts and stops AR leaks the C++ instance and its heap allocations every time.
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
const state = await createARToolKitState(640, 480, cameraUrl);
|
|
152
|
+
// … track markers …
|
|
153
|
+
disposeARToolKitState(state);
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Safe to call more than once. Afterwards every other operation on that state throws `ARToolKitError` rather than reaching freed memory, so a use-after-dispose gives you a clear message instead of a crash inside the WASM module.
|
|
157
|
+
|
|
158
|
+
### `ARToolKitError`
|
|
159
|
+
|
|
160
|
+
Thrown for misuse of this API — currently, using a state after disposing it. Distinct from a plain `Error` so you can tell an API mistake apart from a failure inside the WASM module or your own code.
|
|
161
|
+
|
|
162
|
+
### `getCameraProjectionMatrix(state)`
|
|
163
|
+
|
|
164
|
+
Returns the 4×4 projection matrix ARToolKit computed from your `camera_para.dat`, as a `Float64Array`. Use it in place of a generic perspective camera: it carries the measured focal length and principal point of the actual lens, so rendered geometry lines up with the video rather than merely sitting near it. (Radial distortion is not part of this matrix — no projection matrix can express it. ARToolKit corrects for it separately, when un-distorting detected marker corners.)
|
|
165
|
+
|
|
166
|
+
### `transMatToGLMat(transMat, out?)` / `arglCameraViewRHf(glMatrix, out?, scale?)`
|
|
167
|
+
|
|
168
|
+
Matrix helpers, exported because they are occasionally useful directly. `processFrame` already applies both.
|
|
169
|
+
|
|
170
|
+
ARToolKit produces a 3×4 row-major pose; WebGL wants a 4×4 column-major matrix in a right-handed system. `transMatToGLMat` expands the matrix, `arglCameraViewRHf` negates the Y and Z axes. Without the second step, poses render behind the camera.
|
|
171
|
+
|
|
172
|
+
Both take an optional output buffer — supply one in hot paths to avoid allocating.
|
|
173
|
+
|
|
174
|
+
### Types
|
|
175
|
+
|
|
176
|
+
`ARToolKitState`, `MarkerPose`, `FrameResult`, `TrackedMarkerState`, plus `ARToolKitModule`, `ARToolKitCore` and `MarkerInfo` describing the WASM boundary.
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
interface MarkerPose {
|
|
180
|
+
id: number;
|
|
181
|
+
matrix: Float64Array; // 3x4, row-major, as ARToolKit produces it
|
|
182
|
+
matrixGL: Float32Array; // 4x4, column-major, right-handed, WebGL-ready
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 🖼️ Feeding frames from an ImageBitmap
|
|
187
|
+
|
|
188
|
+
`processFrame` takes raw pixels, so `src/` never touches a canvas API. If your frames arrive as `ImageBitmap` — as they do in AR.js-next — convert them yourself, reusing one canvas rather than creating one per frame:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// The same dimensions the state was created with. Reading back any other
|
|
192
|
+
// size gives processFrame a buffer it will misinterpret.
|
|
193
|
+
const WIDTH = 640;
|
|
194
|
+
const HEIGHT = 480;
|
|
195
|
+
|
|
196
|
+
const canvas = new OffscreenCanvas(WIDTH, HEIGHT);
|
|
197
|
+
const ctx = canvas.getContext('2d', { willReadFrequently: true })!;
|
|
198
|
+
|
|
199
|
+
function toPixels(bitmap: ImageBitmap): Uint8ClampedArray {
|
|
200
|
+
ctx.drawImage(bitmap, 0, 0, WIDTH, HEIGHT);
|
|
201
|
+
return ctx.getImageData(0, 0, WIDTH, HEIGHT).data;
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
A helper that does this is on the roadmap; until then it is a few lines you own.
|
|
206
|
+
|
|
207
|
+
## ⚠️ Limitations
|
|
208
|
+
|
|
209
|
+
- **Pattern markers only.** Barcode/matrix markers are planned; NFT is out of scope for this project — see [Roadmap](#-roadmap).
|
|
210
|
+
- **No detector tuning yet.** Threshold, threshold mode, labelling mode and related settings are exposed by the engine but not yet surfaced here.
|
|
211
|
+
- **Worker support is untested.** Nothing in `src/` touches the DOM, which is necessary but not proof — WASM instantiation in worker scope has not been verified.
|
|
212
|
+
|
|
213
|
+
## 🗺️ Roadmap
|
|
214
|
+
|
|
215
|
+
Detailed design lives in [`docs/DESIGN-v0.1.md`](docs/DESIGN-v0.1.md); work is tracked in [issues](https://github.com/AR-js-org/artoolkit5-ts/issues).
|
|
216
|
+
|
|
217
|
+
**v0.1** (done) — lifecycle, packaging, marker-lost reporting from `processFrame`, a test suite and CI.
|
|
218
|
+
|
|
219
|
+
**Next** — `configureDetector` for threshold and labelling settings, barcode markers, a verified Worker example, an `ImageBitmap` conversion helper, and multi-marker sets.
|
|
220
|
+
|
|
221
|
+
**Out of scope** — NFT tracking. This project and `artoolkit5-wasm` cover pattern and barcode markers; NFT belongs to other projects in the ecosystem.
|
|
222
|
+
|
|
223
|
+
## 🛠️ Development
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
npm run dev # Vite dev server, opens the webcam example
|
|
227
|
+
npm run build # library build (ES + UMD) plus type declarations
|
|
228
|
+
npm run preview # preview the production build
|
|
229
|
+
npm test # run the test suite once
|
|
230
|
+
npm run test:watch # re-run tests on change
|
|
231
|
+
npm run typecheck # tsc --noEmit
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Tests
|
|
235
|
+
|
|
236
|
+
[Vitest](https://vitest.dev) covers the matrix maths, the marker visibility state machine and the dispose lifecycle. The suite runs in well under a second because the WASM boundary is faked: `test/mock-core.ts` stands in for the Emscripten module and the bound C++ instance, so neither a browser nor a compiled binary is needed.
|
|
237
|
+
|
|
238
|
+
The suite aims at the code that fails *quietly* rather than at a line-count target — a transposed matrix still renders, just in the wrong place, and a marker-lost event that fires twice looks fine until something downstream double-handles it.
|
|
239
|
+
|
|
240
|
+
It is validated by mutation: deliberately breaking the collection order, the `Float32Array` return type, or the continuous-tracking condition each makes exactly one test fail. If you add tests, check they can actually fail.
|
|
241
|
+
|
|
242
|
+
### Contributing
|
|
243
|
+
|
|
244
|
+
Branch from `dev`; `main` holds release-ready code only. Commits follow [Conventional Commits](https://www.conventionalcommits.org/). Fuller guidance is in [`AGENTS.md`](AGENTS.md).
|
|
245
|
+
|
|
246
|
+
### Releasing
|
|
247
|
+
|
|
248
|
+
Releases are cut by the **Release** workflow, run manually from the Actions tab. Its only required input is the version to publish, without a leading `v` — for example `0.1.0`.
|
|
249
|
+
|
|
250
|
+
Everything after that is automatic: it runs typecheck, tests and build, sets the version, promotes the changelog, derives release notes from the commits, commits, tags `vX.Y.Z`, creates the GitHub Release and publishes to npm with [provenance](https://docs.npmjs.com/generating-provenance-statements) — so the package carries a verifiable link back to the commit and workflow run that built it.
|
|
251
|
+
|
|
252
|
+
**Run it with `dry_run` first.** That performs every check and prints the notes and the tarball contents without tagging, committing or publishing. It is the only way to rehearse: npm never allows a published version to be replaced.
|
|
253
|
+
|
|
254
|
+
Before running for real, the workflow refuses to start unless:
|
|
255
|
+
|
|
256
|
+
- the version is valid semver, not already tagged, and not already on npm
|
|
257
|
+
- the branch is `main`
|
|
258
|
+
- the repository is public — npm will not generate provenance from a private repository
|
|
259
|
+
|
|
260
|
+
Preparing a release means writing the changelog. Add entries to `## [Unreleased]` as you go; the workflow renames that heading to the released version and opens a fresh one. Anything between `<!-- promote:strip -->` markers is dropped during promotion, so notes meant only for editors do not survive into a released section. `npm run release-notes` prints the Conventional Commits since the last tag if you want to see what has accumulated.
|
|
261
|
+
|
|
262
|
+
It is a single workflow rather than a "create release" and a "publish" pair because a Release created with the default `GITHUB_TOKEN` does not trigger other workflows — GitHub blocks that to prevent recursion, so the second one would silently never fire.
|
|
263
|
+
|
|
264
|
+
## 📄 Licence
|
|
265
|
+
|
|
266
|
+
MIT — see [LICENSE](LICENSE).
|
|
267
|
+
|
|
268
|
+
This library wraps a WebAssembly build of **ARToolkit5 (WebARKitLib), which is licensed under the LGPL v3.0**. The MIT licence covers this TypeScript code, not the engine underneath: redistributing a build that includes the ARToolkit5 (WebARKitLib) WebAssembly binary carries that licence's obligations as well.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { addMarkerFromUrl as e, createARToolKit as t, loadCameraFromUrl as n } from "@ar-js-org/artoolkit5-wasm";
|
|
2
|
+
//#region src/errors.ts
|
|
3
|
+
var r = class e extends Error {
|
|
4
|
+
constructor(t) {
|
|
5
|
+
super(t), this.name = "ARToolKitError", Object.setPrototypeOf(this, e.prototype);
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
function i(e, t) {
|
|
9
|
+
if (e.disposed) throw new r(`${t} was called on a disposed ARToolKitState. Create a new one with createARToolKitState().`);
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/init.ts
|
|
13
|
+
async function a(e, r, i, a) {
|
|
14
|
+
let o = (await t({ locateFile: (e) => a && e.endsWith(".wasm") ? a : e })).mod, s = new o.ARToolKitCore(), c = await n(o, s, i);
|
|
15
|
+
return await s.setup(e, r, c), {
|
|
16
|
+
mod: o,
|
|
17
|
+
core: s,
|
|
18
|
+
width: e,
|
|
19
|
+
height: r,
|
|
20
|
+
markers: {},
|
|
21
|
+
disposed: !1
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function o(e) {
|
|
25
|
+
e.disposed ||= (e.core.teardown(), e.core.delete(), e.markers = {}, !0);
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/markers.ts
|
|
29
|
+
async function s(t, n) {
|
|
30
|
+
return i(t, "loadPatternMarker"), e(t.mod, t.core, n);
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/math.ts
|
|
34
|
+
var c = 16;
|
|
35
|
+
function l(e) {
|
|
36
|
+
return i(e, "getCameraProjectionMatrix"), e.core.getCameraLens();
|
|
37
|
+
}
|
|
38
|
+
function u(e, t = new Float32Array(c)) {
|
|
39
|
+
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
|
+
}
|
|
41
|
+
function d(e, t = new Float32Array(c), n) {
|
|
42
|
+
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
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
//#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,
|
|
51
|
+
inPrevious: !1,
|
|
52
|
+
inCurrent: !1,
|
|
53
|
+
matrix: new Float64Array(f),
|
|
54
|
+
matrixGL: /* @__PURE__ */ new Float32Array(16)
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function y(e, t) {
|
|
58
|
+
return i(e, "processFrame"), b(e, t), x(e), {
|
|
59
|
+
detected: S(e),
|
|
60
|
+
lost: C(e)
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function b(e, t) {
|
|
64
|
+
e.core.passVideoData(t, h, g), e.core.detectMarker();
|
|
65
|
+
}
|
|
66
|
+
function x(e) {
|
|
67
|
+
for (let t in e.markers) {
|
|
68
|
+
let n = e.markers[t];
|
|
69
|
+
n.inPrevious = n.inCurrent, n.inCurrent = !1;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function S(e) {
|
|
73
|
+
let t = [], n = e.core.getMarkerNum();
|
|
74
|
+
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
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
return t;
|
|
85
|
+
}
|
|
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);
|
|
91
|
+
}
|
|
92
|
+
return t;
|
|
93
|
+
}
|
|
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);
|
|
96
|
+
}
|
|
97
|
+
function T(e, t) {
|
|
98
|
+
let n = e.core.getTransform() >> p;
|
|
99
|
+
t.set(e.mod.HEAPF64.subarray(n, n + f));
|
|
100
|
+
}
|
|
101
|
+
//#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 };
|
|
@@ -0,0 +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});
|
package/dist/domain.d.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared data structures.
|
|
3
|
+
*
|
|
4
|
+
* This module contains types only — no logic, no side effects.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Detection result for a single marker in a single frame.
|
|
8
|
+
*
|
|
9
|
+
* `matrix` and `matrixGL` are views onto buffers owned by the tracker and
|
|
10
|
+
* reused every frame. Copy them if you need to retain values across frames.
|
|
11
|
+
*
|
|
12
|
+
* The differing precisions are deliberate: full precision is kept at the
|
|
13
|
+
* source and narrowed exactly once, at the boundary where the data becomes
|
|
14
|
+
* GPU-bound. Prefer `matrix` for any CPU-side maths — smoothing,
|
|
15
|
+
* interpolation, physics — and `matrixGL` only for rendering.
|
|
16
|
+
*/
|
|
17
|
+
export interface MarkerPose {
|
|
18
|
+
id: number;
|
|
19
|
+
/**
|
|
20
|
+
* 3x4 row-major pose, exactly as ARToolKit produces it.
|
|
21
|
+
*
|
|
22
|
+
* 64-bit because the C core computes in `ARdouble` and writes to
|
|
23
|
+
* `HEAPF64`; reading it as `Float64Array` is a lossless copy.
|
|
24
|
+
*/
|
|
25
|
+
matrix: Float64Array;
|
|
26
|
+
/**
|
|
27
|
+
* 4x4 column-major right-handed pose, ready for WebGL.
|
|
28
|
+
*
|
|
29
|
+
* 32-bit because WebGL is single-precision end to end — `uniformMatrix4fv`
|
|
30
|
+
* takes a `Float32Array` and GLSL's `highp float` is 32-bit, so any wider
|
|
31
|
+
* precision is discarded on upload. Not an accuracy compromise: float32
|
|
32
|
+
* resolves below a micron at metre scale, while pose error is dominated by
|
|
33
|
+
* camera noise and calibration in the millimetre range.
|
|
34
|
+
*/
|
|
35
|
+
matrixGL: Float32Array;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Outcome of a single call to `processFrame`.
|
|
39
|
+
*
|
|
40
|
+
* `lost` exists because the visibility transition is already computed while
|
|
41
|
+
* tracking, and discarding it would force every consumer to re-derive it by
|
|
42
|
+
* diffing successive results.
|
|
43
|
+
*/
|
|
44
|
+
export interface FrameResult {
|
|
45
|
+
/** Markers visible in this frame, with their poses. */
|
|
46
|
+
detected: MarkerPose[];
|
|
47
|
+
/**
|
|
48
|
+
* IDs of markers visible in the previous frame but not this one.
|
|
49
|
+
*
|
|
50
|
+
* Reported exactly once, on the frame the marker disappears.
|
|
51
|
+
*/
|
|
52
|
+
lost: number[];
|
|
53
|
+
}
|
|
54
|
+
/** Per-marker tracking state, owned by {@link ARToolKitState}. */
|
|
55
|
+
export interface TrackedMarkerState {
|
|
56
|
+
id: number;
|
|
57
|
+
markerWidth: number;
|
|
58
|
+
/** Visible in the previous frame — enables continuous tracking. */
|
|
59
|
+
inPrevious: boolean;
|
|
60
|
+
/** Visible in the frame currently being processed. */
|
|
61
|
+
inCurrent: boolean;
|
|
62
|
+
/** Reused across frames; never reallocated after registration. */
|
|
63
|
+
matrix: Float64Array;
|
|
64
|
+
/** Reused across frames; never reallocated after registration. */
|
|
65
|
+
matrixGL: Float32Array;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The Emscripten module, narrowed to the surface this library uses.
|
|
69
|
+
*
|
|
70
|
+
* Structurally compatible with the `Mod` type expected by the
|
|
71
|
+
* `@ar-js-org/artoolkit5-wasm` loader helpers.
|
|
72
|
+
*/
|
|
73
|
+
export interface ARToolKitModule {
|
|
74
|
+
/** Emscripten heap, read directly when unpacking pose pointers. */
|
|
75
|
+
HEAPF64: Float64Array;
|
|
76
|
+
FS: unknown;
|
|
77
|
+
loadCameraFromPath(path: string): number;
|
|
78
|
+
addMarker(path: string): number;
|
|
79
|
+
}
|
|
80
|
+
/** Marker metadata returned by the detector for one candidate square. */
|
|
81
|
+
export interface MarkerInfo {
|
|
82
|
+
/** Engine-assigned marker ID, or -1 when unrecognised. */
|
|
83
|
+
id: number;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The C++ `ARToolKitCore` instance, narrowed to the methods this library calls.
|
|
87
|
+
*
|
|
88
|
+
* Pose getters return a pointer into the Emscripten heap rather than a value;
|
|
89
|
+
* see {@link ARToolKitCore.getTransform}.
|
|
90
|
+
*/
|
|
91
|
+
export interface ARToolKitCore {
|
|
92
|
+
setup(width: number, height: number, cameraId: number): Promise<void>;
|
|
93
|
+
passVideoData(frame: Uint8ClampedArray, lumaBuffer: number[], convertToLuma: boolean): void;
|
|
94
|
+
detectMarker(): void;
|
|
95
|
+
getMarkerNum(): number;
|
|
96
|
+
getMarkerInfo(index: number): MarkerInfo;
|
|
97
|
+
getTransMatSquare(index: number, markerWidth: number): void;
|
|
98
|
+
getTransMatSquareCont(index: number, markerWidth: number): void;
|
|
99
|
+
/** Byte offset into `HEAPF64` holding the most recent 3x4 pose. */
|
|
100
|
+
getTransform(): number;
|
|
101
|
+
getCameraLens(): Float64Array;
|
|
102
|
+
/** Releases the ARToolKit handles held by the C++ instance. */
|
|
103
|
+
teardown(): number;
|
|
104
|
+
/** Frees the C++ instance itself. Generated by Embind, not declared in C++. */
|
|
105
|
+
delete(): void;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The central state object threaded through every operation.
|
|
109
|
+
*
|
|
110
|
+
* A pure data container: it has no methods, and functions receive it as their
|
|
111
|
+
* first argument rather than being bound to it.
|
|
112
|
+
*/
|
|
113
|
+
export interface ARToolKitState {
|
|
114
|
+
readonly mod: ARToolKitModule;
|
|
115
|
+
readonly core: ARToolKitCore;
|
|
116
|
+
readonly width: number;
|
|
117
|
+
readonly height: number;
|
|
118
|
+
/** Registered markers, keyed by engine-assigned ID. */
|
|
119
|
+
markers: Record<number, TrackedMarkerState>;
|
|
120
|
+
/**
|
|
121
|
+
* Set by `disposeARToolKitState`. Once true the C++ instance is gone and
|
|
122
|
+
* every operation on this state throws rather than reaching freed memory.
|
|
123
|
+
*/
|
|
124
|
+
disposed: boolean;
|
|
125
|
+
}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ARToolKitState } from './domain';
|
|
2
|
+
/**
|
|
3
|
+
* Error thrown by this library.
|
|
4
|
+
*
|
|
5
|
+
* Distinct from a plain `Error` so callers can tell a misuse of this API apart
|
|
6
|
+
* from a failure inside the WASM module or the host application.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ARToolKitError extends Error {
|
|
9
|
+
constructor(message: string);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Throws if the state has been disposed.
|
|
13
|
+
*
|
|
14
|
+
* Every public operation calls this first. Without it, using a disposed state
|
|
15
|
+
* reaches freed WASM memory and fails somewhere inside the module, where the
|
|
16
|
+
* error says nothing about the actual mistake.
|
|
17
|
+
*
|
|
18
|
+
* @param operation Name of the calling function, used in the message.
|
|
19
|
+
*/
|
|
20
|
+
export declare function assertNotDisposed(state: ARToolKitState, operation: string): void;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { ARToolKitCore, ARToolKitModule, ARToolKitState, FrameResult, MarkerInfo, MarkerPose, TrackedMarkerState, } from './domain';
|
|
2
|
+
export { ARToolKitError } from './errors';
|
|
3
|
+
export { createARToolKitState, disposeARToolKitState } from './init';
|
|
4
|
+
export { loadPatternMarker } from './markers';
|
|
5
|
+
export { processFrame, trackMarker } from './tracking';
|
|
6
|
+
export { arglCameraViewRHf, getCameraProjectionMatrix, transMatToGLMat } from './math';
|
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ARToolKitState } from './domain';
|
|
2
|
+
/**
|
|
3
|
+
* Initialises the WASM module, loads camera parameters and returns the state
|
|
4
|
+
* object that every other operation in this library operates on.
|
|
5
|
+
*
|
|
6
|
+
* @param width Frame width in pixels; must match the frames passed to `processFrame`.
|
|
7
|
+
* @param height Frame height in pixels; must match the frames passed to `processFrame`.
|
|
8
|
+
* @param cameraUrl URL of an ARToolKit `camera_para.dat` calibration file.
|
|
9
|
+
* @param wasmUrl Optional explicit URL for `artoolkit5.wasm`. Required when the
|
|
10
|
+
* bundler rewrites asset paths, as Vite does.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createARToolKitState(width: number, height: number, cameraUrl: string, wasmUrl?: string): Promise<ARToolKitState>;
|
|
13
|
+
/**
|
|
14
|
+
* Releases the WASM resources held by a state.
|
|
15
|
+
*
|
|
16
|
+
* Call this when tracking stops — a single-page app that starts and stops AR,
|
|
17
|
+
* or a test creating a state per case, otherwise leaks the C++ instance and its
|
|
18
|
+
* heap allocations every time.
|
|
19
|
+
*
|
|
20
|
+
* Two steps are needed: `teardown()` frees the ARToolKit handles the instance
|
|
21
|
+
* owns, and `delete()` — generated by Embind rather than declared in C++ —
|
|
22
|
+
* frees the instance itself. Calling only the latter leaks the handles.
|
|
23
|
+
*
|
|
24
|
+
* Safe to call more than once; subsequent calls do nothing. Every other
|
|
25
|
+
* operation on the state throws {@link ARToolKitError} afterwards.
|
|
26
|
+
*/
|
|
27
|
+
export declare function disposeARToolKitState(state: ARToolKitState): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ARToolKitState } from './domain';
|
|
2
|
+
/**
|
|
3
|
+
* Downloads a pattern file (`.patt`), writes it to the WASM virtual file system
|
|
4
|
+
* and registers it with the ARToolKit core.
|
|
5
|
+
*
|
|
6
|
+
* The returned ID is assigned by the C++ engine and must be passed to
|
|
7
|
+
* `trackMarker` before the marker will be tracked. Never hardcode it.
|
|
8
|
+
*
|
|
9
|
+
* @throws {ARToolKitError} if the state has been disposed.
|
|
10
|
+
*/
|
|
11
|
+
export declare function loadPatternMarker(state: ARToolKitState, markerUrl: string): Promise<number>;
|
package/dist/math.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ARToolKitState } from './domain';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the camera projection matrix computed by ARToolKit from the loaded
|
|
4
|
+
* `camera_para.dat`, accounting for real lens distortion.
|
|
5
|
+
*
|
|
6
|
+
* NOTE: unlike `getTransform`, which returns a heap pointer, this returns the
|
|
7
|
+
* matrix directly. That asymmetry is unverified against the C++ source. See
|
|
8
|
+
* "spike: verify what getCameraLens() actually returns":
|
|
9
|
+
* https://github.com/AR-js-org/artoolkit5-ts/issues/10
|
|
10
|
+
*
|
|
11
|
+
* @throws {ARToolKitError} if the state has been disposed.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getCameraProjectionMatrix(state: ARToolKitState): Float64Array;
|
|
14
|
+
/**
|
|
15
|
+
* Expands ARToolKit's 3x4 row-major pose into a 4x4 column-major matrix.
|
|
16
|
+
*
|
|
17
|
+
* @param out Optional destination. Supply one in hot paths to avoid allocating.
|
|
18
|
+
*/
|
|
19
|
+
export declare function transMatToGLMat(transMat: Float64Array, out?: Float32Array): Float32Array;
|
|
20
|
+
/**
|
|
21
|
+
* Converts a 4x4 ARToolKit matrix into the right-handed coordinate system used
|
|
22
|
+
* by WebGL, by negating the Y and Z axes.
|
|
23
|
+
*
|
|
24
|
+
* Without this the pose renders behind the camera. It is the mathematically
|
|
25
|
+
* correct equivalent of manually flipping matrix signs.
|
|
26
|
+
*
|
|
27
|
+
* @param out Optional destination. Supply one in hot paths to avoid allocating.
|
|
28
|
+
* @param scale Optional uniform scale applied to the translation column.
|
|
29
|
+
*/
|
|
30
|
+
export declare function arglCameraViewRHf(glMatrix: Float32Array, out?: Float32Array, scale?: number): Float32Array;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ARToolKitState, FrameResult } from './domain';
|
|
2
|
+
/**
|
|
3
|
+
* Registers a marker for tracking and allocates its reusable pose buffers.
|
|
4
|
+
*
|
|
5
|
+
* @param pattId ID returned by `loadPatternMarker`.
|
|
6
|
+
* @param markerWidth Physical marker width; the unit chosen here is the unit
|
|
7
|
+
* all returned translations are expressed in.
|
|
8
|
+
* @throws {ARToolKitError} if the state has been disposed.
|
|
9
|
+
*/
|
|
10
|
+
export declare function trackMarker(state: ARToolKitState, pattId: number, markerWidth?: number): void;
|
|
11
|
+
/**
|
|
12
|
+
* Detects registered markers in a single frame.
|
|
13
|
+
*
|
|
14
|
+
* Returns both the markers visible now and those that have just disappeared,
|
|
15
|
+
* so a consumer emitting found/updated/lost events does not have to diff
|
|
16
|
+
* successive results to recover information tracking already had.
|
|
17
|
+
*
|
|
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.
|
|
21
|
+
*
|
|
22
|
+
* @param videoFrame RGBA pixels matching the width and height the state was
|
|
23
|
+
* created with.
|
|
24
|
+
* @throws {ARToolKitError} if the state has been disposed.
|
|
25
|
+
*/
|
|
26
|
+
export declare function processFrame(state: ARToolKitState, videoFrame: Uint8ClampedArray): FrameResult;
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ar-js-org/artoolkit5-ts",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "TypeScript marker tracking for the browser, built on a WebAssembly build of ARToolkit5 (WebARKitLib). Composable and tree-shakeable: state is plain data, operations are functions.",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"artoolkit",
|
|
9
|
+
"artoolkit5",
|
|
10
|
+
"augmented-reality",
|
|
11
|
+
"ar",
|
|
12
|
+
"webar",
|
|
13
|
+
"marker-tracking",
|
|
14
|
+
"barcode-marker",
|
|
15
|
+
"webassembly",
|
|
16
|
+
"wasm",
|
|
17
|
+
"typescript",
|
|
18
|
+
"ar.js",
|
|
19
|
+
"webarkit"
|
|
20
|
+
],
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"author": {
|
|
23
|
+
"name": "Walter Perdan",
|
|
24
|
+
"url": "https://github.com/kalwalt"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/AR-js-org/artoolkit5-ts.git"
|
|
29
|
+
},
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/AR-js-org/artoolkit5-ts/issues"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://github.com/AR-js-org/artoolkit5-ts#readme",
|
|
34
|
+
"main": "./dist/artoolkit5-ts.umd.cjs",
|
|
35
|
+
"module": "./dist/artoolkit5-ts.js",
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"exports": {
|
|
38
|
+
".": {
|
|
39
|
+
"types": "./dist/index.d.ts",
|
|
40
|
+
"import": "./dist/artoolkit5-ts.js",
|
|
41
|
+
"require": "./dist/artoolkit5-ts.umd.cjs"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist",
|
|
46
|
+
"CHANGELOG.md"
|
|
47
|
+
],
|
|
48
|
+
"scripts": {
|
|
49
|
+
"dev": "vite",
|
|
50
|
+
"build": "vite build && tsc -p tsconfig.build.json",
|
|
51
|
+
"preview": "vite preview",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:watch": "vitest",
|
|
54
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
55
|
+
"release-notes": "node scripts/release-notes.mjs"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@ar-js-org/artoolkit5-wasm": "^0.1.3"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/node": "^26.0.1",
|
|
62
|
+
"@types/three": "^0.185.0",
|
|
63
|
+
"three": "^0.185.0",
|
|
64
|
+
"typescript": "^6.0.3",
|
|
65
|
+
"vite": "^8.1.0",
|
|
66
|
+
"vitest": "^4.1.10"
|
|
67
|
+
}
|
|
68
|
+
}
|