@zappar/zappar-cv 2.0.0-beta.3 → 2.0.0-beta.7

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/README.md CHANGED
@@ -18,8 +18,8 @@ npm i @zappar/zappar-cv
18
18
 
19
19
  You can use our CDN from within your HTML:
20
20
  ```
21
- <script src="https://libs.zappar.com/zappar-cv/2.0.0-beta.3/zappar-cv.js"></script>
21
+ <script src="https://libs.zappar.com/zappar-cv/2.0.0-beta.7/zappar-cv.js"></script>
22
22
  ```
23
23
 
24
24
  Or you can download and host our standalone JavaScript bundle:
25
- [https://libs.zappar.com/zappar-cv/2.0.0-beta.3/zappar-cv.zip](https://libs.zappar.com/zappar-cv/2.0.0-beta.3/zappar-cv.zip)
25
+ [https://libs.zappar.com/zappar-cv/2.0.0-beta.7/zappar-cv.zip](https://libs.zappar.com/zappar-cv/2.0.0-beta.7/zappar-cv.zip)
@@ -6,6 +6,7 @@ export interface Additional {
6
6
  pipeline_gl_context_set(pipeline: zappar_pipeline_t, gl: WebGLRenderingContext, texturePool?: WebGLTexture[]): void;
7
7
  pipeline_gl_context_lost(pipeline: zappar_pipeline_t): void;
8
8
  pipeline_draw_face(pipeline: zappar_pipeline_t, projectionMatrix: Float32Array, cameraMatrix: Float32Array, targetMatrix: Float32Array, o: zappar_face_mesh_t): void;
9
+ pipeline_draw_image_target_preview(pipeline: zappar_pipeline_t, projectionMatrix: Float32Array, cameraMatrix: Float32Array, targetMatrix: Float32Array, o: zappar_image_tracker_t, indx: number): void;
9
10
  pipeline_draw_face_project(pipeline: zappar_pipeline_t, drawwMatrix: Float32Array, vertices: Float32Array, uvMatrix: Float32Array, uvs: Float32Array, indices: Uint16Array, texture: WebGLTexture): void;
10
11
  draw_plane(gl: WebGLRenderingContext, projectionMatrix: Float32Array, cameraMatrix: Float32Array, targetMatrix: Float32Array, texture: string): void;
11
12
  image_tracker_target_image(o: zappar_image_tracker_t, indx: number): HTMLImageElement | undefined;
package/lib/drawplane.js CHANGED
@@ -63,6 +63,7 @@ export function drawPlane(gl, projectionMatrix, cameraMatrix, targetMatrix, text
63
63
  gl.enableVertexAttribArray(shader.attr_textureCoord);
64
64
  gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
65
65
  gl.disableVertexAttribArray(shader.attr_position);
66
+ gl.disableVertexAttribArray(shader.attr_textureCoord);
66
67
  gl.bindBuffer(gl.ARRAY_BUFFER, null);
67
68
  }
68
69
  function generateLocalMatrix() {
@@ -0,0 +1,16 @@
1
+ import { ImageTracker } from "./imagetracker";
2
+ export declare class PreviewMeshDraw {
3
+ private _gl;
4
+ private _vbo;
5
+ private _uvbo;
6
+ private _ibo;
7
+ private _lastIndices;
8
+ private _shader;
9
+ constructor(_gl: WebGLRenderingContext);
10
+ dispose(): void;
11
+ private _generateIBO;
12
+ private _generateVBO;
13
+ private _generateUVBO;
14
+ draw(matrix: Float32Array, tracker: ImageTracker, indx: number): void;
15
+ private _getShader;
16
+ }
@@ -0,0 +1,186 @@
1
+ import { compileShader, linkProgram } from "./shader";
2
+ export class PreviewMeshDraw {
3
+ constructor(_gl) {
4
+ this._gl = _gl;
5
+ }
6
+ dispose() {
7
+ if (this._vbo)
8
+ this._gl.deleteBuffer(this._vbo);
9
+ if (this._uvbo)
10
+ this._gl.deleteBuffer(this._uvbo);
11
+ if (this._ibo)
12
+ this._gl.deleteBuffer(this._ibo);
13
+ if (this._shader)
14
+ this._gl.deleteProgram(this._shader.prog);
15
+ this._vbo = undefined;
16
+ this._uvbo = undefined;
17
+ this._ibo = undefined;
18
+ this._shader = undefined;
19
+ }
20
+ _generateIBO(indices, gl) {
21
+ if (this._ibo && this._lastIndices === indices)
22
+ return this._ibo;
23
+ this._lastIndices = indices;
24
+ if (!this._ibo)
25
+ this._ibo = gl.createBuffer();
26
+ if (!this._ibo)
27
+ throw new Error("Unable to create buffer object");
28
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._ibo);
29
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
30
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
31
+ return this._ibo;
32
+ }
33
+ _generateVBO(face, gl) {
34
+ if (!this._vbo)
35
+ this._vbo = gl.createBuffer();
36
+ if (!this._vbo)
37
+ throw new Error("Unable to create buffer object");
38
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._vbo);
39
+ gl.bufferData(gl.ARRAY_BUFFER, face, gl.STATIC_DRAW);
40
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
41
+ return this._vbo;
42
+ }
43
+ _generateUVBO(face, gl) {
44
+ if (!this._uvbo)
45
+ this._uvbo = gl.createBuffer();
46
+ if (!this._uvbo)
47
+ throw new Error("Unable to create buffer object");
48
+ gl.bindBuffer(gl.ARRAY_BUFFER, this._uvbo);
49
+ gl.bufferData(gl.ARRAY_BUFFER, face, gl.STATIC_DRAW);
50
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
51
+ return this._uvbo;
52
+ }
53
+ draw(matrix, tracker, indx) {
54
+ var _a;
55
+ const o = tracker.getPreviewMesh(indx);
56
+ const image = (_a = tracker.getTargetInfo(indx).preview) === null || _a === void 0 ? void 0 : _a.image;
57
+ if (!o || !image)
58
+ return;
59
+ if (!image.complete)
60
+ return;
61
+ let gl = this._gl;
62
+ let shader = this._getShader(gl);
63
+ let v = this._generateVBO(o.vertices, gl);
64
+ let n = this._generateUVBO(o.uvs, gl);
65
+ let i = this._generateIBO(o.indices, gl);
66
+ gl.enable(gl.DEPTH_TEST);
67
+ gl.enable(gl.CULL_FACE);
68
+ gl.useProgram(shader.prog);
69
+ gl.uniformMatrix4fv(shader.unif_matrix, false, matrix);
70
+ gl.activeTexture(gl.TEXTURE0);
71
+ gl.bindTexture(gl.TEXTURE_2D, loadTexture(gl, image));
72
+ gl.uniform1i(shader.unif_skinSampler, 0);
73
+ gl.bindBuffer(gl.ARRAY_BUFFER, v);
74
+ gl.vertexAttribPointer(shader.attr_position, 3, gl.FLOAT, false, 0, 0);
75
+ gl.enableVertexAttribArray(shader.attr_position);
76
+ gl.bindBuffer(gl.ARRAY_BUFFER, n);
77
+ gl.vertexAttribPointer(shader.attr_textureCoord, 2, gl.FLOAT, false, 0, 0);
78
+ gl.enableVertexAttribArray(shader.attr_textureCoord);
79
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, i);
80
+ gl.drawElements(gl.TRIANGLES, o.indices.length, gl.UNSIGNED_SHORT, 0);
81
+ gl.disableVertexAttribArray(shader.attr_position);
82
+ gl.disableVertexAttribArray(shader.attr_textureCoord);
83
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
84
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
85
+ }
86
+ _getShader(gl) {
87
+ if (this._shader)
88
+ return this._shader;
89
+ let prog = gl.createProgram();
90
+ if (!prog)
91
+ throw new Error("Unable to create program");
92
+ let vertexShader = compileShader(gl, gl.VERTEX_SHADER, vertexShaderSrc);
93
+ let fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSrc);
94
+ gl.attachShader(prog, vertexShader);
95
+ gl.attachShader(prog, fragmentShader);
96
+ linkProgram(gl, prog);
97
+ let unif_matrix = gl.getUniformLocation(prog, "matrix");
98
+ if (!unif_matrix)
99
+ throw new Error("Unable to get uniform location mattrix");
100
+ let unif_skinSampler = gl.getUniformLocation(prog, "skinSampler");
101
+ if (!unif_skinSampler)
102
+ throw new Error("Unable to get uniform location skinSampler");
103
+ this._shader = {
104
+ prog,
105
+ unif_matrix,
106
+ unif_skinSampler,
107
+ attr_position: gl.getAttribLocation(prog, "position"),
108
+ attr_textureCoord: gl.getAttribLocation(prog, "textureCoord")
109
+ };
110
+ return this._shader;
111
+ }
112
+ }
113
+ const texturesByElement = new Map();
114
+ function loadTexture(gl, elm) {
115
+ let existing = texturesByElement.get(elm);
116
+ if (existing)
117
+ return existing;
118
+ existing = gl.createTexture() || undefined;
119
+ if (!existing)
120
+ throw new Error("Unable to create texture");
121
+ texturesByElement.set(elm, existing);
122
+ gl.bindTexture(gl.TEXTURE_2D, existing);
123
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
124
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
125
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
126
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
127
+ // Because images have to be download over the internet
128
+ // they might take a moment until they are ready.
129
+ // Until then put a single pixel in the texture so we can
130
+ // use it immediately. When the image has finished downloading
131
+ // we'll update the texture with the contents of the image.
132
+ const level = 0;
133
+ const internalFormat = gl.RGBA;
134
+ const srcFormat = gl.RGBA;
135
+ const srcType = gl.UNSIGNED_BYTE;
136
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
137
+ gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, elm);
138
+ elm.addEventListener("load", () => {
139
+ if (!existing)
140
+ return;
141
+ gl.bindTexture(gl.TEXTURE_2D, existing);
142
+ const level = 0;
143
+ const internalFormat = gl.RGBA;
144
+ const srcFormat = gl.RGBA;
145
+ const srcType = gl.UNSIGNED_BYTE;
146
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
147
+ gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, elm);
148
+ });
149
+ return existing;
150
+ }
151
+ let vertexShaderSrc = `
152
+ #ifndef GL_ES
153
+ #define highp
154
+ #define mediump
155
+ #define lowp
156
+ #endif
157
+
158
+ uniform mat4 matrix;
159
+ attribute vec4 position;
160
+ attribute vec2 textureCoord;
161
+
162
+ varying highp vec2 vTextureCoord;
163
+
164
+ void main()
165
+ {
166
+ gl_Position = matrix * position;
167
+ vTextureCoord = textureCoord;
168
+ }`;
169
+ let fragmentShaderSrc = `
170
+ #define highp mediump
171
+ #ifdef GL_ES
172
+ // define default precision for float, vec, mat.
173
+ precision highp float;
174
+ #else
175
+ #define highp
176
+ #define mediump
177
+ #define lowp
178
+ #endif
179
+
180
+ varying highp vec2 vTextureCoord;
181
+ uniform sampler2D skinSampler;
182
+
183
+ void main()
184
+ {
185
+ gl_FragColor = texture2D(skinSampler, vTextureCoord);
186
+ }`;
@@ -56,6 +56,11 @@ export declare enum frame_pixel_format_t {
56
56
  FRAME_PIXEL_FORMAT_BGRA = 6,
57
57
  FRAME_PIXEL_FORMAT_Y = 7
58
58
  }
