@srsergio/taptapp-ar 1.0.25 → 1.0.26
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/dist/compiler/simple-ar.js +31 -21
- package/package.json +1 -1
- package/src/compiler/simple-ar.js +36 -25
|
@@ -136,36 +136,46 @@ class SimpleAR {
|
|
|
136
136
|
const isPortrait = containerRect.height > containerRect.width;
|
|
137
137
|
const isVideoLandscape = videoW > videoH;
|
|
138
138
|
const needsRotation = isPortrait && isVideoLandscape;
|
|
139
|
-
//
|
|
140
|
-
const
|
|
141
|
-
|
|
139
|
+
// Current display dimensions of the video (accounting for rotation)
|
|
140
|
+
const vW = needsRotation ? videoH : videoW;
|
|
141
|
+
const vH = needsRotation ? videoW : videoH;
|
|
142
|
+
// Robust "object-fit: cover" scale calculation
|
|
143
|
+
const perspectiveScale = Math.max(containerRect.width / vW, containerRect.height / vH);
|
|
144
|
+
const displayW = vW * perspectiveScale;
|
|
145
|
+
const displayH = vH * perspectiveScale;
|
|
146
|
+
const offsetX = (containerRect.width - displayW) / 2;
|
|
147
|
+
const offsetY = (containerRect.height - displayH) / 2;
|
|
148
|
+
// The tracker uses focal length based on height dimension in tracker space
|
|
149
|
+
const f = (videoH / 2) / Math.tan((45.0 * Math.PI / 180) / 2);
|
|
150
|
+
// Center of the marker in camera space (marker coordinates origin at top-left)
|
|
142
151
|
const tx = mVT[0][0] * (markerW / 2) + mVT[0][1] * (markerH / 2) + mVT[0][3];
|
|
143
152
|
const ty = mVT[1][0] * (markerW / 2) + mVT[1][1] * (markerH / 2) + mVT[1][3];
|
|
144
153
|
const tz = mVT[2][0] * (markerW / 2) + mVT[2][1] * (markerH / 2) + mVT[2][3];
|
|
145
|
-
let screenX, screenY, rotation
|
|
154
|
+
let screenX, screenY, rotation;
|
|
146
155
|
if (needsRotation) {
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
|
|
150
|
-
const
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
screenY = (containerRect.height / 2 + (tx * f / tz) * scale);
|
|
156
|
+
// Mapping for 90deg clockwise rotation:
|
|
157
|
+
// Buffer X (0..videoW) -> Screen Y (0..displayH)
|
|
158
|
+
// Buffer Y (0..videoH) -> Screen X (displayW..0)
|
|
159
|
+
const bufferOffsetX = (tx * f / tz);
|
|
160
|
+
const bufferOffsetY = (ty * f / tz);
|
|
161
|
+
screenX = offsetX + (displayW / 2) - (bufferOffsetY * perspectiveScale);
|
|
162
|
+
screenY = offsetY + (displayH / 2) + (bufferOffsetX * perspectiveScale);
|
|
155
163
|
rotation = Math.atan2(mVT[1][0], mVT[0][0]) - Math.PI / 2;
|
|
156
|
-
perspectiveScale = scale;
|
|
157
164
|
}
|
|
158
165
|
else {
|
|
159
|
-
//
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
166
|
+
// Normal mapping:
|
|
167
|
+
// Buffer X -> Screen X
|
|
168
|
+
// Buffer Y -> Screen Y
|
|
169
|
+
const bufferOffsetX = (tx * f / tz);
|
|
170
|
+
const bufferOffsetY = (ty * f / tz);
|
|
171
|
+
screenX = offsetX + (displayW / 2) + (bufferOffsetX * perspectiveScale);
|
|
172
|
+
screenY = offsetY + (displayH / 2) + (bufferOffsetY * perspectiveScale);
|
|
165
173
|
rotation = Math.atan2(mVT[1][0], mVT[0][0]);
|
|
166
|
-
perspectiveScale = scale;
|
|
167
174
|
}
|
|
168
|
-
// Final Scale
|
|
175
|
+
// Final Scale calculation:
|
|
176
|
+
// f/tz converts world units to buffer pixels
|
|
177
|
+
// perspectiveScale converts buffer pixels to screen pixels
|
|
178
|
+
// matrixScale handles the target's relative orientation in 2D
|
|
169
179
|
const matrixScale = Math.sqrt(mVT[0][0] ** 2 + mVT[1][0] ** 2);
|
|
170
180
|
const finalScale = (f / tz) * perspectiveScale * matrixScale * this.scaleMultiplier;
|
|
171
181
|
// Apply
|
package/package.json
CHANGED
|
@@ -163,43 +163,54 @@ class SimpleAR {
|
|
|
163
163
|
const isVideoLandscape = videoW > videoH;
|
|
164
164
|
const needsRotation = isPortrait && isVideoLandscape;
|
|
165
165
|
|
|
166
|
-
//
|
|
167
|
-
const
|
|
166
|
+
// Current display dimensions of the video (accounting for rotation)
|
|
167
|
+
const vW = needsRotation ? videoH : videoW;
|
|
168
|
+
const vH = needsRotation ? videoW : videoH;
|
|
168
169
|
|
|
169
|
-
//
|
|
170
|
+
// Robust "object-fit: cover" scale calculation
|
|
171
|
+
const perspectiveScale = Math.max(containerRect.width / vW, containerRect.height / vH);
|
|
172
|
+
|
|
173
|
+
const displayW = vW * perspectiveScale;
|
|
174
|
+
const displayH = vH * perspectiveScale;
|
|
175
|
+
const offsetX = (containerRect.width - displayW) / 2;
|
|
176
|
+
const offsetY = (containerRect.height - displayH) / 2;
|
|
177
|
+
|
|
178
|
+
// The tracker uses focal length based on height dimension in tracker space
|
|
179
|
+
const f = (videoH / 2) / Math.tan((45.0 * Math.PI / 180) / 2);
|
|
180
|
+
|
|
181
|
+
// Center of the marker in camera space (marker coordinates origin at top-left)
|
|
170
182
|
const tx = mVT[0][0] * (markerW / 2) + mVT[0][1] * (markerH / 2) + mVT[0][3];
|
|
171
183
|
const ty = mVT[1][0] * (markerW / 2) + mVT[1][1] * (markerH / 2) + mVT[1][3];
|
|
172
184
|
const tz = mVT[2][0] * (markerW / 2) + mVT[2][1] * (markerH / 2) + mVT[2][3];
|
|
173
185
|
|
|
174
|
-
let screenX, screenY, rotation
|
|
186
|
+
let screenX, screenY, rotation;
|
|
175
187
|
|
|
176
188
|
if (needsRotation) {
|
|
177
|
-
//
|
|
178
|
-
//
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
screenY = (containerRect.height / 2 + (tx * f / tz) * scale);
|
|
186
|
-
|
|
189
|
+
// Mapping for 90deg clockwise rotation:
|
|
190
|
+
// Buffer X (0..videoW) -> Screen Y (0..displayH)
|
|
191
|
+
// Buffer Y (0..videoH) -> Screen X (displayW..0)
|
|
192
|
+
const bufferOffsetX = (tx * f / tz);
|
|
193
|
+
const bufferOffsetY = (ty * f / tz);
|
|
194
|
+
|
|
195
|
+
screenX = offsetX + (displayW / 2) - (bufferOffsetY * perspectiveScale);
|
|
196
|
+
screenY = offsetY + (displayH / 2) + (bufferOffsetX * perspectiveScale);
|
|
187
197
|
rotation = Math.atan2(mVT[1][0], mVT[0][0]) - Math.PI / 2;
|
|
188
|
-
perspectiveScale = scale;
|
|
189
198
|
} else {
|
|
190
|
-
//
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
199
|
+
// Normal mapping:
|
|
200
|
+
// Buffer X -> Screen X
|
|
201
|
+
// Buffer Y -> Screen Y
|
|
202
|
+
const bufferOffsetX = (tx * f / tz);
|
|
203
|
+
const bufferOffsetY = (ty * f / tz);
|
|
204
|
+
|
|
205
|
+
screenX = offsetX + (displayW / 2) + (bufferOffsetX * perspectiveScale);
|
|
206
|
+
screenY = offsetY + (displayH / 2) + (bufferOffsetY * perspectiveScale);
|
|
198
207
|
rotation = Math.atan2(mVT[1][0], mVT[0][0]);
|
|
199
|
-
perspectiveScale = scale;
|
|
200
208
|
}
|
|
201
209
|
|
|
202
|
-
// Final Scale
|
|
210
|
+
// Final Scale calculation:
|
|
211
|
+
// f/tz converts world units to buffer pixels
|
|
212
|
+
// perspectiveScale converts buffer pixels to screen pixels
|
|
213
|
+
// matrixScale handles the target's relative orientation in 2D
|
|
203
214
|
const matrixScale = Math.sqrt(mVT[0][0] ** 2 + mVT[1][0] ** 2);
|
|
204
215
|
const finalScale = (f / tz) * perspectiveScale * matrixScale * this.scaleMultiplier;
|
|
205
216
|
|