@srsergio/taptapp-ar 1.0.22 → 1.0.23

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.
@@ -131,18 +131,16 @@ class SimpleAR {
131
131
  return;
132
132
  const [markerW, markerH] = this.markerDimensions[targetIndex];
133
133
  const containerRect = this.container.getBoundingClientRect();
134
- // Video source dimensions (e.g., 1280x720)
135
- let videoW = this.video.videoWidth;
136
- let videoH = this.video.videoHeight;
137
- // Detect if the video is effectively rotated (Portrait on Mobile)
138
- // Browser displays video vertically but videoWidth > videoHeight
134
+ // 1. Raw Video Dimensions (Sensor Frame)
135
+ const videoW = this.video.videoWidth;
136
+ const videoH = this.video.videoHeight;
137
+ // 2. Detect if screen orientation is different from video buffer
139
138
  const isPortrait = containerRect.height > containerRect.width;
140
139
  const isVideoLandscape = videoW > videoH;
141
140
  const needsRotation = isPortrait && isVideoLandscape;
142
- // If rotated, the effective buffer dimensions are swapped
141
+ // Effective dimensions of the display buffer
143
142
  const effectiveBufferW = needsRotation ? videoH : videoW;
144
143
  const effectiveBufferH = needsRotation ? videoW : videoH;
145
- // Calculate display area considering object-fit: cover
146
144
  const containerAspect = containerRect.width / containerRect.height;
147
145
  const bufferAspect = effectiveBufferW / effectiveBufferH;
148
146
  let displayW, displayH, offsetX, offsetY;
@@ -160,17 +158,19 @@ class SimpleAR {
160
158
  }
161
159
  const scaleX = displayW / effectiveBufferW;
162
160
  const scaleY = displayH / effectiveBufferH;
163
- // Project marker center into camera space
161
+ // 3. Focal Length (MUST match Controller.js projection)
162
+ // Controller.js uses inputHeight / 2 as the vertical reference.
163
+ const f = videoH / 2 / Math.tan((45.0 * Math.PI / 180) / 2);
164
+ // 4. Project marker center into camera space
164
165
  const tx = mVT[0][0] * (markerW / 2) + mVT[0][1] * (markerH / 2) + mVT[0][3];
165
166
  const ty = mVT[1][0] * (markerW / 2) + mVT[1][1] * (markerH / 2) + mVT[1][3];
166
167
  const tz = mVT[2][0] * (markerW / 2) + mVT[2][1] * (markerH / 2) + mVT[2][3];
167
- // focal length (roughly 45 degrees FOV match Controller.js)
168
- const f = effectiveBufferH / 2 / Math.tan((45.0 * Math.PI / 180) / 2);
169
- // Normalized Device Coordinates (NDC) to Screen space
168
+ // 5. Map Camera coordinates to Screen coordinates
170
169
  let screenX, screenY;
171
170
  if (needsRotation) {
172
- // Map camera X/Y to rotated screen Y/X
173
- // Camera X -> Screen Y, Camera Y -> Screen -X
171
+ // Mapping Sensor coordinates to Rotated Screen coordinates
172
+ // Sensor +X -> Screen +Y
173
+ // Sensor +Y -> Screen -X (relative to logical center)
174
174
  screenX = offsetX + (effectiveBufferW / 2 + (ty * f / tz)) * scaleX;
175
175
  screenY = offsetY + (effectiveBufferH / 2 - (tx * f / tz)) * scaleY;
176
176
  }
@@ -178,13 +178,15 @@ class SimpleAR {
178
178
  screenX = offsetX + (effectiveBufferW / 2 + (tx * f / tz)) * scaleX;
179
179
  screenY = offsetY + (effectiveBufferH / 2 + (ty * f / tz)) * scaleY;
180
180
  }
181
- // Rotation: compensate for buffer rotation
181
+ // 6. Rotation: sync with CSS transform
182
+ //atan2 gives angle of world X-axis in camera space.
182
183
  let rotation = Math.atan2(mVT[1][0], mVT[0][0]);
183
- if (needsRotation)
184
- rotation -= Math.PI / 2;
184
+ if (needsRotation) {
185
+ rotation += Math.PI / 2; // Compensate for the 90deg rotation of the video element
186
+ }
187
+ // 7. Scale calculation
185
188
  const matrixScale = Math.sqrt(mVT[0][0] ** 2 + mVT[1][0] ** 2);
186
189
  const perspectiveScale = (f / tz) * scaleX;
187
- // Detect overlay intrinsic size
188
190
  const intrinsicWidth = (this.overlay instanceof HTMLVideoElement)
189
191
  ? this.overlay.videoWidth
190
192
  : (this.overlay instanceof HTMLImageElement ? this.overlay.naturalWidth : 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@srsergio/taptapp-ar",
3
- "version": "1.0.22",
3
+ "version": "1.0.23",
4
4
  "description": "AR Compiler for Node.js and Browser",
5
5
  "repository": {
6
6
  "type": "git",
@@ -156,26 +156,23 @@ class SimpleAR {
156
156
  const [markerW, markerH] = this.markerDimensions[targetIndex];
157
157
  const containerRect = this.container.getBoundingClientRect();
158
158
 
159
- // Video source dimensions (e.g., 1280x720)
160
- let videoW = this.video.videoWidth;
161
- let videoH = this.video.videoHeight;
159
+ // 1. Raw Video Dimensions (Sensor Frame)
160
+ const videoW = this.video.videoWidth;
161
+ const videoH = this.video.videoHeight;
162
162
 
163
- // Detect if the video is effectively rotated (Portrait on Mobile)
164
- // Browser displays video vertically but videoWidth > videoHeight
163
+ // 2. Detect if screen orientation is different from video buffer
165
164
  const isPortrait = containerRect.height > containerRect.width;
166
165
  const isVideoLandscape = videoW > videoH;
167
166
  const needsRotation = isPortrait && isVideoLandscape;
168
167
 
169
- // If rotated, the effective buffer dimensions are swapped
168
+ // Effective dimensions of the display buffer
170
169
  const effectiveBufferW = needsRotation ? videoH : videoW;
171
170
  const effectiveBufferH = needsRotation ? videoW : videoH;
172
171
 
173
- // Calculate display area considering object-fit: cover
174
172
  const containerAspect = containerRect.width / containerRect.height;
175
173
  const bufferAspect = effectiveBufferW / effectiveBufferH;
176
174
 
177
175
  let displayW, displayH, offsetX, offsetY;
178
-
179
176
  if (containerAspect > bufferAspect) {
180
177
  displayW = containerRect.width;
181
178
  displayH = containerRect.width / bufferAspect;
@@ -191,20 +188,21 @@ class SimpleAR {
191
188
  const scaleX = displayW / effectiveBufferW;
192
189
  const scaleY = displayH / effectiveBufferH;
193
190
 
194
- // Project marker center into camera space
191
+ // 3. Focal Length (MUST match Controller.js projection)
192
+ // Controller.js uses inputHeight / 2 as the vertical reference.
193
+ const f = videoH / 2 / Math.tan((45.0 * Math.PI / 180) / 2);
194
+
195
+ // 4. Project marker center into camera space
195
196
  const tx = mVT[0][0] * (markerW / 2) + mVT[0][1] * (markerH / 2) + mVT[0][3];
196
197
  const ty = mVT[1][0] * (markerW / 2) + mVT[1][1] * (markerH / 2) + mVT[1][3];
197
198
  const tz = mVT[2][0] * (markerW / 2) + mVT[2][1] * (markerH / 2) + mVT[2][3];
198
199
 
199
- // focal length (roughly 45 degrees FOV match Controller.js)
200
- const f = effectiveBufferH / 2 / Math.tan((45.0 * Math.PI / 180) / 2);
201
-
202
- // Normalized Device Coordinates (NDC) to Screen space
200
+ // 5. Map Camera coordinates to Screen coordinates
203
201
  let screenX, screenY;
204
-
205
202
  if (needsRotation) {
206
- // Map camera X/Y to rotated screen Y/X
207
- // Camera X -> Screen Y, Camera Y -> Screen -X
203
+ // Mapping Sensor coordinates to Rotated Screen coordinates
204
+ // Sensor +X -> Screen +Y
205
+ // Sensor +Y -> Screen -X (relative to logical center)
208
206
  screenX = offsetX + (effectiveBufferW / 2 + (ty * f / tz)) * scaleX;
209
207
  screenY = offsetY + (effectiveBufferH / 2 - (tx * f / tz)) * scaleY;
210
208
  } else {
@@ -212,14 +210,17 @@ class SimpleAR {
212
210
  screenY = offsetY + (effectiveBufferH / 2 + (ty * f / tz)) * scaleY;
213
211
  }
214
212
 
215
- // Rotation: compensate for buffer rotation
213
+ // 6. Rotation: sync with CSS transform
214
+ //atan2 gives angle of world X-axis in camera space.
216
215
  let rotation = Math.atan2(mVT[1][0], mVT[0][0]);
217
- if (needsRotation) rotation -= Math.PI / 2;
216
+ if (needsRotation) {
217
+ rotation += Math.PI / 2; // Compensate for the 90deg rotation of the video element
218
+ }
218
219
 
220
+ // 7. Scale calculation
219
221
  const matrixScale = Math.sqrt(mVT[0][0] ** 2 + mVT[1][0] ** 2);
220
222
  const perspectiveScale = (f / tz) * scaleX;
221
223
 
222
- // Detect overlay intrinsic size
223
224
  const intrinsicWidth = (this.overlay instanceof HTMLVideoElement)
224
225
  ? this.overlay.videoWidth
225
226
  : (this.overlay instanceof HTMLImageElement ? this.overlay.naturalWidth : 0);