@vectojs/core 1.22.0 → 1.23.0
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/index.js +502 -329
- package/dist/index.mjs +340 -167
- package/dist/tree/ComputeParticleEntity.d.ts +5 -1
- package/dist/tree/Scene.d.ts +89 -0
- package/dist/wasm/anim-backend.d.ts +21 -4
- package/dist/wasm/backend.d.ts +9 -4
- package/dist/wasm/particle-backend.d.ts +12 -1
- package/dist/wasm/vectojs_core.wasm +0 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -308,12 +308,16 @@ var ComputeParticleEntity = (_class = class extends _chunkAGP4VLF4js.Entity {
|
|
|
308
308
|
* The backend holds one resident SoA store, so a Scene with multiple particle
|
|
309
309
|
* entities reuses it sequentially — origin is therefore re-gathered each call
|
|
310
310
|
* (not upload-once), a couple of extra f32 reads per particle.
|
|
311
|
+
*
|
|
312
|
+
* Returns `false` if the kernel declined the call and {@link updateCPU} ran
|
|
313
|
+
* instead, so the Scene can report which path actually simulated this frame
|
|
314
|
+
* rather than assuming an installed backend did the work.
|
|
311
315
|
*/
|
|
312
316
|
stepWithBackend(backend, dt, mouseX, mouseY, width, height) {
|
|
313
317
|
const count = this.maxParticles;
|
|
314
318
|
backend.ensure(count);
|
|
315
319
|
backend.gather(this.particleData, count, true);
|
|
316
|
-
|
|
320
|
+
const pending = backend.step(count, {
|
|
317
321
|
dt,
|
|
318
322
|
mouseX,
|
|
319
323
|
mouseY,
|
|
@@ -325,8 +329,14 @@ var ComputeParticleEntity = (_class = class extends _chunkAGP4VLF4js.Entity {
|
|
|
325
329
|
maxVelocity: this.maxVelocity,
|
|
326
330
|
explosion: this.pendingExplosion
|
|
327
331
|
});
|
|
332
|
+
if (pending === null) {
|
|
333
|
+
this.updateCPU(dt, mouseX, mouseY, width, height);
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
this._wasmPending = pending;
|
|
328
337
|
backend.scatter(this.particleData, count);
|
|
329
338
|
this.pendingExplosion = null;
|
|
339
|
+
return true;
|
|
330
340
|
}
|
|
331
341
|
destroy() {
|
|
332
342
|
this.destroyGPUResources();
|
|
@@ -470,148 +480,6 @@ function buildTreeStore(root) {
|
|
|
470
480
|
return { store, indexOf };
|
|
471
481
|
}
|
|
472
482
|
|
|
473
|
-
// src/wasm/hit-store.ts
|
|
474
|
-
function gatherHitAABBs(root, currentFrame) {
|
|
475
|
-
const slotEntity = [];
|
|
476
|
-
const boundless = [];
|
|
477
|
-
const minxs = [];
|
|
478
|
-
const minys = [];
|
|
479
|
-
const maxxs = [];
|
|
480
|
-
const maxys = [];
|
|
481
|
-
const scratch = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };
|
|
482
|
-
const visit = (node) => {
|
|
483
|
-
const index = slotEntity.length;
|
|
484
|
-
slotEntity.push(node);
|
|
485
|
-
const bounds = node.getBounds();
|
|
486
|
-
if (bounds === null) {
|
|
487
|
-
boundless.push({ entity: node, index });
|
|
488
|
-
minxs.push(0);
|
|
489
|
-
minys.push(0);
|
|
490
|
-
maxxs.push(0);
|
|
491
|
-
maxys.push(0);
|
|
492
|
-
} else {
|
|
493
|
-
if (!node._readWorldCache(currentFrame, scratch)) {
|
|
494
|
-
const t = node.getWorldTransform();
|
|
495
|
-
scratch.a = t.a;
|
|
496
|
-
scratch.b = t.b;
|
|
497
|
-
scratch.c = t.c;
|
|
498
|
-
scratch.d = t.d;
|
|
499
|
-
scratch.e = t.e;
|
|
500
|
-
scratch.f = t.f;
|
|
501
|
-
}
|
|
502
|
-
const { a, b, c, d, e, f } = scratch;
|
|
503
|
-
let minX = Infinity;
|
|
504
|
-
let minY = Infinity;
|
|
505
|
-
let maxX = -Infinity;
|
|
506
|
-
let maxY = -Infinity;
|
|
507
|
-
for (let i = 0; i < 4; i++) {
|
|
508
|
-
const lx = i & 1 ? bounds.x + bounds.width : bounds.x;
|
|
509
|
-
const ly = i & 2 ? bounds.y + bounds.height : bounds.y;
|
|
510
|
-
const wx = a * lx + c * ly + e;
|
|
511
|
-
const wy = b * lx + d * ly + f;
|
|
512
|
-
if (wx < minX) minX = wx;
|
|
513
|
-
if (wx > maxX) maxX = wx;
|
|
514
|
-
if (wy < minY) minY = wy;
|
|
515
|
-
if (wy > maxY) maxY = wy;
|
|
516
|
-
}
|
|
517
|
-
minxs.push(minX);
|
|
518
|
-
minys.push(minY);
|
|
519
|
-
maxxs.push(maxX);
|
|
520
|
-
maxys.push(maxY);
|
|
521
|
-
}
|
|
522
|
-
const kids = node.children;
|
|
523
|
-
for (let i = 0; i < kids.length; i++) visit(kids[i]);
|
|
524
|
-
};
|
|
525
|
-
visit(root);
|
|
526
|
-
return {
|
|
527
|
-
count: slotEntity.length,
|
|
528
|
-
slotEntity,
|
|
529
|
-
boundless,
|
|
530
|
-
minx: Float64Array.from(minxs),
|
|
531
|
-
miny: Float64Array.from(minys),
|
|
532
|
-
maxx: Float64Array.from(maxxs),
|
|
533
|
-
maxy: Float64Array.from(maxys)
|
|
534
|
-
};
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
// src/wasm/hit-store-fused.ts
|
|
538
|
-
function gatherHitAABBsFromStore(root, aabbs, storeSlotEntity, out) {
|
|
539
|
-
const slotEntity = out.slotEntity;
|
|
540
|
-
const boundless = out.boundless;
|
|
541
|
-
slotEntity.length = 0;
|
|
542
|
-
boundless.length = 0;
|
|
543
|
-
let count = 0;
|
|
544
|
-
let capacity = out.minx.length;
|
|
545
|
-
let minx = out.minx;
|
|
546
|
-
let miny = out.miny;
|
|
547
|
-
let maxx = out.maxx;
|
|
548
|
-
let maxy = out.maxy;
|
|
549
|
-
const grow = (needed) => {
|
|
550
|
-
if (needed <= capacity) return;
|
|
551
|
-
let next = capacity || 256;
|
|
552
|
-
while (next < needed) next *= 2;
|
|
553
|
-
const nminx = new Float64Array(next);
|
|
554
|
-
const nminy = new Float64Array(next);
|
|
555
|
-
const nmaxx = new Float64Array(next);
|
|
556
|
-
const nmaxy = new Float64Array(next);
|
|
557
|
-
nminx.set(minx);
|
|
558
|
-
nminy.set(miny);
|
|
559
|
-
nmaxx.set(maxx);
|
|
560
|
-
nmaxy.set(maxy);
|
|
561
|
-
minx = nminx;
|
|
562
|
-
miny = nminy;
|
|
563
|
-
maxx = nmaxx;
|
|
564
|
-
maxy = nmaxy;
|
|
565
|
-
capacity = next;
|
|
566
|
-
};
|
|
567
|
-
let bailed = false;
|
|
568
|
-
const visit = (node) => {
|
|
569
|
-
if (bailed) return;
|
|
570
|
-
const index = count;
|
|
571
|
-
slotEntity.push(node);
|
|
572
|
-
count++;
|
|
573
|
-
grow(count);
|
|
574
|
-
if (node.getBounds() === null) {
|
|
575
|
-
boundless.push({ entity: node, index });
|
|
576
|
-
minx[index] = 0;
|
|
577
|
-
miny[index] = 0;
|
|
578
|
-
maxx[index] = 0;
|
|
579
|
-
maxy[index] = 0;
|
|
580
|
-
} else {
|
|
581
|
-
const slot = node._storeSlot;
|
|
582
|
-
if (slot < 0 || slot >= aabbs.aminx.length || storeSlotEntity[slot] !== node) {
|
|
583
|
-
bailed = true;
|
|
584
|
-
return;
|
|
585
|
-
}
|
|
586
|
-
minx[index] = aabbs.aminx[slot];
|
|
587
|
-
miny[index] = aabbs.aminy[slot];
|
|
588
|
-
maxx[index] = aabbs.amaxx[slot];
|
|
589
|
-
maxy[index] = aabbs.amaxy[slot];
|
|
590
|
-
}
|
|
591
|
-
const children = node.children;
|
|
592
|
-
for (let i = 0; i < children.length; i++) visit(children[i]);
|
|
593
|
-
};
|
|
594
|
-
visit(root);
|
|
595
|
-
if (bailed) return null;
|
|
596
|
-
out.count = count;
|
|
597
|
-
out.minx = minx;
|
|
598
|
-
out.miny = miny;
|
|
599
|
-
out.maxx = maxx;
|
|
600
|
-
out.maxy = maxy;
|
|
601
|
-
return out;
|
|
602
|
-
}
|
|
603
|
-
function createHitGatherBuffer() {
|
|
604
|
-
return {
|
|
605
|
-
count: 0,
|
|
606
|
-
slotEntity: [],
|
|
607
|
-
boundless: [],
|
|
608
|
-
minx: new Float64Array(256),
|
|
609
|
-
miny: new Float64Array(256),
|
|
610
|
-
maxx: new Float64Array(256),
|
|
611
|
-
maxy: new Float64Array(256)
|
|
612
|
-
};
|
|
613
|
-
}
|
|
614
|
-
|
|
615
483
|
// src/wasm/backend.ts
|
|
616
484
|
var WASM_STATUS = {
|
|
617
485
|
OK: 0,
|
|
@@ -704,7 +572,10 @@ var WasmTransformBackend = (_class2 = class {
|
|
|
704
572
|
return status;
|
|
705
573
|
}
|
|
706
574
|
/** Upload only the run table + count (topology), leaving per-entity inputs to
|
|
707
|
-
* the resident views. Call when the tree structure changes, not per frame.
|
|
575
|
+
* the resident views. Call when the tree structure changes, not per frame.
|
|
576
|
+
* Returns `false` if the crate rejected the run count, in which case the
|
|
577
|
+
* PREVIOUS topology is still published and any kernel run against it would
|
|
578
|
+
* compose the wrong tree — the caller must not proceed. */
|
|
708
579
|
uploadRuns(store) {
|
|
709
580
|
this.ensure(store.count, store.runCount);
|
|
710
581
|
const rc = store.runCount;
|
|
@@ -712,6 +583,7 @@ var WasmTransformBackend = (_class2 = class {
|
|
|
712
583
|
this.vrs.set(store.runStart.subarray(0, rc));
|
|
713
584
|
this.vrl.set(store.runLen.subarray(0, rc));
|
|
714
585
|
this.lastStatus = this.ex.set_run_count(rc);
|
|
586
|
+
return this.lastStatus === WASM_STATUS.OK;
|
|
715
587
|
}
|
|
716
588
|
/**
|
|
717
589
|
* Status of the most recent kernel or run-table call. `WASM_STATUS.OK` unless
|
|
@@ -760,7 +632,8 @@ var WasmTransformBackend = (_class2 = class {
|
|
|
760
632
|
this.vby.set(store.by.subarray(0, n));
|
|
761
633
|
this.vbw.set(store.bw.subarray(0, n));
|
|
762
634
|
this.vbh.set(store.bh.subarray(0, n));
|
|
763
|
-
this.ex.compute_aabbs(n);
|
|
635
|
+
this.lastStatus = this.ex.compute_aabbs(n);
|
|
636
|
+
if (this.lastStatus !== WASM_STATUS.OK) return;
|
|
764
637
|
store.aminx.set(this.vaminx.subarray(0, n));
|
|
765
638
|
store.aminy.set(this.vaminy.subarray(0, n));
|
|
766
639
|
store.amaxx.set(this.vamaxx.subarray(0, n));
|
|
@@ -768,9 +641,12 @@ var WasmTransformBackend = (_class2 = class {
|
|
|
768
641
|
}
|
|
769
642
|
/** Run the AABB pass only, over `count` entities already resident in wasm
|
|
770
643
|
* memory (bounds written via {@link boundsView}, world matrices already
|
|
771
|
-
* composed). No upload/readback — the per-frame resident path.
|
|
644
|
+
* composed). No upload/readback — the per-frame resident path. Returns
|
|
645
|
+
* `false` if the kernel rejected `count` (beyond capacity, or uninitialized),
|
|
646
|
+
* in which case {@link aabbView} still holds the previous frame's bounds. */
|
|
772
647
|
runAabbs(count) {
|
|
773
|
-
this.ex.compute_aabbs(count);
|
|
648
|
+
this.lastStatus = this.ex.compute_aabbs(count);
|
|
649
|
+
return this.lastStatus === WASM_STATUS.OK;
|
|
774
650
|
}
|
|
775
651
|
/** Resident wasm local-bounds input views (`bx,by,bw,bh`) for the AABB pass. */
|
|
776
652
|
boundsView() {
|
|
@@ -844,6 +720,148 @@ var WasmTransformBackend = (_class2 = class {
|
|
|
844
720
|
}
|
|
845
721
|
}, _class2);
|
|
846
722
|
|
|
723
|
+
// src/wasm/hit-store.ts
|
|
724
|
+
function gatherHitAABBs(root, currentFrame) {
|
|
725
|
+
const slotEntity = [];
|
|
726
|
+
const boundless = [];
|
|
727
|
+
const minxs = [];
|
|
728
|
+
const minys = [];
|
|
729
|
+
const maxxs = [];
|
|
730
|
+
const maxys = [];
|
|
731
|
+
const scratch = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };
|
|
732
|
+
const visit = (node) => {
|
|
733
|
+
const index = slotEntity.length;
|
|
734
|
+
slotEntity.push(node);
|
|
735
|
+
const bounds = node.getBounds();
|
|
736
|
+
if (bounds === null) {
|
|
737
|
+
boundless.push({ entity: node, index });
|
|
738
|
+
minxs.push(0);
|
|
739
|
+
minys.push(0);
|
|
740
|
+
maxxs.push(0);
|
|
741
|
+
maxys.push(0);
|
|
742
|
+
} else {
|
|
743
|
+
if (!node._readWorldCache(currentFrame, scratch)) {
|
|
744
|
+
const t = node.getWorldTransform();
|
|
745
|
+
scratch.a = t.a;
|
|
746
|
+
scratch.b = t.b;
|
|
747
|
+
scratch.c = t.c;
|
|
748
|
+
scratch.d = t.d;
|
|
749
|
+
scratch.e = t.e;
|
|
750
|
+
scratch.f = t.f;
|
|
751
|
+
}
|
|
752
|
+
const { a, b, c, d, e, f } = scratch;
|
|
753
|
+
let minX = Infinity;
|
|
754
|
+
let minY = Infinity;
|
|
755
|
+
let maxX = -Infinity;
|
|
756
|
+
let maxY = -Infinity;
|
|
757
|
+
for (let i = 0; i < 4; i++) {
|
|
758
|
+
const lx = i & 1 ? bounds.x + bounds.width : bounds.x;
|
|
759
|
+
const ly = i & 2 ? bounds.y + bounds.height : bounds.y;
|
|
760
|
+
const wx = a * lx + c * ly + e;
|
|
761
|
+
const wy = b * lx + d * ly + f;
|
|
762
|
+
if (wx < minX) minX = wx;
|
|
763
|
+
if (wx > maxX) maxX = wx;
|
|
764
|
+
if (wy < minY) minY = wy;
|
|
765
|
+
if (wy > maxY) maxY = wy;
|
|
766
|
+
}
|
|
767
|
+
minxs.push(minX);
|
|
768
|
+
minys.push(minY);
|
|
769
|
+
maxxs.push(maxX);
|
|
770
|
+
maxys.push(maxY);
|
|
771
|
+
}
|
|
772
|
+
const kids = node.children;
|
|
773
|
+
for (let i = 0; i < kids.length; i++) visit(kids[i]);
|
|
774
|
+
};
|
|
775
|
+
visit(root);
|
|
776
|
+
return {
|
|
777
|
+
count: slotEntity.length,
|
|
778
|
+
slotEntity,
|
|
779
|
+
boundless,
|
|
780
|
+
minx: Float64Array.from(minxs),
|
|
781
|
+
miny: Float64Array.from(minys),
|
|
782
|
+
maxx: Float64Array.from(maxxs),
|
|
783
|
+
maxy: Float64Array.from(maxys)
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
// src/wasm/hit-store-fused.ts
|
|
788
|
+
function gatherHitAABBsFromStore(root, aabbs, storeSlotEntity, out) {
|
|
789
|
+
const slotEntity = out.slotEntity;
|
|
790
|
+
const boundless = out.boundless;
|
|
791
|
+
slotEntity.length = 0;
|
|
792
|
+
boundless.length = 0;
|
|
793
|
+
let count = 0;
|
|
794
|
+
let capacity = out.minx.length;
|
|
795
|
+
let minx = out.minx;
|
|
796
|
+
let miny = out.miny;
|
|
797
|
+
let maxx = out.maxx;
|
|
798
|
+
let maxy = out.maxy;
|
|
799
|
+
const grow = (needed) => {
|
|
800
|
+
if (needed <= capacity) return;
|
|
801
|
+
let next = capacity || 256;
|
|
802
|
+
while (next < needed) next *= 2;
|
|
803
|
+
const nminx = new Float64Array(next);
|
|
804
|
+
const nminy = new Float64Array(next);
|
|
805
|
+
const nmaxx = new Float64Array(next);
|
|
806
|
+
const nmaxy = new Float64Array(next);
|
|
807
|
+
nminx.set(minx);
|
|
808
|
+
nminy.set(miny);
|
|
809
|
+
nmaxx.set(maxx);
|
|
810
|
+
nmaxy.set(maxy);
|
|
811
|
+
minx = nminx;
|
|
812
|
+
miny = nminy;
|
|
813
|
+
maxx = nmaxx;
|
|
814
|
+
maxy = nmaxy;
|
|
815
|
+
capacity = next;
|
|
816
|
+
};
|
|
817
|
+
let bailed = false;
|
|
818
|
+
const visit = (node) => {
|
|
819
|
+
if (bailed) return;
|
|
820
|
+
const index = count;
|
|
821
|
+
slotEntity.push(node);
|
|
822
|
+
count++;
|
|
823
|
+
grow(count);
|
|
824
|
+
if (node.getBounds() === null) {
|
|
825
|
+
boundless.push({ entity: node, index });
|
|
826
|
+
minx[index] = 0;
|
|
827
|
+
miny[index] = 0;
|
|
828
|
+
maxx[index] = 0;
|
|
829
|
+
maxy[index] = 0;
|
|
830
|
+
} else {
|
|
831
|
+
const slot = node._storeSlot;
|
|
832
|
+
if (slot < 0 || slot >= aabbs.aminx.length || storeSlotEntity[slot] !== node) {
|
|
833
|
+
bailed = true;
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
minx[index] = aabbs.aminx[slot];
|
|
837
|
+
miny[index] = aabbs.aminy[slot];
|
|
838
|
+
maxx[index] = aabbs.amaxx[slot];
|
|
839
|
+
maxy[index] = aabbs.amaxy[slot];
|
|
840
|
+
}
|
|
841
|
+
const children = node.children;
|
|
842
|
+
for (let i = 0; i < children.length; i++) visit(children[i]);
|
|
843
|
+
};
|
|
844
|
+
visit(root);
|
|
845
|
+
if (bailed) return null;
|
|
846
|
+
out.count = count;
|
|
847
|
+
out.minx = minx;
|
|
848
|
+
out.miny = miny;
|
|
849
|
+
out.maxx = maxx;
|
|
850
|
+
out.maxy = maxy;
|
|
851
|
+
return out;
|
|
852
|
+
}
|
|
853
|
+
function createHitGatherBuffer() {
|
|
854
|
+
return {
|
|
855
|
+
count: 0,
|
|
856
|
+
slotEntity: [],
|
|
857
|
+
boundless: [],
|
|
858
|
+
minx: new Float64Array(256),
|
|
859
|
+
miny: new Float64Array(256),
|
|
860
|
+
maxx: new Float64Array(256),
|
|
861
|
+
maxy: new Float64Array(256)
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
|
|
847
865
|
// src/wasm/anim-backend.ts
|
|
848
866
|
var PAD3 = 8;
|
|
849
867
|
var AnimBackend = (_class3 = class {
|
|
@@ -852,7 +870,7 @@ var AnimBackend = (_class3 = class {
|
|
|
852
870
|
__init13() {this.tweenCap = 0}
|
|
853
871
|
|
|
854
872
|
|
|
855
|
-
constructor(instance) {;_class3.prototype.__init12.call(this);_class3.prototype.__init13.call(this);
|
|
873
|
+
constructor(instance) {;_class3.prototype.__init12.call(this);_class3.prototype.__init13.call(this);_class3.prototype.__init14.call(this);
|
|
856
874
|
this.ex = instance.exports;
|
|
857
875
|
}
|
|
858
876
|
/** The resident spring SoA input/output views, valid until the next capacity
|
|
@@ -878,14 +896,33 @@ var AnimBackend = (_class3 = class {
|
|
|
878
896
|
this.ex.anim_init(this.springCap, this.tweenCap);
|
|
879
897
|
this.refreshViews();
|
|
880
898
|
}
|
|
881
|
-
/**
|
|
899
|
+
/**
|
|
900
|
+
* Advance `count` springs (from index 0) by `dtMs` milliseconds, in place.
|
|
901
|
+
* Returns `true` when the kernel ran. `false` means it rejected the call
|
|
902
|
+
* (count beyond the capacity {@link ensure} allocated, or no `anim_init` yet)
|
|
903
|
+
* and wrote nothing, so the caller must tick those drivers in JS instead of
|
|
904
|
+
* scattering back a pack the kernel never touched. See {@link lastStatus}.
|
|
905
|
+
*/
|
|
882
906
|
stepSprings(dtMs, count) {
|
|
883
|
-
this.ex.spring_step(dtMs / 1e3, count);
|
|
907
|
+
this.lastStatus = this.ex.spring_step(dtMs / 1e3, count);
|
|
908
|
+
return this.lastStatus === WASM_STATUS.OK;
|
|
884
909
|
}
|
|
885
|
-
/**
|
|
910
|
+
/**
|
|
911
|
+
* Advance `count` tweens (from index 0) by `dtMs` milliseconds, writing `val`.
|
|
912
|
+
* Returns `true` when the kernel ran; `false` means it rejected the call and
|
|
913
|
+
* wrote nothing (see {@link stepSprings}). `elapsed` is kernel-side state, so
|
|
914
|
+
* a rejected tween pack must not be read back — it is unadvanced, not
|
|
915
|
+
* partially advanced.
|
|
916
|
+
*/
|
|
886
917
|
stepTweens(dtMs, count) {
|
|
887
|
-
this.ex.tween_step(dtMs, count);
|
|
918
|
+
this.lastStatus = this.ex.tween_step(dtMs, count);
|
|
919
|
+
return this.lastStatus === WASM_STATUS.OK;
|
|
888
920
|
}
|
|
921
|
+
/**
|
|
922
|
+
* Status of the most recent kernel call — `WASM_STATUS.OK` unless the kernel
|
|
923
|
+
* declined it. Mirrors {@link TransformBackend.lastStatus}.
|
|
924
|
+
*/
|
|
925
|
+
__init14() {this.lastStatus = WASM_STATUS.OK}
|
|
889
926
|
refreshViews() {
|
|
890
927
|
const buf = this.ex.memory.buffer;
|
|
891
928
|
const sCap = this.springCap;
|
|
@@ -915,9 +952,9 @@ var PAD4 = 8;
|
|
|
915
952
|
var CELLS_PER_ENTITY_HINT = 4;
|
|
916
953
|
var HitTestBackend = (_class4 = class {
|
|
917
954
|
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
955
|
+
__init15() {this.entityCap = 0}
|
|
956
|
+
__init16() {this.cellCap = 0}
|
|
957
|
+
__init17() {this.itemCap = 0}
|
|
921
958
|
|
|
922
959
|
|
|
923
960
|
|
|
@@ -926,10 +963,10 @@ var HitTestBackend = (_class4 = class {
|
|
|
926
963
|
|
|
927
964
|
|
|
928
965
|
/** Grid geometry from the last {@link ensure} call. */
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
constructor(instance) {;_class4.prototype.
|
|
966
|
+
__init18() {this.gridW = 0}
|
|
967
|
+
__init19() {this.gridH = 0}
|
|
968
|
+
__init20() {this.cellSize = 64}
|
|
969
|
+
constructor(instance) {;_class4.prototype.__init15.call(this);_class4.prototype.__init16.call(this);_class4.prototype.__init17.call(this);_class4.prototype.__init18.call(this);_class4.prototype.__init19.call(this);_class4.prototype.__init20.call(this);
|
|
933
970
|
this.ex = instance.exports;
|
|
934
971
|
}
|
|
935
972
|
/** The resident AABB input views (`minx/miny/maxx/maxy`), valid until the
|
|
@@ -1013,9 +1050,9 @@ var HitTestBackend = (_class4 = class {
|
|
|
1013
1050
|
var PAD5 = 8;
|
|
1014
1051
|
var ParticleBackend = (_class5 = class {
|
|
1015
1052
|
|
|
1016
|
-
|
|
1053
|
+
__init21() {this.cap = 0}
|
|
1017
1054
|
|
|
1018
|
-
constructor(instance) {;_class5.prototype.
|
|
1055
|
+
constructor(instance) {;_class5.prototype.__init21.call(this);_class5.prototype.__init22.call(this);
|
|
1019
1056
|
this.ex = instance.exports;
|
|
1020
1057
|
}
|
|
1021
1058
|
/** The resident SoA views, valid until the next capacity growth. */
|
|
@@ -1036,6 +1073,12 @@ var ParticleBackend = (_class5 = class {
|
|
|
1036
1073
|
* Advance `count` particles one step in place. Returns `true` when at least
|
|
1037
1074
|
* one live particle is still moving or off-origin beyond epsilon (the fused
|
|
1038
1075
|
* `hasPendingAnimations` flag), so the caller need not re-scan the buffer.
|
|
1076
|
+
*
|
|
1077
|
+
* Returns `null` when the kernel REJECTED the call — `count` beyond the
|
|
1078
|
+
* capacity {@link ensure} allocated, or no `particle_init` yet. Nothing was
|
|
1079
|
+
* written, so the caller must NOT {@link scatter} (that would write the
|
|
1080
|
+
* gathered pre-step values back and freeze the simulation) and should fall
|
|
1081
|
+
* back to the JS `updateCPU` path for this frame. See {@link lastStatus}.
|
|
1039
1082
|
*/
|
|
1040
1083
|
step(count, p) {
|
|
1041
1084
|
const e = p.explosion;
|
|
@@ -1055,8 +1098,18 @@ var ParticleBackend = (_class5 = class {
|
|
|
1055
1098
|
e ? e.force : 0,
|
|
1056
1099
|
count
|
|
1057
1100
|
);
|
|
1101
|
+
if (flag < 0) {
|
|
1102
|
+
this.lastStatus = -flag;
|
|
1103
|
+
return null;
|
|
1104
|
+
}
|
|
1105
|
+
this.lastStatus = WASM_STATUS.OK;
|
|
1058
1106
|
return flag !== 0;
|
|
1059
1107
|
}
|
|
1108
|
+
/**
|
|
1109
|
+
* Status of the most recent {@link step} — `WASM_STATUS.OK` unless the kernel
|
|
1110
|
+
* declined it. Mirrors {@link TransformBackend.lastStatus}.
|
|
1111
|
+
*/
|
|
1112
|
+
__init22() {this.lastStatus = WASM_STATUS.OK}
|
|
1060
1113
|
/** Transpose the AoS stride-8 buffer into the SoA views (position/velocity/
|
|
1061
1114
|
* life every frame; origin upload-once when `withOrigin`). */
|
|
1062
1115
|
gather(data, count, withOrigin) {
|
|
@@ -1147,11 +1200,11 @@ async function loadCoreWasmModule(source) {
|
|
|
1147
1200
|
}
|
|
1148
1201
|
var CoreWasmRuntime = (_class6 = class {
|
|
1149
1202
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
constructor(instance) {;_class6.prototype.
|
|
1203
|
+
__init23() {this.transformBackend = null}
|
|
1204
|
+
__init24() {this.animBackend = null}
|
|
1205
|
+
__init25() {this.hitBackend = null}
|
|
1206
|
+
__init26() {this.particleBackendInstance = null}
|
|
1207
|
+
constructor(instance) {;_class6.prototype.__init23.call(this);_class6.prototype.__init24.call(this);_class6.prototype.__init25.call(this);_class6.prototype.__init26.call(this);
|
|
1155
1208
|
this.instance = instance;
|
|
1156
1209
|
}
|
|
1157
1210
|
/**
|
|
@@ -1520,15 +1573,15 @@ var Scene = (_class7 = class _Scene {
|
|
|
1520
1573
|
|
|
1521
1574
|
|
|
1522
1575
|
|
|
1523
|
-
|
|
1576
|
+
__init27() {this.isRunning = false}
|
|
1524
1577
|
/** Whether the canvas is at least partially in the viewport. When it scrolls
|
|
1525
1578
|
* fully off-screen the rAF loop pauses (stops rescheduling) instead of
|
|
1526
1579
|
* burning frames on a scene nobody can see; an IntersectionObserver resumes
|
|
1527
1580
|
* it on re-entry. Defaults true (and stays true where IntersectionObserver
|
|
1528
1581
|
* is unavailable, e.g. SSR/jsdom, so behavior is unchanged there). */
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1582
|
+
__init28() {this._canvasOnScreen = true}
|
|
1583
|
+
__init29() {this._canvasObserver = null}
|
|
1584
|
+
__init30() {this.lastTime = 0}
|
|
1532
1585
|
|
|
1533
1586
|
/**
|
|
1534
1587
|
* Redraw strategy:
|
|
@@ -1537,11 +1590,11 @@ var Scene = (_class7 = class _Scene {
|
|
|
1537
1590
|
* {@link markDirty}) or while an animation is pending. Ideal for static /
|
|
1538
1591
|
* event-driven UIs where idle frames should cost ~0.
|
|
1539
1592
|
*/
|
|
1540
|
-
|
|
1593
|
+
__init31() {this.renderMode = "always"}
|
|
1541
1594
|
/** Cap on distinct recorded dirty reasons (see `recordDirtyReason`). */
|
|
1542
1595
|
static __initStatic4() {this.MAX_DIRTY_REASONS = 200}
|
|
1543
|
-
|
|
1544
|
-
|
|
1596
|
+
__init32() {this._phaseTiming = false}
|
|
1597
|
+
__init33() {this._phaseTotals = /* @__PURE__ */ new Map()}
|
|
1545
1598
|
/**
|
|
1546
1599
|
* Start or stop per-phase render timing.
|
|
1547
1600
|
*
|
|
@@ -1604,32 +1657,32 @@ var Scene = (_class7 = class _Scene {
|
|
|
1604
1657
|
clearRenderPhases() {
|
|
1605
1658
|
this._phaseTotals.clear();
|
|
1606
1659
|
}
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1660
|
+
__init34() {this._dirtyTracking = false}
|
|
1661
|
+
__init35() {this._dirtyReasons = /* @__PURE__ */ new Map()}
|
|
1662
|
+
__init36() {this.dirty = true}
|
|
1610
1663
|
/** Whether to throttle rendering to 2 FPS when the scene is static to save power. */
|
|
1611
|
-
|
|
1664
|
+
__init37() {this.autoThrottle = true}
|
|
1612
1665
|
// --- Frame telemetry (read via `frameStats`) ---------------------------
|
|
1613
1666
|
/** Wall-clock ms spent inside the last `render()` call. */
|
|
1614
|
-
|
|
1667
|
+
__init38() {this._lastFrameMs = 0}
|
|
1615
1668
|
/** Rolling exponential average of rendered-frame intervals, in ms. */
|
|
1616
|
-
|
|
1669
|
+
__init39() {this._avgFrameIntervalMs = 0}
|
|
1617
1670
|
/** dt (ms) handed to the last rendered frame. */
|
|
1618
|
-
|
|
1671
|
+
__init40() {this._lastDt = 0}
|
|
1619
1672
|
/** Count of frames actually rendered since the loop started. */
|
|
1620
|
-
|
|
1673
|
+
__init41() {this._renderedFrames = 0}
|
|
1621
1674
|
/** Count of rAF ticks skipped (idle / capped) since the loop started. */
|
|
1622
|
-
|
|
1675
|
+
__init42() {this._skippedFrames = 0}
|
|
1623
1676
|
/** `time` of the previous *rendered* frame, for interval measurement. */
|
|
1624
|
-
|
|
1677
|
+
__init43() {this._lastRenderTick = 0}
|
|
1625
1678
|
/**
|
|
1626
1679
|
* Frame-rate cap (power saving). `0` = uncapped (native refresh). When set,
|
|
1627
1680
|
* the loop renders at most `maxFPS` times per second; animations still run,
|
|
1628
1681
|
* just less often. See {@link SceneOptions.maxFPS}.
|
|
1629
1682
|
*/
|
|
1630
|
-
|
|
1683
|
+
__init44() {this.maxFPS = 60}
|
|
1631
1684
|
/** Whether the OS prefers-reduced-motion setting auto-caps the loop. */
|
|
1632
|
-
|
|
1685
|
+
__init45() {this.respectReducedMotion = true}
|
|
1633
1686
|
/**
|
|
1634
1687
|
* Reading direction for accessibility tab/traversal order (`'ltr'` default,
|
|
1635
1688
|
* `'rtl'`). Controls the inline sort within a visual row in
|
|
@@ -1645,15 +1698,15 @@ var Scene = (_class7 = class _Scene {
|
|
|
1645
1698
|
this.a11yNeedsReorder = true;
|
|
1646
1699
|
}
|
|
1647
1700
|
}
|
|
1648
|
-
|
|
1701
|
+
__init46() {this._readingDirection = "ltr"}
|
|
1649
1702
|
/** Cached media-query list; `.matches` is read live each frame. */
|
|
1650
|
-
|
|
1703
|
+
__init47() {this.reducedMotionQuery = null}
|
|
1651
1704
|
/** Cached `(forced-colors: active)` query (Windows High Contrast etc.). A
|
|
1652
1705
|
* canvas gets NO automatic forced-colors treatment from the browser (it's
|
|
1653
1706
|
* opaque pixels), so components must read {@link forcedColors} and repaint
|
|
1654
1707
|
* with system colors themselves; a change listener repaints idle scenes. */
|
|
1655
|
-
|
|
1656
|
-
|
|
1708
|
+
__init48() {this.forcedColorsQuery = null}
|
|
1709
|
+
__init49() {this.forcedColorsChangeHandler = null}
|
|
1657
1710
|
/** True when the OS asks for reduced motion and we respect it. Read by the animation drivers. */
|
|
1658
1711
|
get prefersReducedMotion() {
|
|
1659
1712
|
return this.respectReducedMotion && !!_optionalChain([this, 'access', _21 => _21.reducedMotionQuery, 'optionalAccess', _22 => _22.matches]);
|
|
@@ -1673,22 +1726,22 @@ var Scene = (_class7 = class _Scene {
|
|
|
1673
1726
|
* Throttle interval (ms) for the a11y/automation shadow sync. `0` = every
|
|
1674
1727
|
* frame. See {@link SceneOptions.a11ySyncInterval}.
|
|
1675
1728
|
*/
|
|
1676
|
-
|
|
1729
|
+
__init50() {this.a11ySyncInterval = 0}
|
|
1677
1730
|
/** Timestamp of the last a11y sync, for throttling. */
|
|
1678
|
-
|
|
1731
|
+
__init51() {this.lastA11ySync = -Infinity}
|
|
1679
1732
|
/** True if we skipped an a11y sync during animation and need to sync when at rest. */
|
|
1680
|
-
|
|
1733
|
+
__init52() {this.a11yPendingSyncAfterAnimation = false}
|
|
1681
1734
|
// A11y / Automation Layer. `null` in non-DOM (SSR/Node) environments — the
|
|
1682
1735
|
// whole projection degrades to a no-op so the engine's logic stays usable
|
|
1683
1736
|
// server-side (e.g. headless layout / vector export) without jsdom.
|
|
1684
1737
|
|
|
1685
|
-
|
|
1738
|
+
__init53() {this.a11yElements = /* @__PURE__ */ new Map()}
|
|
1686
1739
|
/** DOM nodes mirroring static text content, keyed by entity id. */
|
|
1687
|
-
|
|
1740
|
+
__init54() {this.contentElements = /* @__PURE__ */ new Map()}
|
|
1688
1741
|
/** Pending cold font-calibration frame per projected grid entity. */
|
|
1689
|
-
|
|
1742
|
+
__init55() {this.contentGridCalibrationFrames = /* @__PURE__ */ new Map()}
|
|
1690
1743
|
/** Detached, untransformed font probes used by the cold calibration pass. */
|
|
1691
|
-
|
|
1744
|
+
__init56() {this.contentGridCalibrationProbes = /* @__PURE__ */ new Map()}
|
|
1692
1745
|
/**
|
|
1693
1746
|
* Monotonic stamp identifying the conditions grid cells were calibrated under.
|
|
1694
1747
|
*
|
|
@@ -1709,69 +1762,69 @@ var Scene = (_class7 = class _Scene {
|
|
|
1709
1762
|
* A plain incrementing integer rather than the descriptive calibration key,
|
|
1710
1763
|
* because it goes into an attribute selector and must not need escaping.
|
|
1711
1764
|
*/
|
|
1712
|
-
|
|
1765
|
+
__init57() {this.contentGridCalibrationGeneration = 0}
|
|
1713
1766
|
/** The `(fontEpoch, pageScale)` pair the current generation corresponds to. */
|
|
1714
|
-
|
|
1767
|
+
__init58() {this.contentGridCalibrationStamp = ""}
|
|
1715
1768
|
/** Invalidates grid font calibration after browser font availability changes. */
|
|
1716
|
-
|
|
1769
|
+
__init59() {this.contentFontEpoch = 0}
|
|
1717
1770
|
/** Cached Canvas-to-client scale for the current font/viewport epoch. */
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1771
|
+
__init60() {this.contentMetricScaleEpoch = -1}
|
|
1772
|
+
__init61() {this.contentMetricScaleX = 1}
|
|
1773
|
+
__init62() {this.contentProjectionEnabled = true}
|
|
1721
1774
|
// Virtualization margin (px) for content projection; `undefined` → one
|
|
1722
1775
|
// viewport height, resolved at sync time. `Infinity` = materialize everything.
|
|
1723
|
-
|
|
1776
|
+
__init63() {this.contentProjectionMargin = void 0}
|
|
1724
1777
|
/**
|
|
1725
1778
|
* True while a text-selection drag that started on a projection's blank
|
|
1726
1779
|
* region (no text node under the press) is being driven manually — the
|
|
1727
1780
|
* browser has no native anchor for it, so mousemove extends the Selection
|
|
1728
1781
|
* from the position we resolved ourselves.
|
|
1729
1782
|
*/
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1783
|
+
__init64() {this.blankRegionSelectionDrag = false}
|
|
1784
|
+
__init65() {this.contentSelectionAnchor = null}
|
|
1785
|
+
__init66() {this.contentSelectionEndListener = null}
|
|
1733
1786
|
// Animation/interactive flags collected during the render walk (tree-walk
|
|
1734
1787
|
// fusion): the loop reads last frame's answers instead of re-walking the
|
|
1735
1788
|
// tree up to 4× per tick. Start true so the first tick stays conservative.
|
|
1736
|
-
|
|
1737
|
-
|
|
1789
|
+
__init67() {this.frameHadAnimation = true}
|
|
1790
|
+
__init68() {this.frameHadInteractive = true}
|
|
1738
1791
|
|
|
1739
1792
|
/** Active `(resolution: Ndppx)` media query watching for a runtime DPR change
|
|
1740
1793
|
* (window moved between monitors, browser zoom) so the canvas backing store
|
|
1741
1794
|
* can be re-scaled — otherwise it stays rasterized at the old DPR and blurs.
|
|
1742
1795
|
* A resolution media query only fires when leaving its exact value, so the
|
|
1743
1796
|
* handler re-arms a fresh query for the new DPR each time. */
|
|
1744
|
-
|
|
1797
|
+
__init69() {this.dprMediaQuery = null}
|
|
1745
1798
|
/** For embedded (`disableWindowResize`) scenes: observes the canvas element so
|
|
1746
1799
|
* a CSS/layout-driven size change re-runs `resize()`. A window `resize`
|
|
1747
1800
|
* listener never fires for these (the window isn't what changed), so without
|
|
1748
1801
|
* this an embedded canvas stayed at its initial size forever. */
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1802
|
+
__init70() {this.canvasResizeObserver = null}
|
|
1803
|
+
__init71() {this.dprChangeHandler = null}
|
|
1804
|
+
__init72() {this.focusedA11yElement = null}
|
|
1752
1805
|
/** Last geometry `syncOverlayGeometry` wrote, so an unchanged frame can skip the
|
|
1753
1806
|
* style writes entirely. Reset to `null` to force the next sync (a new overlay
|
|
1754
1807
|
* layer was created and has never been positioned). */
|
|
1755
|
-
|
|
1808
|
+
__init73() {this._overlayGeometry = null}
|
|
1756
1809
|
/** Shadow elements the pointer is currently inside. Lets a removal that happens
|
|
1757
1810
|
* mid-hover synthesize the `pointerleave` the browser never sends for a
|
|
1758
1811
|
* detached element, so the entity doesn't keep its hover state. */
|
|
1759
|
-
|
|
1812
|
+
__init74() {this.hoveredA11yElements = /* @__PURE__ */ new WeakSet()}
|
|
1760
1813
|
/** Persistent tabindex=-1 element in a11yRoot. When the focused a11y mirror is
|
|
1761
1814
|
* pruned (virtualization/streaming/removal) while it holds focus, we move
|
|
1762
1815
|
* focus here instead of letting the browser drop it to <body> — keeping the
|
|
1763
1816
|
* screen-reader virtual cursor inside the scene's a11y region. */
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1817
|
+
__init75() {this.focusSentinel = null}
|
|
1818
|
+
__init76() {this.caretBlinkTimer = null}
|
|
1819
|
+
__init77() {this.a11yNeedsReorder = true}
|
|
1820
|
+
__init78() {this.portalRoot = null}
|
|
1821
|
+
__init79() {this.fullViewportElements = []}
|
|
1822
|
+
__init80() {this.normalElements = []}
|
|
1823
|
+
__init81() {this.activeIds = /* @__PURE__ */ new Set()}
|
|
1824
|
+
__init82() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
|
|
1825
|
+
__init83() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
|
|
1826
|
+
__init84() {this.portalEntities = /* @__PURE__ */ new Map()}
|
|
1827
|
+
__init85() {this.renderOrderCounter = 0}
|
|
1775
1828
|
/**
|
|
1776
1829
|
* Monotonic render-frame counter, bumped once per authoritative `render()`
|
|
1777
1830
|
* pass. Entities stamp their per-frame world-matrix cache with this value and
|
|
@@ -1780,7 +1833,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
1780
1833
|
* back to the ancestor walk. Public for the same reason `Entity._getTrig`/
|
|
1781
1834
|
* `_setWorldCache` are: it is a cross-class render-internal contract.
|
|
1782
1835
|
*/
|
|
1783
|
-
|
|
1836
|
+
__init86() {this.currentFrame = 0}
|
|
1784
1837
|
// ── WASM transform backend (invisible accelerator) ──────────────────────────
|
|
1785
1838
|
// When `_transformBackend === 'wasm'`, the main render walk sources each
|
|
1786
1839
|
// entity's world matrix from an SoA store composed by `_wasm` (see
|
|
@@ -1788,24 +1841,24 @@ var Scene = (_class7 = class _Scene {
|
|
|
1788
1841
|
// fallback and the default: a null backend, a non-main renderer, or any entity
|
|
1789
1842
|
// absent from the store all fall back to the JS composition, so WASM can only
|
|
1790
1843
|
// ever change *how fast* a world matrix is produced, never *what* it is.
|
|
1791
|
-
|
|
1792
|
-
|
|
1844
|
+
__init87() {this._wasm = null}
|
|
1845
|
+
__init88() {this._transformBackend = "js"}
|
|
1793
1846
|
// Resident store state (Stage 3). The store layout — slot assignment + sibling
|
|
1794
1847
|
// runs — depends only on tree TOPOLOGY, so it is rebuilt only when the
|
|
1795
1848
|
// structure changes (add/remove/reparent bump `_structureVersion`). Between
|
|
1796
1849
|
// rebuilds the per-frame cost is: gather each entity's transform into the
|
|
1797
1850
|
// resident wasm input view + run the kernel — no reallocation, no readback.
|
|
1798
|
-
|
|
1799
|
-
|
|
1851
|
+
__init89() {this._treeStore = null}
|
|
1852
|
+
__init90() {this._slotEntity = []}
|
|
1800
1853
|
// store slot -> entity (also validates slots)
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1854
|
+
__init91() {this._wasmInputs = null}
|
|
1855
|
+
__init92() {this._wasmWorld = null}
|
|
1856
|
+
__init93() {this._structureVersion = 0}
|
|
1857
|
+
__init94() {this._storeStructureVersion = -1}
|
|
1805
1858
|
// Cached list of ComputeParticleEntity instances in the tree, keyed by the
|
|
1806
1859
|
// structure version it was gathered at. Rebuilt only on a topology change.
|
|
1807
|
-
|
|
1808
|
-
|
|
1860
|
+
__init95() {this._computeEntities = []}
|
|
1861
|
+
__init96() {this._computeEntitiesVersion = -1}
|
|
1809
1862
|
/** Invalidate the resident WASM store layout; the next wasm-mode frame rebuilds
|
|
1810
1863
|
* it. Called by `Entity.add`/`remove` (topology changes only). */
|
|
1811
1864
|
markStructureChanged() {
|
|
@@ -1867,10 +1920,13 @@ var Scene = (_class7 = class _Scene {
|
|
|
1867
1920
|
return true;
|
|
1868
1921
|
}
|
|
1869
1922
|
// ── WASM hit-test backend (invisible accelerator, G3) ───────────────────────
|
|
1870
|
-
//
|
|
1871
|
-
//
|
|
1872
|
-
//
|
|
1873
|
-
// AABBs into a dense viewport grid for findEntityAt.
|
|
1923
|
+
// Served by the same instance as every other accelerator (see
|
|
1924
|
+
// `_wasmRuntime`): the crate keeps transform/anim/hit/particle in distinct
|
|
1925
|
+
// statics, so one instance runs them all without aliasing. It indexes the
|
|
1926
|
+
// main tree's world AABBs into a dense viewport grid for findEntityAt. Note
|
|
1927
|
+
// that sharing one linear memory means an allocation here can grow it and
|
|
1928
|
+
// detach views built over the old buffer, so each backend re-checks buffer
|
|
1929
|
+
// identity (`revalidateViews`) before use. The JS depth-first walk
|
|
1874
1930
|
// (findHitRecursively) is the permanent fallback: a null backend, a build
|
|
1875
1931
|
// that overflows its item budget, or the overlay tree (never indexed — small
|
|
1876
1932
|
// and rare, not worth accelerating) all fall through to it, so WASM can only
|
|
@@ -1887,7 +1943,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
1887
1943
|
* cached globally; the instance is per-Scene, which is the isolation that
|
|
1888
1944
|
* actually matters.
|
|
1889
1945
|
*/
|
|
1890
|
-
|
|
1946
|
+
__init97() {this._wasmRuntime = null}
|
|
1891
1947
|
/**
|
|
1892
1948
|
* Load (or reuse) this Scene's shared WASM runtime.
|
|
1893
1949
|
*
|
|
@@ -1915,34 +1971,98 @@ var Scene = (_class7 = class _Scene {
|
|
|
1915
1971
|
get wasmRuntime() {
|
|
1916
1972
|
return this._wasmRuntime;
|
|
1917
1973
|
}
|
|
1918
|
-
|
|
1974
|
+
__init98() {this._hitWasm = null}
|
|
1919
1975
|
// Cache key: which frame + structure version the grid was last (successfully,
|
|
1920
1976
|
// non-overflowing) built for. findEntityAt is called ad-hoc (pointer
|
|
1921
1977
|
// hover/click), not every frame, so the grid is refreshed lazily on demand
|
|
1922
1978
|
// rather than proactively every render() — unlike the transform store, which
|
|
1923
1979
|
// every frame's draw depends on.
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1980
|
+
__init99() {this._hitGridFrame = -1}
|
|
1981
|
+
__init100() {this._hitGridOk = false}
|
|
1982
|
+
__init101() {this._hitSlotEntity = []}
|
|
1983
|
+
__init102() {this._hitBoundless = []}
|
|
1928
1984
|
/** Reused buffer for the fused gather, so a pointer query allocates nothing. */
|
|
1929
|
-
|
|
1985
|
+
__init103() {this._hitGatherBuffer = null}
|
|
1930
1986
|
/**
|
|
1931
1987
|
* Whether the last grid build sourced its AABBs from the WASM transform store
|
|
1932
1988
|
* rather than recomputing them in JS. Diagnostic only — both paths must
|
|
1933
1989
|
* produce the same entity for a given point.
|
|
1934
1990
|
*/
|
|
1935
|
-
|
|
1991
|
+
__init104() {this._hitFusedGather = false}
|
|
1936
1992
|
/**
|
|
1937
1993
|
* Whether `compute_aabbs` has run against the current frame's world matrices.
|
|
1938
1994
|
* The AABB pass is only meaningful after a `compose_*`, so the fused gather
|
|
1939
1995
|
* must not read the views before then.
|
|
1940
1996
|
*/
|
|
1941
|
-
|
|
1997
|
+
__init105() {this._wasmAabbsFresh = false}
|
|
1942
1998
|
/** Did the last hit-grid build use the fused (WASM-store) gather? */
|
|
1943
1999
|
get hitGatherPath() {
|
|
1944
2000
|
return this._hitFusedGather ? "fused" : "js";
|
|
1945
2001
|
}
|
|
2002
|
+
/**
|
|
2003
|
+
* Why the transform accelerator did or did not run on the most recent frame.
|
|
2004
|
+
* Written by the render walk and `_syncWasmStore`.
|
|
2005
|
+
*/
|
|
2006
|
+
__init106() {this._transformReason = "not-installed"}
|
|
2007
|
+
/** Why the batched-driver accelerator did or did not run. */
|
|
2008
|
+
__init107() {this._animReason = "not-installed"}
|
|
2009
|
+
/**
|
|
2010
|
+
* Why the hit-test accelerator did or did not serve the last pointer query.
|
|
2011
|
+
* The grid is built lazily on demand, not every frame, so this describes the
|
|
2012
|
+
* most recent BUILD. Starts at `'not-installed'` because that is the truth
|
|
2013
|
+
* before a backend exists; `_ensureHitGrid` moves it to `'not-applicable'`
|
|
2014
|
+
* once one is installed but nothing has queried yet.
|
|
2015
|
+
*/
|
|
2016
|
+
__init108() {this._hitReason = "not-installed"}
|
|
2017
|
+
/** Why the particle accelerator did or did not run. */
|
|
2018
|
+
__init109() {this._particleReason = "not-applicable"}
|
|
2019
|
+
/** Which particle implementation actually simulated the most recent frame. */
|
|
2020
|
+
__init110() {this._particlePath = "none"}
|
|
2021
|
+
/**
|
|
2022
|
+
* Per-frame status of every invisible accelerator: whether each is installed,
|
|
2023
|
+
* whether it actually ran on the most recent frame, and why.
|
|
2024
|
+
*
|
|
2025
|
+
* This exists because the older per-accelerator getters
|
|
2026
|
+
* ({@link transformBackend}, {@link animBackend}, {@link hitTestBackend},
|
|
2027
|
+
* {@link particleBackend}) report only that a backend is INSTALLED. Reading
|
|
2028
|
+
* `'wasm'` from one of those and concluding the accelerator is doing work is
|
|
2029
|
+
* wrong whenever a gate never opens, a kernel rejects its arguments, or a
|
|
2030
|
+
* faster backend takes the pass instead. Read {@link AcceleratorStatus.reason}
|
|
2031
|
+
* for which of those happened.
|
|
2032
|
+
*
|
|
2033
|
+
* Reflects the most recent main-renderer frame; a secondary renderer (SVG
|
|
2034
|
+
* export, offscreen snapshot) does not overwrite it.
|
|
2035
|
+
*/
|
|
2036
|
+
get accelerators() {
|
|
2037
|
+
return {
|
|
2038
|
+
transform: {
|
|
2039
|
+
available: this._wasm !== null && this._transformBackend === "wasm",
|
|
2040
|
+
activeThisFrame: this._transformReason === "active",
|
|
2041
|
+
reason: this._transformReason,
|
|
2042
|
+
path: this._transformReason === "active" ? "wasm" : "js"
|
|
2043
|
+
},
|
|
2044
|
+
animation: {
|
|
2045
|
+
available: this._animWasm !== null,
|
|
2046
|
+
activeThisFrame: this._animBatchedLastFrame,
|
|
2047
|
+
reason: this._animReason,
|
|
2048
|
+
path: this._animBatchedLastFrame ? "wasm" : "js"
|
|
2049
|
+
},
|
|
2050
|
+
hitTest: {
|
|
2051
|
+
available: this._hitWasm !== null,
|
|
2052
|
+
// The grid is built lazily on a pointer query, not every frame, so this
|
|
2053
|
+
// describes the last BUILD rather than the last frame.
|
|
2054
|
+
activeThisFrame: this._hitReason === "active",
|
|
2055
|
+
reason: this._hitReason,
|
|
2056
|
+
path: this._hitReason !== "active" ? "js" : this._hitFusedGather ? "wasm-fused" : "wasm"
|
|
2057
|
+
},
|
|
2058
|
+
particle: {
|
|
2059
|
+
available: this._particleWasm !== null || this.webgpuActive,
|
|
2060
|
+
activeThisFrame: this._particleReason === "active",
|
|
2061
|
+
reason: this._particleReason,
|
|
2062
|
+
path: this._particlePath
|
|
2063
|
+
}
|
|
2064
|
+
};
|
|
2065
|
+
}
|
|
1946
2066
|
/** Which backend answers `findEntityAt` for the main tree. */
|
|
1947
2067
|
get hitTestBackend() {
|
|
1948
2068
|
return this._hitWasm ? "wasm" : "js";
|
|
@@ -1952,6 +2072,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
1952
2072
|
setHitTestBackend(backend) {
|
|
1953
2073
|
this._hitWasm = backend;
|
|
1954
2074
|
this._hitGridFrame = -1;
|
|
2075
|
+
this._hitReason = backend ? "not-applicable" : "not-installed";
|
|
1955
2076
|
}
|
|
1956
2077
|
/**
|
|
1957
2078
|
* Asynchronously instantiate the WASM hit-test core and, on success, hot-swap
|
|
@@ -1978,7 +2099,10 @@ var Scene = (_class7 = class _Scene {
|
|
|
1978
2099
|
*/
|
|
1979
2100
|
_ensureHitGrid() {
|
|
1980
2101
|
const backend = this._hitWasm;
|
|
1981
|
-
if (!backend)
|
|
2102
|
+
if (!backend) {
|
|
2103
|
+
this._hitReason = "not-installed";
|
|
2104
|
+
return false;
|
|
2105
|
+
}
|
|
1982
2106
|
if (this._hitGridFrame === this.currentFrame) return this._hitGridOk;
|
|
1983
2107
|
let gathered = null;
|
|
1984
2108
|
if (this._wasm && this._ensureWasmAabbs()) {
|
|
@@ -2007,6 +2131,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2007
2131
|
this._hitBoundless = gathered.boundless;
|
|
2008
2132
|
this._hitGridFrame = this.currentFrame;
|
|
2009
2133
|
this._hitGridOk = ok;
|
|
2134
|
+
this._hitReason = ok ? "active" : "rejected";
|
|
2010
2135
|
return ok;
|
|
2011
2136
|
}
|
|
2012
2137
|
/**
|
|
@@ -2052,25 +2177,25 @@ var Scene = (_class7 = class _Scene {
|
|
|
2052
2177
|
// EasingFn (which cannot cross into WASM) all fall through to it — WASM can
|
|
2053
2178
|
// only ever change *how* a driver is advanced, never *what* value it lands
|
|
2054
2179
|
// on.
|
|
2055
|
-
|
|
2180
|
+
__init111() {this._animWasm = null}
|
|
2056
2181
|
// Entities with at least one active driver, added by Entity._spawnDriver.
|
|
2057
2182
|
// Self-pruning: _tickBatchedDrivers drops an entry the first time it visits
|
|
2058
2183
|
// an entity whose drivers have since all completed or been removed. This is
|
|
2059
2184
|
// what lets the batch pass find its candidates in O(active drivers), not
|
|
2060
2185
|
// O(tree size) — the exact mistake G3's first integrated benchmark made.
|
|
2061
|
-
|
|
2186
|
+
__init112() {this._activeDriverEntities = /* @__PURE__ */ new Set()}
|
|
2062
2187
|
// Reused across frames instead of allocating a fresh array + N {entity,prop,
|
|
2063
2188
|
// driver} objects every call — the integrated benchmark
|
|
2064
2189
|
// (benchmarks/anim-wasm-scene) found that allocation churn was the
|
|
2065
2190
|
// dominant integrated cost, not the wasm kernel itself. Parallel arrays,
|
|
2066
2191
|
// truncated to the live count after each use so a stale tail slot never
|
|
2067
2192
|
// pins a no-longer-active entity/driver in memory.
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2193
|
+
__init113() {this._springEntities = []}
|
|
2194
|
+
__init114() {this._springProps = []}
|
|
2195
|
+
__init115() {this._springDrivers = []}
|
|
2196
|
+
__init116() {this._tweenEntities = []}
|
|
2197
|
+
__init117() {this._tweenProps = []}
|
|
2198
|
+
__init118() {this._tweenDrivers = []}
|
|
2074
2199
|
/**
|
|
2075
2200
|
* Minimum number of batchable (spring, or named-easing tween) active drivers
|
|
2076
2201
|
* before a frame engages the WASM batch path at all; below it, every driver
|
|
@@ -2142,7 +2267,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2142
2267
|
* Setting {@link animDriverGateCount} overwrites all three, so existing code
|
|
2143
2268
|
* that tuned the single knob keeps working unchanged.
|
|
2144
2269
|
*/
|
|
2145
|
-
|
|
2270
|
+
__init119() {this._animBatchedLastFrame = false}
|
|
2146
2271
|
/**
|
|
2147
2272
|
* Whether the WASM batch path actually ran on the most recent frame.
|
|
2148
2273
|
*
|
|
@@ -2154,7 +2279,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2154
2279
|
get animBatchedLastFrame() {
|
|
2155
2280
|
return this._animBatchedLastFrame;
|
|
2156
2281
|
}
|
|
2157
|
-
|
|
2282
|
+
__init120() {this.animGate = {
|
|
2158
2283
|
spring: 128,
|
|
2159
2284
|
tween: 256,
|
|
2160
2285
|
mixed: 128
|
|
@@ -2192,7 +2317,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2192
2317
|
// (benchmarks/particle-wasm). f32 (matches the WGSL shader), bit-identical to
|
|
2193
2318
|
// a JS f32 reference oracle; updateCPU (f64) stays the permanent fallback when
|
|
2194
2319
|
// no backend is installed or a scene runs on WebGPU.
|
|
2195
|
-
|
|
2320
|
+
__init121() {this._particleWasm = null}
|
|
2196
2321
|
/** Which backend runs the CPU particle simulation. Reflects only whether a
|
|
2197
2322
|
* backend is installed (the WebGPU compute path, when active, is used first
|
|
2198
2323
|
* regardless). */
|
|
@@ -2272,7 +2397,10 @@ var Scene = (_class7 = class _Scene {
|
|
|
2272
2397
|
* pre-pass.
|
|
2273
2398
|
*/
|
|
2274
2399
|
_tickBatchedDrivers(dt) {
|
|
2275
|
-
if (this._activeDriverEntities.size === 0)
|
|
2400
|
+
if (this._activeDriverEntities.size === 0) {
|
|
2401
|
+
this._animReason = "not-applicable";
|
|
2402
|
+
return;
|
|
2403
|
+
}
|
|
2276
2404
|
let springBatchable = 0;
|
|
2277
2405
|
let tweenBatchable = 0;
|
|
2278
2406
|
for (const entity of this._activeDriverEntities) {
|
|
@@ -2289,10 +2417,17 @@ var Scene = (_class7 = class _Scene {
|
|
|
2289
2417
|
const batchable = springBatchable + tweenBatchable;
|
|
2290
2418
|
const backend = this._animWasm;
|
|
2291
2419
|
this._animBatchedLastFrame = false;
|
|
2292
|
-
if (!backend)
|
|
2420
|
+
if (!backend) {
|
|
2421
|
+
this._animReason = "not-installed";
|
|
2422
|
+
return;
|
|
2423
|
+
}
|
|
2293
2424
|
const gate = springBatchable > 0 && tweenBatchable > 0 ? this.animGate.mixed : tweenBatchable > 0 ? this.animGate.tween : this.animGate.spring;
|
|
2294
|
-
if (batchable < gate)
|
|
2425
|
+
if (batchable < gate) {
|
|
2426
|
+
this._animReason = "below-gate";
|
|
2427
|
+
return;
|
|
2428
|
+
}
|
|
2295
2429
|
this._animBatchedLastFrame = true;
|
|
2430
|
+
this._animReason = "active";
|
|
2296
2431
|
const sE = this._springEntities;
|
|
2297
2432
|
const sP = this._springProps;
|
|
2298
2433
|
const sD = this._springDrivers;
|
|
@@ -2339,8 +2474,13 @@ var Scene = (_class7 = class _Scene {
|
|
|
2339
2474
|
sv.damp[i] = phys.damping;
|
|
2340
2475
|
sv.mass[i] = phys.mass;
|
|
2341
2476
|
}
|
|
2342
|
-
backend.stepSprings(dt, springCount)
|
|
2343
|
-
|
|
2477
|
+
if (backend.stepSprings(dt, springCount)) {
|
|
2478
|
+
for (let i = 0; i < springCount; i++) sD[i].syncExternal(sv.val[i], sv.vel[i]);
|
|
2479
|
+
} else {
|
|
2480
|
+
for (let i = 0; i < springCount; i++) sD[i].tick(dt);
|
|
2481
|
+
this._animReason = "rejected";
|
|
2482
|
+
this._animBatchedLastFrame = false;
|
|
2483
|
+
}
|
|
2344
2484
|
}
|
|
2345
2485
|
if (tweenCount > 0) {
|
|
2346
2486
|
const tv = backend.tweenView();
|
|
@@ -2353,8 +2493,13 @@ var Scene = (_class7 = class _Scene {
|
|
|
2353
2493
|
tv.delay[i] = d.delayMs;
|
|
2354
2494
|
tv.ease[i] = d.wasmEasingId;
|
|
2355
2495
|
}
|
|
2356
|
-
backend.stepTweens(dt, tweenCount)
|
|
2357
|
-
|
|
2496
|
+
if (backend.stepTweens(dt, tweenCount)) {
|
|
2497
|
+
for (let i = 0; i < tweenCount; i++) tD[i].syncExternal(tv.val[i], tv.elapsed[i]);
|
|
2498
|
+
} else {
|
|
2499
|
+
for (let i = 0; i < tweenCount; i++) tD[i].tick(dt);
|
|
2500
|
+
this._animReason = "rejected";
|
|
2501
|
+
this._animBatchedLastFrame = false;
|
|
2502
|
+
}
|
|
2358
2503
|
}
|
|
2359
2504
|
for (let i = 0; i < springCount; i++) sE[i]._applyDriverTick(sP[i], sD[i]);
|
|
2360
2505
|
for (let i = 0; i < tweenCount; i++) tE[i]._applyDriverTick(tP[i], tD[i]);
|
|
@@ -2376,7 +2521,10 @@ var Scene = (_class7 = class _Scene {
|
|
|
2376
2521
|
slotEntity2[slot] = entity;
|
|
2377
2522
|
entity._storeSlot = slot;
|
|
2378
2523
|
}
|
|
2379
|
-
backend.uploadRuns(built.store)
|
|
2524
|
+
if (!backend.uploadRuns(built.store)) {
|
|
2525
|
+
this._transformReason = "rejected";
|
|
2526
|
+
return null;
|
|
2527
|
+
}
|
|
2380
2528
|
this._treeStore = built.store;
|
|
2381
2529
|
this._slotEntity = slotEntity2;
|
|
2382
2530
|
this._wasmInputs = backend.inputView();
|
|
@@ -2401,8 +2549,12 @@ var Scene = (_class7 = class _Scene {
|
|
|
2401
2549
|
inp.sin[slot] = trig.sin;
|
|
2402
2550
|
inp.opacity[slot] = e.opacity;
|
|
2403
2551
|
}
|
|
2404
|
-
backend.runKernel("simd")
|
|
2552
|
+
if (backend.runKernel("simd") !== WASM_STATUS.OK) {
|
|
2553
|
+
this._transformReason = "rejected";
|
|
2554
|
+
return null;
|
|
2555
|
+
}
|
|
2405
2556
|
this._wasmAabbsFresh = false;
|
|
2557
|
+
this._transformReason = "active";
|
|
2406
2558
|
return this._wasmWorld;
|
|
2407
2559
|
}
|
|
2408
2560
|
/**
|
|
@@ -2432,7 +2584,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2432
2584
|
bounds.bw[slot] = b ? b.width : 0;
|
|
2433
2585
|
bounds.bh[slot] = b ? b.height : 0;
|
|
2434
2586
|
}
|
|
2435
|
-
backend.runAabbs(slotEntity.length);
|
|
2587
|
+
if (!backend.runAabbs(slotEntity.length)) return false;
|
|
2436
2588
|
this._wasmAabbsFresh = true;
|
|
2437
2589
|
return true;
|
|
2438
2590
|
}
|
|
@@ -2442,24 +2594,24 @@ var Scene = (_class7 = class _Scene {
|
|
|
2442
2594
|
* sync, so retaining the order prevents a newly opened overlay from spending
|
|
2443
2595
|
* its first frame below previously projected controls.
|
|
2444
2596
|
*/
|
|
2445
|
-
|
|
2597
|
+
__init122() {this.a11yRenderOrders = /* @__PURE__ */ new Map()}
|
|
2446
2598
|
// Optional WebGL point-cloud layer (see SceneOptions.pointBackend).
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2599
|
+
__init123() {this.pointRenderer = null}
|
|
2600
|
+
__init124() {this.glCanvas = null}
|
|
2601
|
+
__init125() {this.glContextLostHandler = null}
|
|
2602
|
+
__init126() {this.glContextRestoredHandler = null}
|
|
2451
2603
|
|
|
2452
2604
|
|
|
2453
2605
|
|
|
2454
|
-
|
|
2606
|
+
__init127() {this.disableWindowResize = false}
|
|
2455
2607
|
/** See {@link SceneOptions.maxDPR}. `undefined` = uncapped (real DPR). */
|
|
2456
2608
|
|
|
2457
2609
|
// WebGPU properties
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2610
|
+
__init128() {this.destroyed = false}
|
|
2611
|
+
__init129() {this.device = null}
|
|
2612
|
+
__init130() {this.deviceLost = false}
|
|
2613
|
+
__init131() {this.particleBackend = "auto"}
|
|
2614
|
+
__init132() {this._webgpuDisabled = false}
|
|
2463
2615
|
get webgpuDisabled() {
|
|
2464
2616
|
return this._webgpuDisabled || this.particleBackend === "cpu";
|
|
2465
2617
|
}
|
|
@@ -2487,22 +2639,22 @@ var Scene = (_class7 = class _Scene {
|
|
|
2487
2639
|
set webgpuDisabled(value) {
|
|
2488
2640
|
this._webgpuDisabled = value;
|
|
2489
2641
|
}
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2642
|
+
__init133() {this.recoveryTimerId = null}
|
|
2643
|
+
__init134() {this.manager = null}
|
|
2644
|
+
__init135() {this.initializingWebGPU = false}
|
|
2645
|
+
__init136() {this.gpuCanvas = null}
|
|
2646
|
+
__init137() {this.gpuContext = null}
|
|
2495
2647
|
/** True while the GPU canvas holds a presented particle frame (needs clearing when they leave). */
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2648
|
+
__init138() {this.gpuHasContent = false}
|
|
2649
|
+
__init139() {this.mouseX = -9999}
|
|
2650
|
+
__init140() {this.mouseY = -9999}
|
|
2651
|
+
__init141() {this.pointerMoveListener = null}
|
|
2652
|
+
__init142() {this.pointerLeaveListener = null}
|
|
2501
2653
|
/** Element the pointer listeners are bound to (parent container if present,
|
|
2502
2654
|
* else the canvas). Stored so `destroy()` detaches from the same element. */
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2655
|
+
__init143() {this.pointerEventTarget = null}
|
|
2656
|
+
__init144() {this.hasWarnedZeroSize = false}
|
|
2657
|
+
__init145() {this.fontLoadHandler = null}
|
|
2506
2658
|
// ── Dev-mode warning infrastructure ──────────────────────────────
|
|
2507
2659
|
//
|
|
2508
2660
|
// Enable with `Scene.devMode = true` or by setting `globalThis.__DEV__`.
|
|
@@ -2520,7 +2672,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2520
2672
|
return false;
|
|
2521
2673
|
}
|
|
2522
2674
|
|
|
2523
|
-
|
|
2675
|
+
__init146() {this._devFrameCount = 0}
|
|
2524
2676
|
_devWarn(message) {
|
|
2525
2677
|
if (!this._devActive) return;
|
|
2526
2678
|
console.warn(`[vectojs/dev] ${message}`);
|
|
@@ -2564,7 +2716,7 @@ var Scene = (_class7 = class _Scene {
|
|
|
2564
2716
|
};
|
|
2565
2717
|
walkProjections(this.root);
|
|
2566
2718
|
}
|
|
2567
|
-
constructor(canvas, options = {}) {;_class7.prototype.
|
|
2719
|
+
constructor(canvas, options = {}) {;_class7.prototype.__init27.call(this);_class7.prototype.__init28.call(this);_class7.prototype.__init29.call(this);_class7.prototype.__init30.call(this);_class7.prototype.__init31.call(this);_class7.prototype.__init32.call(this);_class7.prototype.__init33.call(this);_class7.prototype.__init34.call(this);_class7.prototype.__init35.call(this);_class7.prototype.__init36.call(this);_class7.prototype.__init37.call(this);_class7.prototype.__init38.call(this);_class7.prototype.__init39.call(this);_class7.prototype.__init40.call(this);_class7.prototype.__init41.call(this);_class7.prototype.__init42.call(this);_class7.prototype.__init43.call(this);_class7.prototype.__init44.call(this);_class7.prototype.__init45.call(this);_class7.prototype.__init46.call(this);_class7.prototype.__init47.call(this);_class7.prototype.__init48.call(this);_class7.prototype.__init49.call(this);_class7.prototype.__init50.call(this);_class7.prototype.__init51.call(this);_class7.prototype.__init52.call(this);_class7.prototype.__init53.call(this);_class7.prototype.__init54.call(this);_class7.prototype.__init55.call(this);_class7.prototype.__init56.call(this);_class7.prototype.__init57.call(this);_class7.prototype.__init58.call(this);_class7.prototype.__init59.call(this);_class7.prototype.__init60.call(this);_class7.prototype.__init61.call(this);_class7.prototype.__init62.call(this);_class7.prototype.__init63.call(this);_class7.prototype.__init64.call(this);_class7.prototype.__init65.call(this);_class7.prototype.__init66.call(this);_class7.prototype.__init67.call(this);_class7.prototype.__init68.call(this);_class7.prototype.__init69.call(this);_class7.prototype.__init70.call(this);_class7.prototype.__init71.call(this);_class7.prototype.__init72.call(this);_class7.prototype.__init73.call(this);_class7.prototype.__init74.call(this);_class7.prototype.__init75.call(this);_class7.prototype.__init76.call(this);_class7.prototype.__init77.call(this);_class7.prototype.__init78.call(this);_class7.prototype.__init79.call(this);_class7.prototype.__init80.call(this);_class7.prototype.__init81.call(this);_class7.prototype.__init82.call(this);_class7.prototype.__init83.call(this);_class7.prototype.__init84.call(this);_class7.prototype.__init85.call(this);_class7.prototype.__init86.call(this);_class7.prototype.__init87.call(this);_class7.prototype.__init88.call(this);_class7.prototype.__init89.call(this);_class7.prototype.__init90.call(this);_class7.prototype.__init91.call(this);_class7.prototype.__init92.call(this);_class7.prototype.__init93.call(this);_class7.prototype.__init94.call(this);_class7.prototype.__init95.call(this);_class7.prototype.__init96.call(this);_class7.prototype.__init97.call(this);_class7.prototype.__init98.call(this);_class7.prototype.__init99.call(this);_class7.prototype.__init100.call(this);_class7.prototype.__init101.call(this);_class7.prototype.__init102.call(this);_class7.prototype.__init103.call(this);_class7.prototype.__init104.call(this);_class7.prototype.__init105.call(this);_class7.prototype.__init106.call(this);_class7.prototype.__init107.call(this);_class7.prototype.__init108.call(this);_class7.prototype.__init109.call(this);_class7.prototype.__init110.call(this);_class7.prototype.__init111.call(this);_class7.prototype.__init112.call(this);_class7.prototype.__init113.call(this);_class7.prototype.__init114.call(this);_class7.prototype.__init115.call(this);_class7.prototype.__init116.call(this);_class7.prototype.__init117.call(this);_class7.prototype.__init118.call(this);_class7.prototype.__init119.call(this);_class7.prototype.__init120.call(this);_class7.prototype.__init121.call(this);_class7.prototype.__init122.call(this);_class7.prototype.__init123.call(this);_class7.prototype.__init124.call(this);_class7.prototype.__init125.call(this);_class7.prototype.__init126.call(this);_class7.prototype.__init127.call(this);_class7.prototype.__init128.call(this);_class7.prototype.__init129.call(this);_class7.prototype.__init130.call(this);_class7.prototype.__init131.call(this);_class7.prototype.__init132.call(this);_class7.prototype.__init133.call(this);_class7.prototype.__init134.call(this);_class7.prototype.__init135.call(this);_class7.prototype.__init136.call(this);_class7.prototype.__init137.call(this);_class7.prototype.__init138.call(this);_class7.prototype.__init139.call(this);_class7.prototype.__init140.call(this);_class7.prototype.__init141.call(this);_class7.prototype.__init142.call(this);_class7.prototype.__init143.call(this);_class7.prototype.__init144.call(this);_class7.prototype.__init145.call(this);_class7.prototype.__init146.call(this);
|
|
2568
2720
|
this.canvas = canvas;
|
|
2569
2721
|
this.debugA11y = _nullishCoalesce(options.debugA11y, () => ( false));
|
|
2570
2722
|
this.disableWindowResize = _nullishCoalesce(options.disableWindowResize, () => ( false));
|
|
@@ -4706,6 +4858,10 @@ var Scene = (_class7 = class _Scene {
|
|
|
4706
4858
|
const computeEntities = this._computeEntitiesFor(this._structureVersion);
|
|
4707
4859
|
if (computeEntities.length > 0) {
|
|
4708
4860
|
const isMainRenderPath = renderer === this.renderer;
|
|
4861
|
+
if (isMainRenderPath) {
|
|
4862
|
+
this._particleReason = this._particleWasm ? "active" : "not-installed";
|
|
4863
|
+
this._particlePath = this._particleWasm ? "wasm" : "js";
|
|
4864
|
+
}
|
|
4709
4865
|
if (isMainRenderPath && !this.device && !this.webgpuDisabled && !this.initializingWebGPU && !this.deviceLost) {
|
|
4710
4866
|
this.initializingWebGPU = true;
|
|
4711
4867
|
this.initWebGPUContext(computeEntities).then((newDevice) => {
|
|
@@ -4781,6 +4937,8 @@ var Scene = (_class7 = class _Scene {
|
|
|
4781
4937
|
}
|
|
4782
4938
|
this.device.queue.submit([commandEncoder.finish()]);
|
|
4783
4939
|
if (this.gpuContext) this.gpuHasContent = true;
|
|
4940
|
+
this._particleReason = "active";
|
|
4941
|
+
this._particlePath = "webgpu";
|
|
4784
4942
|
} catch (e) {
|
|
4785
4943
|
console.error("WebGPU frame execution failed. Falling back.", e);
|
|
4786
4944
|
this.deviceLost = true;
|
|
@@ -4802,13 +4960,25 @@ var Scene = (_class7 = class _Scene {
|
|
|
4802
4960
|
}
|
|
4803
4961
|
}
|
|
4804
4962
|
if (this._particleWasm) {
|
|
4805
|
-
entity.stepWithBackend(
|
|
4963
|
+
if (!entity.stepWithBackend(
|
|
4964
|
+
this._particleWasm,
|
|
4965
|
+
dt / 1e3,
|
|
4966
|
+
mx,
|
|
4967
|
+
my,
|
|
4968
|
+
this.width,
|
|
4969
|
+
this.height
|
|
4970
|
+
)) {
|
|
4971
|
+
this._particleReason = "rejected";
|
|
4972
|
+
this._particlePath = "js";
|
|
4973
|
+
}
|
|
4806
4974
|
} else {
|
|
4807
4975
|
entity.updateCPU(dt / 1e3, mx, my, this.width, this.height);
|
|
4808
4976
|
}
|
|
4809
4977
|
}
|
|
4810
4978
|
}
|
|
4811
4979
|
} else if (isMainRenderer) {
|
|
4980
|
+
this._particleReason = "not-applicable";
|
|
4981
|
+
this._particlePath = "none";
|
|
4812
4982
|
this.clearGPUCanvasIfStale();
|
|
4813
4983
|
}
|
|
4814
4984
|
renderer.clear();
|
|
@@ -4837,6 +5007,9 @@ var Scene = (_class7 = class _Scene {
|
|
|
4837
5007
|
}
|
|
4838
5008
|
};
|
|
4839
5009
|
const wasmMain = isMainRenderer && this._wasm !== null && this._transformBackend === "wasm";
|
|
5010
|
+
if (isMainRenderer) {
|
|
5011
|
+
this._transformReason = wasmMain ? "active" : "not-installed";
|
|
5012
|
+
}
|
|
4840
5013
|
if (wasmMain) {
|
|
4841
5014
|
const updateWalk = (node) => {
|
|
4842
5015
|
runUpdate(node);
|
|
@@ -5340,15 +5513,15 @@ var TextEntity = (_class8 = class extends _chunkAGP4VLF4js.Entity {
|
|
|
5340
5513
|
|
|
5341
5514
|
|
|
5342
5515
|
|
|
5343
|
-
|
|
5516
|
+
__init147() {this.nodes = []}
|
|
5344
5517
|
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5518
|
+
__init148() {this.fillStyle = "#94a3b8"}
|
|
5519
|
+
__init149() {this.strokeStyle = null}
|
|
5520
|
+
__init150() {this.hoveredFillStyle = "#ffffff"}
|
|
5521
|
+
__init151() {this.lineWidth = 1}
|
|
5522
|
+
__init152() {this.isHovered = false}
|
|
5350
5523
|
constructor(text, atlas, maxWidth, fontSize = 24) {
|
|
5351
|
-
super();_class8.prototype.
|
|
5524
|
+
super();_class8.prototype.__init147.call(this);_class8.prototype.__init148.call(this);_class8.prototype.__init149.call(this);_class8.prototype.__init150.call(this);_class8.prototype.__init151.call(this);_class8.prototype.__init152.call(this);;
|
|
5352
5525
|
this.text = text;
|
|
5353
5526
|
this.atlas = atlas;
|
|
5354
5527
|
this.fontSize = fontSize;
|
|
@@ -5463,15 +5636,15 @@ var TextEntity = (_class8 = class extends _chunkAGP4VLF4js.Entity {
|
|
|
5463
5636
|
// src/components/GridTextEntity.ts
|
|
5464
5637
|
var GridTextEntity = (_class9 = class extends _chunkAGP4VLF4js.Entity {
|
|
5465
5638
|
|
|
5466
|
-
|
|
5467
|
-
|
|
5639
|
+
__init153() {this.fillStyle = "#ffffff"}
|
|
5640
|
+
__init154() {this.grid = []}
|
|
5468
5641
|
// Array of rows
|
|
5469
|
-
|
|
5470
|
-
|
|
5642
|
+
__init155() {this.cols = 0}
|
|
5643
|
+
__init156() {this.rows = 0}
|
|
5471
5644
|
|
|
5472
5645
|
|
|
5473
5646
|
constructor(_atlas, fontSize = 10) {
|
|
5474
|
-
super();_class9.prototype.
|
|
5647
|
+
super();_class9.prototype.__init153.call(this);_class9.prototype.__init154.call(this);_class9.prototype.__init155.call(this);_class9.prototype.__init156.call(this);;
|
|
5475
5648
|
this.fontSize = fontSize;
|
|
5476
5649
|
this.charWidth = fontSize * 1;
|
|
5477
5650
|
this.charHeight = fontSize * 1.1;
|
|
@@ -5563,23 +5736,23 @@ var SplineEntity = (_class10 = class extends _chunkAGP4VLF4js.Entity {
|
|
|
5563
5736
|
|
|
5564
5737
|
|
|
5565
5738
|
|
|
5566
|
-
|
|
5567
|
-
|
|
5739
|
+
__init157() {this.offscreen = null}
|
|
5740
|
+
__init158() {this.baked = false}
|
|
5568
5741
|
/** Logical (CSS-pixel) size of the baked bitmap — the blit destination size. */
|
|
5569
|
-
|
|
5570
|
-
|
|
5742
|
+
__init159() {this.bakedWidth = 0}
|
|
5743
|
+
__init160() {this.bakedHeight = 0}
|
|
5571
5744
|
/** Gradient strokes can't be baked to a solid-color bitmap; they render per-frame. */
|
|
5572
5745
|
|
|
5573
5746
|
/** Lazily-flattened polylines (one Float32Array of [x,y,...] per segment) for hit-testing. */
|
|
5574
|
-
|
|
5747
|
+
__init161() {this.polylines = null}
|
|
5575
5748
|
/**
|
|
5576
5749
|
* When `true`, the renderer draws a rounded-rect outline of the entity's
|
|
5577
5750
|
* local bounds after painting the curves. Useful for drag feedback and
|
|
5578
5751
|
* debugging hit areas. Defaults to `false`.
|
|
5579
5752
|
*/
|
|
5580
|
-
|
|
5753
|
+
__init162() {this.showBounds = false}
|
|
5581
5754
|
constructor(doc, opts = {}) {
|
|
5582
|
-
super();_class10.prototype.
|
|
5755
|
+
super();_class10.prototype.__init157.call(this);_class10.prototype.__init158.call(this);_class10.prototype.__init159.call(this);_class10.prototype.__init160.call(this);_class10.prototype.__init161.call(this);_class10.prototype.__init162.call(this);;
|
|
5583
5756
|
this.doc = doc;
|
|
5584
5757
|
this.lineWidth = _nullishCoalesce(opts.lineWidth, () => ( 2));
|
|
5585
5758
|
this.cache = _nullishCoalesce(opts.cache, () => ( true));
|
|
@@ -5960,19 +6133,19 @@ var _math = require('@vectojs/math'); _createStarExport(_math);
|
|
|
5960
6133
|
// src/tree/DOMPortalEntity.ts
|
|
5961
6134
|
var DOMPortalEntity = (_class11 = class extends _chunkAGP4VLF4js.Entity {
|
|
5962
6135
|
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
6136
|
+
__init163() {this.isDOMPortal = true}
|
|
6137
|
+
__init164() {this.domListeners = []}
|
|
6138
|
+
__init165() {this.resizeObserver = null}
|
|
6139
|
+
__init166() {this.domBound = false}
|
|
6140
|
+
__init167() {this.cachedWidth = 100}
|
|
6141
|
+
__init168() {this.cachedHeight = 100}
|
|
6142
|
+
__init169() {this.lastWidth = ""}
|
|
6143
|
+
__init170() {this.lastHeight = ""}
|
|
6144
|
+
__init171() {this.lastTransform = ""}
|
|
6145
|
+
__init172() {this.lastZIndex = ""}
|
|
6146
|
+
__init173() {this.lastOpacity = ""}
|
|
5974
6147
|
constructor(domElement, width, height, id) {
|
|
5975
|
-
super(id);_class11.prototype.
|
|
6148
|
+
super(id);_class11.prototype.__init163.call(this);_class11.prototype.__init164.call(this);_class11.prototype.__init165.call(this);_class11.prototype.__init166.call(this);_class11.prototype.__init167.call(this);_class11.prototype.__init168.call(this);_class11.prototype.__init169.call(this);_class11.prototype.__init170.call(this);_class11.prototype.__init171.call(this);_class11.prototype.__init172.call(this);_class11.prototype.__init173.call(this);;
|
|
5976
6149
|
this.domElement = domElement;
|
|
5977
6150
|
this.width = _nullishCoalesce(width, () => ( 0));
|
|
5978
6151
|
this.height = _nullishCoalesce(height, () => ( 0));
|