59
+ export declare enum image_target_type_t {
60
+ IMAGE_TRACKER_TYPE_PLANAR = 0,
61
+ IMAGE_TRACKER_TYPE_CYLINDRICAL = 1,
62
+ IMAGE_TRACKER_TYPE_CONICAL = 2
63
+ }
59
64
  export declare type zappar_pipeline_t = number & {
60
65
  _: 'zappar_pipeline_t';
61
66
  };
@@ -66,3 +66,10 @@ export var frame_pixel_format_t;
66
66
  frame_pixel_format_t[frame_pixel_format_t["FRAME_PIXEL_FORMAT_Y"] = 7] = "FRAME_PIXEL_FORMAT_Y";
67
67
  })(frame_pixel_format_t || (frame_pixel_format_t = {}));
68
68
  ;
69
+ export var image_target_type_t;
70
+ (function (image_target_type_t) {
71
+ image_target_type_t[image_target_type_t["IMAGE_TRACKER_TYPE_PLANAR"] = 0] = "IMAGE_TRACKER_TYPE_PLANAR";
72
+ image_target_type_t[image_target_type_t["IMAGE_TRACKER_TYPE_CYLINDRICAL"] = 1] = "IMAGE_TRACKER_TYPE_CYLINDRICAL";
73
+ image_target_type_t[image_target_type_t["IMAGE_TRACKER_TYPE_CONICAL"] = 2] = "IMAGE_TRACKER_TYPE_CONICAL";
74
+ })(image_target_type_t || (image_target_type_t = {}));
75
+ ;
@@ -7,6 +7,8 @@ import { instant_world_tracker_transform_orientation_t } from "./zappar-native";
7
7
  export { instant_world_tracker_transform_orientation_t } from "./zappar-native";
