@expofp/renderer 2.0.0 → 2.0.1
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.d.ts +0 -4
- package/dist/index.js +113 -84
- package/package.json +3 -1
package/dist/index.d.ts
CHANGED
|
@@ -408,8 +408,6 @@ export declare type RenderableDefCollection<T = RenderableDef> = T extends Rende
|
|
|
408
408
|
* Main class for rendering the content of a {@link SceneDef}
|
|
409
409
|
*/
|
|
410
410
|
export declare class Renderer {
|
|
411
|
-
/** Whether to log debug information */
|
|
412
|
-
readonly debugLog: boolean;
|
|
413
411
|
/** {@link HTMLCanvasElement} that this renderer is rendering to */
|
|
414
412
|
readonly canvas: HTMLCanvasElement;
|
|
415
413
|
private ui?;
|
|
@@ -523,8 +521,6 @@ export declare interface RendererOptions {
|
|
|
523
521
|
canvas: HTMLCanvasElement;
|
|
524
522
|
/** Optional {@link WebGLRenderingContext} to use (e.g. for Mapbox GL JS) */
|
|
525
523
|
gl?: WebGLRenderingContext;
|
|
526
|
-
/** Whether to log debug information */
|
|
527
|
-
debugLog?: boolean;
|
|
528
524
|
/** Optional partial {@link UI} configuration */
|
|
529
525
|
ui?: Partial<UI>;
|
|
530
526
|
}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ var _a;
|
|
|
5
5
|
import { Color, Matrix4, Vector3, DataTexture, RGBAFormat, FloatType, RedFormat, UnsignedIntType, IntType, RGBAIntegerFormat, RGFormat, RGIntegerFormat, RedIntegerFormat, BatchedMesh as BatchedMesh$1, BufferAttribute, StreamDrawUsage, Vector4, AlwaysDepth, DoubleSide, MeshBasicMaterial, Texture, Group, PlaneGeometry, SRGBColorSpace, Vector2, Mesh, LessEqualDepth, Quaternion, BufferGeometry, LinearSRGBColorSpace, Plane, Raycaster, Sphere, Box3, Spherical, PerspectiveCamera, Camera, Scene, MathUtils, Clock, WebGLRenderer } from "three";
|
|
6
6
|
import { traverseAncestorsGenerator } from "three/examples/jsm/utils/SceneUtils.js";
|
|
7
7
|
import { BatchedText as BatchedText$1, Text as Text$1 } from "troika-three-text";
|
|
8
|
+
import createLog from "debug";
|
|
8
9
|
import { LineMaterial, LineSegmentsGeometry } from "three/examples/jsm/Addons.js";
|
|
9
10
|
import { MaxRectsPacker, Rectangle } from "maxrects-packer";
|
|
10
11
|
import { converter, parse } from "culori";
|
|
@@ -366,6 +367,34 @@ const dimColorFrag = (
|
|
|
366
367
|
return vec4(m * col.a, col.a);
|
|
367
368
|
}`
|
|
368
369
|
);
|
|
370
|
+
function createLogger(namespace) {
|
|
371
|
+
const info = createLog(namespace);
|
|
372
|
+
info.log = console.info.bind(console);
|
|
373
|
+
const debug = info.extend("debug");
|
|
374
|
+
debug.log = console.debug.bind(console);
|
|
375
|
+
const warn = info.extend("warn");
|
|
376
|
+
warn.log = console.warn.bind(console);
|
|
377
|
+
const error = info.extend("error");
|
|
378
|
+
error.log = console.error.bind(console);
|
|
379
|
+
return {
|
|
380
|
+
debug,
|
|
381
|
+
info,
|
|
382
|
+
warn,
|
|
383
|
+
error
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
function printTree(object, logger2) {
|
|
387
|
+
if (!logger2.enabled) return;
|
|
388
|
+
const isGroup = object.isGroup;
|
|
389
|
+
const name = object.name.split(":").at(-1);
|
|
390
|
+
if (isGroup) {
|
|
391
|
+
console.groupCollapsed(name);
|
|
392
|
+
object.children.forEach((child) => printTree(child, logger2));
|
|
393
|
+
console.groupEnd();
|
|
394
|
+
} else {
|
|
395
|
+
logger2.log(`${name}<${object.type}>, render order: ${object.renderOrder}`);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
369
398
|
function isObject(item) {
|
|
370
399
|
return !!item && typeof item === "object" && !Array.isArray(item);
|
|
371
400
|
}
|
|
@@ -394,7 +423,7 @@ function getSquareTextureSize(capacity, pixelsPerInstance) {
|
|
|
394
423
|
}
|
|
395
424
|
function getSquareTextureInfo(arrayType, channels, pixelsPerInstance, capacity) {
|
|
396
425
|
if (channels === 3) {
|
|
397
|
-
|
|
426
|
+
logger$b.debug('"channels" cannot be 3. Set to 4. More info: https://github.com/mrdoob/three.js/pull/23228');
|
|
398
427
|
channels = 4;
|
|
399
428
|
}
|
|
400
429
|
const size = getSquareTextureSize(capacity, pixelsPerInstance);
|
|
@@ -416,6 +445,7 @@ function getSquareTextureInfo(arrayType, channels, pixelsPerInstance, capacity)
|
|
|
416
445
|
}
|
|
417
446
|
return { array, size, type, format };
|
|
418
447
|
}
|
|
448
|
+
const logger$b = createLogger("SquareDataTexture");
|
|
419
449
|
class SquareDataTexture extends DataTexture {
|
|
420
450
|
/**
|
|
421
451
|
* @param arrayType The constructor for the TypedArray.
|
|
@@ -453,7 +483,7 @@ class SquareDataTexture extends DataTexture {
|
|
|
453
483
|
setUniformAt(id, name, value) {
|
|
454
484
|
const schema = this.uniformMap.get(name);
|
|
455
485
|
if (!schema) {
|
|
456
|
-
|
|
486
|
+
logger$b.debug(`setUniformAt: uniform ${name} not found`);
|
|
457
487
|
return;
|
|
458
488
|
}
|
|
459
489
|
const { offset, size } = schema;
|
|
@@ -474,7 +504,7 @@ class SquareDataTexture extends DataTexture {
|
|
|
474
504
|
getUniformAt(id, name, target) {
|
|
475
505
|
const schema = this.uniformMap.get(name);
|
|
476
506
|
if (!schema) {
|
|
477
|
-
|
|
507
|
+
logger$b.debug(`getUniformAt: uniform ${name} not found`);
|
|
478
508
|
return 0;
|
|
479
509
|
}
|
|
480
510
|
const { offset, size } = schema;
|
|
@@ -620,6 +650,7 @@ class SquareDataTexture extends DataTexture {
|
|
|
620
650
|
}
|
|
621
651
|
const componentsArray = ["r", "g", "b", "a"];
|
|
622
652
|
const batchIdName = "batchId";
|
|
653
|
+
const logger$a = createLogger("BatchedMesh");
|
|
623
654
|
const _BatchedMesh = class _BatchedMesh extends BatchedMesh$1 {
|
|
624
655
|
/**
|
|
625
656
|
* @param instanceCount the max number of individual geometries planned to be added.
|
|
@@ -699,7 +730,7 @@ const _BatchedMesh = class _BatchedMesh extends BatchedMesh$1 {
|
|
|
699
730
|
if (_BatchedMesh.useMultiDraw) return;
|
|
700
731
|
const batchCount = this.batchCount;
|
|
701
732
|
const gl = renderer.getContext();
|
|
702
|
-
if (geometry.index == null) return
|
|
733
|
+
if (geometry.index == null) return logger$a.debug("No index buffer", (_a2 = this.parent) == null ? void 0 : _a2.name);
|
|
703
734
|
const type = this.getIndexType(gl, geometry.index);
|
|
704
735
|
gl.drawElements(gl.TRIANGLES, batchCount, type, 0);
|
|
705
736
|
renderer.info.update(batchCount, gl.TRIANGLES, 1);
|
|
@@ -714,7 +745,7 @@ const _BatchedMesh = class _BatchedMesh extends BatchedMesh$1 {
|
|
|
714
745
|
*/
|
|
715
746
|
getUniformAt(id, name, target) {
|
|
716
747
|
if (!this.uniformsTexture) {
|
|
717
|
-
|
|
748
|
+
logger$a.debug(`getUniformAt: uniforms texture not initialized`);
|
|
718
749
|
return 0;
|
|
719
750
|
}
|
|
720
751
|
return this.uniformsTexture.getUniformAt(id, name, target);
|
|
@@ -727,7 +758,7 @@ const _BatchedMesh = class _BatchedMesh extends BatchedMesh$1 {
|
|
|
727
758
|
*/
|
|
728
759
|
setUniformAt(instanceId, name, value) {
|
|
729
760
|
if (!this.uniformsTexture) {
|
|
730
|
-
|
|
761
|
+
logger$a.debug(`setUniformAt: uniforms texture not initialized`);
|
|
731
762
|
return;
|
|
732
763
|
}
|
|
733
764
|
this.uniformsTexture.setUniformAt(instanceId, name, value);
|
|
@@ -1086,12 +1117,14 @@ class RenderableSystem {
|
|
|
1086
1117
|
/**
|
|
1087
1118
|
* @param type readable name of the system's type for debugging
|
|
1088
1119
|
* @param renderer {@link Renderer}
|
|
1120
|
+
* @param logger {@link Logger}
|
|
1089
1121
|
*/
|
|
1090
|
-
constructor(type, renderer) {
|
|
1122
|
+
constructor(type, renderer, logger2) {
|
|
1091
1123
|
__publicField(this, "mapDefToObject", /* @__PURE__ */ new Map());
|
|
1092
1124
|
__publicField(this, "mapObjectToDefs", /* @__PURE__ */ new Map());
|
|
1093
1125
|
this.type = type;
|
|
1094
1126
|
this.renderer = renderer;
|
|
1127
|
+
this.logger = logger2;
|
|
1095
1128
|
}
|
|
1096
1129
|
/**
|
|
1097
1130
|
* Update a def with its current properties.
|
|
@@ -1118,7 +1151,7 @@ class RenderableSystem {
|
|
|
1118
1151
|
* @param layerDef {@link TypedLayerDef} layer definition to update
|
|
1119
1152
|
*/
|
|
1120
1153
|
updateLayer(group, layerDef) {
|
|
1121
|
-
|
|
1154
|
+
this.logger.debug(`Updating layer ${layerDef.name} %O`, layerDef);
|
|
1122
1155
|
this.updateLayerImpl(group, layerDef);
|
|
1123
1156
|
}
|
|
1124
1157
|
/**
|
|
@@ -1223,7 +1256,7 @@ class RenderableSystem {
|
|
|
1223
1256
|
registerDefObject(def, object, instanceIds) {
|
|
1224
1257
|
const ids = Array.isArray(instanceIds) ? instanceIds : [instanceIds];
|
|
1225
1258
|
if (ids.length === 0) {
|
|
1226
|
-
|
|
1259
|
+
this.logger.debug(`Tried to register def with empty instanceIds %O`, def);
|
|
1227
1260
|
return;
|
|
1228
1261
|
}
|
|
1229
1262
|
this.mapDefToObject.set(def, { object, instanceIds: ids });
|
|
@@ -1282,7 +1315,7 @@ class RenderableSystem {
|
|
|
1282
1315
|
getObjectInstanceByDef(def) {
|
|
1283
1316
|
const mapping = this.mapDefToObject.get(def);
|
|
1284
1317
|
if (!mapping) {
|
|
1285
|
-
|
|
1318
|
+
this.logger.debug(`No object mapping found for def %O`, def);
|
|
1286
1319
|
return void 0;
|
|
1287
1320
|
}
|
|
1288
1321
|
return mapping;
|
|
@@ -1303,13 +1336,14 @@ class RenderableSystem {
|
|
|
1303
1336
|
return Array.from(this.mapObjectToDefs.keys());
|
|
1304
1337
|
}
|
|
1305
1338
|
}
|
|
1339
|
+
const logger$9 = createLogger("image");
|
|
1306
1340
|
class ImageSystem extends RenderableSystem {
|
|
1307
1341
|
/**
|
|
1308
1342
|
* @param materialSystem {@link MaterialSystem}
|
|
1309
1343
|
* @param renderer {@link Renderer}
|
|
1310
1344
|
*/
|
|
1311
1345
|
constructor(materialSystem, renderer) {
|
|
1312
|
-
super("image", renderer);
|
|
1346
|
+
super("image", renderer, logger$9);
|
|
1313
1347
|
/** Textures memory limit in megabytes */
|
|
1314
1348
|
__publicField(this, "memoryLimitMb");
|
|
1315
1349
|
__publicField(this, "packer");
|
|
@@ -1319,7 +1353,7 @@ class ImageSystem extends RenderableSystem {
|
|
|
1319
1353
|
__publicField(this, "scaleMatrix", new Matrix4());
|
|
1320
1354
|
this.materialSystem = materialSystem;
|
|
1321
1355
|
const atlasTextureSize = renderer.context.capabilities.maxTextureSize;
|
|
1322
|
-
|
|
1356
|
+
logger$9.debug(`Max texture size: ${atlasTextureSize}`);
|
|
1323
1357
|
const padding = 1;
|
|
1324
1358
|
this.packer = new MaxRectsPacker(atlasTextureSize, atlasTextureSize, padding, { pot: false });
|
|
1325
1359
|
}
|
|
@@ -1369,10 +1403,10 @@ class ImageSystem extends RenderableSystem {
|
|
|
1369
1403
|
resizeTextures() {
|
|
1370
1404
|
var _a2;
|
|
1371
1405
|
if (!this.memoryLimitMb) {
|
|
1372
|
-
|
|
1406
|
+
logger$9.debug("Memory limit is not set, unable to resize textures.");
|
|
1373
1407
|
return;
|
|
1374
1408
|
}
|
|
1375
|
-
|
|
1409
|
+
logger$9.debug(`Resizing textures to fit memory limit: ${this.memoryLimitMb} MB`);
|
|
1376
1410
|
const texturesToResize = [];
|
|
1377
1411
|
let totalResizable = 0;
|
|
1378
1412
|
let totalNonResizable = 0;
|
|
@@ -1389,15 +1423,15 @@ class ImageSystem extends RenderableSystem {
|
|
|
1389
1423
|
}
|
|
1390
1424
|
const budget = this.memoryLimitMb * 1024 * 1024 - totalNonResizable;
|
|
1391
1425
|
if (budget < 0) {
|
|
1392
|
-
|
|
1426
|
+
logger$9.debug("Memory limit is too low, unable to resize textures.");
|
|
1393
1427
|
return;
|
|
1394
1428
|
}
|
|
1395
1429
|
const resizeFactor = Math.sqrt(budget / totalResizable);
|
|
1396
1430
|
if (resizeFactor >= 1) {
|
|
1397
|
-
|
|
1431
|
+
logger$9.debug("Textures are already within the memory limit, no need to resize");
|
|
1398
1432
|
return;
|
|
1399
1433
|
}
|
|
1400
|
-
|
|
1434
|
+
logger$9.debug(`Resize factor: ${resizeFactor}`);
|
|
1401
1435
|
let newTotal = totalNonResizable;
|
|
1402
1436
|
for (const mesh of texturesToResize) {
|
|
1403
1437
|
const material = mesh.material;
|
|
@@ -1405,14 +1439,14 @@ class ImageSystem extends RenderableSystem {
|
|
|
1405
1439
|
const resizedTexture = resizeTexture(texture, resizeFactor);
|
|
1406
1440
|
const textureDim = `${texture.image.width}x${texture.image.height}`;
|
|
1407
1441
|
const resizedDim = `${resizedTexture.image.width}x${resizedTexture.image.height}`;
|
|
1408
|
-
|
|
1442
|
+
logger$9.debug(`Resized atlas for ${mesh.name || ((_a2 = mesh.parent) == null ? void 0 : _a2.name)}, from ${textureDim} to ${resizedDim}`);
|
|
1409
1443
|
newTotal += getTextureSizeBytes(resizedTexture);
|
|
1410
1444
|
material.map = resizedTexture;
|
|
1411
1445
|
material.needsUpdate = true;
|
|
1412
1446
|
texture.dispose();
|
|
1413
1447
|
mesh.userData["nonResizable"] = true;
|
|
1414
1448
|
}
|
|
1415
|
-
|
|
1449
|
+
logger$9.debug(`New memory usage after resizing: ${newTotal} bytes`);
|
|
1416
1450
|
}
|
|
1417
1451
|
updateDefImpl(imageDef, mesh, instanceIds) {
|
|
1418
1452
|
const bounds = imageDef.bounds;
|
|
@@ -1441,8 +1475,8 @@ class ImageSystem extends RenderableSystem {
|
|
|
1441
1475
|
const boundsArea = boundsWidth * boundsHeight;
|
|
1442
1476
|
const ratio = sourceArea / boundsArea;
|
|
1443
1477
|
if (ratio > 1e3) {
|
|
1444
|
-
|
|
1445
|
-
|
|
1478
|
+
logger$9.debug(`Image bounds: ${boundsWidth}x${boundsHeight}`, `Image source: ${sourceWidth}x${sourceHeight}`);
|
|
1479
|
+
logger$9.warn(`Image bounds area is ${ratio.toFixed(2)} times smaller than the image.`);
|
|
1446
1480
|
}
|
|
1447
1481
|
const rect = new Rectangle(image.source.width, image.source.height);
|
|
1448
1482
|
rect.data = [imageWithIndex];
|
|
@@ -1453,7 +1487,7 @@ class ImageSystem extends RenderableSystem {
|
|
|
1453
1487
|
}
|
|
1454
1488
|
}
|
|
1455
1489
|
this.packer.addArray(rectangles);
|
|
1456
|
-
this.packer.bins.forEach((bin) =>
|
|
1490
|
+
this.packer.bins.forEach((bin) => logger$9.debug(`Bin: ${bin.width}x${bin.height}, ${bin.rects.length} rectangles`));
|
|
1457
1491
|
return this.packer.bins;
|
|
1458
1492
|
}
|
|
1459
1493
|
}
|
|
@@ -1467,7 +1501,7 @@ function createAtlas(bin) {
|
|
|
1467
1501
|
ctx.drawImage(rect.data[0].def.source, rect.x, rect.y, rect.width, rect.height);
|
|
1468
1502
|
}
|
|
1469
1503
|
const t1 = performance.now();
|
|
1470
|
-
|
|
1504
|
+
logger$9.debug(`Create atlas took ${(t1 - t0).toFixed(2)} milliseconds.`);
|
|
1471
1505
|
return createTexture(canvas);
|
|
1472
1506
|
}
|
|
1473
1507
|
function resizeTexture(texture, resizeFactor) {
|
|
@@ -1490,13 +1524,14 @@ function getTextureSizeBytes(texture) {
|
|
|
1490
1524
|
const imageBytes = texture.image.width * texture.image.height * 4 * (texture.generateMipmaps ? 1.33 : 1);
|
|
1491
1525
|
return Math.ceil(imageBytes);
|
|
1492
1526
|
}
|
|
1527
|
+
const logger$8 = createLogger("line");
|
|
1493
1528
|
class LineSystem extends RenderableSystem {
|
|
1494
1529
|
/**
|
|
1495
1530
|
* @param materialSystem {@link MaterialSystem}
|
|
1496
1531
|
* @param renderer {@link Renderer}
|
|
1497
1532
|
*/
|
|
1498
1533
|
constructor(materialSystem, renderer) {
|
|
1499
|
-
super("line", renderer);
|
|
1534
|
+
super("line", renderer, logger$8);
|
|
1500
1535
|
__publicField(this, "lineColor", new Color());
|
|
1501
1536
|
this.materialSystem = materialSystem;
|
|
1502
1537
|
}
|
|
@@ -1685,13 +1720,14 @@ class Polygon {
|
|
|
1685
1720
|
return this;
|
|
1686
1721
|
}
|
|
1687
1722
|
}
|
|
1723
|
+
const logger$7 = createLogger("mesh");
|
|
1688
1724
|
class MeshSystem extends RenderableSystem {
|
|
1689
1725
|
/**
|
|
1690
1726
|
* @param materialSystem {@link MaterialSystem}
|
|
1691
1727
|
* @param renderer {@link Renderer}
|
|
1692
1728
|
*/
|
|
1693
1729
|
constructor(materialSystem, renderer) {
|
|
1694
|
-
super("mesh", renderer);
|
|
1730
|
+
super("mesh", renderer, logger$7);
|
|
1695
1731
|
__publicField(this, "toRgbConverter", converter("rgb"));
|
|
1696
1732
|
__publicField(this, "meshColor", new Color());
|
|
1697
1733
|
this.materialSystem = materialSystem;
|
|
@@ -1802,13 +1838,14 @@ class MeshSystem extends RenderableSystem {
|
|
|
1802
1838
|
});
|
|
1803
1839
|
}
|
|
1804
1840
|
}
|
|
1841
|
+
const logger$6 = createLogger("text");
|
|
1805
1842
|
class TextSystem extends RenderableSystem {
|
|
1806
1843
|
/**
|
|
1807
1844
|
* @param materialSystem {@link MaterialSystem}
|
|
1808
1845
|
* @param renderer {@link Renderer}
|
|
1809
1846
|
*/
|
|
1810
1847
|
constructor(materialSystem, renderer) {
|
|
1811
|
-
super("text", renderer);
|
|
1848
|
+
super("text", renderer, logger$6);
|
|
1812
1849
|
__publicField(this, "initialTextScale", new Vector2(1, -1));
|
|
1813
1850
|
__publicField(this, "textColor", new Color());
|
|
1814
1851
|
__publicField(this, "pendingUpdates", /* @__PURE__ */ new Map());
|
|
@@ -1996,6 +2033,7 @@ function setAnchorsAndAlignment(text, alignment) {
|
|
|
1996
2033
|
text.anchorY = alignment.vertical === "bottom" ? "bottom" : "top";
|
|
1997
2034
|
text.textAlign = alignment.text ?? alignment.horizontal;
|
|
1998
2035
|
}
|
|
2036
|
+
const logger$5 = createLogger("layer");
|
|
1999
2037
|
class LayerSystem {
|
|
2000
2038
|
/**
|
|
2001
2039
|
* @param renderer {@link Renderer}
|
|
@@ -2067,12 +2105,8 @@ class LayerSystem {
|
|
|
2067
2105
|
this.updateDef(def);
|
|
2068
2106
|
processed++;
|
|
2069
2107
|
}
|
|
2070
|
-
const took = performance.now() - startTime;
|
|
2071
|
-
if (processed
|
|
2072
|
-
console.log(
|
|
2073
|
-
`LayerSystem: processed ${processed} defs in ${took.toFixed(2)}ms, ${this.pendingDefs.size} remaining`
|
|
2074
|
-
);
|
|
2075
|
-
}
|
|
2108
|
+
const took = (performance.now() - startTime).toFixed(2);
|
|
2109
|
+
if (processed) logger$5.debug(`processed ${processed} defs in ${took}ms, ${this.pendingDefs.size} remaining`);
|
|
2076
2110
|
return processed > 0;
|
|
2077
2111
|
}
|
|
2078
2112
|
/**
|
|
@@ -2082,11 +2116,8 @@ class LayerSystem {
|
|
|
2082
2116
|
*/
|
|
2083
2117
|
buildScene(sceneDef) {
|
|
2084
2118
|
this.initRenderOrder(sceneDef.rootLayer);
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
"Render order",
|
|
2088
|
-
this.layerDefRenderOrder.map((layer) => this.getFullLayerName(layer))
|
|
2089
|
-
);
|
|
2119
|
+
const renderOrder = this.layerDefRenderOrder.map((layer) => this.getFullLayerName(layer));
|
|
2120
|
+
logger$5.debug("Render order %O", renderOrder);
|
|
2090
2121
|
const rootGroup = new Group();
|
|
2091
2122
|
rootGroup.name = sceneDef.rootLayer.name;
|
|
2092
2123
|
this.mapLayerDefsToObjects.set(sceneDef.rootLayer, rootGroup);
|
|
@@ -2095,7 +2126,7 @@ class LayerSystem {
|
|
|
2095
2126
|
rootGroup.add(this.buildLayer(child));
|
|
2096
2127
|
}
|
|
2097
2128
|
this.updateLayer(sceneDef.rootLayer, false);
|
|
2098
|
-
|
|
2129
|
+
printTree(rootGroup, logger$5.debug);
|
|
2099
2130
|
if (sceneDef.memoryLimit) {
|
|
2100
2131
|
this.imageSystem.memoryLimitMb = sceneDef.memoryLimit;
|
|
2101
2132
|
this.imageSystem.resizeTextures();
|
|
@@ -2139,7 +2170,7 @@ class LayerSystem {
|
|
|
2139
2170
|
}
|
|
2140
2171
|
buildLayer(layerDef, parentPrefix = "") {
|
|
2141
2172
|
const layerFullName = parentPrefix + layerDef.name;
|
|
2142
|
-
|
|
2173
|
+
logger$5.debug(`Building layer ${layerFullName}...`);
|
|
2143
2174
|
let layerObject;
|
|
2144
2175
|
if (isShapeLayer(layerDef)) layerObject = this.meshSystem.buildLayer(layerDef);
|
|
2145
2176
|
else if (isImageLayer(layerDef)) layerObject = this.imageSystem.buildLayer(layerDef);
|
|
@@ -2209,19 +2240,6 @@ class LayerSystem {
|
|
|
2209
2240
|
return fullName;
|
|
2210
2241
|
}
|
|
2211
2242
|
}
|
|
2212
|
-
function printTree(object, fullName = false) {
|
|
2213
|
-
object.traverse((obj) => {
|
|
2214
|
-
let s = "";
|
|
2215
|
-
let obj2 = obj;
|
|
2216
|
-
while (obj2 !== object) {
|
|
2217
|
-
s = "|___ " + s;
|
|
2218
|
-
obj2 = (obj2 == null ? void 0 : obj2.parent) ?? null;
|
|
2219
|
-
}
|
|
2220
|
-
const renderOrder = obj.isGroup ? "" : `, RO: ${obj.renderOrder}`;
|
|
2221
|
-
const name = fullName ? obj.name : obj.name.split(":").at(-1);
|
|
2222
|
-
console.log(`${s}${name}<${obj.type}>${renderOrder}`);
|
|
2223
|
-
});
|
|
2224
|
-
}
|
|
2225
2243
|
/*!
|
|
2226
2244
|
* camera-controls
|
|
2227
2245
|
* https://github.com/yomotsu/camera-controls
|
|
@@ -4750,14 +4768,13 @@ const subsetOfTHREE = {
|
|
|
4750
4768
|
Plane
|
|
4751
4769
|
};
|
|
4752
4770
|
CameraControls.install({ THREE: subsetOfTHREE });
|
|
4771
|
+
const logger$4 = createLogger("cameraController");
|
|
4753
4772
|
class CameraController extends CameraControls {
|
|
4754
4773
|
/**
|
|
4755
4774
|
* @param camera {@link PerspectiveCamera} instance
|
|
4756
|
-
* @param renderer {@link Renderer} instance
|
|
4757
4775
|
*/
|
|
4758
|
-
constructor(camera
|
|
4776
|
+
constructor(camera) {
|
|
4759
4777
|
super(camera);
|
|
4760
|
-
this.renderer = renderer;
|
|
4761
4778
|
this.dollyToCursor = true;
|
|
4762
4779
|
this.draggingSmoothTime = 0;
|
|
4763
4780
|
void this.rotatePolarTo(0, false);
|
|
@@ -4774,15 +4791,13 @@ class CameraController extends CameraControls {
|
|
|
4774
4791
|
};
|
|
4775
4792
|
}
|
|
4776
4793
|
update(delta) {
|
|
4777
|
-
var _a2;
|
|
4778
4794
|
const needsUpdate = super.update(delta);
|
|
4779
|
-
if (needsUpdate
|
|
4780
|
-
const position = this.camera.position.toArray().map((value) => value.toFixed(2))
|
|
4781
|
-
const target = this._target.toArray().map((value) => value.toFixed(2))
|
|
4782
|
-
const
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
spherical: [${spherical}]`);
|
|
4795
|
+
if (needsUpdate) {
|
|
4796
|
+
const position = this.camera.position.toArray().map((value) => +value.toFixed(2));
|
|
4797
|
+
const target = this._target.toArray().map((value) => +value.toFixed(2));
|
|
4798
|
+
const { theta, phi, radius } = this._spherical;
|
|
4799
|
+
const spherical = [theta * RAD2DEG, phi * RAD2DEG, radius].map((value) => +value.toFixed(2));
|
|
4800
|
+
logger$4.debug("camera update %O", { position, target, spherical });
|
|
4786
4801
|
}
|
|
4787
4802
|
return needsUpdate;
|
|
4788
4803
|
}
|
|
@@ -4810,7 +4825,7 @@ class CameraSystem {
|
|
|
4810
4825
|
this.prevViewportHeightPx = h;
|
|
4811
4826
|
this.camera = new PerspectiveCamera(this.defaultFov);
|
|
4812
4827
|
this.camera.up.set(0, 0, -1);
|
|
4813
|
-
this.controller = new CameraController(this.camera
|
|
4828
|
+
this.controller = new CameraController(this.camera);
|
|
4814
4829
|
this.controller.distance = this.zoomIdentityDistance;
|
|
4815
4830
|
}
|
|
4816
4831
|
/** Current camera zoom factor. */
|
|
@@ -4823,6 +4838,7 @@ class CameraSystem {
|
|
|
4823
4838
|
* @returns Corresponding camera distance on the Z axis
|
|
4824
4839
|
*/
|
|
4825
4840
|
zoomFactorToDistance(zoomFactor) {
|
|
4841
|
+
if (zoomFactor <= 0) return this.zoomIdentityDistance;
|
|
4826
4842
|
return this.zoomIdentityDistance / zoomFactor;
|
|
4827
4843
|
}
|
|
4828
4844
|
/**
|
|
@@ -4878,6 +4894,7 @@ class CameraSystem {
|
|
|
4878
4894
|
return zid / (this.controller.distance || zid);
|
|
4879
4895
|
}
|
|
4880
4896
|
}
|
|
4897
|
+
const logger$3 = createLogger("external");
|
|
4881
4898
|
class ExternalSystem {
|
|
4882
4899
|
/**
|
|
4883
4900
|
* @param pickingSystem {@link PickingSystem} instance
|
|
@@ -4974,7 +4991,7 @@ class ExternalSystem {
|
|
|
4974
4991
|
}
|
|
4975
4992
|
validateMatrix(matrix, name) {
|
|
4976
4993
|
if (matrix.length !== 16) {
|
|
4977
|
-
|
|
4994
|
+
logger$3.warn(`${name}: Matrix must be 16 elements long`);
|
|
4978
4995
|
return false;
|
|
4979
4996
|
}
|
|
4980
4997
|
return true;
|
|
@@ -5102,6 +5119,7 @@ class SceneSystem {
|
|
|
5102
5119
|
this.scene.matrixWorldNeedsUpdate = true;
|
|
5103
5120
|
}
|
|
5104
5121
|
}
|
|
5122
|
+
const logger$2 = createLogger("viewport");
|
|
5105
5123
|
class ViewportSystem {
|
|
5106
5124
|
/**
|
|
5107
5125
|
* @param renderer {@link Renderer} instance
|
|
@@ -5172,7 +5190,7 @@ class ViewportSystem {
|
|
|
5172
5190
|
updatePtScale() {
|
|
5173
5191
|
const pxToSvgScale = this.pxToSvgScale;
|
|
5174
5192
|
if (Math.abs(pxToSvgScale - (this.prevPxToSvgScale ?? 0)) < this.pxToSvgScaleThreshold) return;
|
|
5175
|
-
|
|
5193
|
+
logger$2.debug(`pxToSvgScale ${+pxToSvgScale.toFixed(3)}`);
|
|
5176
5194
|
this.eventSystem.emit("viewport:ptscale", pxToSvgScale);
|
|
5177
5195
|
this.prevPxToSvgScale = pxToSvgScale;
|
|
5178
5196
|
}
|
|
@@ -5219,9 +5237,13 @@ class ViewportSystem {
|
|
|
5219
5237
|
* @returns Point in NDC space
|
|
5220
5238
|
*/
|
|
5221
5239
|
canvasToNDC(point, out = new Vector2()) {
|
|
5240
|
+
const [w, h] = this.renderer.size;
|
|
5241
|
+
if (w <= 0 || h <= 0) {
|
|
5242
|
+
logger$2.warn("canvasToNDC: renderer size is 0");
|
|
5243
|
+
return out.set(0, 0);
|
|
5244
|
+
}
|
|
5222
5245
|
const dpr = this.renderer.context.getPixelRatio();
|
|
5223
|
-
const
|
|
5224
|
-
const uv = [point.x / width, point.y / height];
|
|
5246
|
+
const uv = [point.x / (w / dpr), point.y / (h / dpr)];
|
|
5225
5247
|
const ndc = [uv[0] * 2 - 1, -uv[1] * 2 + 1];
|
|
5226
5248
|
return out.set(MathUtils.clamp(ndc[0], -1, 1), MathUtils.clamp(ndc[1], -1, 1));
|
|
5227
5249
|
}
|
|
@@ -5271,6 +5293,7 @@ function asViewportAPI(viewportSystem) {
|
|
|
5271
5293
|
function eventToCanvas(event) {
|
|
5272
5294
|
return { x: event.offsetX, y: event.offsetY };
|
|
5273
5295
|
}
|
|
5296
|
+
const logger$1 = createLogger("controls");
|
|
5274
5297
|
class ControlsSystem {
|
|
5275
5298
|
/**
|
|
5276
5299
|
* @param renderer {@link Renderer} instance
|
|
@@ -5321,6 +5344,10 @@ class ControlsSystem {
|
|
|
5321
5344
|
[Math.min(...xValues), Math.min(...yValues)],
|
|
5322
5345
|
[Math.max(...xValues), Math.max(...yValues)]
|
|
5323
5346
|
);
|
|
5347
|
+
if (sourceRect.size.x <= 0 || sourceRect.size.y <= 0) {
|
|
5348
|
+
logger$1.warn("zoomTo: sourceRect size is 0");
|
|
5349
|
+
return;
|
|
5350
|
+
}
|
|
5324
5351
|
const targetRect = visibleRect ? new Rect(visibleRect.min.clone().multiplyScalar(dpr), visibleRect.max.clone().multiplyScalar(dpr)) : new Rect([0, 0], [...this.renderer.size]);
|
|
5325
5352
|
if (paddingPercent) targetRect.addPadding(targetRect.size.x * paddingPercent, targetRect.size.y * paddingPercent);
|
|
5326
5353
|
const zoomByWidth = targetRect.size.x / sourceRect.size.x;
|
|
@@ -5329,7 +5356,7 @@ class ControlsSystem {
|
|
|
5329
5356
|
const zoom = maxZoom ? Math.min(minZoom, maxZoom) : minZoom;
|
|
5330
5357
|
const translate = sourceRect.center;
|
|
5331
5358
|
if (visibleRect) {
|
|
5332
|
-
const offset = new Vector2(...this.renderer.size).multiplyScalar(0.5).sub(targetRect.center).multiplyScalar(1 / zoom).rotateAround({ x: 0, y: 0 }, bearingAngle);
|
|
5359
|
+
const offset = new Vector2(...this.renderer.size).multiplyScalar(0.5).sub(targetRect.center).multiplyScalar(1 / (zoom || 1)).rotateAround({ x: 0, y: 0 }, bearingAngle);
|
|
5333
5360
|
translate.add(offset);
|
|
5334
5361
|
}
|
|
5335
5362
|
const enableTransition = !immediate;
|
|
@@ -5390,7 +5417,6 @@ class ControlsSystem {
|
|
|
5390
5417
|
const spherical = this.controller.getSpherical(new Spherical());
|
|
5391
5418
|
const azimuthAngle = spherical.theta;
|
|
5392
5419
|
const deltaAngleRad = shortestRotationAngle(targetAngleRad, azimuthAngle);
|
|
5393
|
-
console.log("rollTo", deltaAngleRad * RAD2DEG, targetAngleRad * RAD2DEG, azimuthAngle * RAD2DEG);
|
|
5394
5420
|
return this.rollBy(-deltaAngleRad * RAD2DEG, immediate);
|
|
5395
5421
|
}
|
|
5396
5422
|
/**
|
|
@@ -6186,14 +6212,12 @@ class InteractionsSystem {
|
|
|
6186
6212
|
this.canvasListeners = void 0;
|
|
6187
6213
|
}
|
|
6188
6214
|
}
|
|
6215
|
+
const logger = createLogger("renderer");
|
|
6189
6216
|
class Renderer {
|
|
6190
6217
|
/**
|
|
6191
6218
|
* @param opts {@link RendererOptions}
|
|
6192
6219
|
*/
|
|
6193
6220
|
constructor(opts) {
|
|
6194
|
-
/** Whether to log debug information */
|
|
6195
|
-
__publicField(this, "debugLog");
|
|
6196
|
-
//FIXME: Add https://www.npmjs.com/package/debug
|
|
6197
6221
|
/** {@link HTMLCanvasElement} that this renderer is rendering to */
|
|
6198
6222
|
__publicField(this, "canvas");
|
|
6199
6223
|
__publicField(this, "ui");
|
|
@@ -6214,9 +6238,8 @@ class Renderer {
|
|
|
6214
6238
|
__publicField(this, "initialized", false);
|
|
6215
6239
|
__publicField(this, "disposed", false);
|
|
6216
6240
|
__publicField(this, "needsRedraw", true);
|
|
6217
|
-
const { canvas, gl,
|
|
6241
|
+
const { canvas, gl, ui } = opts;
|
|
6218
6242
|
this.canvas = canvas;
|
|
6219
|
-
this.debugLog = debugLog;
|
|
6220
6243
|
this.ui = ui;
|
|
6221
6244
|
this.gl = gl;
|
|
6222
6245
|
const rendererOptions = {
|
|
@@ -6234,6 +6257,8 @@ class Renderer {
|
|
|
6234
6257
|
this.layerSystem = new LayerSystem(this);
|
|
6235
6258
|
this.interactionsSystem = new InteractionsSystem(this, this.eventSystem, this.viewportSystem, this.layerSystem);
|
|
6236
6259
|
this.controlsSystem = new ControlsSystem(this, this.viewportSystem, this.interactionsSystem);
|
|
6260
|
+
this.canvas.addEventListener("webglcontextlost", (e) => this.onContextLost(e), false);
|
|
6261
|
+
this.canvas.addEventListener("webglcontextrestored", (e) => this.onContextRestored(e), false);
|
|
6237
6262
|
this.initContext(this.renderer.getContext());
|
|
6238
6263
|
BatchedMesh.useMultiDraw = this.renderer.extensions.has("WEBGL_multi_draw");
|
|
6239
6264
|
}
|
|
@@ -6353,6 +6378,7 @@ class Renderer {
|
|
|
6353
6378
|
this.interactionsSystem.init();
|
|
6354
6379
|
this.viewportSystem.scene.add(this.layerSystem.buildScene(sceneDef));
|
|
6355
6380
|
this.initialized = true;
|
|
6381
|
+
logger.info("initialized");
|
|
6356
6382
|
}
|
|
6357
6383
|
/**
|
|
6358
6384
|
* Start the rendering loop
|
|
@@ -6363,6 +6389,7 @@ class Renderer {
|
|
|
6363
6389
|
if (this.clock.running) return;
|
|
6364
6390
|
this.clock.start();
|
|
6365
6391
|
this.renderer.setAnimationLoop(() => this.render());
|
|
6392
|
+
logger.info("started");
|
|
6366
6393
|
}
|
|
6367
6394
|
/**
|
|
6368
6395
|
* Update the given defs to make them reflect the current state
|
|
@@ -6402,6 +6429,7 @@ class Renderer {
|
|
|
6402
6429
|
stop() {
|
|
6403
6430
|
this.renderer.setAnimationLoop(null);
|
|
6404
6431
|
this.clock.stop();
|
|
6432
|
+
logger.info("stopped");
|
|
6405
6433
|
}
|
|
6406
6434
|
/**
|
|
6407
6435
|
* Dispose all WebGL resources. This calls {@link Renderer.stop} internally.
|
|
@@ -6419,6 +6447,7 @@ class Renderer {
|
|
|
6419
6447
|
this.renderer.dispose();
|
|
6420
6448
|
this.updateMemoryInfo();
|
|
6421
6449
|
this.disposed = true;
|
|
6450
|
+
logger.info("disposed");
|
|
6422
6451
|
}
|
|
6423
6452
|
// https://webgl2fundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
|
|
6424
6453
|
resizeCanvasToDisplaySize() {
|
|
@@ -6427,7 +6456,7 @@ class Renderer {
|
|
|
6427
6456
|
const displayWidth = Math.floor(width * dpr);
|
|
6428
6457
|
const displayHeight = Math.floor(height * dpr);
|
|
6429
6458
|
if (this.canvas.width !== displayWidth || this.canvas.height !== displayHeight || this.renderer.getPixelRatio() !== dpr) {
|
|
6430
|
-
|
|
6459
|
+
logger.debug("renderer resize", width, height, dpr);
|
|
6431
6460
|
this.renderer.setSize(width, height, false);
|
|
6432
6461
|
this.renderer.setPixelRatio(dpr);
|
|
6433
6462
|
this.viewportSystem.updateViewport();
|
|
@@ -6442,7 +6471,7 @@ class Renderer {
|
|
|
6442
6471
|
if (memoryInfo.memory["texture"] !== ((_b = this.memoryInfo) == null ? void 0 : _b.memory["texture"]) || memoryInfo.memory["buffer"] !== ((_c = this.memoryInfo) == null ? void 0 : _c.memory["buffer"]) || memoryInfo.memory["renderbuffer"] !== ((_d = this.memoryInfo) == null ? void 0 : _d.memory["renderbuffer"])) {
|
|
6443
6472
|
const elapsedTime = this.clock.getElapsedTime() * 1e3;
|
|
6444
6473
|
const logMarker = `memoryInfo [${elapsedTime.toFixed(2)}ms since start]`;
|
|
6445
|
-
|
|
6474
|
+
logger.debug(logMarker, memoryInfo);
|
|
6446
6475
|
this.memoryInfo = memoryInfo;
|
|
6447
6476
|
this.ui.memoryInfoPanel.textContent = JSON.stringify(memoryInfo, null, 2);
|
|
6448
6477
|
}
|
|
@@ -6451,7 +6480,7 @@ class Renderer {
|
|
|
6451
6480
|
onContextLost(event) {
|
|
6452
6481
|
var _a2, _b;
|
|
6453
6482
|
event.preventDefault();
|
|
6454
|
-
|
|
6483
|
+
logger.debug("webglcontextlost event", event);
|
|
6455
6484
|
const stats = (_a2 = this.ui) == null ? void 0 : _a2.stats;
|
|
6456
6485
|
const context = this.renderer.getContext();
|
|
6457
6486
|
if (stats && "deleteQuery" in context) {
|
|
@@ -6470,7 +6499,7 @@ class Renderer {
|
|
|
6470
6499
|
}
|
|
6471
6500
|
onContextRestored(event) {
|
|
6472
6501
|
event.preventDefault();
|
|
6473
|
-
|
|
6502
|
+
logger.debug("webglcontextrestored event", event);
|
|
6474
6503
|
this.initContext(this.renderer.getContext());
|
|
6475
6504
|
this.needsRedraw = true;
|
|
6476
6505
|
this.start();
|
|
@@ -6482,35 +6511,35 @@ class Renderer {
|
|
|
6482
6511
|
}
|
|
6483
6512
|
assertNotDisposed(funcName) {
|
|
6484
6513
|
if (this.disposed) {
|
|
6485
|
-
|
|
6514
|
+
logger.warn(`[${funcName}]: Renderer is used after being disposed. Please create a new instance.`);
|
|
6486
6515
|
return false;
|
|
6487
6516
|
}
|
|
6488
6517
|
return true;
|
|
6489
6518
|
}
|
|
6490
6519
|
assertInitialized(funcName) {
|
|
6491
6520
|
if (!this.initialized) {
|
|
6492
|
-
|
|
6521
|
+
logger.warn(`${funcName}: Renderer is not initialized. Please call init() before using it.`);
|
|
6493
6522
|
return false;
|
|
6494
6523
|
}
|
|
6495
6524
|
return true;
|
|
6496
6525
|
}
|
|
6497
6526
|
assertNotInitialized(funcName) {
|
|
6498
6527
|
if (this.initialized) {
|
|
6499
|
-
|
|
6528
|
+
logger.warn(`${funcName}: Renderer is already initialized. Please call init() only once.`);
|
|
6500
6529
|
return false;
|
|
6501
6530
|
}
|
|
6502
6531
|
return true;
|
|
6503
6532
|
}
|
|
6504
6533
|
assertNotExternalMode(funcName) {
|
|
6505
6534
|
if (this.isExternalMode) {
|
|
6506
|
-
|
|
6535
|
+
logger.warn(`${funcName}: This operation is not supported in external mode.`);
|
|
6507
6536
|
return false;
|
|
6508
6537
|
}
|
|
6509
6538
|
return true;
|
|
6510
6539
|
}
|
|
6511
6540
|
assertExternalMode(funcName) {
|
|
6512
6541
|
if (!this.isExternalMode) {
|
|
6513
|
-
|
|
6542
|
+
logger.warn(`${funcName}: This operation is only supported in external mode.`);
|
|
6514
6543
|
return false;
|
|
6515
6544
|
}
|
|
6516
6545
|
return true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expofp/renderer",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"exports": "./dist/index.js",
|
|
12
12
|
"devDependencies": {
|
|
13
13
|
"@types/culori": "^2.1.1",
|
|
14
|
+
"@types/debug": "^4.1.12",
|
|
14
15
|
"@types/object-hash": "^3.0.6",
|
|
15
16
|
"@types/three": "^0.174.0",
|
|
16
17
|
"stats-gl": "^3.6.0",
|
|
@@ -22,6 +23,7 @@
|
|
|
22
23
|
"dependencies": {
|
|
23
24
|
"camera-controls": "^3.1.1",
|
|
24
25
|
"culori": "^4.0.1",
|
|
26
|
+
"debug": "^4.4.3",
|
|
25
27
|
"maxrects-packer": "^2.7.3",
|
|
26
28
|
"mjolnir.js": "^3.0.0",
|
|
27
29
|
"three": "^0.174.0",
|