Skip to content

Commit 568b13f

Browse files
Merge pull request #46 from artoolkit/nft
Merging NFT tracking dev branch - thanks @kig
2 parents 63b4d4e + b281408 commit 568b13f

27 files changed

+117247
-62596
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
doc/reference
22
node_modules
3-
build/libar.bc
3+
build/*.bc
4+
emscripten/jpeg-6b/

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,17 @@ Emscripten port of [ARToolKit](https://github.com/artoolkit/artoolkit5) to JavaS
2323
- or, set the `ARTOOLKIT5_ROOT` environment variable to point to your ARToolKit5 clone
2424
- or, change the `tools/makem.js` file to point to your artoolkit5 clone (line 62, 83, 107, 140)
2525

26-
3. Building
26+
3. Copy libjpeg-6b to emscripten/jpeg-6b
27+
- or, set the `LIBJPEG_ROOT` environment variable to point to your libjpeg source directory
28+
29+
4. Building
2730
1. Make sure `EMSCRIPTEN` env variable is set (e.g. `EMSCRIPTEN=/usr/lib/emsdk_portable/emscripten/master/ node tools/makem.js`
2831
2. Rename the `ARTOOLKIT5_ROOT/include/AR/config.h.in` file to `config.h`
2932
3. Run `npm run build`
3033

3134
During development, you can run ```npm run watch```, it will rebuild the library everytime you change ```./js/``` directory.
3235

33-
4. The built ASM.js files are in `/build`. There's a build with debug symbols in `artoolkit.debug.js` and the optimized build with bundled JS API in `artoolkit.min.js`.
36+
5. The built ASM.js files are in `/build`. There's a build with debug symbols in `artoolkit.debug.js` and the optimized build with bundled JS API in `artoolkit.min.js`.
3437

3538
# ARToolKit JS API
3639

build/artoolkit.debug.js

Lines changed: 115826 additions & 61760 deletions
Large diffs are not rendered by default.

build/artoolkit.min.js

Lines changed: 16 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

emscripten/ARBindEM.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ EMSCRIPTEN_BINDINGS(constant_bindings) {
77
function("setup", &setup);
88
function("teardown", &teardown);
99

10+
function("setupAR2", &setupAR2);
11+
1012
function("_addMarker", &addMarker);
1113
function("_addMultiMarker", &addMultiMarker);
14+
function("_addNFTMarker", &addNFTMarker);
1215

1316
function("getMultiMarkerNum", &getMultiMarkerNum);
1417
function("getMultiMarkerCount", &getMultiMarkerCount);
@@ -27,8 +30,11 @@ EMSCRIPTEN_BINDINGS(constant_bindings) {
2730
function("detectMarker", &detectMarker);
2831
function("getMarkerNum", &getMarkerNum);
2932

33+
function("detectNFTMarker", &detectNFTMarker);
34+
3035
function("getMultiEachMarker", &getMultiEachMarkerInfo);
3136
function("getMarker", &getMarkerInfo);
37+
function("getNFTMarker", &getNFTMarkerInfo);
3238

3339

3440
/* AR Toolkit C APIS */

emscripten/ARToolKitJS.cpp

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#include <vector>
99
#include <unordered_map>
1010
#include <AR/config.h>
11+
#include <AR/arFilterTransMat.h>
12+
#include <AR2/tracking.h>
13+
#include <KPM/kpm.h>
1114

