3dtiles-inspector 0.1.5 → 0.1.7
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/CHANGELOG.md +13 -0
- package/README.md +3 -1
- package/dist/inspector-assets/viewer/app.js +39 -29
- package/package.json +1 -1
- package/src/viewer/app.js +62 -32
- package/src/viewer/session.js +87 -74
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,19 @@ The format is based on Keep a Changelog and this project follows Semantic Versio
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.1.7] - 2026-04-27
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Changed `Layer Multiplier` to use the tileset-wide minimum leaf geometric error as the baseline, so non-minimum leaf tiles are scaled too.
|
|
14
|
+
|
|
15
|
+
## [0.1.6] - 2026-04-27
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Changed `Layer Multiplier` to scale each tile's geometric-error difference from its leaf baseline instead of applying a depth-based multiplier.
|
|
20
|
+
- Expanded the `Layer Multiplier` range to `1/8x` through `8x`.
|
|
21
|
+
|
|
9
22
|
## [0.1.5] - 2026-04-27
|
|
10
23
|
|
|
11
24
|
### Added
|
package/README.md
CHANGED
|
@@ -76,13 +76,15 @@ const {
|
|
|
76
76
|
|
|
77
77
|
## Inspector Features
|
|
78
78
|
|
|
79
|
+
<img src="https://raw.githubusercontent.com/WilliamLiu-1997/3DTiles-Inspector/main/screenshot.png" alt="screenshot" width="960" />
|
|
80
|
+
|
|
79
81
|
- `Translate`, `Rotate`, and `Reset` for root transform edits
|
|
80
82
|
- `Move Camera` to a WGS84 latitude / longitude / height
|
|
81
83
|
- `Move Tiles` to relocate the tileset root with an ENU-aligned transform
|
|
82
84
|
- `Set Position` to click the globe, terrain, or loaded tiles and place the tileset there
|
|
83
85
|
- `Terrain` to toggle Cesium World Terrain while keeping satellite imagery
|
|
84
86
|
- `Geometric Error` scaling from `1/16x` to `16x`
|
|
85
|
-
- `Layer Multiplier` scaling from `1/
|
|
87
|
+
- `Layer Multiplier` scaling from `1/8x` to `8x` for each tile's geometric-error difference from the tileset's global leaf baseline
|
|
86
88
|
- `Save` to persist the updated root transform and geometric-error scale back to disk
|
|
87
89
|
|
|
88
90
|
If `build_summary.json` exists next to the root tileset, `Save` also updates:
|
|
@@ -65496,14 +65496,9 @@ var saveButton = document.getElementById("save");
|
|
|
65496
65496
|
var GEOMETRIC_ERROR_SCALE_MIN_EXPONENT = -4;
|
|
65497
65497
|
var GEOMETRIC_ERROR_SCALE_MAX_EXPONENT = 4;
|
|
65498
65498
|
var GEOMETRIC_ERROR_SCALE_STEP = 0.1;
|
|
65499
|
-
var
|
|
65500
|
-
var
|
|
65501
|
-
|
|
65502
|
-
);
|
|
65503
|
-
var GEOMETRIC_ERROR_LAYER_SCALE_MAX_EXPONENT = Math.log2(
|
|
65504
|
-
GEOMETRIC_ERROR_LAYER_SCALE_MAX
|
|
65505
|
-
);
|
|
65506
|
-
var GEOMETRIC_ERROR_LAYER_SCALE_STEP = "any";
|
|
65499
|
+
var GEOMETRIC_ERROR_LAYER_SCALE_MIN_EXPONENT = -3;
|
|
65500
|
+
var GEOMETRIC_ERROR_LAYER_SCALE_MAX_EXPONENT = 3;
|
|
65501
|
+
var GEOMETRIC_ERROR_LAYER_SCALE_STEP = 0.1;
|
|
65507
65502
|
var DEFAULT_ERROR_TARGET = 16;
|
|
65508
65503
|
var DEFAULT_TERRAIN_ERROR_TARGET = 16;
|
|
65509
65504
|
var RUNTIME_STATS_UPDATE_INTERVAL_MS = 250;
|
|
@@ -65860,22 +65855,6 @@ function getEffectiveGeometricErrorScale() {
|
|
|
65860
65855
|
function getEffectiveGeometricErrorLayerScale() {
|
|
65861
65856
|
return lastSavedGeometricErrorLayerScale * geometricErrorLayerScale;
|
|
65862
65857
|
}
|
|
65863
|
-
function getKnownTileLeafDistance(tile, visited = /* @__PURE__ */ new Set()) {
|
|
65864
|
-
if (!tile || typeof tile !== "object" || visited.has(tile)) {
|
|
65865
|
-
return 0;
|
|
65866
|
-
}
|
|
65867
|
-
visited.add(tile);
|
|
65868
|
-
let maxDistance = 0;
|
|
65869
|
-
const children = Array.isArray(tile.children) ? tile.children : [];
|
|
65870
|
-
for (const child of children) {
|
|
65871
|
-
maxDistance = Math.max(
|
|
65872
|
-
maxDistance,
|
|
65873
|
-
getKnownTileLeafDistance(child, visited) + 1
|
|
65874
|
-
);
|
|
65875
|
-
}
|
|
65876
|
-
visited.delete(tile);
|
|
65877
|
-
return maxDistance;
|
|
65878
|
-
}
|
|
65879
65858
|
function getOriginalTileGeometricError(tile) {
|
|
65880
65859
|
if (!tile || typeof tile !== "object") {
|
|
65881
65860
|
return null;
|
|
@@ -65889,21 +65868,52 @@ function getOriginalTileGeometricError(tile) {
|
|
|
65889
65868
|
}
|
|
65890
65869
|
return originalTileGeometricErrors.get(tile);
|
|
65891
65870
|
}
|
|
65892
|
-
function
|
|
65871
|
+
function getKnownTileLeafGeometricError(tile, visited = /* @__PURE__ */ new Set()) {
|
|
65872
|
+
const originalGeometricError = getOriginalTileGeometricError(tile);
|
|
65873
|
+
if (originalGeometricError === null || !tile || typeof tile !== "object" || visited.has(tile)) {
|
|
65874
|
+
return originalGeometricError;
|
|
65875
|
+
}
|
|
65876
|
+
visited.add(tile);
|
|
65877
|
+
let leafGeometricError = null;
|
|
65878
|
+
const children = Array.isArray(tile.children) ? tile.children : [];
|
|
65879
|
+
for (const child of children) {
|
|
65880
|
+
const childLeafGeometricError = getKnownTileLeafGeometricError(
|
|
65881
|
+
child,
|
|
65882
|
+
visited
|
|
65883
|
+
);
|
|
65884
|
+
if (childLeafGeometricError !== null) {
|
|
65885
|
+
leafGeometricError = leafGeometricError === null ? childLeafGeometricError : Math.min(leafGeometricError, childLeafGeometricError);
|
|
65886
|
+
}
|
|
65887
|
+
}
|
|
65888
|
+
visited.delete(tile);
|
|
65889
|
+
return leafGeometricError === null ? originalGeometricError : leafGeometricError;
|
|
65890
|
+
}
|
|
65891
|
+
function getGlobalTileLeafGeometricError(tile) {
|
|
65892
|
+
const rootLeafGeometricError = tiles?.root ? getKnownTileLeafGeometricError(tiles.root) : null;
|
|
65893
|
+
const tileLeafGeometricError = getKnownTileLeafGeometricError(tile);
|
|
65894
|
+
if (rootLeafGeometricError === null) {
|
|
65895
|
+
return tileLeafGeometricError;
|
|
65896
|
+
}
|
|
65897
|
+
if (tileLeafGeometricError === null) {
|
|
65898
|
+
return rootLeafGeometricError;
|
|
65899
|
+
}
|
|
65900
|
+
return Math.min(rootLeafGeometricError, tileLeafGeometricError);
|
|
65901
|
+
}
|
|
65902
|
+
function applyGeometricErrorLayerScaleToTile(tile, leafGeometricError = getGlobalTileLeafGeometricError(tile)) {
|
|
65893
65903
|
const originalGeometricError = getOriginalTileGeometricError(tile);
|
|
65894
|
-
if (originalGeometricError === null) {
|
|
65904
|
+
if (originalGeometricError === null || leafGeometricError === null) {
|
|
65895
65905
|
return;
|
|
65896
65906
|
}
|
|
65897
|
-
|
|
65898
|
-
tile.geometricError = originalGeometricError * getEffectiveGeometricErrorLayerScale() ** leafDistance;
|
|
65907
|
+
tile.geometricError = leafGeometricError + (originalGeometricError - leafGeometricError) * getEffectiveGeometricErrorLayerScale();
|
|
65899
65908
|
}
|
|
65900
65909
|
function applyGeometricErrorLayerScaleToTileset() {
|
|
65901
65910
|
if (!tiles) {
|
|
65902
65911
|
return;
|
|
65903
65912
|
}
|
|
65913
|
+
const leafGeometricError = getGlobalTileLeafGeometricError(tiles.root);
|
|
65904
65914
|
tiles.traverse(
|
|
65905
65915
|
(tile) => {
|
|
65906
|
-
applyGeometricErrorLayerScaleToTile(tile);
|
|
65916
|
+
applyGeometricErrorLayerScaleToTile(tile, leafGeometricError);
|
|
65907
65917
|
return false;
|
|
65908
65918
|
},
|
|
65909
65919
|
null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "3dtiles-inspector",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Inspect, align, and save local 3D Tiles root transforms in an interactive browser session.",
|
|
5
5
|
"author": "William Liu <lyz15972107087@gmail.com>",
|
|
6
6
|
"license": "Apache-2.0",
|
package/src/viewer/app.js
CHANGED
|
@@ -112,14 +112,9 @@ const saveButton = document.getElementById('save');
|
|
|
112
112
|
const GEOMETRIC_ERROR_SCALE_MIN_EXPONENT = -4;
|
|
113
113
|
const GEOMETRIC_ERROR_SCALE_MAX_EXPONENT = 4;
|
|
114
114
|
const GEOMETRIC_ERROR_SCALE_STEP = 0.1;
|
|
115
|
-
const
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
);
|
|
119
|
-
const GEOMETRIC_ERROR_LAYER_SCALE_MAX_EXPONENT = Math.log2(
|
|
120
|
-
GEOMETRIC_ERROR_LAYER_SCALE_MAX,
|
|
121
|
-
);
|
|
122
|
-
const GEOMETRIC_ERROR_LAYER_SCALE_STEP = 'any';
|
|
115
|
+
const GEOMETRIC_ERROR_LAYER_SCALE_MIN_EXPONENT = -3;
|
|
116
|
+
const GEOMETRIC_ERROR_LAYER_SCALE_MAX_EXPONENT = 3;
|
|
117
|
+
const GEOMETRIC_ERROR_LAYER_SCALE_STEP = 0.1;
|
|
123
118
|
const DEFAULT_ERROR_TARGET = 16;
|
|
124
119
|
const DEFAULT_TERRAIN_ERROR_TARGET = 16;
|
|
125
120
|
const RUNTIME_STATS_UPDATE_INTERVAL_MS = 250;
|
|
@@ -537,24 +532,6 @@ function getEffectiveGeometricErrorLayerScale() {
|
|
|
537
532
|
return lastSavedGeometricErrorLayerScale * geometricErrorLayerScale;
|
|
538
533
|
}
|
|
539
534
|
|
|
540
|
-
function getKnownTileLeafDistance(tile, visited = new Set()) {
|
|
541
|
-
if (!tile || typeof tile !== 'object' || visited.has(tile)) {
|
|
542
|
-
return 0;
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
visited.add(tile);
|
|
546
|
-
let maxDistance = 0;
|
|
547
|
-
const children = Array.isArray(tile.children) ? tile.children : [];
|
|
548
|
-
for (const child of children) {
|
|
549
|
-
maxDistance = Math.max(
|
|
550
|
-
maxDistance,
|
|
551
|
-
getKnownTileLeafDistance(child, visited) + 1,
|
|
552
|
-
);
|
|
553
|
-
}
|
|
554
|
-
visited.delete(tile);
|
|
555
|
-
return maxDistance;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
535
|
function getOriginalTileGeometricError(tile) {
|
|
559
536
|
if (!tile || typeof tile !== 'object') {
|
|
560
537
|
return null;
|
|
@@ -571,16 +548,68 @@ function getOriginalTileGeometricError(tile) {
|
|
|
571
548
|
return originalTileGeometricErrors.get(tile);
|
|
572
549
|
}
|
|
573
550
|
|
|
574
|
-
function
|
|
551
|
+
function getKnownTileLeafGeometricError(tile, visited = new Set()) {
|
|
552
|
+
const originalGeometricError = getOriginalTileGeometricError(tile);
|
|
553
|
+
if (
|
|
554
|
+
originalGeometricError === null ||
|
|
555
|
+
!tile ||
|
|
556
|
+
typeof tile !== 'object' ||
|
|
557
|
+
visited.has(tile)
|
|
558
|
+
) {
|
|
559
|
+
return originalGeometricError;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
visited.add(tile);
|
|
563
|
+
let leafGeometricError = null;
|
|
564
|
+
const children = Array.isArray(tile.children) ? tile.children : [];
|
|
565
|
+
for (const child of children) {
|
|
566
|
+
const childLeafGeometricError = getKnownTileLeafGeometricError(
|
|
567
|
+
child,
|
|
568
|
+
visited,
|
|
569
|
+
);
|
|
570
|
+
if (childLeafGeometricError !== null) {
|
|
571
|
+
leafGeometricError =
|
|
572
|
+
leafGeometricError === null
|
|
573
|
+
? childLeafGeometricError
|
|
574
|
+
: Math.min(leafGeometricError, childLeafGeometricError);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
visited.delete(tile);
|
|
578
|
+
return leafGeometricError === null
|
|
579
|
+
? originalGeometricError
|
|
580
|
+
: leafGeometricError;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
function getGlobalTileLeafGeometricError(tile) {
|
|
584
|
+
const rootLeafGeometricError = tiles?.root
|
|
585
|
+
? getKnownTileLeafGeometricError(tiles.root)
|
|
586
|
+
: null;
|
|
587
|
+
const tileLeafGeometricError = getKnownTileLeafGeometricError(tile);
|
|
588
|
+
|
|
589
|
+
if (rootLeafGeometricError === null) {
|
|
590
|
+
return tileLeafGeometricError;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
if (tileLeafGeometricError === null) {
|
|
594
|
+
return rootLeafGeometricError;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
return Math.min(rootLeafGeometricError, tileLeafGeometricError);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
function applyGeometricErrorLayerScaleToTile(
|
|
601
|
+
tile,
|
|
602
|
+
leafGeometricError = getGlobalTileLeafGeometricError(tile),
|
|
603
|
+
) {
|
|
575
604
|
const originalGeometricError = getOriginalTileGeometricError(tile);
|
|
576
|
-
if (originalGeometricError === null) {
|
|
605
|
+
if (originalGeometricError === null || leafGeometricError === null) {
|
|
577
606
|
return;
|
|
578
607
|
}
|
|
579
608
|
|
|
580
|
-
const leafDistance = getKnownTileLeafDistance(tile);
|
|
581
609
|
tile.geometricError =
|
|
582
|
-
|
|
583
|
-
|
|
610
|
+
leafGeometricError +
|
|
611
|
+
(originalGeometricError - leafGeometricError) *
|
|
612
|
+
getEffectiveGeometricErrorLayerScale();
|
|
584
613
|
}
|
|
585
614
|
|
|
586
615
|
function applyGeometricErrorLayerScaleToTileset() {
|
|
@@ -588,9 +617,10 @@ function applyGeometricErrorLayerScaleToTileset() {
|
|
|
588
617
|
return;
|
|
589
618
|
}
|
|
590
619
|
|
|
620
|
+
const leafGeometricError = getGlobalTileLeafGeometricError(tiles.root);
|
|
591
621
|
tiles.traverse(
|
|
592
622
|
(tile) => {
|
|
593
|
-
applyGeometricErrorLayerScaleToTile(tile);
|
|
623
|
+
applyGeometricErrorLayerScaleToTile(tile, leafGeometricError);
|
|
594
624
|
return false;
|
|
595
625
|
},
|
|
596
626
|
null,
|
package/src/viewer/session.js
CHANGED
|
@@ -174,7 +174,14 @@ function normalizePositiveFinite(value, name) {
|
|
|
174
174
|
return number;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
function scaleGeometricErrorValue(
|
|
177
|
+
function scaleGeometricErrorValue(
|
|
178
|
+
target,
|
|
179
|
+
key,
|
|
180
|
+
geometricErrorScale,
|
|
181
|
+
geometricErrorLayerScale,
|
|
182
|
+
leafGeometricError,
|
|
183
|
+
label,
|
|
184
|
+
) {
|
|
178
185
|
if (target[key] == null) {
|
|
179
186
|
return;
|
|
180
187
|
}
|
|
@@ -184,7 +191,14 @@ function scaleGeometricErrorValue(target, key, scale, label) {
|
|
|
184
191
|
throw new InspectorError(`${label} must be a finite number.`);
|
|
185
192
|
}
|
|
186
193
|
|
|
187
|
-
|
|
194
|
+
if (!Number.isFinite(leafGeometricError)) {
|
|
195
|
+
throw new InspectorError(`${label} leaf geometricError must be finite.`);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const adjusted =
|
|
199
|
+
leafGeometricError +
|
|
200
|
+
(number - leafGeometricError) * geometricErrorLayerScale;
|
|
201
|
+
const next = adjusted * geometricErrorScale;
|
|
188
202
|
if (!Number.isFinite(next)) {
|
|
189
203
|
throw new InspectorError(`${label} scaled value must be finite.`);
|
|
190
204
|
}
|
|
@@ -192,20 +206,6 @@ function scaleGeometricErrorValue(target, key, scale, label) {
|
|
|
192
206
|
target[key] = next;
|
|
193
207
|
}
|
|
194
208
|
|
|
195
|
-
function getGeometricErrorScaleForLeafDistance(
|
|
196
|
-
geometricErrorScale,
|
|
197
|
-
geometricErrorLayerScale,
|
|
198
|
-
leafDistance,
|
|
199
|
-
label,
|
|
200
|
-
) {
|
|
201
|
-
const scale =
|
|
202
|
-
geometricErrorScale * geometricErrorLayerScale ** Math.max(0, leafDistance);
|
|
203
|
-
if (!Number.isFinite(scale)) {
|
|
204
|
-
throw new InspectorError(`${label} scale must be a finite number.`);
|
|
205
|
-
}
|
|
206
|
-
return scale;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
209
|
function assertTilesetPathInsideRoot(resolvedPath, rootDir) {
|
|
210
210
|
if (
|
|
211
211
|
resolvedPath !== rootDir &&
|
|
@@ -250,15 +250,15 @@ function getLocalExternalTilesetPaths(tile, baseDir) {
|
|
|
250
250
|
return paths;
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
function
|
|
253
|
+
function getTilesetRootLeafGeometricError(
|
|
254
254
|
tilesetPath,
|
|
255
255
|
rootDir,
|
|
256
|
-
|
|
256
|
+
leafGeometricErrorCache,
|
|
257
257
|
stack,
|
|
258
258
|
) {
|
|
259
259
|
const resolvedPath = path.resolve(tilesetPath);
|
|
260
|
-
if (
|
|
261
|
-
return
|
|
260
|
+
if (leafGeometricErrorCache.has(resolvedPath)) {
|
|
261
|
+
return leafGeometricErrorCache.get(resolvedPath);
|
|
262
262
|
}
|
|
263
263
|
|
|
264
264
|
if (stack.has(resolvedPath)) {
|
|
@@ -279,56 +279,72 @@ function getTilesetRootLeafDistance(
|
|
|
279
279
|
}
|
|
280
280
|
|
|
281
281
|
stack.add(resolvedPath);
|
|
282
|
-
const
|
|
282
|
+
const leafGeometricError = getTileLeafGeometricError(
|
|
283
283
|
tileset.root,
|
|
284
284
|
path.dirname(resolvedPath),
|
|
285
285
|
rootDir,
|
|
286
|
-
|
|
286
|
+
leafGeometricErrorCache,
|
|
287
287
|
stack,
|
|
288
288
|
);
|
|
289
289
|
stack.delete(resolvedPath);
|
|
290
|
-
|
|
291
|
-
return
|
|
290
|
+
leafGeometricErrorCache.set(resolvedPath, leafGeometricError);
|
|
291
|
+
return leafGeometricError;
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
function
|
|
294
|
+
function getTileLeafGeometricError(
|
|
295
|
+
tile,
|
|
296
|
+
baseDir,
|
|
297
|
+
rootDir,
|
|
298
|
+
leafGeometricErrorCache,
|
|
299
|
+
stack,
|
|
300
|
+
) {
|
|
295
301
|
if (!tile || typeof tile !== 'object') {
|
|
296
302
|
return 0;
|
|
297
303
|
}
|
|
298
304
|
|
|
299
|
-
|
|
305
|
+
const ownGeometricError = Number(tile.geometricError);
|
|
306
|
+
if (!Number.isFinite(ownGeometricError)) {
|
|
307
|
+
return 0;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
let leafGeometricError = null;
|
|
300
311
|
if (Array.isArray(tile.children)) {
|
|
301
312
|
tile.children.forEach((child) => {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
313
|
+
const childLeafGeometricError = getTileLeafGeometricError(
|
|
314
|
+
child,
|
|
315
|
+
baseDir,
|
|
316
|
+
rootDir,
|
|
317
|
+
leafGeometricErrorCache,
|
|
318
|
+
stack,
|
|
306
319
|
);
|
|
320
|
+
leafGeometricError =
|
|
321
|
+
leafGeometricError === null
|
|
322
|
+
? childLeafGeometricError
|
|
323
|
+
: Math.min(leafGeometricError, childLeafGeometricError);
|
|
307
324
|
});
|
|
308
325
|
}
|
|
309
326
|
|
|
310
327
|
getLocalExternalTilesetPaths(tile, baseDir).forEach((childTilesetPath) => {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
leafDistanceCache,
|
|
317
|
-
stack,
|
|
318
|
-
) + 1,
|
|
328
|
+
const childLeafGeometricError = getTilesetRootLeafGeometricError(
|
|
329
|
+
childTilesetPath,
|
|
330
|
+
rootDir,
|
|
331
|
+
leafGeometricErrorCache,
|
|
332
|
+
stack,
|
|
319
333
|
);
|
|
334
|
+
leafGeometricError =
|
|
335
|
+
leafGeometricError === null
|
|
336
|
+
? childLeafGeometricError
|
|
337
|
+
: Math.min(leafGeometricError, childLeafGeometricError);
|
|
320
338
|
});
|
|
321
339
|
|
|
322
|
-
return
|
|
340
|
+
return leafGeometricError === null ? ownGeometricError : leafGeometricError;
|
|
323
341
|
}
|
|
324
342
|
|
|
325
343
|
function scaleTilesetGeometricErrors(
|
|
326
344
|
tile,
|
|
327
345
|
geometricErrorScale,
|
|
328
346
|
geometricErrorLayerScale,
|
|
329
|
-
|
|
330
|
-
rootDir,
|
|
331
|
-
leafDistanceCache,
|
|
347
|
+
leafGeometricError,
|
|
332
348
|
pathLabel = 'tileset.root',
|
|
333
349
|
) {
|
|
334
350
|
if (!tile || typeof tile !== 'object') {
|
|
@@ -338,12 +354,9 @@ function scaleTilesetGeometricErrors(
|
|
|
338
354
|
scaleGeometricErrorValue(
|
|
339
355
|
tile,
|
|
340
356
|
'geometricError',
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
getTileLeafDistance(tile, baseDir, rootDir, leafDistanceCache, new Set()),
|
|
345
|
-
pathLabel,
|
|
346
|
-
),
|
|
357
|
+
geometricErrorScale,
|
|
358
|
+
geometricErrorLayerScale,
|
|
359
|
+
leafGeometricError,
|
|
347
360
|
`${pathLabel}.geometricError`,
|
|
348
361
|
);
|
|
349
362
|
|
|
@@ -356,9 +369,7 @@ function scaleTilesetGeometricErrors(
|
|
|
356
369
|
child,
|
|
357
370
|
geometricErrorScale,
|
|
358
371
|
geometricErrorLayerScale,
|
|
359
|
-
|
|
360
|
-
rootDir,
|
|
361
|
-
leafDistanceCache,
|
|
372
|
+
leafGeometricError,
|
|
362
373
|
`${pathLabel}.children[${index}]`,
|
|
363
374
|
);
|
|
364
375
|
});
|
|
@@ -406,7 +417,8 @@ function updateTilesetJsonFile(
|
|
|
406
417
|
geometricErrorScale,
|
|
407
418
|
rootDir,
|
|
408
419
|
rootTransform = null,
|
|
409
|
-
|
|
420
|
+
leafGeometricErrorCache = new Map(),
|
|
421
|
+
globalLeafGeometricError = null,
|
|
410
422
|
},
|
|
411
423
|
visited = new Set(),
|
|
412
424
|
) {
|
|
@@ -434,30 +446,30 @@ function updateTilesetJsonFile(
|
|
|
434
446
|
}
|
|
435
447
|
|
|
436
448
|
const tilesetDir = path.dirname(resolvedPath);
|
|
449
|
+
const effectiveLeafGeometricError =
|
|
450
|
+
globalLeafGeometricError == null
|
|
451
|
+
? getTileLeafGeometricError(
|
|
452
|
+
tileset.root,
|
|
453
|
+
tilesetDir,
|
|
454
|
+
rootDir,
|
|
455
|
+
leafGeometricErrorCache,
|
|
456
|
+
new Set(),
|
|
457
|
+
)
|
|
458
|
+
: globalLeafGeometricError;
|
|
459
|
+
|
|
437
460
|
scaleGeometricErrorValue(
|
|
438
461
|
tileset,
|
|
439
462
|
'geometricError',
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
getTileLeafDistance(
|
|
444
|
-
tileset.root,
|
|
445
|
-
tilesetDir,
|
|
446
|
-
rootDir,
|
|
447
|
-
leafDistanceCache,
|
|
448
|
-
new Set(),
|
|
449
|
-
),
|
|
450
|
-
resolvedPath,
|
|
451
|
-
),
|
|
463
|
+
geometricErrorScale,
|
|
464
|
+
geometricErrorLayerScale,
|
|
465
|
+
effectiveLeafGeometricError,
|
|
452
466
|
`${resolvedPath}.geometricError`,
|
|
453
467
|
);
|
|
454
468
|
scaleTilesetGeometricErrors(
|
|
455
469
|
tileset.root,
|
|
456
470
|
geometricErrorScale,
|
|
457
471
|
geometricErrorLayerScale,
|
|
458
|
-
|
|
459
|
-
rootDir,
|
|
460
|
-
leafDistanceCache,
|
|
472
|
+
effectiveLeafGeometricError,
|
|
461
473
|
`${resolvedPath}.root`,
|
|
462
474
|
);
|
|
463
475
|
writeJsonAtomic(resolvedPath, tileset);
|
|
@@ -470,7 +482,8 @@ function updateTilesetJsonFile(
|
|
|
470
482
|
{
|
|
471
483
|
geometricErrorLayerScale,
|
|
472
484
|
geometricErrorScale,
|
|
473
|
-
|
|
485
|
+
leafGeometricErrorCache,
|
|
486
|
+
globalLeafGeometricError: effectiveLeafGeometricError,
|
|
474
487
|
rootDir,
|
|
475
488
|
},
|
|
476
489
|
visited,
|
|
@@ -936,8 +949,8 @@ function buildViewerHtml(viewerConfig) {
|
|
|
936
949
|
.toolbar {
|
|
937
950
|
display: grid;
|
|
938
951
|
align-content: start;
|
|
939
|
-
gap:
|
|
940
|
-
padding: 14px;
|
|
952
|
+
gap: 8px;
|
|
953
|
+
padding: 10px 14px;
|
|
941
954
|
border: 1px solid rgba(22, 50, 79, 0.12);
|
|
942
955
|
border-top: 0;
|
|
943
956
|
border-radius: 0 0 20px 20px;
|
|
@@ -1102,7 +1115,7 @@ function buildViewerHtml(viewerConfig) {
|
|
|
1102
1115
|
|
|
1103
1116
|
.range-field {
|
|
1104
1117
|
display: grid;
|
|
1105
|
-
gap:
|
|
1118
|
+
gap: 4px;
|
|
1106
1119
|
min-width: 0;
|
|
1107
1120
|
}
|
|
1108
1121
|
|
|
@@ -1316,9 +1329,9 @@ function buildViewerHtml(viewerConfig) {
|
|
|
1316
1329
|
<input
|
|
1317
1330
|
id="geometric-error-layer-scale"
|
|
1318
1331
|
type="range"
|
|
1319
|
-
min="-
|
|
1320
|
-
max="
|
|
1321
|
-
step="
|
|
1332
|
+
min="-3"
|
|
1333
|
+
max="3"
|
|
1334
|
+
step="0.1"
|
|
1322
1335
|
value="0"
|
|
1323
1336
|
/>
|
|
1324
1337
|
</label>
|