Skip to content

Commit 75527aa

Browse files
committed
Merge branch 'copilot/scaffold-artoolkit'
# Conflicts: # README.md # package-lock.json # package.json # src/plugin.js # src/worker/worker.js
2 parents fa9d0cb + 8a241af commit 75527aa

File tree

9 files changed

+1298
-62
lines changed

9 files changed

+1298
-62
lines changed

README.md

Lines changed: 156 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,169 @@
1-
# arjs-plugin-artoolkit
2-
```markdown
31
# @ar-js-org/arjs-plugin-artoolkit
42

5-
Minimal ARToolKit detection plugin scaffold for AR.js core.
3+
ARToolKit marker detection plugin for AR.js core with WebAssembly support.
4+
5+
## Features
6+
7+
- Web Worker-based detection — marker detection runs off the main thread
8+
- ImageBitmap support — zero-copy frame transfer (browser)
9+
- Cross-platform — browser Workers and Node.js worker_threads (stub path)
10+
- ARToolKit integration — square pattern markers
11+
- Event-driven API — marker found/updated/lost + raw getMarker forwarding
12+
- Filtering — only forwards PATTERN_MARKER events above a minimum confidence
13+
14+
## Installation
15+
16+
```bash
17+
npm install @ar-js-org/arjs-plugin-artoolkit
18+
```
19+
20+
## Configuration (module + assets)
21+
22+
To ensure the Worker can import ARToolKit in the browser, pass an explicit ESM URL (recommended):
23+
24+
```js
25+
const plugin = new ArtoolkitPlugin({
26+
worker: true,
27+
artoolkitModuleUrl: '/node_modules/@ar-js-org/artoolkit5-js/dist/ARToolkit.js', // explicit ESM
28+
cameraParametersUrl: '/path/to/camera_para.dat', // optional override
29+
wasmBaseUrl: '/node_modules/@ar-js-org/artoolkit5-js/dist/', // optional; if your build needs it
30+
minConfidence: 0.6 // forward only confident detections
31+
});
32+
```
33+
34+
CDN fallback (if you don’t serve node_modules):
35+
- Set `artoolkitModuleUrl` to a CDN ESM endpoint, e.g. a jsDelivr/UNPKG URL for the package’s ESM bundle.
36+
37+
Notes:
38+
- The previous “loader.js” and manual WASM placement flow is no longer used.
39+
- If your ARToolKit build fetches auxiliary assets (WASM, data), set `wasmBaseUrl` accordingly.
640

741
## Usage
842

9-
Register with the Engine plugin manager:
43+
### Register and enable
1044

1145
```js
1246
import { ArtoolkitPlugin } from '@ar-js-org/arjs-plugin-artoolkit';
1347

