@treasuryspatial/viewer-kit 0.2.45 → 0.2.50
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/autoGenerate.d.ts.map +1 -1
- package/dist/autoGenerate.js +7 -1
- package/dist/camera.d.ts +1 -0
- package/dist/camera.d.ts.map +1 -1
- package/dist/camera.js +8 -1
- package/dist/engine/ViewerEngine.d.ts +20 -0
- package/dist/engine/ViewerEngine.d.ts.map +1 -1
- package/dist/engine/ViewerEngine.js +254 -63
- package/dist/engine/types.d.ts +69 -3
- package/dist/engine/types.d.ts.map +1 -1
- package/dist/exports/download.d.ts +6 -0
- package/dist/exports/download.d.ts.map +1 -1
- package/dist/exports/download.js +142 -0
- package/dist/exports/three-export.d.ts +4 -1
- package/dist/exports/three-export.d.ts.map +1 -1
- package/dist/exports/three-export.js +138 -4
- package/dist/index.d.ts +13 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/materials/architectural.d.ts +3 -3
- package/dist/materials/architectural.d.ts.map +1 -1
- package/dist/materials/architectural.js +295 -37
- package/dist/materials/catalogue-data.d.ts +15 -0
- package/dist/materials/catalogue-data.d.ts.map +1 -1
- package/dist/materials/catalogue-data.js +16 -0
- package/dist/materials/presets.d.ts +15 -8
- package/dist/materials/presets.d.ts.map +1 -1
- package/dist/materials/presets.js +140 -39
- package/dist/materials/resolve.d.ts +42 -0
- package/dist/materials/resolve.d.ts.map +1 -1
- package/dist/materials/resolve.js +228 -13
- package/dist/materials/types.d.ts +32 -3
- package/dist/materials/types.d.ts.map +1 -1
- package/dist/presets/defaults.d.ts.map +1 -1
- package/dist/presets/defaults.js +17 -1
- package/dist/presets/sciencePresets.d.ts.map +1 -1
- package/dist/presets/sciencePresets.js +167 -50
- package/dist/scene.d.ts +28 -4
- package/dist/scene.d.ts.map +1 -1
- package/dist/scene.js +196 -31
- package/dist/sceneSemanticRegistry.d.ts +64 -0
- package/dist/sceneSemanticRegistry.d.ts.map +1 -0
- package/dist/sceneSemanticRegistry.js +199 -0
- package/dist/sky/scienceSky.d.ts.map +1 -1
- package/dist/sky/scienceSky.js +16 -0
- package/dist/systems/debugSystem.d.ts +24 -1
- package/dist/systems/debugSystem.d.ts.map +1 -1
- package/dist/systems/debugSystem.js +324 -77
- package/dist/systems/environmentSystem.d.ts +5 -4
- package/dist/systems/environmentSystem.d.ts.map +1 -1
- package/dist/systems/environmentSystem.js +138 -62
- package/dist/systems/lightingSystem.d.ts +10 -1
- package/dist/systems/lightingSystem.d.ts.map +1 -1
- package/dist/systems/lightingSystem.js +118 -17
- package/dist/systems/postfxSystem.d.ts +5 -1
- package/dist/systems/postfxSystem.d.ts.map +1 -1
- package/dist/systems/postfxSystem.js +84 -1
- package/dist/systems/rendererSystem.d.ts.map +1 -1
- package/dist/systems/rendererSystem.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/uploads/geometry3dm.d.ts.map +1 -1
- package/dist/uploads/geometry3dm.js +1 -0
- package/dist/uploads/grasshopper.d.ts.map +1 -1
- package/dist/uploads/grasshopper.js +63 -5
- package/dist/uploads/mesh.js +5 -5
- package/dist/uploads/types.d.ts +4 -0
- package/dist/uploads/types.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -2,15 +2,22 @@ import * as THREE from "three";
|
|
|
2
2
|
const DEFAULT_EXTRAS = {
|
|
3
3
|
grid: true,
|
|
4
4
|
ground: true,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
groundMode: "infinite",
|
|
6
|
+
gridMode: "infinite",
|
|
7
|
+
axes: false,
|
|
8
|
+
shadowHelpers: false,
|
|
9
|
+
origin: false,
|
|
10
|
+
gridUnit: 1,
|
|
11
|
+
gridMajorEvery: 5,
|
|
12
|
+
gridSuperMajorEvery: 10,
|
|
13
|
+
gridOpacity: 0.055,
|
|
14
|
+
gridMajorOpacity: 0.12,
|
|
15
|
+
gridSuperMajorOpacity: 0.2,
|
|
16
|
+
gridSize: 120,
|
|
10
17
|
groundRoughness: 0.8,
|
|
11
18
|
groundMetalness: 0.05,
|
|
12
19
|
lightTarget: [0, 1.5, 0],
|
|
13
|
-
originHighlight:
|
|
20
|
+
originHighlight: false,
|
|
14
21
|
originLineColor: 0x94a3b8,
|
|
15
22
|
originLineLength: 40,
|
|
16
23
|
originLineThickness: 0.06,
|
|
@@ -21,14 +28,27 @@ const DEFAULT_EXTRAS = {
|
|
|
21
28
|
offset: 0.4,
|
|
22
29
|
secondaryOffset: 0.5,
|
|
23
30
|
},
|
|
31
|
+
outline: false,
|
|
32
|
+
outlineColor: 0x1f2937,
|
|
33
|
+
outlineOpacity: 0.38,
|
|
34
|
+
outlineThresholdAngle: 35,
|
|
35
|
+
outlineDepthTest: true,
|
|
24
36
|
};
|
|
25
37
|
const DEFAULT_GRID_SIZE = 100;
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const
|
|
38
|
+
const DEFAULT_GRID_OPACITY = 0.055;
|
|
39
|
+
const DEFAULT_GRID_MAJOR_OPACITY = 0.12;
|
|
40
|
+
const DEFAULT_GRID_SUPER_MAJOR_OPACITY = 0.2;
|
|
41
|
+
const DEFAULT_GRID_UNIT = 1;
|
|
42
|
+
const DEFAULT_GRID_MAJOR_EVERY = 5;
|
|
43
|
+
const DEFAULT_GRID_SUPER_MAJOR_EVERY = 10;
|
|
44
|
+
const MAX_METRIC_GRID_SIZE = 2000;
|
|
45
|
+
const DEFAULT_GRID_HEIGHT_OFFSET = 0.05;
|
|
46
|
+
const DEFAULT_GROUND_OFFSET = -0.08;
|
|
47
|
+
const AO_GROUND_PROXY_CLEARANCE = 0.001;
|
|
48
|
+
const MIN_GRID_GROUND_CLEARANCE = 0.05;
|
|
49
|
+
const MIN_GRID_FLOOR_CLEARANCE = 0.05;
|
|
50
|
+
const INFINITE_GROUND_SIZE = 20000;
|
|
51
|
+
export const AO_DEPTH_PROXY_USER_DATA_KEY = "treasuryAoDepthProxy";
|
|
32
52
|
const AXIS_COLORS = {
|
|
33
53
|
x: 0xef4444,
|
|
34
54
|
y: 0x22c55e,
|
|
@@ -176,80 +196,270 @@ function adjustGridColor(groundHex) {
|
|
|
176
196
|
adjusted.setHSL(hsl.h, hsl.s, hsl.l);
|
|
177
197
|
return adjusted.getHex();
|
|
178
198
|
}
|
|
199
|
+
const clampOpacity = (value) => Math.max(0, Math.min(1, value));
|
|
200
|
+
function buildGridLineSegments(positions, color, opacity) {
|
|
201
|
+
if (positions.length === 0)
|
|
202
|
+
return null;
|
|
203
|
+
const geometry = new THREE.BufferGeometry();
|
|
204
|
+
geometry.setAttribute("position", new THREE.Float32BufferAttribute(positions, 3));
|
|
205
|
+
const material = new THREE.LineBasicMaterial({
|
|
206
|
+
color,
|
|
207
|
+
transparent: true,
|
|
208
|
+
opacity: clampOpacity(opacity),
|
|
209
|
+
depthTest: true,
|
|
210
|
+
depthWrite: false,
|
|
211
|
+
toneMapped: false,
|
|
212
|
+
});
|
|
213
|
+
const lines = new THREE.LineSegments(geometry, material);
|
|
214
|
+
lines.frustumCulled = false;
|
|
215
|
+
lines.renderOrder = -10;
|
|
216
|
+
return lines;
|
|
217
|
+
}
|
|
218
|
+
function buildMetricGrid(extras, groundColor, requestedSize) {
|
|
219
|
+
const step = Math.max(0.001, extras.gridUnit ?? DEFAULT_GRID_UNIT);
|
|
220
|
+
const majorEvery = Math.max(1, Math.round(extras.gridMajorEvery ?? DEFAULT_GRID_MAJOR_EVERY));
|
|
221
|
+
const superMajorEvery = Math.max(majorEvery, Math.round(extras.gridSuperMajorEvery ?? DEFAULT_GRID_SUPER_MAJOR_EVERY));
|
|
222
|
+
const halfLines = Math.max(1, Math.ceil(Math.min(requestedSize, MAX_METRIC_GRID_SIZE) / (2 * step)));
|
|
223
|
+
const extent = halfLines * step;
|
|
224
|
+
const size = extent * 2;
|
|
225
|
+
const divisions = halfLines * 2;
|
|
226
|
+
const minorColor = extras.gridColorSecondary ?? adjustGridColor(groundColor);
|
|
227
|
+
const majorColor = extras.gridMajorColor ?? extras.gridColor ?? adjustGridColor(groundColor);
|
|
228
|
+
const superMajorColor = extras.gridSuperMajorColor ?? extras.gridColor ?? majorColor;
|
|
229
|
+
const minorOpacity = extras.gridOpacity ?? DEFAULT_GRID_OPACITY;
|
|
230
|
+
const majorOpacity = extras.gridMajorOpacity ?? Math.max(DEFAULT_GRID_MAJOR_OPACITY, minorOpacity * 2.1);
|
|
231
|
+
const superMajorOpacity = extras.gridSuperMajorOpacity ?? Math.max(DEFAULT_GRID_SUPER_MAJOR_OPACITY, majorOpacity * 1.55);
|
|
232
|
+
const minorPositions = [];
|
|
233
|
+
const majorPositions = [];
|
|
234
|
+
const superMajorPositions = [];
|
|
235
|
+
const appendLinePair = (target, coordinate) => {
|
|
236
|
+
target.push(-extent, 0, coordinate, extent, 0, coordinate);
|
|
237
|
+
target.push(coordinate, 0, -extent, coordinate, 0, extent);
|
|
238
|
+
};
|
|
239
|
+
for (let i = -halfLines; i <= halfLines; i += 1) {
|
|
240
|
+
const coordinate = i * step;
|
|
241
|
+
const absIndex = Math.abs(i);
|
|
242
|
+
if (superMajorEvery > 0 && absIndex % superMajorEvery === 0) {
|
|
243
|
+
appendLinePair(superMajorPositions, coordinate);
|
|
244
|
+
}
|
|
245
|
+
else if (majorEvery > 0 && absIndex % majorEvery === 0) {
|
|
246
|
+
appendLinePair(majorPositions, coordinate);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
appendLinePair(minorPositions, coordinate);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
const group = new THREE.Group();
|
|
253
|
+
group.name = "metric-grid";
|
|
254
|
+
const minor = buildGridLineSegments(minorPositions, minorColor, minorOpacity);
|
|
255
|
+
const major = buildGridLineSegments(majorPositions, majorColor, majorOpacity);
|
|
256
|
+
const superMajor = buildGridLineSegments(superMajorPositions, superMajorColor, superMajorOpacity);
|
|
257
|
+
if (minor)
|
|
258
|
+
group.add(minor);
|
|
259
|
+
if (major)
|
|
260
|
+
group.add(major);
|
|
261
|
+
if (superMajor)
|
|
262
|
+
group.add(superMajor);
|
|
263
|
+
group.renderOrder = -10;
|
|
264
|
+
return { object: group, size, step, divisions, majorEvery, superMajorEvery };
|
|
265
|
+
}
|
|
266
|
+
function hasOwnSceneExtra(preset, key) {
|
|
267
|
+
return Object.prototype.hasOwnProperty.call(preset.sceneExtras ?? {}, key);
|
|
268
|
+
}
|
|
269
|
+
function buildOutlineGroup(root, extras) {
|
|
270
|
+
if (!root || extras.outline !== true)
|
|
271
|
+
return null;
|
|
272
|
+
const group = new THREE.Group();
|
|
273
|
+
const thresholdAngle = extras.outlineThresholdAngle ?? 35;
|
|
274
|
+
const baseMaterial = new THREE.LineBasicMaterial({
|
|
275
|
+
color: extras.outlineColor ?? 0x1f2937,
|
|
276
|
+
transparent: true,
|
|
277
|
+
opacity: extras.outlineOpacity ?? 0.38,
|
|
278
|
+
depthTest: extras.outlineDepthTest !== false,
|
|
279
|
+
depthWrite: false,
|
|
280
|
+
toneMapped: false,
|
|
281
|
+
});
|
|
282
|
+
root.updateMatrixWorld(true);
|
|
283
|
+
root.traverse((object) => {
|
|
284
|
+
const mesh = object;
|
|
285
|
+
if (!mesh.isMesh || !mesh.geometry)
|
|
286
|
+
return;
|
|
287
|
+
const geometry = mesh.geometry;
|
|
288
|
+
const edges = new THREE.EdgesGeometry(geometry, thresholdAngle);
|
|
289
|
+
const line = new THREE.LineSegments(edges, baseMaterial.clone());
|
|
290
|
+
line.matrix.copy(mesh.matrixWorld);
|
|
291
|
+
line.matrixAutoUpdate = false;
|
|
292
|
+
line.renderOrder = 20;
|
|
293
|
+
line.frustumCulled = false;
|
|
294
|
+
group.add(line);
|
|
295
|
+
});
|
|
296
|
+
baseMaterial.dispose();
|
|
297
|
+
return group.children.length > 0 ? group : null;
|
|
298
|
+
}
|
|
179
299
|
export class DebugSystem {
|
|
180
300
|
scene;
|
|
181
301
|
objects = [];
|
|
302
|
+
ground = null;
|
|
303
|
+
groundAoProxy = null;
|
|
304
|
+
grid = null;
|
|
305
|
+
groundInfinite = false;
|
|
306
|
+
gridInfinite = false;
|
|
307
|
+
gridDivisionSize = 1;
|
|
308
|
+
state = {
|
|
309
|
+
groundEnabled: false,
|
|
310
|
+
gridEnabled: false,
|
|
311
|
+
groundY: null,
|
|
312
|
+
gridY: null,
|
|
313
|
+
gridSize: null,
|
|
314
|
+
gridDivisions: null,
|
|
315
|
+
gridStep: null,
|
|
316
|
+
gridMajorEvery: null,
|
|
317
|
+
gridSuperMajorEvery: null,
|
|
318
|
+
groundMode: null,
|
|
319
|
+
gridMode: null,
|
|
320
|
+
};
|
|
182
321
|
constructor(scene) {
|
|
183
322
|
this.scene = scene;
|
|
184
323
|
}
|
|
185
|
-
|
|
324
|
+
update(anchor) {
|
|
325
|
+
if (!anchor)
|
|
326
|
+
return;
|
|
327
|
+
if (this.groundInfinite && this.ground) {
|
|
328
|
+
this.ground.position.x = anchor.x;
|
|
329
|
+
this.ground.position.z = anchor.z;
|
|
330
|
+
}
|
|
331
|
+
if (this.groundInfinite && this.groundAoProxy) {
|
|
332
|
+
this.groundAoProxy.position.x = anchor.x;
|
|
333
|
+
this.groundAoProxy.position.z = anchor.z;
|
|
334
|
+
}
|
|
335
|
+
if (this.gridInfinite && this.grid) {
|
|
336
|
+
const snap = Number.isFinite(this.gridDivisionSize) && this.gridDivisionSize > 0 ? this.gridDivisionSize : 1;
|
|
337
|
+
this.grid.position.x = Math.round(anchor.x / snap) * snap;
|
|
338
|
+
this.grid.position.z = Math.round(anchor.z / snap) * snap;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
getState() {
|
|
342
|
+
return { ...this.state };
|
|
343
|
+
}
|
|
344
|
+
apply(preset, bounds, root) {
|
|
186
345
|
const extras = { ...DEFAULT_EXTRAS, ...(preset.sceneExtras ?? {}) };
|
|
187
346
|
this.clear();
|
|
188
|
-
const skyMode = preset.sky?.mode ?? "gradient";
|
|
189
|
-
const isHdr = skyMode === "hdr";
|
|
190
347
|
const groundEnabled = extras.ground !== false;
|
|
191
348
|
const gridEnabled = extras.grid !== false;
|
|
192
349
|
const axesEnabled = extras.axes !== false;
|
|
350
|
+
const shadowHelpersEnabled = extras.shadowHelpers === true;
|
|
193
351
|
const originEnabled = extras.origin !== false;
|
|
194
352
|
const groundColor = extras.groundColor ?? 0x2c2f33;
|
|
195
|
-
const
|
|
353
|
+
const hasBounds = Boolean(bounds && !bounds.isEmpty());
|
|
354
|
+
const boundsSize = hasBounds ? bounds.getSize(new THREE.Vector3()) : null;
|
|
355
|
+
const boundsMinY = hasBounds && Number.isFinite(bounds.min.y) ? bounds.min.y : 0;
|
|
196
356
|
const modelSpan = boundsSize ? Math.max(boundsSize.x, boundsSize.z, 1) : null;
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const
|
|
202
|
-
const
|
|
203
|
-
const derivedGroundSize = modelSpan ? modelSpan * groundScale :
|
|
357
|
+
// Ground/grid sizing is independent of sky mode. The metric grid uses real-world step
|
|
358
|
+
// size (gridUnit) so HDR-vs-non-HDR proportional scaling no longer adds value, and ground
|
|
359
|
+
// is forced to INFINITE_GROUND_SIZE in infinite mode regardless. Authors who genuinely
|
|
360
|
+
// want a different look under HDR can express it through gridUnit/gridMajorEvery directly.
|
|
361
|
+
const groundScale = extras.groundAutoScale ?? 2.5;
|
|
362
|
+
const gridScale = extras.gridAutoScale ?? extras.groundAutoScale ?? 2.5;
|
|
363
|
+
const derivedGroundSize = modelSpan ? modelSpan * groundScale : DEFAULT_GRID_SIZE;
|
|
204
364
|
const derivedGridSize = groundEnabled
|
|
205
365
|
? (extras.groundSize ?? derivedGroundSize)
|
|
206
366
|
: modelSpan
|
|
207
367
|
? modelSpan * gridScale
|
|
208
|
-
:
|
|
209
|
-
const
|
|
210
|
-
const
|
|
368
|
+
: DEFAULT_GRID_SIZE;
|
|
369
|
+
const groundOffsetAuthored = hasOwnSceneExtra(preset, "groundOffset");
|
|
370
|
+
const groundOffset = groundOffsetAuthored ? (extras.groundOffset ?? DEFAULT_GROUND_OFFSET) : boundsMinY + DEFAULT_GROUND_OFFSET;
|
|
371
|
+
const defaultGroundOffset = boundsMinY + DEFAULT_GROUND_OFFSET;
|
|
372
|
+
const useContactAoProxy = hasBounds &&
|
|
373
|
+
Number.isFinite(boundsMinY) &&
|
|
374
|
+
Math.abs(groundOffset - defaultGroundOffset) <= 1e-6;
|
|
375
|
+
const groundAoProxyY = useContactAoProxy ? boundsMinY - AO_GROUND_PROXY_CLEARANCE : groundOffset;
|
|
376
|
+
const rawGridHeightOffset = extras.gridHeightOffset ?? DEFAULT_GRID_HEIGHT_OFFSET;
|
|
377
|
+
const gridHeightOffsetFromGround = groundEnabled
|
|
378
|
+
? Math.max(rawGridHeightOffset, MIN_GRID_GROUND_CLEARANCE)
|
|
379
|
+
: rawGridHeightOffset;
|
|
380
|
+
const gridFloorOffset = Math.max(rawGridHeightOffset, MIN_GRID_FLOOR_CLEARANCE);
|
|
381
|
+
const groundMode = extras.groundMode ?? "infinite";
|
|
382
|
+
const gridMode = extras.gridMode ?? groundMode;
|
|
383
|
+
this.groundInfinite = groundMode === "infinite";
|
|
384
|
+
this.gridInfinite = gridMode === "infinite";
|
|
211
385
|
if (groundEnabled) {
|
|
212
|
-
const size =
|
|
386
|
+
const size = groundMode === "infinite"
|
|
387
|
+
? Math.max(extras.groundSize ?? derivedGroundSize, INFINITE_GROUND_SIZE)
|
|
388
|
+
: extras.groundSize ?? derivedGroundSize;
|
|
213
389
|
const groundGeometry = new THREE.PlaneGeometry(size, size);
|
|
214
390
|
const groundMaterial = new THREE.MeshStandardMaterial({
|
|
215
391
|
color: groundColor,
|
|
216
|
-
roughness: extras.groundRoughness ??
|
|
217
|
-
metalness: extras.groundMetalness ??
|
|
392
|
+
roughness: extras.groundRoughness ?? 0.8,
|
|
393
|
+
metalness: extras.groundMetalness ?? 0.05,
|
|
218
394
|
toneMapped: false,
|
|
219
395
|
});
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
396
|
+
// Ground draws first (renderOrder=-20) and must never z-fight with the model floor or grid.
|
|
397
|
+
// polygonOffset is view-angle-dependent (slope→0 at top-down), so the visible plane stays
|
|
398
|
+
// depthless and relies on render order. AO gets a separate invisible depth proxy instead.
|
|
399
|
+
groundMaterial.depthWrite = false;
|
|
223
400
|
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
|
|
224
401
|
ground.rotation.x = -Math.PI / 2;
|
|
225
402
|
ground.position.y = groundOffset;
|
|
226
403
|
ground.receiveShadow = true;
|
|
404
|
+
ground.renderOrder = -20;
|
|
405
|
+
this.ground = ground;
|
|
227
406
|
this.add(ground);
|
|
407
|
+
const groundAoProxyMaterial = new THREE.MeshBasicMaterial({
|
|
408
|
+
color: 0xffffff,
|
|
409
|
+
toneMapped: false,
|
|
410
|
+
});
|
|
411
|
+
groundAoProxyMaterial.colorWrite = false;
|
|
412
|
+
const groundAoProxy = new THREE.Mesh(groundGeometry.clone(), groundAoProxyMaterial);
|
|
413
|
+
groundAoProxy.rotation.x = -Math.PI / 2;
|
|
414
|
+
groundAoProxy.position.y = groundAoProxyY;
|
|
415
|
+
groundAoProxy.renderOrder = -19;
|
|
416
|
+
groundAoProxy.visible = false;
|
|
417
|
+
groundAoProxy.userData[AO_DEPTH_PROXY_USER_DATA_KEY] = true;
|
|
418
|
+
this.groundAoProxy = groundAoProxy;
|
|
419
|
+
this.add(groundAoProxy);
|
|
228
420
|
}
|
|
229
421
|
let lastGridPositionY = 0;
|
|
230
|
-
const gridSize = extras.gridSize ?? derivedGridSize;
|
|
422
|
+
const gridSize = Math.max(1, extras.gridSize ?? derivedGridSize);
|
|
423
|
+
let gridDivisionsResolved = null;
|
|
424
|
+
let gridStepResolved = null;
|
|
425
|
+
let gridMajorEveryResolved = null;
|
|
426
|
+
let gridSuperMajorEveryResolved = null;
|
|
427
|
+
let gridSizeResolved = null;
|
|
231
428
|
if (gridEnabled) {
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
|
|
429
|
+
const requestedGridSize = gridMode === "infinite"
|
|
430
|
+
? Math.max(gridSize, DEFAULT_GRID_SIZE)
|
|
431
|
+
: gridSize;
|
|
432
|
+
const metricGrid = buildMetricGrid(extras, groundColor, requestedGridSize);
|
|
433
|
+
gridDivisionsResolved = metricGrid.divisions;
|
|
434
|
+
gridStepResolved = metricGrid.step;
|
|
435
|
+
gridMajorEveryResolved = metricGrid.majorEvery;
|
|
436
|
+
gridSuperMajorEveryResolved = metricGrid.superMajorEvery;
|
|
437
|
+
gridSizeResolved = metricGrid.size;
|
|
438
|
+
this.gridDivisionSize = metricGrid.step;
|
|
439
|
+
const grid = metricGrid.object;
|
|
440
|
+
const gridPlane = extras.gridPlane ?? (groundEnabled ? "ground" : "floor");
|
|
441
|
+
const gridY = gridPlane === "ground" && groundEnabled
|
|
442
|
+
? groundOffset + gridHeightOffsetFromGround
|
|
443
|
+
: boundsMinY + gridFloorOffset;
|
|
237
444
|
grid.position.y = gridY;
|
|
238
445
|
lastGridPositionY = grid.position.y;
|
|
239
|
-
|
|
240
|
-
const setTransparency = (mat) => {
|
|
241
|
-
mat.transparent = true;
|
|
242
|
-
mat.opacity = extras.gridOpacity ?? DEFAULT_GRID_OPACITY;
|
|
243
|
-
};
|
|
244
|
-
if (Array.isArray(gridMaterial)) {
|
|
245
|
-
gridMaterial.forEach((mat) => setTransparency(mat));
|
|
246
|
-
}
|
|
247
|
-
else if (gridMaterial) {
|
|
248
|
-
setTransparency(gridMaterial);
|
|
249
|
-
}
|
|
446
|
+
this.grid = grid;
|
|
250
447
|
this.add(grid);
|
|
251
448
|
}
|
|
252
|
-
|
|
449
|
+
this.state = {
|
|
450
|
+
groundEnabled,
|
|
451
|
+
gridEnabled,
|
|
452
|
+
groundY: groundEnabled ? groundOffset : null,
|
|
453
|
+
gridY: gridEnabled ? lastGridPositionY : null,
|
|
454
|
+
gridSize: gridEnabled ? gridSizeResolved : null,
|
|
455
|
+
gridDivisions: gridDivisionsResolved,
|
|
456
|
+
gridStep: gridStepResolved,
|
|
457
|
+
gridMajorEvery: gridMajorEveryResolved,
|
|
458
|
+
gridSuperMajorEvery: gridSuperMajorEveryResolved,
|
|
459
|
+
groundMode,
|
|
460
|
+
gridMode,
|
|
461
|
+
};
|
|
462
|
+
const originPlaneY = gridEnabled ? lastGridPositionY : groundEnabled ? groundOffset : boundsMinY + gridFloorOffset;
|
|
253
463
|
if (extras.originHighlight !== false) {
|
|
254
464
|
const originCross = buildOriginCross(extras, gridSize, originPlaneY);
|
|
255
465
|
this.add(originCross);
|
|
@@ -275,6 +485,22 @@ export class DebugSystem {
|
|
|
275
485
|
this.add(axes);
|
|
276
486
|
}
|
|
277
487
|
}
|
|
488
|
+
if (shadowHelpersEnabled) {
|
|
489
|
+
this.scene.traverse((child) => {
|
|
490
|
+
if (!(child instanceof THREE.DirectionalLight) || !child.castShadow)
|
|
491
|
+
return;
|
|
492
|
+
const lightHelper = new THREE.DirectionalLightHelper(child, 3);
|
|
493
|
+
lightHelper.update();
|
|
494
|
+
this.add(lightHelper);
|
|
495
|
+
if (child.shadow?.camera) {
|
|
496
|
+
this.add(new THREE.CameraHelper(child.shadow.camera));
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
const outline = buildOutlineGroup(root, extras);
|
|
501
|
+
if (outline) {
|
|
502
|
+
this.add(outline);
|
|
503
|
+
}
|
|
278
504
|
}
|
|
279
505
|
dispose() {
|
|
280
506
|
this.clear();
|
|
@@ -284,40 +510,61 @@ export class DebugSystem {
|
|
|
284
510
|
this.objects.push(object);
|
|
285
511
|
}
|
|
286
512
|
clear() {
|
|
513
|
+
this.ground = null;
|
|
514
|
+
this.groundAoProxy = null;
|
|
515
|
+
this.grid = null;
|
|
516
|
+
this.groundInfinite = false;
|
|
517
|
+
this.gridInfinite = false;
|
|
518
|
+
this.gridDivisionSize = 1;
|
|
519
|
+
this.state = {
|
|
520
|
+
groundEnabled: false,
|
|
521
|
+
gridEnabled: false,
|
|
522
|
+
groundY: null,
|
|
523
|
+
gridY: null,
|
|
524
|
+
gridSize: null,
|
|
525
|
+
gridDivisions: null,
|
|
526
|
+
gridStep: null,
|
|
527
|
+
gridMajorEvery: null,
|
|
528
|
+
gridSuperMajorEvery: null,
|
|
529
|
+
groundMode: null,
|
|
530
|
+
gridMode: null,
|
|
531
|
+
};
|
|
287
532
|
this.objects.forEach((object) => {
|
|
288
533
|
if (object.parent)
|
|
289
534
|
object.parent.remove(object);
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (object instanceof THREE.Line) {
|
|
302
|
-
object.geometry.dispose();
|
|
303
|
-
const material = object.material;
|
|
304
|
-
if (Array.isArray(material)) {
|
|
305
|
-
material.forEach((mat) => mat.dispose?.());
|
|
535
|
+
object.traverse((child) => {
|
|
536
|
+
if (child instanceof THREE.Mesh) {
|
|
537
|
+
child.geometry.dispose();
|
|
538
|
+
const material = child.material;
|
|
539
|
+
if (Array.isArray(material)) {
|
|
540
|
+
material.forEach((mat) => mat.dispose?.());
|
|
541
|
+
}
|
|
542
|
+
else {
|
|
543
|
+
material.dispose?.();
|
|
544
|
+
}
|
|
545
|
+
return;
|
|
306
546
|
}
|
|
307
|
-
|
|
308
|
-
|
|
547
|
+
if (child instanceof THREE.Line) {
|
|
548
|
+
child.geometry.dispose();
|
|
549
|
+
const material = child.material;
|
|
550
|
+
if (Array.isArray(material)) {
|
|
551
|
+
material.forEach((mat) => mat.dispose?.());
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
material?.dispose?.();
|
|
555
|
+
}
|
|
556
|
+
return;
|
|
309
557
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
material.
|
|
558
|
+
if (child instanceof THREE.Sprite) {
|
|
559
|
+
const material = child.material;
|
|
560
|
+
if (material) {
|
|
561
|
+
if (material.map) {
|
|
562
|
+
material.map.dispose?.();
|
|
563
|
+
}
|
|
564
|
+
material.dispose?.();
|
|
317
565
|
}
|
|
318
|
-
material.dispose?.();
|
|
319
566
|
}
|
|
320
|
-
}
|
|
567
|
+
});
|
|
321
568
|
});
|
|
322
569
|
this.objects = [];
|
|
323
570
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as THREE from "three";
|
|
2
2
|
import type { AssetResolver, RenderPresetDefinition } from "../engine/types";
|
|
3
3
|
export type EnvironmentState = {
|
|
4
|
-
mode: "none" | "gradient" | "hdr" | "cube";
|
|
4
|
+
mode: "none" | "gradient" | "image" | "hdr" | "cube";
|
|
5
5
|
backgroundEnabled: boolean;
|
|
6
6
|
lightingEnabled: boolean;
|
|
7
7
|
};
|
|
@@ -13,21 +13,22 @@ export declare class EnvironmentSystem {
|
|
|
13
13
|
private currentObjects;
|
|
14
14
|
private currentBackground;
|
|
15
15
|
private currentEnvironment;
|
|
16
|
-
private gradientSky;
|
|
17
|
-
private readonly gradientBaseRadius;
|
|
18
16
|
private objectUrls;
|
|
19
17
|
private loadToken;
|
|
18
|
+
private appliedSkySignature;
|
|
20
19
|
private state;
|
|
21
20
|
private fallbackGradient;
|
|
22
21
|
constructor(scene: THREE.Scene, renderer: THREE.WebGLRenderer, assetResolver?: AssetResolver);
|
|
23
22
|
getState(): EnvironmentState;
|
|
24
|
-
update(
|
|
23
|
+
update(_camera?: THREE.Camera): void;
|
|
25
24
|
apply(preset: RenderPresetDefinition): Promise<void>;
|
|
26
25
|
dispose(): void;
|
|
26
|
+
private static skySignature;
|
|
27
27
|
private disposeCurrent;
|
|
28
28
|
private applyGradientSky;
|
|
29
29
|
private resolveAsset;
|
|
30
30
|
private applyHdrSky;
|
|
31
|
+
private applyImageSky;
|
|
31
32
|
private applyCubeSky;
|
|
32
33
|
private applyRotationToScene;
|
|
33
34
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environmentSystem.d.ts","sourceRoot":"","sources":["../../src/systems/environmentSystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"environmentSystem.d.ts","sourceRoot":"","sources":["../../src/systems/environmentSystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAa,aAAa,EAAE,sBAAsB,EAA8D,MAAM,iBAAiB,CAAC;AAEpJ,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IACrD,iBAAiB,EAAE,OAAO,CAAC;IAC3B,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,cAAc,CAAqC;IAE3D,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,iBAAiB,CAAkD;IAC3E,OAAO,CAAC,kBAAkB,CAAkD;IAC5E,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,mBAAmB,CAAuB;IAElD,OAAO,CAAC,KAAK,CAAwF;IACrG,OAAO,CAAC,gBAAgB,CAMtB;gBAEU,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE,aAAa,CAAC,EAAE,aAAa;IAM5F,QAAQ,IAAI,gBAAgB;IAI5B,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI;IAE9B,KAAK,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IA2D1D,OAAO,IAAI,IAAI;IASf,OAAO,CAAC,MAAM,CAAC,YAAY;IAS3B,OAAO,CAAC,cAAc;IAoCtB,OAAO,CAAC,gBAAgB;YA8CV,YAAY;YAaZ,WAAW;YA0DX,aAAa;YAoEb,YAAY;IAyD1B,OAAO,CAAC,oBAAoB;CAY7B"}
|