@needle-tools/engine 4.11.5-next.9fa3148 → 4.11.5-next.a900688
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/{needle-engine.bundle-D8QnRDOA.js → needle-engine.bundle-Bwinyjsh.js} +2338 -2373
- package/dist/{needle-engine.bundle-aQ4JfO6G.umd.cjs → needle-engine.bundle-Dsfd8BPk.umd.cjs} +113 -121
- package/dist/{needle-engine.bundle-BODHvc75.min.js → needle-engine.bundle-vPWPv18K.min.js} +108 -116
- package/dist/needle-engine.js +2 -2
- package/dist/needle-engine.min.js +1 -1
- package/dist/needle-engine.umd.cjs +1 -1
- package/lib/engine/engine_application.d.ts +0 -7
- package/lib/engine/engine_application.js +1 -8
- package/lib/engine/engine_application.js.map +1 -1
- package/lib/engine/engine_assetdatabase.d.ts +6 -0
- package/lib/engine/engine_assetdatabase.js +15 -0
- package/lib/engine/engine_assetdatabase.js.map +1 -1
- package/lib/engine/engine_context.d.ts +0 -1
- package/lib/engine/engine_context.js +2 -5
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_loaders.js +25 -24
- package/lib/engine/engine_loaders.js.map +1 -1
- package/lib/engine-components/RendererInstancing.d.ts +3 -5
- package/lib/engine-components/RendererInstancing.js +31 -64
- package/lib/engine-components/RendererInstancing.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/engine_application.ts +1 -16
- package/src/engine/engine_assetdatabase.ts +21 -0
- package/src/engine/engine_context.ts +2 -6
- package/src/engine/engine_loaders.ts +26 -24
- package/src/engine-components/RendererInstancing.ts +33 -69
- package/lib/engine/debug/debug_spector.d.ts +0 -16
- package/lib/engine/debug/debug_spector.js +0 -28
- package/lib/engine/debug/debug_spector.js.map +0 -1
- package/src/engine/debug/debug_spector.ts +0 -43
|
@@ -29,9 +29,8 @@ export class InstancingHandler {
|
|
|
29
29
|
* (The instancing mesh renderer will grow x2 if the max instance count is reached)
|
|
30
30
|
* @default 4
|
|
31
31
|
* @returns The initial instance count
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
static getStartInstanceCount = (obj: Object3D) => {
|
|
32
|
+
* */
|
|
33
|
+
static getStartInstanceCount = (_obj: Object3D) => {
|
|
35
34
|
return 4;
|
|
36
35
|
};
|
|
37
36
|
|
|
@@ -46,24 +45,20 @@ export class InstancingHandler {
|
|
|
46
45
|
if (res) {
|
|
47
46
|
if (handlesArray === null) handlesArray = [];
|
|
48
47
|
handlesArray.push(res);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
// load texture lods
|
|
49
|
+
NEEDLE_progressive.assignTextureLOD(res.renderer.material, 0);
|
|
50
|
+
|
|
51
|
+
// Load mesh lods
|
|
52
|
+
// TODO: technically for multi meshes we do this work multiple times (we search for meshes in children and then use the renderer sharedMeshes... that doesnt make sense)
|
|
53
|
+
for (let i = 0; i < renderer.sharedMeshes.length; i++) {
|
|
54
|
+
const mesh = renderer.sharedMeshes[i];
|
|
55
|
+
const geometry = mesh.geometry;
|
|
56
|
+
NEEDLE_progressive.assignMeshLOD(mesh, 0).then(lod => {
|
|
57
|
+
if (lod && renderer.activeAndEnabled && geometry != lod) {
|
|
58
|
+
res.setGeometry(lod);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
57
61
|
}
|
|
58
|
-
|
|
59
|
-
// Load LOD for geometry
|
|
60
|
-
const mesh = res.object;
|
|
61
|
-
const geometry = mesh.geometry;
|
|
62
|
-
NEEDLE_progressive.assignMeshLOD(mesh, 0).then(lod => {
|
|
63
|
-
if (lod && geometry != lod) {
|
|
64
|
-
res.setGeometry(lod);
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
62
|
}
|
|
68
63
|
|
|
69
64
|
else if (level <= 0 && obj.type !== "Mesh") {
|
|
@@ -354,7 +349,7 @@ class InstancedMeshRenderer {
|
|
|
354
349
|
private _context: Context;
|
|
355
350
|
private _batchedMesh: BatchedMesh;
|
|
356
351
|
private _handles: (InstanceHandle | null)[] = [];
|
|
357
|
-
private _geometryIds
|
|
352
|
+
private readonly _geometryIds: Map<BufferGeometry, number> = new Map();
|
|
358
353
|
private _maxInstanceCount: number;
|
|
359
354
|
|
|
360
355
|
private _currentInstanceCount = 0;
|
|
@@ -444,10 +439,6 @@ class InstancedMeshRenderer {
|
|
|
444
439
|
private _needUpdateBounds: boolean = false;
|
|
445
440
|
private _debugMaterial: MeshStandardMaterial | null = null;
|
|
446
441
|
|
|
447
|
-
private getBatchedMeshName() {
|
|
448
|
-
return this.name ? `${this.name} (BatchedMesh)` : "BatchedMesh";
|
|
449
|
-
}
|
|
450
|
-
|
|
451
442
|
constructor(name: string, geo: BufferGeometry, material: Material, initialMaxCount: number, context: Context) {
|
|
452
443
|
this.name = name;
|
|
453
444
|
this.geometry = geo;
|
|
@@ -461,7 +452,6 @@ class InstancedMeshRenderer {
|
|
|
461
452
|
this._maxVertexCount = estimate.vertexCount;
|
|
462
453
|
this._maxIndexCount = estimate.indexCount;
|
|
463
454
|
this._batchedMesh = new BatchedMesh(this._maxInstanceCount, this._maxVertexCount, this._maxIndexCount, this._debugMaterial ?? this.material);
|
|
464
|
-
this._batchedMesh.name = this.getBatchedMeshName();
|
|
465
455
|
// this.inst = new InstancedMesh(geo, material, count);
|
|
466
456
|
this._batchedMesh[$instancingAutoUpdateBounds] = true;
|
|
467
457
|
// this.inst.count = 0;
|
|
@@ -485,7 +475,7 @@ class InstancedMeshRenderer {
|
|
|
485
475
|
context.post_render_callbacks.push(this.onAfterRender);
|
|
486
476
|
|
|
487
477
|
if (debugInstancing) {
|
|
488
|
-
console.log(`Instanced renderer
|
|
478
|
+
console.log(`Instanced renderer created with ${this._maxInstanceCount} instances, ${this._maxVertexCount} max vertices and ${this._maxIndexCount} max indices for \"${name}\"`)
|
|
489
479
|
}
|
|
490
480
|
}
|
|
491
481
|
|
|
@@ -532,8 +522,7 @@ class InstancedMeshRenderer {
|
|
|
532
522
|
return false;
|
|
533
523
|
}
|
|
534
524
|
|
|
535
|
-
|
|
536
|
-
if (newInstanceCount > this._maxInstanceCount || this.mustGrow(geo)) {
|
|
525
|
+
if (this.mustGrow(geo)) {
|
|
537
526
|
if (this.allowResize) {
|
|
538
527
|
this.grow(geo);
|
|
539
528
|
}
|
|
@@ -655,42 +644,34 @@ class InstancedMeshRenderer {
|
|
|
655
644
|
private mustGrow(geo?: BufferGeometry): boolean {
|
|
656
645
|
if (this.count >= this._maxInstanceCount) return true;
|
|
657
646
|
if (!geo || !geo.attributes) return false;
|
|
658
|
-
|
|
659
|
-
const isKnownGeometry = this._geometryIds.has(geo);
|
|
660
|
-
if (isKnownGeometry) return false;
|
|
661
|
-
|
|
662
647
|
const meshInfo = getMeshInformation(geo);
|
|
663
648
|
const newVertexCount = meshInfo.vertexCount;
|
|
664
649
|
const newIndexCount = meshInfo.indexCount;
|
|
665
650
|
return this._currentVertexCount + newVertexCount > this._maxVertexCount || this._currentIndexCount + newIndexCount > this._maxIndexCount;
|
|
666
651
|
}
|
|
667
652
|
|
|
668
|
-
private _growId = 0;
|
|
669
653
|
private grow(geometry: BufferGeometry) {
|
|
670
|
-
const id = ++this._growId;
|
|
671
654
|
const growFactor = 2;
|
|
672
655
|
const newSize = Math.ceil(this._maxInstanceCount * growFactor);
|
|
673
656
|
|
|
674
657
|
// create a new BatchedMesh instance
|
|
675
|
-
// TODO: we should keep track of how many instances for each geometry we have and consider that when estimating new space
|
|
676
658
|
const estimatedSpace = this.tryEstimateVertexCountSize(newSize, [geometry]);// geometry.attributes.position.count;
|
|
677
659
|
// const indices = geometry.index ? geometry.index.count : 0;
|
|
678
660
|
const newMaxVertexCount = Math.max(this._maxVertexCount, estimatedSpace.vertexCount);
|
|
679
|
-
const newMaxIndexCount = Math.max(this._maxIndexCount, estimatedSpace.indexCount
|
|
661
|
+
const newMaxIndexCount = Math.max(this._maxIndexCount, estimatedSpace.indexCount, Math.ceil(this._maxVertexCount * growFactor));
|
|
680
662
|
|
|
681
663
|
if (debugInstancing) {
|
|
682
664
|
const geometryInfo = getMeshInformation(geometry);
|
|
683
|
-
console.warn(`[Instancing] Growing Buffer\nMesh: \"${this.name}${geometry.name?.length ? "/" + geometry.name : ""}\"
|
|
665
|
+
console.warn(`[Instancing] Growing Buffer\nMesh: \"${this.name}${geometry.name?.length ? "/" + geometry.name : ""}\"\n${geometryInfo.vertexCount} vertices, ${geometryInfo.indexCount} indices\nMax count ${this._maxInstanceCount} → ${newSize}\nMax vertex count ${this._maxVertexCount} -> ${newMaxVertexCount}\nMax index count ${this._maxIndexCount} -> ${newMaxIndexCount}`);
|
|
684
666
|
this._debugMaterial = createDebugMaterial();
|
|
685
667
|
}
|
|
686
668
|
else if (isDevEnvironment()) {
|
|
687
|
-
console.debug(`[Instancing] Growing Buffer\nMesh: \"${this.name}${geometry.name?.length ? "/" + geometry.name : ""}\"\nMax count ${this._maxInstanceCount} → ${newSize}\nMax vertex count ${this._maxVertexCount
|
|
669
|
+
console.debug(`[Instancing] Growing Buffer\nMesh: \"${this.name}${geometry.name?.length ? "/" + geometry.name : ""}\"\nMax count ${this._maxInstanceCount} → ${newSize}\nMax vertex count ${this._maxVertexCount} -> ${newMaxVertexCount}\nMax index count ${this._maxIndexCount} -> ${newMaxIndexCount}`);
|
|
688
670
|
}
|
|
689
671
|
|
|
690
672
|
this._maxVertexCount = newMaxVertexCount;
|
|
691
673
|
this._maxIndexCount = newMaxIndexCount;
|
|
692
674
|
const newInst = new BatchedMesh(newSize, this._maxVertexCount, this._maxIndexCount, this._debugMaterial ?? this.material);
|
|
693
|
-
newInst.name = this.getBatchedMeshName();
|
|
694
675
|
newInst.layers = this._batchedMesh.layers;
|
|
695
676
|
newInst.castShadow = this._batchedMesh.castShadow;
|
|
696
677
|
newInst.receiveShadow = this._batchedMesh.receiveShadow;
|
|
@@ -705,7 +686,7 @@ class InstancedMeshRenderer {
|
|
|
705
686
|
// dispose the old batched mesh
|
|
706
687
|
this._batchedMesh.dispose();
|
|
707
688
|
this._batchedMesh.removeFromParent();
|
|
708
|
-
this._geometryIds
|
|
689
|
+
this._geometryIds.clear();
|
|
709
690
|
|
|
710
691
|
this._batchedMesh = newInst;
|
|
711
692
|
this._maxInstanceCount = newSize;
|
|
@@ -717,11 +698,6 @@ class InstancedMeshRenderer {
|
|
|
717
698
|
const original = [...this._handles];
|
|
718
699
|
this._handles = [];
|
|
719
700
|
for (const handle of original) {
|
|
720
|
-
if (id !== this._growId) {
|
|
721
|
-
// another grow happened in the meantime
|
|
722
|
-
if (debugInstancing) console.warn("[Instancing] Aborting grow since another grow happened in the meantime");
|
|
723
|
-
return;
|
|
724
|
-
}
|
|
725
701
|
if (handle && handle.__instanceIndex >= 0) {
|
|
726
702
|
this.addGeometry(handle);
|
|
727
703
|
this._handles[handle.__instanceIndex] = handle;
|
|
@@ -746,31 +722,23 @@ class InstancedMeshRenderer {
|
|
|
746
722
|
entry.count += 1;
|
|
747
723
|
}
|
|
748
724
|
|
|
749
|
-
if (_newGeometries && _newGeometries?.length > 0) {
|
|
750
|
-
const index = _newGeometries.indexOf(handle.object.geometry as BufferGeometry);
|
|
751
|
-
if (index !== -1) {
|
|
752
|
-
_newGeometries.splice(index, 1);
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
725
|
}
|
|
756
726
|
}
|
|
757
727
|
|
|
758
728
|
// then calculate the total vertex count
|
|
759
729
|
let totalVertices = 0;
|
|
760
730
|
let totalIndices = 0;
|
|
761
|
-
let totalGeometries = 0;
|
|
762
731
|
// let maxVertices = 0;
|
|
763
732
|
for (const [_geo, data] of usedGeometries) {
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
totalIndices += data.indexCount;
|
|
733
|
+
totalVertices += data.vertexCount * data.count;
|
|
734
|
+
totalIndices += data.indexCount * data.count;
|
|
767
735
|
// maxVertices = Math.max(maxVertices, geo.attributes.position.count * count);
|
|
768
736
|
}
|
|
769
737
|
// we calculate the average to make an educated guess of how many vertices will be needed with the new buffer count
|
|
770
|
-
const averageVerts = Math.ceil(totalVertices / Math.max(1,
|
|
771
|
-
let maxVertexCount = averageVerts *
|
|
772
|
-
const averageIndices = Math.ceil(totalIndices / Math.max(1,
|
|
773
|
-
let maxIndexCount = averageIndices *
|
|
738
|
+
const averageVerts = Math.ceil(totalVertices / Math.max(1, this._currentInstanceCount));
|
|
739
|
+
let maxVertexCount = averageVerts * newMaxInstances;
|
|
740
|
+
const averageIndices = Math.ceil(totalIndices / Math.max(1, this._currentInstanceCount));
|
|
741
|
+
let maxIndexCount = averageIndices * newMaxInstances * 2;
|
|
774
742
|
|
|
775
743
|
// if new geometries are provided we *know* that they will be added
|
|
776
744
|
// so we make sure to include them in the calculation
|
|
@@ -785,10 +753,6 @@ class InstancedMeshRenderer {
|
|
|
785
753
|
}
|
|
786
754
|
}
|
|
787
755
|
|
|
788
|
-
if (debugInstancing) {
|
|
789
|
-
console.log(`[Instancing] Estimated size for new buffer ${this.name}\nGeometries: ${totalGeometries} (New: ${_newGeometries?.length || 0})\nInstances: ${newMaxInstances}\nEstimated Vertices: ${maxVertexCount.toLocaleString()}\nEstimated Indices: ${maxIndexCount.toLocaleString()}`);
|
|
790
|
-
}
|
|
791
|
-
|
|
792
756
|
return { vertexCount: maxVertexCount, indexCount: maxIndexCount };
|
|
793
757
|
}
|
|
794
758
|
|
|
@@ -806,16 +770,16 @@ class InstancedMeshRenderer {
|
|
|
806
770
|
let geometryId = this._geometryIds.get(geo);
|
|
807
771
|
if (geometryId === undefined || geometryId === null) {
|
|
808
772
|
if (debugInstancing)
|
|
809
|
-
console.
|
|
773
|
+
console.debug(`[Instancing] > ADD NEW GEOMETRY \"${handle.name} (${geo.name}; ${geo.uuid})\"\n${this._currentInstanceCount} instances, ${handle.maxVertexCount} max vertices, ${handle.maxIndexCount} max indices`);
|
|
810
774
|
|
|
811
775
|
geometryId = this._batchedMesh.addGeometry(geo, handle.maxVertexCount, handle.maxIndexCount);
|
|
812
776
|
this._geometryIds.set(geo, geometryId);
|
|
813
|
-
this._currentVertexCount += handle.maxVertexCount;
|
|
814
|
-
this._currentIndexCount += handle.maxIndexCount;
|
|
815
777
|
}
|
|
816
778
|
else {
|
|
817
779
|
if (debugInstancing === "verbose") console.log(`[Instancing] > ADD INSTANCE \"${handle.name}\"\nGEOMETRY_ID=${geometryId}\n${this._currentInstanceCount} instances`);
|
|
818
780
|
}
|
|
781
|
+
this._currentVertexCount += handle.maxVertexCount;
|
|
782
|
+
this._currentIndexCount += handle.maxIndexCount;
|
|
819
783
|
const i = this._batchedMesh.addInstance(geometryId);
|
|
820
784
|
handle.__geometryIndex = geometryId;
|
|
821
785
|
handle.__instanceIndex = i;
|
|
@@ -823,7 +787,7 @@ class InstancedMeshRenderer {
|
|
|
823
787
|
handle.__reservedIndexRange = handle.maxIndexCount;
|
|
824
788
|
this._batchedMesh.setMatrixAt(i, handle.object.matrixWorld);
|
|
825
789
|
if (debugInstancing)
|
|
826
|
-
console.debug(`[Instancing] > ADDED INSTANCE \"${handle.name}\"\nGEOMETRY_ID=${geometryId}\n${this._currentInstanceCount} instances\nIndex: ${handle.__instanceIndex}
|
|
790
|
+
console.debug(`[Instancing] > ADDED INSTANCE \"${handle.name}\"\nGEOMETRY_ID=${geometryId}\n${this._currentInstanceCount} instances\nIndex: ${handle.__instanceIndex}`);
|
|
827
791
|
|
|
828
792
|
}
|
|
829
793
|
|
|
@@ -839,7 +803,7 @@ class InstancedMeshRenderer {
|
|
|
839
803
|
// this.inst.deleteGeometry(handle.__instanceIndex);
|
|
840
804
|
// else
|
|
841
805
|
// this._batchedMesh.setVisibleAt(handle.__instanceIndex, false);
|
|
842
|
-
if
|
|
806
|
+
if(debugInstancing) {
|
|
843
807
|
console.debug(`[Instancing] < REMOVE INSTANCE \"${handle.name}\" at [${handle.__instanceIndex}]\nGEOMETRY_ID=${handle.__geometryIndex}\n${this._currentInstanceCount} instances\nIndex: ${handle.__instanceIndex}`);
|
|
844
808
|
}
|
|
845
809
|
this._batchedMesh.deleteInstance(handle.__instanceIndex);
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { Context } from "../engine_setup.js";
|
|
2
|
-
declare global {
|
|
3
|
-
interface Window {
|
|
4
|
-
SPECTOR?: {
|
|
5
|
-
Spector: new () => Spector;
|
|
6
|
-
};
|
|
7
|
-
}
|
|
8
|
-
interface Spector {
|
|
9
|
-
displayUI: () => void;
|
|
10
|
-
setCanvas: (canvas: HTMLCanvasElement) => void;
|
|
11
|
-
spyCanvases: boolean;
|
|
12
|
-
startCaptureOnNextFrame: () => void;
|
|
13
|
-
captureCanvas: (canvas: HTMLCanvasElement) => any;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
export declare function initSpectorIfAvailable(_context: Context, canvas: HTMLCanvasElement): void;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { isDevEnvironment } from "./debug.js";
|
|
2
|
-
export function initSpectorIfAvailable(_context, canvas) {
|
|
3
|
-
if (typeof window !== undefined && window.SPECTOR) {
|
|
4
|
-
console.log(window.SPECTOR);
|
|
5
|
-
const params = new URLSearchParams(window.location.search);
|
|
6
|
-
if (params.has("spector")) {
|
|
7
|
-
const frame = Number.parseInt(params.get("spector") || "0") || 0;
|
|
8
|
-
console.log("Scheduled Spector capture at frame #" + frame);
|
|
9
|
-
const spector = new window.SPECTOR.Spector();
|
|
10
|
-
spector.spyCanvases = true;
|
|
11
|
-
waitForFrameAndCapture();
|
|
12
|
-
return;
|
|
13
|
-
function waitForFrameAndCapture() {
|
|
14
|
-
if (frame > _context.time.frame)
|
|
15
|
-
return window.requestAnimationFrame(() => waitForFrameAndCapture());
|
|
16
|
-
const res = spector.captureCanvas(canvas);
|
|
17
|
-
if (res && res instanceof Promise)
|
|
18
|
-
res.then(() => spector.displayUI());
|
|
19
|
-
else
|
|
20
|
-
spector.displayUI();
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
else if (isDevEnvironment()) {
|
|
24
|
-
console.debug("Spector available: Add '?spector=<frame>' to the URL to enable it and capture a frame.");
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=debug_spector.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"debug_spector.js","sourceRoot":"","sources":["../../../src/engine/debug/debug_spector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAkB9C,MAAM,UAAU,sBAAsB,CAAC,QAAiB,EAAE,MAAyB;IAC/E,IAAI,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,OAAO,EAAE;QAC/C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC5B,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC3D,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;YACvB,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;YACjE,OAAO,CAAC,GAAG,CAAC,sCAAsC,GAAG,KAAK,CAAC,CAAC;YAC5D,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC7C,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;YAC3B,sBAAsB,EAAE,CAAC;YACzB,OAAO;YAEP,SAAS,sBAAsB;gBAC3B,IAAI,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK;oBAAE,OAAO,MAAM,CAAC,qBAAqB,CAAC,GAAG,EAAE,CAAC,sBAAsB,EAAE,CAAC,CAAC;gBACrG,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;gBAC1C,IAAI,GAAG,IAAI,GAAG,YAAY,OAAO;oBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;;oBAClE,OAAO,CAAC,SAAS,EAAE,CAAC;YAC7B,CAAC;SACJ;aACI,IAAI,gBAAgB,EAAE,EAAE;YACzB,OAAO,CAAC,KAAK,CAAC,wFAAwF,CAAC,CAAC;SAC3G;KACJ;AACL,CAAC"}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { Context } from "../engine_setup.js";
|
|
2
|
-
import { isDevEnvironment } from "./debug.js";
|
|
3
|
-
|
|
4
|
-
declare global {
|
|
5
|
-
interface Window {
|
|
6
|
-
SPECTOR?: {
|
|
7
|
-
Spector: new () => Spector;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
interface Spector {
|
|
11
|
-
displayUI: () => void;
|
|
12
|
-
setCanvas: (canvas: HTMLCanvasElement) => void;
|
|
13
|
-
spyCanvases: boolean;
|
|
14
|
-
startCaptureOnNextFrame: () => void;
|
|
15
|
-
captureCanvas: (canvas: HTMLCanvasElement) => any;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export function initSpectorIfAvailable(_context: Context, canvas: HTMLCanvasElement): void {
|
|
21
|
-
if (typeof window !== undefined && window.SPECTOR) {
|
|
22
|
-
console.log(window.SPECTOR);
|
|
23
|
-
const params = new URLSearchParams(window.location.search);
|
|
24
|
-
if (params.has("spector")) {
|
|
25
|
-
const frame = Number.parseInt(params.get("spector") || "0") || 0;
|
|
26
|
-
console.log("Scheduled Spector capture at frame #" + frame);
|
|
27
|
-
const spector = new window.SPECTOR.Spector();
|
|
28
|
-
spector.spyCanvases = true;
|
|
29
|
-
waitForFrameAndCapture();
|
|
30
|
-
return;
|
|
31
|
-
|
|
32
|
-
function waitForFrameAndCapture() {
|
|
33
|
-
if (frame > _context.time.frame) return window.requestAnimationFrame(() => waitForFrameAndCapture());
|
|
34
|
-
const res = spector.captureCanvas(canvas);
|
|
35
|
-
if (res && res instanceof Promise) res.then(() => spector.displayUI());
|
|
36
|
-
else spector.displayUI();
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
else if (isDevEnvironment()) {
|
|
40
|
-
console.debug("Spector available: Add '?spector=<frame>' to the URL to enable it and capture a frame.");
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|