8
8
  import { log_level_t } from "./zappar-native";
9
9
  export { log_level_t } from "./zappar-native";
10
+ import { image_target_type_t } from "./zappar-native";
11
+ export { image_target_type_t } from "./zappar-native";
10
12
  export declare type zappar_pipeline_t = number & {
11
13
  _: 'zappar_pipeline_t';
12
14
  };
@@ -37,6 +39,10 @@ export declare type zappar_instant_world_tracker_t = number & {
37
39
  export interface zappar {
38
40
  loaded(): boolean;
39
41
  camera_default_device_id(userFacing: boolean): string;
42
+ camera_count(): number;
43
+ camera_id(indx: number): string;
44
+ camera_name(indx: number): string;
45
+ camera_user_facing(indx: number): boolean;
40
46
  projection_matrix_from_camera_model(model: Float32Array, renderWidth: number, renderHeight: number): Float32Array;
41
47
  projection_matrix_from_camera_model_ext(model: Float32Array, renderWidth: number, renderHeight: number, zNear: number, zFar: number): Float32Array;
42
48
  log_level(): log_level_t;
@@ -95,6 +101,7 @@ export interface zappar {
95
101
  image_tracker_target_load_from_memory(o: zappar_image_tracker_t, data: ArrayBuffer): void;
96
102
  image_tracker_target_loaded_version(o: zappar_image_tracker_t): number;
97
103
  image_tracker_target_count(o: zappar_image_tracker_t): number;
104
+ image_tracker_target_type(o: zappar_image_tracker_t, indx: number): image_target_type_t;
98
105
  image_tracker_target_radius_top(o: zappar_image_tracker_t, indx: number): number;
99
106
  image_tracker_target_radius_bottom(o: zappar_image_tracker_t, indx: number): number;
100
107
  image_tracker_target_side_length(o: zappar_image_tracker_t, indx: number): number;
@@ -102,6 +109,14 @@ export interface zappar {
102
109
  image_tracker_target_preview_compressed(o: zappar_image_tracker_t, indx: number): Uint8Array;
103
110
  image_tracker_target_preview_compressed_size(o: zappar_image_tracker_t, indx: number): number;
104
111
  image_tracker_target_preview_compressed_mimetype(o: zappar_image_tracker_t, indx: number): string;
112
+ image_tracker_target_preview_mesh_indices(o: zappar_image_tracker_t, indx: number): Uint16Array;
113
+ image_tracker_target_preview_mesh_indices_size(o: zappar_image_tracker_t, indx: number): number;
114
+ image_tracker_target_preview_mesh_vertices(o: zappar_image_tracker_t, indx: number): Float32Array;
115
+ image_tracker_target_preview_mesh_vertices_size(o: zappar_image_tracker_t, indx: number): number;
116
+ image_tracker_target_preview_mesh_normals(o: zappar_image_tracker_t, indx: number): Float32Array;
117
+ image_tracker_target_preview_mesh_normals_size(o: zappar_image_tracker_t, indx: number): number;
118
+ image_tracker_target_preview_mesh_uvs(o: zappar_image_tracker_t, indx: number): Float32Array;
119
+ image_tracker_target_preview_mesh_uvs_size(o: zappar_image_tracker_t, indx: number): number;
105
120
  image_tracker_enabled(o: zappar_image_tracker_t): boolean;
106
121
  image_tracker_enabled_set(o: zappar_image_tracker_t, enabled: boolean): void;
107
122
  image_tracker_anchor_count(o: zappar_image_tracker_t): number;
package/lib/gen/zappar.js CHANGED
@@ -3,3 +3,4 @@ export { face_landmark_name_t } from "./zappar-native";
3
3
  export { frame_pixel_format_t } from "./zappar-native";
4
4
  export { instant_world_tracker_transform_orientation_t } from "./zappar-native";
5
5
  export { log_level_t } from "./zappar-native";
6
+ export { image_target_type_t } from "./zappar-native";
@@ -0,0 +1,2 @@
1
+ import { ParsedTargetInfo, PreviewMesh } from "./imagetracker";
2
+ export declare function getPreviewMesh(info: ParsedTargetInfo): PreviewMesh;
@@ -0,0 +1,212 @@
1
+ import { vec2 } from "gl-matrix";
2
+ import { image_target_type_t } from "./gen/zappar-native";
3
+ export function getPreviewMesh(info) {
4
+ switch (info.type) {
5
+ case image_target_type_t.IMAGE_TRACKER_TYPE_PLANAR: return planar(info);
6
+ case image_target_type_t.IMAGE_TRACKER_TYPE_CYLINDRICAL: return cylindrical(info);
7
+ case image_target_type_t.IMAGE_TRACKER_TYPE_CONICAL: return conical(info);
8
+ }
9
+ return defaultMesh();
10
+ }
11
+ function planar(info) {
12
+ const aspectRatio = info.trainedWidth / info.trainedHeight;
13
+ if (isNaN(aspectRatio))
14
+ return defaultMesh();
15
+ const scaling = info.physicalScaleFactor > 0 ? info.physicalScaleFactor : 1;
16
+ const vertices = new Float32Array([
17
+ -1.0 * aspectRatio * scaling, -1 * scaling, 0,
18
+ -1.0 * aspectRatio * scaling, scaling, 0,
19
+ aspectRatio * scaling, scaling, 0,
20
+ aspectRatio * scaling, -1 * scaling, 0
21
+ ]);
22
+ const indices = new Uint16Array([0, 2, 1, 0, 3, 2]);
23
+ const uvs = new Float32Array([
24
+ 0, 0,
25
+ 0, 1,
26
+ 1, 1,
27
+ 1, 0
28
+ ]);
29
+ const normals = new Float32Array([
30
+ 0, 0, 1,
31
+ 0, 0, 1,
32
+ 0, 0, 1,
33
+ 0, 0, 1,
34
+ ]);
35
+ return { vertices, indices, uvs, normals };
36
+ }
37
+ function defaultMesh() {
38
+ return {
39
+ indices: new Uint16Array(0),
40
+ vertices: new Float32Array(0),
41
+ normals: new Float32Array(0),
42
+ uvs: new Float32Array(0)
43
+ };
44
+ }
45
+ function cylindrical(info) {
46
+ const wrap_amount = 2 * info.trainedWidth / (info.trainedHeight * info.topRadius);
47
+ return generalConical(info, 2, false, 0, 0, 0, vec2.create(), info.trainedWidth / info.trainedHeight, wrap_amount, info.physicalScaleFactor);
48
+ }
49
+ function conical(info) {
50
+ const radius_diff = info.topRadius - info.bottomRadius;
51
+ const height_3d = Math.sqrt(info.sideLength * info.sideLength - radius_diff * radius_diff);
52
+ const flip = info.bottomRadius > info.topRadius;
53
+ let aspect_ratio = info.trainedWidth / info.trainedHeight;
54
+ if (isNaN(aspect_ratio))
55
+ aspect_ratio = 1;
56
+ const cone = !(info.bottomRadius > 0) || !(info.topRadius > 0);
57
+ const wide = info.sideLength < (2 * Math.abs(info.topRadius - info.bottomRadius));
58
+ const top_corner = vec2.create();
59
+ const bottom_corner = vec2.create();
60
+ const rotation_center = vec2.create();
61
+ if (cone) {
62
+ if (wide) {
63
+ if (flip) {
64
+ rotation_center[1] = aspect_ratio - 1;
65
+ const omega = Math.acos((2 - aspect_ratio) / aspect_ratio);
66
+ top_corner[0] = aspect_ratio * Math.sin(omega);
67
+ top_corner[1] = (aspect_ratio - 1) + aspect_ratio * Math.cos(omega);
68
+ vec2.copy(bottom_corner, rotation_center);
69
+ }
70
+ else {
71
+ rotation_center[1] = 1.0 - aspect_ratio;
72
+ const omega = Math.PI + Math.acos((2 - aspect_ratio) / aspect_ratio);
73
+ top_corner[0] = aspect_ratio * Math.sin(omega);
74
+ top_corner[1] = (1 - aspect_ratio) + aspect_ratio * Math.cos(omega);
75
+ vec2.copy(bottom_corner, rotation_center);
76
+ }
77
+ }
78
+ else {
79
+ if (flip) {
80
+ rotation_center[1] = 1;
81
+ vec2.copy(bottom_corner, rotation_center);
82
+ top_corner[0] = aspect_ratio;
83
+ top_corner[1] = 1 - Math.sqrt(4 - Math.pow(aspect_ratio, 2));
84
+ }
85
+ else {
86
+ rotation_center[1] = -1;
87
+ vec2.copy(bottom_corner, rotation_center);
88
+ top_corner[0] = -aspect_ratio;
89
+ top_corner[1] = Math.sqrt(4 - Math.pow(aspect_ratio, 2)) - 1;
90
+ }
91
+ }
92
+ }
93
+ else {
94
+ if (wide) {
95
+ if (flip) {
96
+ rotation_center[1] = aspect_ratio - 1;
97
+ const omega = Math.acos((2 - aspect_ratio) / aspect_ratio);
98
+ top_corner[0] = aspect_ratio * Math.sin(omega);
99
+ top_corner[1] = (aspect_ratio - 1) + aspect_ratio * Math.cos(omega);
100
+ bottom_corner[0] = (aspect_ratio - info.sideLength) * Math.sin(omega);
101
+ bottom_corner[1] = (aspect_ratio - 1) + (aspect_ratio - info.sideLength) * Math.cos(omega);
102
+ }
103
+ else {
104
+ rotation_center[1] = 1.0 - aspect_ratio;
105
+ const omega = Math.PI + Math.acos((2 - aspect_ratio) / aspect_ratio);
106
+ top_corner[0] = aspect_ratio * Math.sin(omega);
107
+ top_corner[1] = (1 - aspect_ratio) + aspect_ratio * Math.cos(omega);
108
+ bottom_corner[0] = (aspect_ratio - info.sideLength) * Math.sin(omega);
109
+ bottom_corner[1] = (1 - aspect_ratio) + (aspect_ratio - info.sideLength) * Math.cos(omega);
110
+ }
111
+ }
112
+ else {
113
+ const radius_ratio = flip ? (info.topRadius / info.bottomRadius) : (info.bottomRadius / info.topRadius);
114
+ if (flip) {
115
+ bottom_corner[0] = radius_ratio * aspect_ratio;
116
+ bottom_corner[1] = 1;
117
+ top_corner[0] = aspect_ratio;
118
+ top_corner[1] = 1 - Math.sqrt((info.sideLength * info.sideLength) - ((bottom_corner[0] - top_corner[0]) * (bottom_corner[0] - top_corner[0])));
119
+ rotation_center[1] = top_corner[1] + (top_corner[0] / (top_corner[0] - bottom_corner[0])) * (bottom_corner[1] - top_corner[1]);
120
+ }
121
+ else {
122
+ bottom_corner[0] = -radius_ratio * aspect_ratio;
123
+ bottom_corner[1] = -1;
124
+ top_corner[0] = -aspect_ratio;
125
+ top_corner[1] = Math.sqrt((info.sideLength * info.sideLength) - ((bottom_corner[0] - top_corner[0]) * (bottom_corner[0] - top_corner[0]))) - 1;
126
+ rotation_center[1] = top_corner[1] - (-top_corner[0] / (bottom_corner[0] - top_corner[0])) * (top_corner[1] - bottom_corner[1]);
127
+ }
128
+ }
129
+ }
130
+ const top_from_center = vec2.create();
131
+ vec2.subtract(top_from_center, top_corner, rotation_center);
132
+ const bottom_from_center = vec2.create();
133
+ vec2.subtract(bottom_from_center, bottom_corner, rotation_center);
134
+ const top_2d_radius = vec2.length(top_from_center);
135
+ const bottom_2d_radius = vec2.length(bottom_from_center);
136
+ let max_angle = 2 * Math.abs(Math.atan(top_from_center[0] / top_from_center[1]));
137
+ if (wide)
138
+ max_angle = (2 * Math.PI) - max_angle;
139
+ let theta_3d = (top_2d_radius * max_angle) / info.topRadius;
140
+ let theta = Math.abs(Math.atan(top_from_center[0] / top_from_center[1]));
141
+ if (wide)
142
+ theta = Math.PI - theta;
143
+ return generalConical(info, height_3d, flip, theta, bottom_2d_radius, top_2d_radius, rotation_center, aspect_ratio, theta_3d, info.physicalScaleFactor);
144
+ }
145
+ function generalConical(info, height_3d, flip, theta, bottom_2d_radius, top_2d_radius, rotation_center, aspect_ratio, wrap_amount, psf) {
146
+ if (isNaN(aspect_ratio))
147
+ aspect_ratio = 1;
148
+ const vertices = [];
149
+ const uvs = [];
150
+ const physical_scale = psf > 0 ? psf : 1;
151
+ const scale_factor = physical_scale * 2.0 / height_3d;
152
+ const subdivisons = 64;
153
+ for (let s = 0; s <= subdivisons; ++s) {
154
+ const angle = (s * wrap_amount / subdivisons) + (((2 * Math.PI) - wrap_amount) / 2);
155
+ const bx = info.bottomRadius * Math.sin(angle) * scale_factor;
156
+ const bz = info.bottomRadius * Math.cos(angle) * scale_factor;
157
+ const tx = info.topRadius * Math.sin(angle) * scale_factor;
158
+ const tz = info.topRadius * Math.cos(angle) * scale_factor;
159
+ const btm = -1 * physical_scale;
160
+ const top = physical_scale;
161
+ if (flip) {
162
+ vertices.push(bx, btm, bz);
163
+ vertices.push(tx, top, tz);
164
+ }
165
+ else {
166
+ vertices.push(tx, top, -tz);
167
+ vertices.push(bx, btm, -bz);
168
+ }
169
+ }
170
+ for (let s = 0; s <= subdivisons; ++s) {
171
+ if (info.type == image_target_type_t.IMAGE_TRACKER_TYPE_CYLINDRICAL) {
172
+ const offset = 1 - (s / subdivisons);
173
+ uvs.push(offset, 1);
174
+ uvs.push(offset, 0);
175
+ }
176
+ else {
177
+ let angle_2d = -((s / subdivisons) - 0.5) * 2 * theta;
178
+ if (flip) {
179
+ angle_2d = -angle_2d + theta;
180
+ if (angle_2d > theta)
181
+ angle_2d = -theta + (angle_2d - theta);
182
+ }
183
+ const direction = vec2.create();
184
+ direction[0] = Math.sin(angle_2d);
185
+ direction[1] = Math.cos(angle_2d);
186
+ if (flip)
187
+ direction[1] *= -1;
188
+ const bottom_px = vec2.create();
189
+ vec2.copy(bottom_px, direction);
190
+ vec2.scale(bottom_px, bottom_px, bottom_2d_radius);
191
+ vec2.add(bottom_px, rotation_center, bottom_px);
192
+ const top_px = vec2.create();
193
+ vec2.copy(top_px, direction);
194
+ vec2.scale(top_px, top_px, top_2d_radius);
195
+ vec2.add(top_px, rotation_center, top_px);
196
+ uvs.push((top_px[0] + aspect_ratio) / (2 * aspect_ratio), 1 - ((-top_px[1] + 1) / 2));
197
+ uvs.push((bottom_px[0] + aspect_ratio) / (2 * aspect_ratio), 1 - ((-bottom_px[1] + 1) / 2));
198
+ }
199
+ }
200
+ const indices = [];
201
+ for (let i = 0; i < subdivisons; ++i) {
202
+ const bi = i * 2;
203
+ indices.push(bi + 1, bi + 2, bi + 3);
204
+ indices.push(bi + 0, bi + 2, bi + 1);
205
+ }
206
+ return {
207
+ vertices: new Float32Array(vertices),
208
+ indices: new Uint16Array(indices),
209
+ normals: new Float32Array(0),
210
+ uvs: new Float32Array(uvs)
211
+ };
212
+ }
@@ -1,15 +1,26 @@
1
1
  import { zappar_image_tracker_t, zappar_pipeline_t } from "./gen/zappar";
2
- import { zappar_cwrap } from "./gen/zappar-native";
2
+ import { image_target_type_t, zappar_cwrap } from "./gen/zappar-native";
3
3
  interface PreviewInfo {
4
4
  compressed: Uint8Array;
5
5
  mimeType: string;
6
+ image?: HTMLImageElement;
6
7
  }
7
- interface ParsedTargetInfo {
8
+ export interface PreviewMesh {
9
+ indices: Uint16Array;
10
+ vertices: Float32Array;
11
+ normals: Float32Array;
12
+ uvs: Float32Array;
13
+ }
14
+ export interface ParsedTargetInfo {
8
15
  preview?: PreviewInfo;
16
+ previewMesh?: PreviewMesh;
9
17
  physicalScaleFactor: number;
10
18
  topRadius: number;
11
19
  bottomRadius: number;
12
20
  sideLength: number;
21
+ type: image_target_type_t;
22
+ trainedWidth: number;
23
+ trainedHeight: number;
13
24
  }
14
25
  export declare class ImageTracker {
15
26
  private _client;
@@ -23,6 +34,9 @@ export declare class ImageTracker {
23
34
  targetCount(): number;
24
35
  getTargetInfo(i: number): ParsedTargetInfo;
25
36
  private _parseOdle;
37
+ private _parseOdleV1;
38
+ private _parseOdleV3;
26
39
  getDecodedPreview(i: number): HTMLImageElement | undefined;
40
+ getPreviewMesh(i: number): PreviewMesh;
27
41
  }
28
42
  export {};