14-
engine.pluginManager.register('artoolkit', new ArtoolkitPlugin({ /* options */ }));
48+
const plugin = new ArtoolkitPlugin({
49+
worker: true,
50+
lostThreshold: 5, // frames before a marker is considered lost
51+
frameDurationMs: 100, // expected ms per frame (affects lost timing)
52+
artoolkitModuleUrl: '/node_modules/@ar-js-org/artoolkit5-js/dist/ARToolkit.js',
53+
cameraParametersUrl: '/data/camera_para.dat',
54+
minConfidence: 0.6
55+
});
56+
57+
engine.pluginManager.register('artoolkit', plugin);
1558
await engine.pluginManager.enable('artoolkit');
1659
```
1760

18-
The plugin emits events on the engine event bus:
19-
- `ar:markerFound`
20-
- `ar:markerUpdated`
21-
- `ar:markerLost`
61+
### Events
62+
63+
The plugin emits the following events on your engine’s event bus:
64+
65+
```js
66+
// Marker first detected
67+
engine.eventBus.on('ar:markerFound', ({ id, poseMatrix, confidence, corners }) => {
68+
// poseMatrix is Float32Array(16)
69+
});
70+
71+
// Marker updated (tracking)
72+
engine.eventBus.on('ar:markerUpdated', (data) => {
73+
// same shape as markerFound
74+
});
75+
76+
// Marker lost
77+
engine.eventBus.on('ar:markerLost', ({ id }) => {});
78+
79+
// Worker lifecycle
80+
engine.eventBus.on('ar:workerReady', () => {});
81+
engine.eventBus.on('ar:workerError', (error) => {});
82+
83+
// Raw ARToolKit getMarker (filtered: PATTERN_MARKER only, above minConfidence)
84+
engine.eventBus.on('ar:getMarker', (payload) => {
85+
// payload = { type, matrix: number[16], marker: { idPatt, cfPatt, idMatrix?, cfMatrix?, vertex? } }
86+
});
87+
```
88+
89+
### Sending frames
90+
91+
```js
92+
// Create ImageBitmap from a <video> or <canvas>
93+
const imageBitmap = await createImageBitmap(video);
94+
95+
// Emit an engine update; the plugin transfers the ImageBitmap to the worker
96+
engine.eventBus.emit('engine:update', {
97+
id: frameId,
98+
timestamp: Date.now(),
99+
imageBitmap,
100+
width: imageBitmap.width,
101+
height: imageBitmap.height
102+
});
103+
104+
// The ImageBitmap is transferred and cannot be reused; the worker will close it.
105+
```
106+
107+
### Loading a pattern marker
108+
109+
```js
110+
const { markerId, size } = await plugin.loadMarker('/examples/simple-marker/data/patt.hiro', 1);
111+
```
112+
113+
## Examples
114+
115+
A complete webcam-based example is available under `examples/simple-marker/`.
116+
117+
Serve from the repository root so that ES modules and node_modules paths resolve:
118+
119+
```bash
120+
# From repository root
121+
npx http-server -p 8080
122+
# or
123+
python3 -m http.server 8080
124+
```
125+
126+
Open:
127+
- http://localhost:8080/examples/simple-marker/index.html
128+
129+
The example demonstrates:
130+
- Webcam capture with getUserMedia
131+
- ImageBitmap creation and frame submission
132+
- Event handling and console output
133+
- Raw `ar:getMarker` payloads for debugging
134+
135+
## API Reference
136+
137+
### ArtoolkitPlugin options
138+
139+
```ts
140+
{
141+
worker?: boolean; // Enable worker (default: true)
142+
lostThreshold?: number; // Frames before 'lost' (default: 5)
143+
frameDurationMs?: number; // ms per frame (default: 200)
144+
sweepIntervalMs?: number; // Lost-sweep interval (default: 100)
145+
artoolkitModuleUrl?: string; // ESM URL for ARToolKit (recommended)
146+
cameraParametersUrl?: string;// Camera params file URL
147+
wasmBaseUrl?: string; // Base URL for ARToolKit assets (if required)
148+
minConfidence?: number; // Minimum confidence to forward getMarker (default: 0.6)
149+
}
150+
```
151+
152+
### Methods
153+
154+
- `async init(core)` — initialize with engine core
155+
- `async enable()` — start worker and subscribe to frames
156+
- `async disable()` — stop worker and timers
157+
- `dispose()` — alias for disable
158+
- `getMarkerState(markerId)` — current tracked state
159+
- `async loadMarker(patternUrl: string, size = 1)` — load and track a pattern
160+
161+
## Troubleshooting
22162

23-
This repo contains a skeleton. Detection and worker/WASM integration will be implemented in follow-up work.
24-
```
163+
- “Failed to resolve module specifier” in the Worker:
164+
- Provide `artoolkitModuleUrl` or serve `/node_modules` from your dev server
165+
- Worker not starting:
166+
- Serve via HTTP/HTTPS; ensure ES modules and Workers are supported
167+
- No detections:
168+
- Confirm camera started, correct marker pattern, sufficient lighting
169+
- Adjust `minConfidence` to reduce/raise filtering