1215
struct multi_marker {
1316
int id;
@@ -31,6 +34,12 @@ struct arController {
3134
ARMultiMarkerInfoT *arMultiMarkerHandle = NULL;
3235
AR3DHandle* ar3DHandle;
3336

37+
KpmHandle* kpmHandle;
38+
AR2HandleT* ar2Handle;
39+
40+
int surfaceSetCount = 0; // Running NFT marker id
41+
std::unordered_map<int, AR2SurfaceSetT*> surfaceSets;
42+
3443
ARdouble nearPlane = 0.0001;
3544
ARdouble farPlane = 1000.0;
3645

@@ -63,6 +72,212 @@ static ARMarkerInfo gMarkerInfo;
6372

6473
extern "C" {
6574

75+
/**
76+
NFT API bindings
77+
*/
78+
79+
int getNFTMarkerInfo(int id, int markerIndex) {
80+
if (arControllers.find(id) == arControllers.end()) { return ARCONTROLLER_NOT_FOUND; }
81+
arController *arc = &(arControllers[id]);
82+
83+
if (arc->surfaceSetCount <= markerIndex) {
84+
return MARKER_INDEX_OUT_OF_BOUNDS;
85+
}
86+
87+
KpmResult *kpmResult = NULL;
88+
int kpmResultNum = -1;
89+
90+
kpmGetResult( arc->kpmHandle, &kpmResult, &kpmResultNum );
91+
92+
int i, j, k;
93+
int flag = -1;
94+
float err = -1;
95+
float trans[3][4];
96+
for( i = 0; i < kpmResultNum; i++ ) {
97+
if (kpmResult[i].pageNo == markerIndex && kpmResult[i].camPoseF == 0 ) {
98+
if( flag == -1 || err > kpmResult[i].error ) { // Take the first or best result.
99+
flag = i;
100+
err = kpmResult[i].error;
101+
}
102+
}
103+
}
104+
105+
if (flag > -1) {
106+
for (j = 0; j < 3; j++) {
107+
for (k = 0; k < 4; k++) {
108+
trans[j][k] = kpmResult[flag].camPose[j][k];
109+
}
110+
}
111+
EM_ASM_({
112+
var $a = arguments;
113+
var i = 0;
114+
if (!artoolkit["NFTMarkerInfo"]) {
115+
artoolkit["NFTMarkerInfo"] = ({
116+
id: 0,
117+
error: -1,
118+
found: 0,
119+
pose: [0,0,0,0, 0,0,0,0, 0,0,0,0]
120+
});
121+
}
122+
var markerInfo = artoolkit["NFTMarkerInfo"];
123+
markerInfo["id"] = $a[i++];
124+
markerInfo["error"] = $a[i++];
125+
markerInfo["found"] = 1;
126+
markerInfo["pose"][0] = $a[i++];
127+
markerInfo["pose"][1] = $a[i++];
128+
markerInfo["pose"][2] = $a[i++];
129+
markerInfo["pose"][3] = $a[i++];
130+
markerInfo["pose"][4] = $a[i++];
131+
markerInfo["pose"][5] = $a[i++];
132+
markerInfo["pose"][6] = $a[i++];
133+
markerInfo["pose"][7] = $a[i++];
134+
markerInfo["pose"][8] = $a[i++];
135+
markerInfo["pose"][9] = $a[i++];
136+
markerInfo["pose"][10] = $a[i++];
137+
markerInfo["pose"][11] = $a[i++];
138+
},
139+
markerIndex,
140+
err,
141+
142+
trans[0][0],
143+
trans[0][1],
144+
trans[0][2],
145+
trans[0][3],
146+
147+
trans[1][0],
148+
trans[1][1],
149+
trans[1][2],
150+
trans[1][3],
151+
152+
trans[2][0],
153+
trans[2][1],
154+
trans[2][2],
155+
trans[2][3]
156+
);
157+
} else {
158+
EM_ASM_({
159+
var $a = arguments;
160+
var i = 0;
161+
if (!artoolkit["NFTMarkerInfo"]) {
162+
artoolkit["NFTMarkerInfo"] = ({
163+
id: 0,
164+
error: -1,
165+
found: 0,
166+
pose: [0,0,0,0, 0,0,0,0, 0,0,0,0]
167+
});
168+
}
169+
var markerInfo = artoolkit["NFTMarkerInfo"];
170+
markerInfo["id"] = $a[i++];
171+
markerInfo["error"] = -1;
172+
markerInfo["found"] = 0;
173+
markerInfo["pose"][0] = 0;
174+
markerInfo["pose"][1] = 0;
175+
markerInfo["pose"][2] = 0;
176+
markerInfo["pose"][3] = 0;
177+
markerInfo["pose"][4] = 0;
178+
markerInfo["pose"][5] = 0;
179+
markerInfo["pose"][6] = 0;
180+
markerInfo["pose"][7] = 0;
181+
markerInfo["pose"][8] = 0;
182+
markerInfo["pose"][9] = 0;
183+
markerInfo["pose"][10] = 0;
184+
markerInfo["pose"][11] = 0;
185+
},
186+
markerIndex
187+
);
188+
}
189+
190+
return 0;
191+
}
192+
193+
int detectNFTMarker(int id) {
194+
if (arControllers.find(id) == arControllers.end()) { return -1; }
195+
arController *arc = &(arControllers[id]);
196+
197+
KpmResult *kpmResult = NULL;
198+
int kpmResultNum = -1;
199+
200+
kpmMatching( arc->kpmHandle, arc->videoFrame );
201+
kpmGetResult( arc->kpmHandle, &kpmResult, &kpmResultNum );
202+
return kpmResultNum;
203+
}
204+
205+
KpmHandle *createKpmHandle(ARParamLT *cparamLT) {
206+
KpmHandle *kpmHandle;
207+
kpmHandle = kpmCreateHandle(cparamLT, AR_PIXEL_FORMAT_RGBA);
208+
return kpmHandle;
209+
}
210+
211+
int getKpmImageWidth(KpmHandle *kpmHandle) {
212+
return kpmHandleGetXSize(kpmHandle);
213+
}
214+
215+
int getKpmImageHeight(KpmHandle *kpmHandle) {
216+
return kpmHandleGetYSize(kpmHandle);
217+
}
218+
219+
int getKpmPixelSize(KpmHandle *kpmHandle) {
220+
return arUtilGetPixelSize(kpmHandleGetPixelFormat(kpmHandle));
221+
}
222+
223+
int setupAR2(int id) {
224+
if (arControllers.find(id) == arControllers.end()) { return -1; }
225+
arController *arc = &(arControllers[id]);
226+
227+
arc->kpmHandle = createKpmHandle(arc->paramLT);
228+
229+
return 0;
230+
}
231+
232+
int loadNFTMarker(arController *arc, int surfaceSetCount, const char* datasetPathname) {
233+
int i, pageNo;
234+
AR2SurfaceSetT *surfaceSet;
235+
KpmRefDataSet *refDataSet;
236+
237+
KpmHandle *kpmHandle = arc->kpmHandle;
238+
239+
refDataSet = NULL;
240+
241+
// Load KPM data.
242+
KpmRefDataSet *refDataSet2;
243+
ARLOGi("Reading %s.fset3\n", datasetPathname);
244+
if (kpmLoadRefDataSet(datasetPathname, "fset3", &refDataSet2) < 0 ) {
245+
ARLOGe("Error reading KPM data from %s.fset3\n", datasetPathname);
246+
pageNo = -1;
247+
return (FALSE);
248+
}
249+
pageNo = surfaceSetCount;
250+
ARLOGi(" Assigned page no. %d.\n", surfaceSetCount);
251+
if (kpmChangePageNoOfRefDataSet(refDataSet2, KpmChangePageNoAllPages, surfaceSetCount) < 0) {
252+
ARLOGe("Error: kpmChangePageNoOfRefDataSet\n");
253+
return (FALSE);
254+
}
255+
if (kpmMergeRefDataSet(&refDataSet, &refDataSet2) < 0) {
256+
ARLOGe("Error: kpmMergeRefDataSet\n");
257+
return (FALSE);
258+
}
259+
ARLOGi(" Done.\n");
260+
261+
// Load AR2 data.
262+
ARLOGi("Reading %s.fset\n", datasetPathname);
263+
264+
if ((surfaceSet = ar2ReadSurfaceSet(datasetPathname, "fset", NULL)) == NULL ) {
265+
ARLOGe("Error reading data from %s.fset\n", datasetPathname);
266+
}
267+
ARLOGi(" Done.\n");
268+
269+
arc->surfaceSets[surfaceSetCount] = surfaceSet;
270+
271+
if (kpmSetRefDataSet(kpmHandle, refDataSet) < 0) {
272+
ARLOGe("Error: kpmSetRefDataSet\n");
273+
return (FALSE);
274+
}
275+
kpmDeleteRefDataSet(&refDataSet);
276+
277+
ARLOGi("Loading of NFT data complete.\n");
278+
return (TRUE);
279+
}
280+
66281
/***************
67282
* Set Log Level
68283
****************/
@@ -186,6 +401,8 @@ extern "C" {
186401

187402
arglCameraFrustum(&((arc->paramLT)->param), arc->nearPlane, arc->farPlane, arc->cameraLens);
188403

404+
arc->kpmHandle = createKpmHandle(arc->paramLT);
405+
189406
return 0;
190407
}
191408

@@ -240,6 +457,22 @@ extern "C" {
240457
return arc->patt_id;
241458
}
242459

460+
int addNFTMarker(int id, std::string datasetPathname) {
461+
if (arControllers.find(id) == arControllers.end()) { return -1; }
462+
arController *arc = &(arControllers[id]);
463+
464+
// Load marker(s).
465+
int patt_id = arc->surfaceSetCount;
466+
if (!loadNFTMarker(arc, patt_id, datasetPathname.c_str())) {
467+
ARLOGe("ARToolKitJS(): Unable to set up NFT marker.\n");
468+
return -1;
469+
}
470+
471+
arc->surfaceSetCount++;
472+
473+
return patt_id;
474+
}
475+
243476
int addMultiMarker(int id, std::string patt_name) {
244477
if (arControllers.find(id) == arControllers.end()) { return -1; }
245478
arController *arc = &(arControllers[id]);

0 commit comments

Comments
 (0)