@webarkit/nft-marker-creator-app
Version:
NFt Marker Creator based on WebARKitLib, ported thanks to Emscripten
1,702 lines • 6.12 MB
JavaScript
var Module = typeof Module !== "undefined" ? Module : {};
(function () {
"use strict";
var scope;
if (typeof window !== "undefined") {
scope = window;
} else {
scope = self;
}
if (scope.artoolkit_wasm_url) {
var downloadWasm = function (url) {
return new Promise(function (resolve, reject) {
var wasmXHR = new XMLHttpRequest();
wasmXHR.open("GET", url, true);
wasmXHR.responseType = "arraybuffer";
wasmXHR.onload = function () {
resolve(wasmXHR.response);
};
wasmXHR.onerror = function () {
reject("error " + wasmXHR.status);
};
wasmXHR.send(null);
});
};
var wasm = downloadWasm(scope.artoolkit_wasm_url);
Module.instantiateWasm = function (imports, successCallback) {
console.log("instantiateWasm: instantiating synchronously");
wasm.then(function (wasmBinary) {
console.log("wasm download finished, begin instantiating");
var wasmInstantiate = WebAssembly.instantiate(
new Uint8Array(wasmBinary),
imports
)
.then(function (output) {
console.log("wasm instantiation succeeded");
successCallback(output.instance);
})
.catch(function (e) {
console.log("wasm instantiation failed! " + e);
});
});
return {};
};
}
var ARController = function (width, height, cameraPara) {
this.id = undefined;
var w = width,
h = height;
this.orientation = "landscape";
this.listeners = {};
if (typeof width !== "number") {
var image = width;
cameraPara = height;
w = image.videoWidth || image.width;
h = image.videoHeight || image.height;
this.image = image;
}
this.width = w;
this.height = h;
this.nftMarkerCount = 0;
this.defaultMarkerWidth = 1;
this.patternMarkers = {};
this.barcodeMarkers = {};
this.nftMarkers = {};
this.transform_mat = new Float32Array(16);
this.transformGL_RH = new Float64Array(16);
if (typeof document !== "undefined") {
this.canvas = document.createElement("canvas");
this.canvas.width = w;
this.canvas.height = h;
this.ctx = this.canvas.getContext("2d");
}
this.videoWidth = w;
this.videoHeight = h;
this.videoSize = this.videoWidth * this.videoHeight;
this.framepointer = null;
this.framesize = null;
this.dataHeap = null;
this.videoLuma = null;
this.camera_mat = null;
this.marker_transform_mat = null;
this.videoLumaPointer = null;
this._bwpointer = undefined;
this._lumaCtx = undefined;
if (typeof cameraPara === "string") {
this.cameraParam = new ARCameraParam(
cameraPara,
function () {
this._initialize();
}.bind(this),
function (err) {
console.error("ARController: Failed to load ARCameraParam", err);
this.onload(err);
}.bind(this)
);
} else {
this.cameraParam = cameraPara;
this._initialize();
}
};
ARController.prototype.dispose = function () {
if (this.id > -1) {
artoolkit.teardown(this.id);
}
if (this.image && this.image.srcObject) {
ARController._teardownVideo(this.image);
}
for (var t in this) {
this[t] = null;
}
};
ARController.prototype.process = function (image) {
var result = this.detectMarker(image);
if (result != 0) {
console.error("detectMarker error: " + result);
}
var markerNum = this.getMarkerNum();
var k, o;
for (k in this.patternMarkers) {
o = this.patternMarkers[k];
o.inPrevious = o.inCurrent;
o.inCurrent = false;
}
for (k in this.barcodeMarkers) {
o = this.barcodeMarkers[k];
o.inPrevious = o.inCurrent;
o.inCurrent = false;
}
for (k in this.nftMarkers) {
o = this.nftMarkers[k];
o.inPrevious = o.inCurrent;
o.inCurrent = false;
}
for (var i = 0; i < markerNum; i++) {
var markerInfo = this.getMarker(i);
var markerType = artoolkit.UNKNOWN_MARKER;
var visible = this.trackPatternMarkerId(-1);
if (
markerInfo.idPatt > -1 &&
(markerInfo.id === markerInfo.idPatt || markerInfo.idMatrix === -1)
) {
visible = this.trackPatternMarkerId(markerInfo.idPatt);
markerType = artoolkit.PATTERN_MARKER;
if (markerInfo.dir !== markerInfo.dirPatt) {
this.setMarkerInfoDir(i, markerInfo.dirPatt);
}
} else if (markerInfo.idMatrix > -1) {
visible = this.trackBarcodeMarkerId(markerInfo.idMatrix);
markerType = artoolkit.BARCODE_MARKER;
if (markerInfo.dir !== markerInfo.dirMatrix) {
this.setMarkerInfoDir(i, markerInfo.dirMatrix);
}
}
if (markerType !== artoolkit.UNKNOWN_MARKER && visible.inPrevious) {
this.getTransMatSquareCont(
i,
visible.markerWidth,
visible.matrix,
visible.matrix
);
} else {
this.getTransMatSquare(i, visible.markerWidth, visible.matrix);
}
visible.inCurrent = true;
this.transMatToGLMat(visible.matrix, this.transform_mat);
this.transformGL_RH = this.arglCameraViewRHf(this.transform_mat);
this.dispatchEvent({
name: "getMarker",
target: this,
data: {
index: i,
type: markerType,
marker: markerInfo,
matrix: this.transform_mat,
matrixGL_RH: this.transformGL_RH,
},
});
}
var nftMarkerCount = this.nftMarkerCount;
this.detectNFTMarker();
var MARKER_LOST_TIME = 200;
for (var i = 0; i < nftMarkerCount; i++) {
var nftMarkerInfo = this.getNFTMarker(i);
var markerType = artoolkit.NFT_MARKER;
if (nftMarkerInfo.found) {
self.markerFound = i;
self.markerFoundTime = Date.now();
var visible = this.trackNFTMarkerId(i);
visible.matrix.set(nftMarkerInfo.pose);
visible.inCurrent = true;
this.transMatToGLMat(visible.matrix, this.transform_mat);
this.transformGL_RH = this.arglCameraViewRHf(this.transform_mat);
this.dispatchEvent({
name: "getNFTMarker",
target: this,
data: {
index: i,
type: markerType,
marker: nftMarkerInfo,
matrix: this.transform_mat,
matrixGL_RH: this.transformGL_RH,
},
});
} else if (self.markerFound === i) {
if (Date.now() - self.markerFoundTime <= MARKER_LOST_TIME) {
return;
}
delete self.markerFound;
this.dispatchEvent({
name: "lostNFTMarker",
target: this,
data: {
index: i,
type: markerType,
marker: nftMarkerInfo,
matrix: this.transform_mat,
matrixGL_RH: this.transformGL_RH,
},
});
}
}
var multiMarkerCount = this.getMultiMarkerCount();
for (var i = 0; i < multiMarkerCount; i++) {
var subMarkerCount = this.getMultiMarkerPatternCount(i);
var visible = false;
artoolkit.getTransMatMultiSquareRobust(this.id, i);
this.transMatToGLMat(this.marker_transform_mat, this.transform_mat);
this.transformGL_RH = this.arglCameraViewRHf(this.transform_mat);
for (var j = 0; j < subMarkerCount; j++) {
var multiEachMarkerInfo = this.getMultiEachMarker(i, j);
if (multiEachMarkerInfo.visible >= 0) {
visible = true;
this.dispatchEvent({
name: "getMultiMarker",
target: this,
data: {
multiMarkerId: i,
matrix: this.transform_mat,
matrixGL_RH: this.transformGL_RH,
},
});
break;
}
}
if (visible) {
for (var j = 0; j < subMarkerCount; j++) {
var multiEachMarkerInfo = this.getMultiEachMarker(i, j);
this.transMatToGLMat(this.marker_transform_mat, this.transform_mat);
this.transformGL_RH = this.arglCameraViewRHf(this.transform_mat);
this.dispatchEvent({
name: "getMultiMarkerSub",
target: this,
data: {
multiMarkerId: i,
markerIndex: j,
marker: multiEachMarkerInfo,
matrix: this.transform_mat,
matrixGL_RH: this.transformGL_RH,
},
});
}
}
}
if (this._bwpointer) {
this.debugDraw();
}
};
ARController.prototype.detectNFTMarker = function () {
artoolkit.detectNFTMarker(this.id);
};
ARController.prototype.trackPatternMarkerId = function (id, markerWidth) {
var obj = this.patternMarkers[id];
if (!obj) {
this.patternMarkers[id] = obj = {
inPrevious: false,
inCurrent: false,
matrix: new Float64Array(12),
matrixGL_RH: new Float64Array(12),
markerWidth: markerWidth || this.defaultMarkerWidth,
};
}
if (markerWidth) {
obj.markerWidth = markerWidth;
}
return obj;
};
ARController.prototype.trackBarcodeMarkerId = function (id, markerWidth) {
var obj = this.barcodeMarkers[id];
if (!obj) {
this.barcodeMarkers[id] = obj = {
inPrevious: false,
inCurrent: false,
matrix: new Float64Array(12),
matrixGL_RH: new Float64Array(12),
markerWidth: markerWidth || this.defaultMarkerWidth,
};
}
if (markerWidth) {
obj.markerWidth = markerWidth;
}
return obj;
};
ARController.prototype.trackNFTMarkerId = function (id, markerWidth) {
var obj = this.nftMarkers[id];
if (!obj) {
this.nftMarkers[id] = obj = {
inPrevious: false,
inCurrent: false,
matrix: new Float64Array(12),
matrixGL_RH: new Float64Array(12),
markerWidth: markerWidth || this.defaultMarkerWidth,
};
}
if (markerWidth) {
obj.markerWidth = markerWidth;
}
return obj;
};
ARController.prototype.getMultiMarkerCount = function () {
return artoolkit.getMultiMarkerCount(this.id);
};
ARController.prototype.getMultiMarkerPatternCount = function (multiMarkerId) {
return artoolkit.getMultiMarkerNum(this.id, multiMarkerId);
};
ARController.prototype.addEventListener = function (name, callback) {
if (!this.listeners[name]) {
this.listeners[name] = [];
}
this.listeners[name].push(callback);
};
ARController.prototype.removeEventListener = function (name, callback) {
if (this.listeners[name]) {
var index = this.listeners[name].indexOf(callback);
if (index > -1) {
this.listeners[name].splice(index, 1);
}
}
};
ARController.prototype.dispatchEvent = function (event) {
var listeners = this.listeners[event.name];
if (listeners) {
for (var i = 0; i < listeners.length; i++) {
listeners[i].call(this, event);
}
}
};
ARController.prototype.debugSetup = function () {
document.body.appendChild(this.canvas);
var lumaCanvas = document.createElement("canvas");
lumaCanvas.width = this.canvas.width;
lumaCanvas.height = this.canvas.height;
this._lumaCtx = lumaCanvas.getContext("2d");
document.body.appendChild(lumaCanvas);
this.setDebugMode(true);
this._bwpointer = this.getProcessingImage();
};
ARController.prototype.loadMarker = function (markerURL, onSuccess, onError) {
if (markerURL) {
artoolkit.addMarker(this.id, markerURL, onSuccess, onError);
} else {
if (onError) {
onError("Marker URL needs to be defined and not equal empty string!");
} else {
console.error(
"Marker URL needs to be defined and not equal empty string!"
);
}
}
};
ARController.prototype.loadNFTMarker = function (
markerURL,
onSuccess,
onError
) {
var self = this;
if (markerURL) {
return artoolkit.addNFTMarker(
this.id,
markerURL,
function (id) {
self.nftMarkerCount = id + 1;
onSuccess(id);
},
onError
);
} else {
if (onError) {
onError("Marker URL needs to be defined and not equal empty string!");
} else {
console.error(
"Marker URL needs to be defined and not equal empty string!"
);
}
}
};
ARController.prototype.loadMultiMarker = function (
markerURL,
onSuccess,
onError
) {
return artoolkit.addMultiMarker(this.id, markerURL, onSuccess, onError);
};
ARController.prototype.getTransMatSquare = function (
markerUID,
markerWidth,
dst
) {
artoolkit.getTransMatSquare(this.id, markerUID, markerWidth);
dst.set(this.marker_transform_mat);
return dst;
};
ARController.prototype.getTransMatSquareCont = function (
markerUID,
markerWidth,
previousMarkerTransform,
dst
) {
this.marker_transform_mat.set(previousMarkerTransform);
artoolkit.getTransMatSquareCont(this.id, markerUID, markerWidth);
dst.set(this.marker_transform_mat);
return dst;
};
ARController.prototype.getTransMatMultiSquare = function (markerUID, dst) {
artoolkit.getTransMatMultiSquare(this.id, markerUID);
dst.set(this.marker_transform_mat);
return dst;
};
ARController.prototype.getTransMatMultiSquareRobust = function (
markerUID,
dst
) {
artoolkit.getTransMatMultiSquare(this.id, markerUID);
dst.set(this.marker_transform_mat);
return dst;
};
ARController.prototype.transMatToGLMat = function (transMat, glMat, scale) {
if (glMat == undefined) {
glMat = new Float64Array(16);
}
glMat[0 + 0 * 4] = transMat[0];
glMat[0 + 1 * 4] = transMat[1];
glMat[0 + 2 * 4] = transMat[2];
glMat[0 + 3 * 4] = transMat[3];
glMat[1 + 0 * 4] = transMat[4];
glMat[1 + 1 * 4] = transMat[5];
glMat[1 + 2 * 4] = transMat[6];
glMat[1 + 3 * 4] = transMat[7];
glMat[2 + 0 * 4] = transMat[8];
glMat[2 + 1 * 4] = transMat[9];
glMat[2 + 2 * 4] = transMat[10];
glMat[2 + 3 * 4] = transMat[11];
glMat[3 + 0 * 4] = 0;
glMat[3 + 1 * 4] = 0;
glMat[3 + 2 * 4] = 0;
glMat[3 + 3 * 4] = 1;
if (scale != undefined && scale !== 0) {
glMat[12] *= scale;
glMat[13] *= scale;
glMat[14] *= scale;
}
return glMat;
};
ARController.prototype.arglCameraViewRHf = function (
glMatrix,
glRhMatrix,
scale
) {
var m_modelview;
if (glRhMatrix == undefined) m_modelview = new Float64Array(16);
else m_modelview = glRhMatrix;
m_modelview[0] = glMatrix[0];
m_modelview[4] = glMatrix[4];
m_modelview[8] = glMatrix[8];
m_modelview[12] = glMatrix[12];
m_modelview[1] = -glMatrix[1];
m_modelview[5] = -glMatrix[5];
m_modelview[9] = -glMatrix[9];
m_modelview[13] = -glMatrix[13];
m_modelview[2] = -glMatrix[2];
m_modelview[6] = -glMatrix[6];
m_modelview[10] = -glMatrix[10];
m_modelview[14] = -glMatrix[14];
m_modelview[3] = 0;
m_modelview[7] = 0;
m_modelview[11] = 0;
m_modelview[15] = 1;
if (scale != undefined && scale !== 0) {
m_modelview[12] *= scale;
m_modelview[13] *= scale;
m_modelview[14] *= scale;
}
glRhMatrix = m_modelview;
return glRhMatrix;
};
ARController.prototype.detectMarker = function (image) {
if (this._copyImageToHeap(image)) {
return artoolkit.detectMarker(this.id);
}
return -99;
};
ARController.prototype.getMarkerNum = function () {
return artoolkit.getMarkerNum(this.id);
};
ARController.prototype.getMarker = function (markerIndex) {
if (0 === artoolkit.getMarker(this.id, markerIndex)) {
return artoolkit.markerInfo;
}
};
ARController.prototype.getNFTMarker = function (markerIndex) {
if (0 === artoolkit.getNFTMarker(this.id, markerIndex)) {
return artoolkit.NFTMarkerInfo;
}
};
ARController.prototype.setMarkerInfoVertex = function (
markerIndex,
vertexData
) {
for (var i = 0; i < vertexData.length; i++) {
this.marker_transform_mat[i * 2 + 0] = vertexData[i][0];
this.marker_transform_mat[i * 2 + 1] = vertexData[i][1];
}
return artoolkit.setMarkerInfoVertex(this.id, markerIndex);
};
ARController.prototype.cloneMarkerInfo = function (markerInfo) {
return JSON.parse(JSON.stringify(markerInfo));
};
ARController.prototype.getMultiEachMarker = function (
multiMarkerId,
markerIndex
) {
if (
0 === artoolkit.getMultiEachMarker(this.id, multiMarkerId, markerIndex)
) {
return artoolkit.multiEachMarkerInfo;
}
};
ARController.prototype.getTransformationMatrix = function () {
return this.transform_mat;
};
ARController.prototype.getCameraMatrix = function () {
return this.camera_mat;
};
ARController.prototype.getMarkerTransformationMatrix = function () {
return this.marker_transform_mat;
};
ARController.prototype.setDebugMode = function (mode) {
return artoolkit.setDebugMode(this.id, mode);
};
ARController.prototype.getDebugMode = function () {
return artoolkit.getDebugMode(this.id);
};
ARController.prototype.getProcessingImage = function () {
return artoolkit.getProcessingImage(this.id);
};
ARController.prototype.setLogLevel = function (mode) {
return artoolkit.setLogLevel(mode);
};
ARController.prototype.getLogLevel = function () {
return artoolkit.getLogLevel();
};
ARController.prototype.setMarkerInfoDir = function (markerIndex, dir) {
return artoolkit.setMarkerInfoDir(this.id, markerIndex, dir);
};
ARController.prototype.setProjectionNearPlane = function (value) {
return artoolkit.setProjectionNearPlane(this.id, value);
};
ARController.prototype.getProjectionNearPlane = function () {
return artoolkit.getProjectionNearPlane(this.id);
};
ARController.prototype.setProjectionFarPlane = function (value) {
return artoolkit.setProjectionFarPlane(this.id, value);
};
ARController.prototype.getProjectionFarPlane = function () {
return artoolkit.getProjectionFarPlane(this.id);
};
ARController.prototype.setThresholdMode = function (mode) {
return artoolkit.setThresholdMode(this.id, mode);
};
ARController.prototype.getThresholdMode = function () {
return artoolkit.getThresholdMode(this.id);
};
ARController.prototype.setThreshold = function (threshold) {
return artoolkit.setThreshold(this.id, threshold);
};
ARController.prototype.getThreshold = function () {
return artoolkit.getThreshold(this.id);
};
ARController.prototype.setPatternDetectionMode = function (mode) {
return artoolkit.setPatternDetectionMode(this.id, mode);
};
ARController.prototype.getPatternDetectionMode = function () {
return artoolkit.getPatternDetectionMode(this.id);
};
ARController.prototype.setMatrixCodeType = function (type) {
return artoolkit.setMatrixCodeType(this.id, type);
};
ARController.prototype.getMatrixCodeType = function () {
return artoolkit.getMatrixCodeType(this.id);
};
ARController.prototype.setLabelingMode = function (mode) {
return artoolkit.setLabelingMode(this.id, mode);
};
ARController.prototype.getLabelingMode = function () {
return artoolkit.getLabelingMode(this.id);
};
ARController.prototype.setPattRatio = function (pattRatio) {
return artoolkit.setPattRatio(this.id, pattRatio);
};
ARController.prototype.getPattRatio = function () {
return artoolkit.getPattRatio(this.id);
};
ARController.prototype.setImageProcMode = function (mode) {
return artoolkit.setImageProcMode(this.id, mode);
};
ARController.prototype.getImageProcMode = function () {
return artoolkit.getImageProcMode(this.id);
};
ARController.prototype.debugDraw = function () {
var debugBuffer = new Uint8ClampedArray(
Module.HEAPU8.buffer,
this._bwpointer,
this.framesize
);
var id = new ImageData(
new Uint8ClampedArray(this.canvas.width * this.canvas.height * 4),
this.canvas.width,
this.canvas.height
);
for (var i = 0, j = 0; i < debugBuffer.length; i++, j += 4) {
var v = debugBuffer[i];
id.data[j + 0] = v;
id.data[j + 1] = v;
id.data[j + 2] = v;
id.data[j + 3] = 255;
}
this.ctx.putImageData(id, 0, 0);
var lumaBuffer = new Uint8ClampedArray(this.framesize);
lumaBuffer.set(this.videoLuma);
var lumaImageData = new ImageData(
lumaBuffer,
this.videoWidth,
this.videoHeight
);
this._lumaCtx.putImageData(lumaImageData, 0, 0);
var marker_num = this.getMarkerNum();
for (var i = 0; i < marker_num; i++) {
this._debugMarker(this.getMarker(i));
}
if (this.transform_mat && this.transformGL_RH) {
console.log("GL 4x4 Matrix: " + this.transform_mat);
console.log("GL_RH 4x4 Mat: " + this.transformGL_RH);
}
};
ARController.prototype._initialize = function () {
this.id = artoolkit.setup(this.width, this.height, this.cameraParam.id);
this._initNFT();
var params = artoolkit.frameMalloc;
this.framepointer = params.framepointer;
this.framesize = params.framesize;
this.videoLumaPointer = params.videoLumaPointer;
this.dataHeap = new Uint8Array(
Module.HEAPU8.buffer,
this.framepointer,
this.framesize
);
this.videoLuma = new Uint8Array(
Module.HEAPU8.buffer,
this.videoLumaPointer,
this.framesize / 4
);
this.camera_mat = new Float64Array(Module.HEAPU8.buffer, params.camera, 16);
this.marker_transform_mat = new Float64Array(
Module.HEAPU8.buffer,
params.transform,
12
);
this.setProjectionNearPlane(0.1);
this.setProjectionFarPlane(1e3);
setTimeout(
function () {
if (this.onload) {
this.onload();
}
this.dispatchEvent({ name: "load", target: this });
}.bind(this),
1
);
};
ARController.prototype._initNFT = function () {
artoolkit.setupAR2(this.id);
};
ARController.prototype._copyImageToHeap = function (image) {
if (!image) {
image = this.image;
}
if (image.data) {
var imageData = image;
} else {
this.ctx.save();
if (this.orientation === "portrait") {
this.ctx.translate(this.canvas.width, 0);
this.ctx.rotate(Math.PI / 2);
this.ctx.drawImage(image, 0, 0, this.canvas.height, this.canvas.width);
} else {
this.ctx.drawImage(image, 0, 0, this.canvas.width, this.canvas.height);
}
this.ctx.restore();
var imageData = this.ctx.getImageData(
0,
0,
this.canvas.width,
this.canvas.height
);
}
var data = imageData.data;
if (this.videoLuma) {
var q = 0;
for (var p = 0; p < this.videoSize; p++) {
var r = data[q + 0],
g = data[q + 1],
b = data[q + 2];
this.videoLuma[p] = (r + r + r + b + g + g + g + g) >> 3;
q += 4;
}
}
if (this.dataHeap) {
this.dataHeap.set(data);
return true;
}
return false;
};
ARController.prototype._debugMarker = function (marker) {
var vertex, pos;
vertex = marker.vertex;
var ctx = this.ctx;
ctx.strokeStyle = "red";
ctx.beginPath();
ctx.moveTo(vertex[0][0], vertex[0][1]);
ctx.lineTo(vertex[1][0], vertex[1][1]);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(vertex[2][0], vertex[2][1]);
ctx.lineTo(vertex[3][0], vertex[3][1]);
ctx.stroke();
ctx.strokeStyle = "green";
ctx.beginPath();
ctx.lineTo(vertex[1][0], vertex[1][1]);
ctx.lineTo(vertex[2][0], vertex[2][1]);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(vertex[3][0], vertex[3][1]);
ctx.lineTo(vertex[0][0], vertex[0][1]);
ctx.stroke();
pos = marker.pos;
ctx.beginPath();
ctx.arc(pos[0], pos[1], 8, 0, Math.PI * 2);
ctx.fillStyle = "red";
ctx.fill();
};
ARController.getUserMedia = function (configuration) {
var facing = configuration.facingMode || "environment";
var onSuccess = configuration.onSuccess;
var onError =
configuration.onError ||
function (err) {
console.error("ARController.getUserMedia", err);
};
var video = document.createElement("video");
var readyToPlay = false;
var eventNames = [
"touchstart",
"touchend",
"touchmove",
"touchcancel",
"click",
"mousedown",
"mouseup",
"mousemove",
"keydown",
"keyup",
"keypress",
"scroll",
];
var play = function () {
if (readyToPlay) {
video
.play()
.then(function () {
onSuccess(video);
})
.catch(function (error) {
onError(error);
ARController._teardownVideo(video);
});
if (!video.paused) {
eventNames.forEach(function (eventName) {
window.removeEventListener(eventName, play, true);
});
}
}
};
eventNames.forEach(function (eventName) {
window.addEventListener(eventName, play, true);
});
var success = function (stream) {
if (window.URL.createObjectURL) {
try {
video.srcObject = stream;
} catch (ex) {}
}
video.srcObject = stream;
readyToPlay = true;
video.autoplay = true;
video.playsInline = true;
play();
};
var constraints = {};
var mediaDevicesConstraints = {};
if (configuration.width) {
mediaDevicesConstraints.width = configuration.width;
if (typeof configuration.width === "object") {
if (configuration.width.max) {
constraints.maxWidth = configuration.width.max;
}
if (configuration.width.min) {
constraints.minWidth = configuration.width.min;
}
} else {
constraints.maxWidth = configuration.width;
}
}
if (configuration.height) {
mediaDevicesConstraints.height = configuration.height;
if (typeof configuration.height === "object") {
if (configuration.height.max) {
constraints.maxHeight = configuration.height.max;
}
if (configuration.height.min) {
constraints.minHeight = configuration.height.min;
}
} else {
constraints.maxHeight = configuration.height;
}
}
mediaDevicesConstraints.facingMode = facing;
mediaDevicesConstraints.deviceId = configuration.deviceId;
navigator.getUserMedia =
navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
var hdConstraints = { audio: false, video: constraints };
if (navigator.mediaDevices || window.MediaStreamTrack.getSources) {
if (navigator.mediaDevices) {
navigator.mediaDevices
.getUserMedia({ audio: false, video: mediaDevicesConstraints })
.then(success, onError);
} else {
window.MediaStreamTrack.getSources(function (sources) {
var facingDir = mediaDevicesConstraints.facingMode;
if (facing && facing.exact) {
facingDir = facing.exact;
}
for (var i = 0; i < sources.length; i++) {
if (
sources[i].kind === "video" &&
sources[i].facing === facingDir
) {
hdConstraints.video.mandatory.sourceId = sources[i].id;
break;
}
}
if (
facing &&
facing.exact &&
!hdConstraints.video.mandatory.sourceId
) {
onError("Failed to get camera facing the wanted direction");
} else {
if (navigator.getUserMedia) {
navigator.getUserMedia(hdConstraints, success, onError);
} else {
onError(
"navigator.getUserMedia is not supported on your browser"
);
}
}
});
}
} else {
if (navigator.getUserMedia) {
navigator.getUserMedia(hdConstraints, success, onError);
} else {
onError("navigator.getUserMedia is not supported on your browser");
}
}
return video;
};
ARController.getUserMediaARController = function (configuration) {
var obj = {};
for (var i in configuration) {
obj[i] = configuration[i];
}
var onSuccess = configuration.onSuccess;
var cameraParamURL = configuration.cameraParam;
var onError =
configuration.onError ||
function (err) {
console.error("ARController: Failed to load ARCameraParam", err);
};
obj.onSuccess = function () {
new ARCameraParam(
cameraParamURL,
function () {
var arCameraParam = this;
var maxSize =
configuration.maxARVideoSize ||
Math.max(video.videoWidth, video.videoHeight);
var f = maxSize / Math.max(video.videoWidth, video.videoHeight);
var w = f * video.videoWidth;
var h = f * video.videoHeight;
if (video.videoWidth < video.videoHeight) {
var tmp = w;
w = h;
h = tmp;
}
var arController = new ARController(w, h, arCameraParam);
arController.image = video;
if (video.videoWidth < video.videoHeight) {
arController.orientation = "portrait";
arController.videoWidth = video.videoHeight;
arController.videoHeight = video.videoWidth;
} else {
arController.orientation = "landscape";
arController.videoWidth = video.videoWidth;
arController.videoHeight = video.videoHeight;
}
onSuccess(arController, arCameraParam);
},
function (err) {
ARController._teardownVideo(video);
onError(err);
}
);
};
var video = ARController.getUserMedia(obj);
return video;
};
ARController._teardownVideo = function (video) {
video.srcObject.getVideoTracks()[0].stop();
video.srcObject = null;
video.src = null;
};
var ARCameraParam = function (src, onload, onerror) {
this.id = -1;
this._src = "";
this.complete = false;
if (!onload) {
this.onload = function () {
console.log("Successfully loaded");
};
console.warn("onload callback should be defined");
} else {
this.onload = onload;
}
if (!onerror) {
this.onerror = function (err) {
console.error("Error: " + err);
};
console.warn("onerror callback should be defined");
} else {
this.onerror = onerror;
}
if (src) {
this.load(src);
} else {
console.warn(
"No camera parameter file defined! It should be defined in constructor or in ARCameraParam.load(url)"
);
}
};
ARCameraParam.prototype.load = function (src) {
if (this._src !== "") {
throw "ARCameraParam: Trying to load camera parameters twice.";
}
this._src = src;
if (src) {
artoolkit.loadCamera(
src,
function (id) {
this.id = id;
this.complete = true;
this.onload();
}.bind(this),
function (err) {
this.onerror(err);
}.bind(this)
);
}
};
Object.defineProperty(ARCameraParam.prototype, "src", {
set: function (src) {
this.load(src);
},
get: function () {
return this._src;
},
});
ARCameraParam.prototype.dispose = function () {
if (this.id !== -1) {
artoolkit.deleteCamera(this.id);
}
this.id = -1;
this._src = "";
this.complete = false;
};
var artoolkit = {
UNKNOWN_MARKER: -1,
PATTERN_MARKER: 0,
BARCODE_MARKER: 1,
NFT_MARKER: 2,
loadCamera: loadCamera,
addMarker: addMarker,
addMultiMarker: addMultiMarker,
addNFTMarker: addNFTMarker,
};
var FUNCTIONS = [
"setup",
"teardown",
"setupAR2",
"setLogLevel",
"getLogLevel",
"setDebugMode",
"getDebugMode",
"getProcessingImage",
"setMarkerInfoDir",
"setMarkerInfoVertex",
"getTransMatSquare",
"getTransMatSquareCont",
"getTransMatMultiSquare",
"getTransMatMultiSquareRobust",
"getMultiMarkerNum",
"getMultiMarkerCount",
"detectMarker",
"getMarkerNum",
"detectNFTMarker",
"getNFTMarker",
"getMarker",
"getMultiEachMarker",
"setProjectionNearPlane",
"getProjectionNearPlane",
"setProjectionFarPlane",
"getProjectionFarPlane",
"setThresholdMode",
"getThresholdMode",
"setThreshold",
"getThreshold",
"setPatternDetectionMode",
"getPatternDetectionMode",
"setMatrixCodeType",
"getMatrixCodeType",
"setLabelingMode",
"getLabelingMode",
"setPattRatio",
"getPattRatio",
"setImageProcMode",
"getImageProcMode",
];
function runWhenLoaded() {
FUNCTIONS.forEach(function (n) {
artoolkit[n] = Module[n];
});
for (var m in Module) {
if (m.match(/^AR/)) artoolkit[m] = Module[m];
}
}
var marker_count = 0;
function addMarker(arId, url, callback, onError) {
var filename = "/marker_" + marker_count++;
ajax(
url,
filename,
function () {
var id = Module._addMarker(arId, filename);
if (callback) callback(id);
},
function (errorNumber) {
if (onError) onError(errorNumber);
}
);
}
function addNFTMarker(arId, url, callback, onError) {
var mId = marker_count++;
var prefix = "/markerNFT_" + mId;
var filename1 = prefix + ".fset";
var filename2 = prefix + ".iset";
var filename3 = prefix + ".fset3";
ajax(
url + ".fset",
filename1,
function () {
ajax(
url + ".iset",
filename2,
function () {
ajax(
url + ".fset3",
filename3,
function () {
var id = Module._addNFTMarker(arId, prefix);
if (callback) callback(id);
},
function (errorNumber) {
if (onError) onError(errorNumber);
}
);
},
function (errorNumber) {
if (onError) onError(errorNumber);
}
);
},
function (errorNumber) {
if (onError) onError(errorNumber);
}
);
}
function bytesToString(array) {
return String.fromCharCode.apply(String, array);
}
function parseMultiFile(bytes) {
var str = bytesToString(bytes);
var lines = str.split("\n");
var files = [];
var state = 0;
var markers = 0;
lines.forEach(function (line) {
line = line.trim();
if (!line || line.startsWith("#")) return;
switch (state) {
case 0:
markers = +line;
state = 1;
return;
case 1:
if (!line.match(/^\d+$/)) {
files.push(line);
}
case 2:
case 3:
case 4:
state++;
return;
case 5:
state = 1;
return;
}
});
return files;
}
var multi_marker_count = 0;
function addMultiMarker(arId, url, callback, onError) {
var filename = "/multi_marker_" + multi_marker_count++;
ajax(
url,
filename,
function (bytes) {
var files = parseMultiFile(bytes);
function ok() {
var markerID = Module._addMultiMarker(arId, filename);
var markerNum = Module.getMultiMarkerNum(arId, markerID);
if (callback) callback(markerID, markerNum);
}
if (!files.length) return ok();
var path = url.split("/").slice(0, -1).join("/");
files = files.map(function (file) {
return [path + "/" + file, file];
});
ajaxDependencies(files, ok);
},
function (error) {
if (onError) onError(error);
}
);
}
var camera_count = 0;
function loadCamera(url, callback, errorCallback) {
var filename = "/camera_param_" + camera_count++;
var writeCallback = function (errorCode) {
if (!Module._loadCamera) {
if (callback) callback(id);
setTimeout(writeCallback, 10);
} else {
var id = Module._loadCamera(filename);
if (callback) callback(id);
}
};
if (typeof url === "object") {
writeByteArrayToFS(filename, url, writeCallback);
} else if (url.indexOf("\n") > -1) {
writeStringToFS(filename, url, writeCallback);
} else {
ajax(url, filename, writeCallback, errorCallback);
}
}
function writeStringToFS(target, string, callback) {
var byteArray = new Uint8Array(string.length);
for (var i = 0; i < byteArray.length; i++) {
byteArray[i] = string.charCodeAt(i) & 255;
}
writeByteArrayToFS(target, byteArray, callback);
}
function writeByteArrayToFS(target, byteArray, callback) {
FS.writeFile(target, byteArray, { encoding: "binary" });
callback(byteArray);
}
function ajax(url, target, callback, errorCallback) {
var oReq = new XMLHttpRequest();
oReq.open("GET", url, true);
oReq.responseType = "arraybuffer";
oReq.onload = function () {
if (this.status == 200) {
var arrayBuffer = oReq.response;
var byteArray = new Uint8Array(arrayBuffer);
writeByteArrayToFS(target, byteArray, callback);
} else {
errorCallback(this.status);
}
};
oReq.send();
}
function ajaxDependencies(files, callback) {
var next = files.pop();
if (next) {
ajax(next[0], next[1], function () {
ajaxDependencies(files, callback);
});
} else {
callback();
}
}
scope.artoolkit = artoolkit;
scope.ARController = ARController;
scope.ARCameraParam = ARCameraParam;
if (scope.artoolkit_wasm_url) {
scope.Module = Module;
}
if (scope.Module) {
scope.Module.onRuntimeInitialized = function () {
runWhenLoaded();
var event = new Event("artoolkit-loaded");
scope.dispatchEvent(event);
};
} else {
scope.Module = {
onRuntimeInitialized: function () {
runWhenLoaded();
},
};
}
})();
var moduleOverrides = {};
var key;
for (key in Module) {
if (Module.hasOwnProperty(key)) {
moduleOverrides[key] = Module[key];
}
}
var arguments_ = [];
var thisProgram = "./this.program";
var quit_ = function (status, toThrow) {
throw toThrow;
};
var ENVIRONMENT_IS_WEB = false;
var ENVIRONMENT_IS_WORKER = false;
var ENVIRONMENT_IS_NODE = false;
var ENVIRONMENT_HAS_NODE = false;
var ENVIRONMENT_IS_SHELL = false;
ENVIRONMENT_IS_WEB = typeof window === "object";
ENVIRONMENT_IS_WORKER = typeof importScripts === "function";
ENVIRONMENT_HAS_NODE =
typeof process === "object" &&
typeof process.versions === "object" &&
typeof process.versions.node === "string";
ENVIRONMENT_IS_NODE =
ENVIRONMENT_HAS_NODE && !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_WORKER;
ENVIRONMENT_IS_SHELL =
!ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
var scriptDirectory = "";
function locateFile(path) {
if (Module["locateFile"]) {
return Module["locateFile"](path, scriptDirectory);
}
return scriptDirectory + path;
}
var read_, readAsync, readBinary, setWindowTitle;
var nodeFS;
var nodePath;
if (ENVIRONMENT_IS_NODE) {
scriptDirectory = __dirname + "/";
read_ = function shell_read(filename, binary) {
var ret = tryParseAsDataURI(filename);
if (ret) {
return binary ? ret : ret.toString();
}
if (!nodeFS) nodeFS = require("fs");
if (!nodePath) nodePath = require("path");
filename = nodePath["normalize"](filename);
return nodeFS["readFileSync"](filename, binary ? null : "utf8");
};
readBinary = function readBinary(filename) {
var ret = read_(filename, true);
if (!ret.buffer) {
ret = new Uint8Array(ret);
}
assert(ret.buffer);
return ret;
};
if (process["argv"].length > 1) {
thisProgram = process["argv"][1].replace(/\\/g, "/");
}
arguments_ = process["argv"].slice(2);
if (typeof module !== "undefined") {
module["exports"] = Module;
}
process["on"]("uncaughtException", function (ex) {
if (!(ex instanceof ExitStatus)) {
throw ex;
}
});
process["on"]("unhandledRejection", abort);
quit_ = function (status) {
process["exit"](status);
};
Module["inspect"] = function () {
return "[Emscripten Module object]";
};
} else if (ENVIRONMENT_IS_SHELL) {
if (typeof read != "undefined") {
read_ = function shell_read(f) {
var data = tryParseAsDataURI(f);
if (data) {
return intArrayToString(data);
}
return read(f);
};
}
readBinary = function readBinary(f) {
var data;
data = tryParseAsDataURI(f);
if (data) {
return data;
}
if (typeof readbuffer === "function") {
return new Uint8Array(readbuffer(f));
}
data = read(f, "binary");
assert(typeof data === "object");
return data;
};
if (typeof scriptArgs != "undefined") {
arguments_ = scriptArgs;
} else if (typeof arguments != "undefined") {
arguments_ = arguments;
}
if (typeof quit === "function") {
quit_ = function (status) {
quit(status);
};
}
if (typeof print !== "undefined") {
if (typeof console === "undefined") console = {};
console.log = print;
console.warn = console.error =
typeof printErr !== "undefined" ? printErr : print;
}
} else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
if (ENVIRONMENT_IS_WORKER) {
scriptDirectory = self.location.href;
} else if (document.currentScript) {
scriptDirectory = document.currentScript.src;
}
if (scriptDirectory.indexOf("blob:") !== 0) {
scriptDirectory = scriptDirectory.substr(
0,
scriptDirectory.lastIndexOf("/") + 1
);
} else {
scriptDirectory = "";
}
{
read_ = function shell_read(url) {
try {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.send(null);
return xhr.responseText;
} catch (err) {
var data = tryParseAsDataURI(url);
if (data) {
return intArrayToString(data);
}
throw err;
}
};
if (ENVIRONMENT_IS_WORKER) {
readBinary = function readBinary(url) {
try {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
xhr.responseType = "arraybuffer";
xhr.send(null);
return new Uint8Array(xhr.response);
} catch (err) {
var data = tryParseAsDataURI(url);
if (data) {
return data;
}
throw err;
}
};
}
readAsync = function readAsync(url, onload, onerror) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "arraybuffer";
xhr.onload = function xhr_onload() {
if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) {
onload(xhr.response);
return;
}
var data = tryParseAsDataURI(url);
if (data) {
onload(data.buffer);
return;
}
onerror();
};
xhr.onerror = onerror;
xhr.send(null);
};
}
setWindowTitle = function (title) {
document.title = title;
};
} else {
}
var out = Module["print"] || console.log.bind(console);
var err = Module["printErr"] || console.warn.bind(console);
for (key in moduleOverrides) {
if (moduleOverrides.hasOwnProperty(key)) {
Module[key] = moduleOverrides[key];
}
}
moduleOverrides = null;
if (Module["arguments"]) arguments_ = Module["arguments"];
if (Module["thisProgram"]) thisProgram = Module["thisProgram"];
if (Module["quit"]) quit_ = Module["quit"];
var STACK_ALIGN = 16;
function dynamicAlloc(size) {
var ret = HEAP32[DYNAMICTOP_PTR >> 2];
var end = (ret + size + 15) & -16;
if (end > _emscripten_get_heap_size()) {
abort();
}
HEAP32[DYNAMICTOP_PTR >> 2] = end;
return ret;
}
function getNativeTypeSize(type) {
switch (type) {
case "i1":
case "i8":
return 1;
case "i16":
return 2;
case "i32":
return 4;
case "i64":
return 8;
case "float":
return 4;
case "double":
return 8;
default: {
if (type[type.length - 1] === "*") {
return 4;
} else if (type[0] === "i") {
var bits = parseInt(type.substr(1));
assert(
bits % 8 === 0,
"getNativeTypeSize invalid bits " + bits + ", type " + type
);
return bits / 8;
} else {
return 0;
}
}
}
}
function warnOnce(text) {
if (!warnOnce.shown) warnOnce.shown = {};
if (!warnOnce.shown[text]) {
warnOnce.shown[text] = 1;
err(text);
}
}
var jsCallStartIndex = 1;
var functionPointers = new Array(0);
var funcWrappers = {};
function dynCall(sig, ptr, args) {
if (args && args.length) {
return Module["dynCall_" + sig].apply(null, [ptr].concat(args));
} else {
return Module["dynCall_" + sig].call(null, ptr);
}
}
var tempRet0 = 0;
var setTempRet0 = function (value) {
tempRet0 = value;
};
var getTempRet0 = function () {
return tempRet0;
};
var GLOBAL_BASE = 8;
var wasmBinary;
if (Module["wasmBinary"]) wasmBinary = Module["wasmBinary"];
var noExitRuntime;
if (Module["noExitRuntime"]) noExitRuntime = Module["noExitRuntime"];
function setValue(ptr, value, type, noSafe) {
type = type || "i8";
if (type.charAt(type.length - 1) === "*") type = "i32";
switch (type) {
case "i1":
HEAP8[ptr >> 0] = value;
break;
case "i8":
HEAP8[ptr >> 0] = value;
break;
case "i16":
HEAP16[ptr >> 1] = value;
break;
case "i32":
HEAP32[ptr >> 2] = value;
break;
case "i64":
(tempI64 = [
value >>> 0,
((tempDouble = value),
+Math_abs(tempDouble) >= +1
? tempDouble > +0
? (Math_min(+Math_floor(tempDouble / +4294967296), +4294967295) |
0) >>>
0
: ~~+Math_ceil(
(tempDouble - +(~~tempDouble >>> 0)) / +4294967296
) >>> 0
: 0),
]),
(HEAP32[ptr >> 2] = tempI64[0]),
(HEAP32[(ptr + 4) >> 2] = tempI64[1]);
break;
case "float":
HEAPF32[ptr >> 2] = value;
break;
case "double":
HEAPF64[ptr >> 3] = value;
break;
default:
abort("invalid type for setValue: " + type);
}
}
var ABORT = false;
var EXITSTATUS = 0;
function assert(condition, text) {
if (!condition) {
abort("Assertion failed: " + text);
}
}
function getCFunc(ident) {
var func = Module["_" + ident];
assert(
func,
"Cannot call unknown function " + ident + ", make sure it is exported"
);
return func;
}
function ccall(ident, returnType, argTypes, args, opts) {
var toC = {
string: function (str) {
var ret = 0;
if (str !== null && str !== undefined && str !== 0) {
var len = (str.length << 2) + 1;
ret = stackAlloc(len);
stringToUTF8(str, ret, len);
}
return ret;
},
array: function (arr) {
var ret = stackAlloc(arr.length);
writeArrayToMemory(arr, ret);
return ret;
},
};
function convertReturnValue(ret) {
if (returnType === "string") return UTF8ToString(ret);
if (returnType === "boolean") return Boolean(ret);
return ret;
}
var func = getCFunc(ident);
var cArgs = [];
var stack = 0;
if (args) {
for (var i = 0; i < args.length; i++) {
var converter = toC[argTypes[i]];
if (converter) {
if (stack === 0) stack = stackSave();
cArgs[i] = converter(args[i]);
} else {
cArgs[i] = args[i];
}
}
}
var ret = func.apply(null, cArgs);
ret = convertReturnValue(ret);
if (stack !== 0) stackRestore(stack);
return ret;
}
var ALLOC_NORMAL = 0;
var ALLOC_NONE = 3;
function allocate(slab, types, allocator, ptr) {
var zeroinit, size;
if (typeof slab === "number") {
zeroinit = true;
size = slab;
} else {
zeroinit = false;
size = slab.length;
}
var singleType = typeof types === "string" ? types : null;
var ret;
if (allocator == ALLOC_NONE) {
ret = ptr;
} else {
ret = [_malloc, stackAlloc, dynamicAlloc][allocator](
Math.max(size, singleType ? 1 : types.length)
);
}
if (zeroinit) {
var stop;
ptr = ret;
assert((ret & 3) == 0);
stop = ret + (size & ~3);
for (; ptr < stop; ptr += 4) {
HEAP32[ptr >> 2] = 0;
}
stop = ret + size;
while (ptr < stop) {
HEAP8[ptr++ >> 0] = 0;
}
return ret;
}
if (singleType === "i8") {
if (slab.subarray || slab.slice) {
HEAPU8.set(slab, ret);
} else {
HEAPU8.set(new Uint8Array(slab), ret);
}
return ret;
}
var i = 0,
type,
typeSize,
previousType;
while (i < size) {
var curr = slab[i];
type = singleType || types[i];
if (type === 0) {
i++;
continue;
}
if (type == "i64") type = "i32";
setValue(ret + i, curr, type);
if (previousType !== type) {
typeSize = getNativeTypeSize(type);
previousType = type;
}
i += typeSize;
}
return ret;
}
function getMemory(size) {
if (!runtimeInitialized) return dynamicAlloc(size);
return _malloc(size);
}
var UTF8Decoder =
typeof TextDecoder !== "undefined" ? new TextDecoder("utf8") : undefined;
function UTF8ArrayToString(u8Array, idx, maxBytesToRead) {
var endIdx = idx + maxBytesToRead;
var endPtr = idx;
while (u8Array[endPtr] && !(endPtr >= endIdx)) ++endPtr;
if (endPtr - idx > 16 && u8Array.subarray && UTF8Decoder) {
return UTF8Decoder.decode(u8Array.sub