examples/simple-marker/README.md

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Simple Marker Example
2+
3+
This example demonstrates how to load and track a pattern marker using the ARToolKit plugin.
4+
5+
## Setup Instructions
6+
7+
### 1. Install Dependencies
8+
9+
From the repository root, install the dependencies:
10+
11+
```bash
12+
npm install
13+
```
14+
15+
### 2. Serve the Example
16+
17+
You must serve from the repository root so that:
18+
- ES modules resolve (../../src/plugin.js)
19+
- The worker module URL (../../node_modules/...) is reachable
20+
21+
You can use any static file server. Examples:
22+
23+
#### Option A: Using Python
24+
25+
```bash
26+
# From repository root
27+
python3 -m http.server 8080
28+
```
29+
30+
Then open: http://localhost:8080/examples/simple-marker/index.html
31+
32+
#### Option B: Using Node.js http-server
33+
34+
```bash
35+
# Install http-server globally if not already installed
36+
npm install -g http-server
37+
38+
# From repository root
39+
http-server -p 8080
40+
```
41+
42+
Then open: http://localhost:8080/examples/simple-marker/index.html
43+
44+
#### Option C: Using VS Code Live Server
45+
46+
If you're using VS Code with the Live Server extension:
47+
1. Right-click on `examples/simple-marker/index.html`
48+
2. Select "Open with Live Server"
49+
50+
### 3. Using the Example
51+
52+
1. Wait for the worker to be ready (status will change to “Worker ready”)
53+
2. Click “Start Camera” to begin sending frames
54+
3. Click “Load Marker” to load the Hiro pattern marker
55+
4. Show the marker to the camera and watch the event log and console
56+
57+
## Module resolution
58+
59+
The example config (in `index.html`) passes explicit URLs so the worker can import ARToolKit and camera params:
60+
61+
```js
62+
const plugin = new ArtoolkitPlugin({
63+
worker: true,
64+
artoolkitModuleUrl: '/node_modules/@ar-js-org/artoolkit5-js/dist/ARToolkit.js',
65+
cameraParametersUrl: '/examples/simple-marker/data/camera_para.dat'
66+
});
67+
```
68+
69+
If your server can’t serve `/node_modules`, either:
70+
- Adjust `artoolkitModuleUrl` to a path your server exposes, or
71+
- Use a CDN ESM URL as a fallback (see project README for details)
72+
73+
## What’s Happening
74+
75+
This example demonstrates:
76+
77+
1. Plugin Initialization: creating and enabling `ArtoolkitPlugin`
78+
2. Worker Communication: the plugin starts a Worker for detection
79+
3. Pattern Loading: `plugin.loadMarker('/examples/simple-marker/data/patt.hiro', 1)`
80+
4. Event Handling:
81+
- `ar:workerReady` — Worker initialized
82+
- `ar:markerFound` — First detection of a marker
83+
- `ar:markerUpdated` — Subsequent tracking updates
84+
- `ar:markerLost` — Marker no longer visible
85+
- `ar:getMarker` — Raw ARToolKit getMarker payload (type, matrix, marker fields)
86+
87+
## Pattern File
88+
89+
The `data/patt.hiro` file is a standard ARToolKit pattern. You can replace it with your own pattern and update the URL accordingly.
90+
91+
## Code Overview
92+
93+
Key parts of the example:
94+
95+
```javascript
96+
// Create plugin instance with worker enabled and explicit module/params URLs
97+
const plugin = new ArtoolkitPlugin({
98+
worker: true,
99+
artoolkitModuleUrl: '/node_modules/@ar-js-org/artoolkit5-js/dist/ARToolkit.js',
100+
cameraParametersUrl: '/examples/simple-marker/data/camera_para.dat'
101+
});
102+
103+
// Initialize and enable
104+
await plugin.init(core);
105+
await plugin.enable();
106+
107+
// Load a pattern marker
108+
const result = await plugin.loadMarker('/examples/simple-marker/data/patt.hiro', 1);
109+
console.log(`Marker loaded with ID: ${result.markerId}`);
110+
```
111+
112+
## Troubleshooting
113+
114+
- Worker not loading?
115+
- Ensure you’re serving via HTTP/HTTPS from the repository root (not `file://`)
116+
- Check console for module resolution/CORS errors
117+
- Module import errors?
118+
- Make sure `/node_modules/@ar-js-org/artoolkit5-js/dist/ARToolkit.js` is reachable, or use a CDN URL
119+
- Marker not loading?
120+
- Verify the pattern file path is correct and accessible
121+
- Ensure the worker is ready before calling `loadMarker()`
122+
- No detections?
123+
- Click “Start Camera” before “Load Marker”
124+
- Ensure good lighting and the correct marker
125+
- Increase confidence tolerance if needed (see README options)
126+
127+
## Browser Support
128+
129+
This example requires:
130+
- ES modules
131+
- Web Workers
132+
- Modern browser (Chrome 80+, Firefox 75+, Safari 13.1+, Edge 80+)
176 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)