|
@@ -5,7 +5,7 @@
|
5
|
5
|
* https://github.com/alemart/encantar-js
|
6
|
6
|
*
|
7
|
7
|
* @license LGPL-3.0-or-later
|
8
|
|
- * Date: 2024-09-02T19:15:04.498Z
|
|
8
|
+ * Date: 2024-10-05T04:17:49.391Z
|
9
|
9
|
*/
|
10
|
10
|
(function webpackUniversalModuleDefinition(root, factory) {
|
11
|
11
|
if(typeof exports === 'object' && typeof module === 'object')
|
|
@@ -19651,6 +19651,25 @@ class Utils {
|
19651
|
19651
|
return Array.from({ length: n }, (_, i) => i);
|
19652
|
19652
|
}
|
19653
|
19653
|
/**
|
|
19654
|
+ * Wait a few milliseconds
|
|
19655
|
+ * @param milliseconds how long should we wait?
|
|
19656
|
+ * @returns a promise that is resolved soon after the specified time
|
|
19657
|
+ */
|
|
19658
|
+ static wait(milliseconds) {
|
|
19659
|
+ return new (speedy_vision_default()).Promise(resolve => {
|
|
19660
|
+ setTimeout(resolve, milliseconds);
|
|
19661
|
+ });
|
|
19662
|
+ }
|
|
19663
|
+ /**
|
|
19664
|
+ * Run SpeedyPromises sequentially
|
|
19665
|
+ * @param promises an array of SpeedyPromises
|
|
19666
|
+ * @returns a promise that is resolved as soon as all input promises are
|
|
19667
|
+ * resolved, or that is rejected as soon as an input promise is rejected
|
|
19668
|
+ */
|
|
19669
|
+ static runInSequence(promises) {
|
|
19670
|
+ return promises.reduce((prev, curr) => prev.then(() => curr), speedy_vision_default().Promise.resolve());
|
|
19671
|
+ }
|
|
19672
|
+ /**
|
19654
|
19673
|
* Convert a resolution type to a resolution measured in pixels
|
19655
|
19674
|
* @param resolution resolution type
|
19656
|
19675
|
* @param aspectRatio width / height ratio
|
|
@@ -20109,24 +20128,6 @@ class StatsPanel {
|
20109
|
20128
|
* A Frame holds information used to render a single animation frame of a Session
|
20110
|
20129
|
*/
|
20111
|
20130
|
/**
|
20112
|
|
- * Iterable frame results (helper class)
|
20113
|
|
- */
|
20114
|
|
-class IterableTrackerResults {
|
20115
|
|
- constructor(_results) {
|
20116
|
|
- this._results = _results;
|
20117
|
|
- this._index = 0;
|
20118
|
|
- }
|
20119
|
|
- next() {
|
20120
|
|
- const i = this._index++;
|
20121
|
|
- return i < this._results.length ?
|
20122
|
|
- { done: false, value: this._results[i] } :
|
20123
|
|
- { done: true, value: undefined };
|
20124
|
|
- }
|
20125
|
|
- [Symbol.iterator]() {
|
20126
|
|
- return this;
|
20127
|
|
- }
|
20128
|
|
-}
|
20129
|
|
-/**
|
20130
|
20131
|
* A Frame holds information used to render a single animation frame of a Session
|
20131
|
20132
|
*/
|
20132
|
20133
|
class Frame {
|
|
@@ -20137,7 +20138,7 @@ class Frame {
|
20137
|
20138
|
*/
|
20138
|
20139
|
constructor(session, results) {
|
20139
|
20140
|
this._session = session;
|
20140
|
|
- this._results = new IterableTrackerResults(results);
|
|
20141
|
+ this._results = results;
|
20141
|
20142
|
}
|
20142
|
20143
|
/**
|
20143
|
20144
|
* The session of which this frame holds data
|
|
@@ -20149,7 +20150,8 @@ class Frame {
|
20149
|
20150
|
* The results of all trackers in this frame
|
20150
|
20151
|
*/
|
20151
|
20152
|
get results() {
|
20152
|
|
- return this._results;
|
|
20153
|
+ // we want to be able to iterate over the results of a frame multiple times
|
|
20154
|
+ return this._results[Symbol.iterator]();
|
20153
|
20155
|
}
|
20154
|
20156
|
}
|
20155
|
20157
|
|
|
@@ -20749,11 +20751,8 @@ class Session extends AREventTarget {
|
20749
|
20751
|
Utils.log('Shutting down the session...');
|
20750
|
20752
|
this._active = false; // set before wait()
|
20751
|
20753
|
// wait a few ms, so that the GPU is no longer sending any data
|
20752
|
|
- const wait = (ms) => new (speedy_vision_default()).Promise(resolve => {
|
20753
|
|
- setTimeout(resolve, ms);
|
20754
|
|
- });
|
20755
|
|
- // release resources
|
20756
|
|
- return wait(100).then(() => speedy_vision_default().Promise.all(
|
|
20754
|
+ // then, release resources
|
|
20755
|
+ return Utils.wait(100).then(() => speedy_vision_default().Promise.all(
|
20757
|
20756
|
// release trackers
|
20758
|
20757
|
this._trackers.map(tracker => tracker._release()))).then(() => speedy_vision_default().Promise.all(
|
20759
|
20758
|
// release input sources
|
|
@@ -20781,10 +20780,13 @@ class Session extends AREventTarget {
|
20781
|
20780
|
*/
|
20782
|
20781
|
requestAnimationFrame(callback) {
|
20783
|
20782
|
const handle = Symbol('raf-handle');
|
20784
|
|
- if (this._active)
|
|
20783
|
+ if (this._active) {
|
20785
|
20784
|
this._rafQueue.push([handle, callback]);
|
20786
|
|
- else
|
20787
|
|
- throw new IllegalOperationError(`Can't requestAnimationFrame(): session ended.`);
|
|
20785
|
+ }
|
|
20786
|
+ else {
|
|
20787
|
+ // if the session is inactive, we simply ignore this call
|
|
20788
|
+ // this is friendly behavior, since RAF is used in animation loops
|
|
20789
|
+ }
|
20788
|
20790
|
return handle;
|
20789
|
20791
|
}
|
20790
|
20792
|
/**
|
|
@@ -20818,10 +20820,10 @@ class Session extends AREventTarget {
|
20818
|
20820
|
return this._mode;
|
20819
|
20821
|
}
|
20820
|
20822
|
/**
|
20821
|
|
- * Rendering viewport
|
|
20823
|
+ * Whether or not the session has been ended
|
20822
|
20824
|
*/
|
20823
|
|
- get viewport() {
|
20824
|
|
- return this._viewport;
|
|
20825
|
+ get ended() {
|
|
20826
|
+ return !this._active;
|
20825
|
20827
|
}
|
20826
|
20828
|
/**
|
20827
|
20829
|
* Time utilities
|
|
@@ -20836,6 +20838,24 @@ class Session extends AREventTarget {
|
20836
|
20838
|
return this._gizmos;
|
20837
|
20839
|
}
|
20838
|
20840
|
/**
|
|
20841
|
+ * Rendering viewport
|
|
20842
|
+ */
|
|
20843
|
+ get viewport() {
|
|
20844
|
+ return this._viewport;
|
|
20845
|
+ }
|
|
20846
|
+ /**
|
|
20847
|
+ * Attached trackers
|
|
20848
|
+ */
|
|
20849
|
+ get trackers() {
|
|
20850
|
+ return this._trackers[Symbol.iterator]();
|
|
20851
|
+ }
|
|
20852
|
+ /**
|
|
20853
|
+ * Sources of data
|
|
20854
|
+ */
|
|
20855
|
+ get sources() {
|
|
20856
|
+ return this._sources[Symbol.iterator]();
|
|
20857
|
+ }
|
|
20858
|
+ /**
|
20839
|
20859
|
* Attach a tracker to the session
|
20840
|
20860
|
* @param tracker
|
20841
|
20861
|
*/
|
|
@@ -21093,6 +21113,7 @@ Settings._powerPreference = 'default';
|
21093
|
21113
|
*/
|
21094
|
21114
|
|
21095
|
21115
|
|
|
21116
|
+
|
21096
|
21117
|
/** Default capacity of a Reference Image Database */
|
21097
|
21118
|
const DEFAULT_CAPACITY = 100; // this number should exceed normal usage
|
21098
|
21119
|
// XXX this number may be changed (is 100 too conservative?)
|
|
@@ -21111,6 +21132,7 @@ class ReferenceImageDatabase {
|
21111
|
21132
|
this._capacity = DEFAULT_CAPACITY;
|
21112
|
21133
|
this._database = [];
|
21113
|
21134
|
this._locked = false;
|
|
21135
|
+ this._busy = false;
|
21114
|
21136
|
}
|
21115
|
21137
|
/**
|
21116
|
21138
|
* The number of reference images stored in this database
|
|
@@ -21156,13 +21178,16 @@ class ReferenceImageDatabase {
|
21156
|
21178
|
// handle multiple images as input
|
21157
|
21179
|
if (referenceImages.length > 1) {
|
21158
|
21180
|
const promises = referenceImages.map(image => this.add([image]));
|
21159
|
|
- return speedy_vision_default().Promise.all(promises).then(() => void (0));
|
|
21181
|
+ return Utils.runInSequence(promises);
|
21160
|
21182
|
}
|
21161
|
21183
|
// handle a single image as input
|
21162
|
21184
|
const referenceImage = referenceImages[0];
|
21163
|
21185
|
// locked database?
|
21164
|
21186
|
if (this._locked)
|
21165
|
21187
|
throw new IllegalOperationError(`Can't add reference image to the database: it's locked`);
|
|
21188
|
+ // busy loading another image?
|
|
21189
|
+ if (this._busy)
|
|
21190
|
+ return Utils.wait(4).then(() => this.add(referenceImages)); // try again later
|
21166
|
21191
|
// reached full capacity?
|
21167
|
21192
|
if (this.count >= this.capacity)
|
21168
|
21193
|
throw new IllegalOperationError(`Can't add reference image to the database: the capacity of ${this.capacity} images has been exceeded.`);
|
|
@@ -21170,7 +21195,9 @@ class ReferenceImageDatabase {
|
21170
|
21195
|
if (this._database.find(entry => entry.referenceImage.name === referenceImage.name) !== undefined)
|
21171
|
21196
|
throw new IllegalArgumentError(`Can't add reference image to the database: found duplicated name "${referenceImage.name}"`);
|
21172
|
21197
|
// load the media and add the reference image to the database
|
|
21198
|
+ this._busy = true;
|
21173
|
21199
|
return speedy_vision_default().load(referenceImage.image).then(media => {
|
|
21200
|
+ this._busy = false;
|
21174
|
21201
|
this._database.push({
|
21175
|
21202
|
referenceImage: Object.freeze(Object.assign(Object.assign({}, referenceImage), { name: referenceImage.name || generateUniqueName() })),
|
21176
|
21203
|
media: media
|
|
@@ -21182,6 +21209,8 @@ class ReferenceImageDatabase {
|
21182
|
21209
|
* @internal
|
21183
|
21210
|
*/
|
21184
|
21211
|
_lock() {
|
|
21212
|
+ if (this._busy)
|
|
21213
|
+ throw new IllegalOperationError(`Can't lock the reference image database: we're busy loading an image`);
|
21185
|
21214
|
this._locked = true;
|
21186
|
21215
|
}
|
21187
|
21216
|
/**
|
|
@@ -23729,6 +23758,7 @@ class PerspectiveView {
|
23729
|
23758
|
if (this._near >= this._far)
|
23730
|
23759
|
throw new IllegalArgumentError(`View expects near < far (found near = ${this._near} and far = ${this._far})`);
|
23731
|
23760
|
this._aspect = screenSize.width / screenSize.height;
|
|
23761
|
+ this._tanOfHalfFovx = intrinsics[U0] / intrinsics[FX];
|
23732
|
23762
|
this._tanOfHalfFovy = intrinsics[V0] / intrinsics[FY];
|
23733
|
23763
|
this._projectionMatrix = PerspectiveView._computeProjectionMatrix(intrinsics, this._near, this._far);
|
23734
|
23764
|
}
|
|
@@ -23745,6 +23775,12 @@ class PerspectiveView {
|
23745
|
23775
|
return this._aspect;
|
23746
|
23776
|
}
|
23747
|
23777
|
/**
|
|
23778
|
+ * Horizontal field-of-view of the frustum, measured in radians
|
|
23779
|
+ */
|
|
23780
|
+ get fovx() {
|
|
23781
|
+ return 2 * Math.atan(this._tanOfHalfFovx);
|
|
23782
|
+ }
|
|
23783
|
+ /**
|
23748
|
23784
|
* Vertical field-of-view of the frustum, measured in radians
|
23749
|
23785
|
*/
|
23750
|
23786
|
get fovy() {
|
|
@@ -25322,6 +25358,7 @@ class HUD {
|
25322
|
25358
|
* @internal
|
25323
|
25359
|
*/
|
25324
|
25360
|
_release() {
|
|
25361
|
+ this.visible = false;
|
25325
|
25362
|
if (this._isOwnContainer) {
|
25326
|
25363
|
this._isOwnContainer = false;
|
25327
|
25364
|
this._container.remove();
|
|
@@ -25480,6 +25517,8 @@ class ViewportCanvases {
|
25480
|
25517
|
* Release
|
25481
|
25518
|
*/
|
25482
|
25519
|
release() {
|
|
25520
|
+ this._backgroundCanvas.hidden = true;
|
|
25521
|
+ this._foregroundCanvas.hidden = true;
|
25483
|
25522
|
this._backgroundCanvas.style.cssText = '';
|
25484
|
25523
|
this._foregroundCanvas.style.cssText = this._originalCSSTextOfForegroundCanvas;
|
25485
|
25524
|
}
|
|
@@ -25759,6 +25798,7 @@ class InlineResizeStrategy extends ViewportResizeStrategy {
|
25759
|
25798
|
const container = viewport.container;
|
25760
|
25799
|
const subContainer = viewport._subContainer;
|
25761
|
25800
|
const virtualSize = viewport.virtualSize;
|
|
25801
|
+ container.style.display = 'inline-block'; // fixes a potential issue of the viewport not showing up
|
25762
|
25802
|
container.style.position = 'relative';
|
25763
|
25803
|
container.style.left = '0px';
|
25764
|
25804
|
container.style.top = '0px';
|