@expofp/renderer 3.1.2 → 3.1.4
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 +88 -70
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -310,6 +310,7 @@ var BatchedMesh$1 = class BatchedMesh$1 extends BatchedMesh {
|
|
|
310
310
|
uniformsTexture;
|
|
311
311
|
uniformSchema = {};
|
|
312
312
|
isMaterialPatched = false;
|
|
313
|
+
boundsNeedsUpdate = false;
|
|
313
314
|
batchCount = 0;
|
|
314
315
|
indexBuffer;
|
|
315
316
|
geometryById = /* @__PURE__ */ new Map();
|
|
@@ -408,6 +409,19 @@ var BatchedMesh$1 = class BatchedMesh$1 extends BatchedMesh {
|
|
|
408
409
|
}
|
|
409
410
|
this.uniformsTexture.setUniformAt(instanceId, name, value);
|
|
410
411
|
}
|
|
412
|
+
updateMatrixWorld(force) {
|
|
413
|
+
super.updateMatrixWorld(force);
|
|
414
|
+
if (this.boundsNeedsUpdate) {
|
|
415
|
+
this.computeBoundingBox();
|
|
416
|
+
this.computeBoundingSphere();
|
|
417
|
+
this.boundsNeedsUpdate = false;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
setMatrixAt(instanceId, matrix) {
|
|
421
|
+
super.setMatrixAt(instanceId, matrix);
|
|
422
|
+
this.boundsNeedsUpdate = true;
|
|
423
|
+
return this;
|
|
424
|
+
}
|
|
411
425
|
dispose() {
|
|
412
426
|
if (this.indexBuffer) this.geometry.setIndex(this.indexBuffer);
|
|
413
427
|
super.dispose();
|
|
@@ -1485,7 +1499,7 @@ var ImageSystem = class extends RenderableSystem {
|
|
|
1485
1499
|
/** Textures memory limit in megabytes */
|
|
1486
1500
|
memoryLimitMb;
|
|
1487
1501
|
packer;
|
|
1488
|
-
|
|
1502
|
+
atlasData = /* @__PURE__ */ new Map();
|
|
1489
1503
|
globalTranslationMatrix = new Matrix4();
|
|
1490
1504
|
originTranslationMatrix = new Matrix4();
|
|
1491
1505
|
rotationMatrix = new Matrix4();
|
|
@@ -1503,11 +1517,11 @@ var ImageSystem = class extends RenderableSystem {
|
|
|
1503
1517
|
}
|
|
1504
1518
|
dispose() {
|
|
1505
1519
|
super.dispose();
|
|
1506
|
-
this.
|
|
1520
|
+
this.atlasData.clear();
|
|
1507
1521
|
}
|
|
1508
1522
|
updateLayerImpl(group, layerDef) {
|
|
1509
1523
|
super.updateLayerImpl(group, layerDef);
|
|
1510
|
-
|
|
1524
|
+
this.renderAtlases();
|
|
1511
1525
|
}
|
|
1512
1526
|
buildLayer(layer) {
|
|
1513
1527
|
const is3D = layer.mode === "3D";
|
|
@@ -1522,9 +1536,8 @@ var ImageSystem = class extends RenderableSystem {
|
|
|
1522
1536
|
originalIndex: imageWithIndex.originalIndex
|
|
1523
1537
|
}))).sort((a, b) => a.originalIndex - b.originalIndex);
|
|
1524
1538
|
const instanceCount = rectsWithDef.length;
|
|
1525
|
-
const texture = createAtlas(bin);
|
|
1526
1539
|
const instanceMaterial = this.materialSystem.createTextureMaterial({
|
|
1527
|
-
map:
|
|
1540
|
+
map: createPlaceholderTexture(),
|
|
1528
1541
|
uvOffset: true,
|
|
1529
1542
|
depthEnable: is3D
|
|
1530
1543
|
});
|
|
@@ -1532,6 +1545,7 @@ var ImageSystem = class extends RenderableSystem {
|
|
|
1532
1545
|
const vertexCount = instanceGeometry.attributes["position"].count;
|
|
1533
1546
|
const batchedMesh = new BatchedMesh$1(instanceCount, vertexCount, instanceGeometry.index?.count ?? 0, instanceMaterial);
|
|
1534
1547
|
batchedMesh.sortObjects = false;
|
|
1548
|
+
batchedMesh.visible = false;
|
|
1535
1549
|
batchedMesh.addPerInstanceUniforms({ vertex: { uvOffset: "vec4" } });
|
|
1536
1550
|
const geometryId = batchedMesh.addGeometry(instanceGeometry);
|
|
1537
1551
|
for (const { def, rect } of rectsWithDef) {
|
|
@@ -1540,66 +1554,40 @@ var ImageSystem = class extends RenderableSystem {
|
|
|
1540
1554
|
batchedMesh.setUniformAt(instanceId, "uvOffset", uvOffset);
|
|
1541
1555
|
this.registerDefObject(def, batchedMesh, instanceId);
|
|
1542
1556
|
}
|
|
1543
|
-
|
|
1557
|
+
const resizable = !rectsWithDef.some(({ def }) => def.source instanceof HTMLCanvasElement);
|
|
1558
|
+
this.atlasData.set(batchedMesh, {
|
|
1559
|
+
bin,
|
|
1560
|
+
resizable,
|
|
1561
|
+
appliedScale: 0
|
|
1562
|
+
});
|
|
1544
1563
|
group.add(batchedMesh);
|
|
1545
1564
|
}
|
|
1546
1565
|
return group;
|
|
1547
1566
|
}
|
|
1548
1567
|
/**
|
|
1549
|
-
*
|
|
1550
|
-
*
|
|
1551
|
-
*
|
|
1568
|
+
* Render (or re-render) atlas textures for all meshes, scaling to fit the memory limit when set.
|
|
1569
|
+
* Atlases are rendered directly at the target scale — no full-size intermediate is created.
|
|
1570
|
+
* Meshes already at the target scale are skipped.
|
|
1552
1571
|
*/
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
logger$12.debug("Memory limit is not set, unable to resize textures.");
|
|
1556
|
-
return;
|
|
1557
|
-
}
|
|
1558
|
-
logger$12.debug(`Resizing textures to fit memory limit: ${this.memoryLimitMb} MB`);
|
|
1559
|
-
const resizableMeshes = [];
|
|
1560
|
-
let totalOriginal = 0;
|
|
1561
|
-
let totalNonResizable = 0;
|
|
1572
|
+
renderAtlases() {
|
|
1573
|
+
const scale = this.computeResizeFactor();
|
|
1562
1574
|
for (const mesh of this.getAllObjects()) {
|
|
1563
|
-
const
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
resizableMeshes.push(mesh);
|
|
1568
|
-
} else totalNonResizable += getCanvasSizeBytes(texture.image, texture.generateMipmaps);
|
|
1569
|
-
}
|
|
1570
|
-
if (resizableMeshes.length === 0) {
|
|
1571
|
-
logger$12.debug("No resizable meshes found, no need to resize textures.");
|
|
1572
|
-
return;
|
|
1573
|
-
}
|
|
1574
|
-
const budget = this.memoryLimitMb * 1024 * 1024 - totalNonResizable;
|
|
1575
|
-
if (budget < 0) {
|
|
1576
|
-
logger$12.debug("Memory limit is too low, unable to resize textures.");
|
|
1577
|
-
return;
|
|
1578
|
-
}
|
|
1579
|
-
const resizeFactor = Math.sqrt(budget / totalOriginal);
|
|
1580
|
-
if (resizeFactor >= 1) {
|
|
1581
|
-
logger$12.debug("Textures are already within the memory limit, no need to resize");
|
|
1582
|
-
return;
|
|
1583
|
-
}
|
|
1584
|
-
logger$12.debug(`Resize factor: ${resizeFactor}`);
|
|
1585
|
-
let newTotal = totalNonResizable;
|
|
1586
|
-
for (const mesh of resizableMeshes) {
|
|
1575
|
+
const data = this.atlasData.get(mesh);
|
|
1576
|
+
if (!data) continue;
|
|
1577
|
+
const targetScale = data.resizable ? scale : 1;
|
|
1578
|
+
if (data.appliedScale === targetScale) continue;
|
|
1587
1579
|
const material = mesh.material;
|
|
1588
|
-
const
|
|
1589
|
-
|
|
1590
|
-
const resizedTexture = resizeCanvas(originalCanvas, resizeFactor);
|
|
1591
|
-
const originalDim = `${originalCanvas.width}x${originalCanvas.height}`;
|
|
1592
|
-
const resizedDim = `${resizedTexture.image.width}x${resizedTexture.image.height}`;
|
|
1593
|
-
logger$12.debug(`Resized atlas for ${mesh.name || mesh.parent?.name}, from ${originalDim} to ${resizedDim}`);
|
|
1594
|
-
newTotal += getCanvasSizeBytes(resizedTexture.image, resizedTexture.generateMipmaps);
|
|
1595
|
-
material.map = resizedTexture;
|
|
1580
|
+
const oldTexture = material.map;
|
|
1581
|
+
material.map = createAtlas(data.bin, targetScale);
|
|
1596
1582
|
material.needsUpdate = true;
|
|
1597
|
-
|
|
1583
|
+
oldTexture?.dispose();
|
|
1584
|
+
mesh.visible = true;
|
|
1585
|
+
data.appliedScale = targetScale;
|
|
1586
|
+
logger$12.debug(`Rendered atlas for ${mesh.name || mesh.parent?.name} at scale ${targetScale.toFixed(3)}`);
|
|
1598
1587
|
}
|
|
1599
|
-
logger$12.debug(`New memory usage after resizing: ${newTotal} bytes`);
|
|
1600
1588
|
}
|
|
1601
1589
|
disposeObject(object) {
|
|
1602
|
-
this.
|
|
1590
|
+
this.atlasData.delete(object);
|
|
1603
1591
|
super.disposeObject(object);
|
|
1604
1592
|
}
|
|
1605
1593
|
updateDefImpl(imageDef, mesh, instanceIds) {
|
|
@@ -1613,6 +1601,32 @@ var ImageSystem = class extends RenderableSystem {
|
|
|
1613
1601
|
const matrix = this.originTranslationMatrix.premultiply(this.scaleMatrix).premultiply(this.rotationMatrix).premultiply(this.globalTranslationMatrix);
|
|
1614
1602
|
mesh.setMatrixAt(instanceId, matrix);
|
|
1615
1603
|
}
|
|
1604
|
+
computeResizeFactor() {
|
|
1605
|
+
if (!this.memoryLimitMb) {
|
|
1606
|
+
logger$12.debug("Memory limit is not set, atlases will not be scaled");
|
|
1607
|
+
return 1;
|
|
1608
|
+
}
|
|
1609
|
+
let totalResizable = 0;
|
|
1610
|
+
let totalNonResizable = 0;
|
|
1611
|
+
for (const data of this.atlasData.values()) {
|
|
1612
|
+
const bytes = getAtlasSizeBytes(data.bin.width, data.bin.height);
|
|
1613
|
+
if (data.resizable) totalResizable += bytes;
|
|
1614
|
+
else totalNonResizable += bytes;
|
|
1615
|
+
}
|
|
1616
|
+
if (totalResizable === 0) {
|
|
1617
|
+
logger$12.debug("No resizable atlases, atlases will not be scaled");
|
|
1618
|
+
return 1;
|
|
1619
|
+
}
|
|
1620
|
+
const budget = this.memoryLimitMb * 1024 * 1024 - totalNonResizable;
|
|
1621
|
+
if (budget <= 0) {
|
|
1622
|
+
logger$12.debug("Memory limit is too low, unable to resize textures.");
|
|
1623
|
+
return 1;
|
|
1624
|
+
}
|
|
1625
|
+
const factor = Math.sqrt(budget / totalResizable);
|
|
1626
|
+
if (factor >= 1) return 1;
|
|
1627
|
+
logger$12.debug(`Resize factor: ${factor.toFixed(3)} (budget ${budget} bytes, resizable ${totalResizable} bytes)`);
|
|
1628
|
+
return factor;
|
|
1629
|
+
}
|
|
1616
1630
|
packImages(images) {
|
|
1617
1631
|
this.packer.reset();
|
|
1618
1632
|
const rectangles = [];
|
|
@@ -1646,23 +1660,19 @@ var ImageSystem = class extends RenderableSystem {
|
|
|
1646
1660
|
return this.packer.bins;
|
|
1647
1661
|
}
|
|
1648
1662
|
};
|
|
1649
|
-
function createAtlas(bin) {
|
|
1663
|
+
function createAtlas(bin, scale) {
|
|
1650
1664
|
const t0 = performance.now();
|
|
1651
1665
|
const canvas = document.createElement("canvas");
|
|
1652
|
-
canvas.width = bin.width;
|
|
1653
|
-
canvas.height = bin.height;
|
|
1666
|
+
canvas.width = Math.max(1, Math.floor(bin.width * scale));
|
|
1667
|
+
canvas.height = Math.max(1, Math.floor(bin.height * scale));
|
|
1654
1668
|
const ctx = canvas.getContext("2d");
|
|
1655
|
-
for (const rect of bin.rects) ctx.drawImage(rect.data[0].def.source, rect.x, rect.y, rect.width, rect.height);
|
|
1669
|
+
for (const rect of bin.rects) ctx.drawImage(rect.data[0].def.source, Math.floor(rect.x * scale), Math.floor(rect.y * scale), Math.floor(rect.width * scale), Math.floor(rect.height * scale));
|
|
1656
1670
|
const t1 = performance.now();
|
|
1657
|
-
logger$12.debug(`Create atlas took ${(t1 - t0).toFixed(2)} milliseconds.`);
|
|
1671
|
+
logger$12.debug(`Create atlas (${canvas.width}x${canvas.height}) took ${(t1 - t0).toFixed(2)} milliseconds.`);
|
|
1658
1672
|
return createTexture(canvas);
|
|
1659
1673
|
}
|
|
1660
|
-
function
|
|
1661
|
-
|
|
1662
|
-
canvas.width = Math.floor(source.width * resizeFactor);
|
|
1663
|
-
canvas.height = Math.floor(source.height * resizeFactor);
|
|
1664
|
-
canvas.getContext("2d").drawImage(source, 0, 0, canvas.width, canvas.height);
|
|
1665
|
-
return createTexture(canvas);
|
|
1674
|
+
function createPlaceholderTexture() {
|
|
1675
|
+
return new Texture(document.createElement("canvas"));
|
|
1666
1676
|
}
|
|
1667
1677
|
function createTexture(source) {
|
|
1668
1678
|
const texture = new Texture(source);
|
|
@@ -1672,8 +1682,8 @@ function createTexture(source) {
|
|
|
1672
1682
|
texture.needsUpdate = true;
|
|
1673
1683
|
return texture;
|
|
1674
1684
|
}
|
|
1675
|
-
function
|
|
1676
|
-
return Math.ceil(
|
|
1685
|
+
function getAtlasSizeBytes(width, height) {
|
|
1686
|
+
return Math.ceil(width * height * 4 * 1.33);
|
|
1677
1687
|
}
|
|
1678
1688
|
//#endregion
|
|
1679
1689
|
//#region src/geometry/line.ts
|
|
@@ -2511,10 +2521,8 @@ var LayerSystem = class {
|
|
|
2511
2521
|
for (const child of sceneDef.rootLayer.children) rootGroup.add(this.buildLayer(child));
|
|
2512
2522
|
this.updateLayer(sceneDef.rootLayer, false);
|
|
2513
2523
|
printTree(rootGroup, logger$8.debug);
|
|
2514
|
-
if (sceneDef.memoryLimit)
|
|
2515
|
-
|
|
2516
|
-
this.imageSystem.resizeTextures();
|
|
2517
|
-
}
|
|
2524
|
+
if (sceneDef.memoryLimit) this.imageSystem.memoryLimitMb = sceneDef.memoryLimit;
|
|
2525
|
+
this.imageSystem.renderAtlases();
|
|
2518
2526
|
return rootGroup;
|
|
2519
2527
|
}
|
|
2520
2528
|
/**
|
|
@@ -6125,6 +6133,16 @@ var PitchHandler = class extends Handler {
|
|
|
6125
6133
|
p0 = new Vector2();
|
|
6126
6134
|
p1 = new Vector2();
|
|
6127
6135
|
prevTwoFingerAction;
|
|
6136
|
+
/**
|
|
6137
|
+
* @param domElement {@link HTMLElement} instance
|
|
6138
|
+
* @param eventManager {@link EventManager} instance
|
|
6139
|
+
* @param cameraAccess {@link InternalCameraAccess} instance
|
|
6140
|
+
* @param coordinatesSystem {@link CoordinatesSystem} instance
|
|
6141
|
+
*/
|
|
6142
|
+
constructor(domElement, eventManager, cameraAccess, coordinatesSystem) {
|
|
6143
|
+
super(domElement, eventManager, cameraAccess, coordinatesSystem);
|
|
6144
|
+
this.updatePolarAngles();
|
|
6145
|
+
}
|
|
6128
6146
|
reset(enableTransition = true) {
|
|
6129
6147
|
const polarAngle = this.enabled ? this.minPitch * DEG2RAD : 0;
|
|
6130
6148
|
return this.controller.rotatePolarTo(polarAngle, enableTransition);
|