@treasuryspatial/viewer-kit 0.2.39 → 0.2.41
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/engine/ViewerEngine.d.ts +1 -0
- package/dist/engine/ViewerEngine.d.ts.map +1 -1
- package/dist/engine/ViewerEngine.js +46 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/materials/resolve.d.ts +13 -0
- package/dist/materials/resolve.d.ts.map +1 -0
- package/dist/materials/resolve.js +28 -0
- package/dist/scene.d.ts +43 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +148 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ViewerEngine.d.ts","sourceRoot":"","sources":["../../src/engine/ViewerEngine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAiB,WAAW,EAAiB,sBAAsB,EAAE,mBAAmB,EAAmB,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAQrK,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAiB;IAE1D,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,WAAW,CAA2B;IAE9C,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,iBAAiB,CAAU;IAEnC,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;
|
|
1
|
+
{"version":3,"file":"ViewerEngine.d.ts","sourceRoot":"","sources":["../../src/engine/ViewerEngine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAiB,WAAW,EAAiB,sBAAsB,EAAE,mBAAmB,EAAmB,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAQrK,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAiB;IAE1D,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,WAAW,CAA2B;IAE9C,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,iBAAiB,CAAU;IAEnC,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAE9B,OAAO,CAAC,sBAAsB;gBAiClB,OAAO,EAAE,mBAAmB;IAwDxC,SAAS,IAAI,YAAY;IA0BzB,OAAO,CAAC,UAAU;IAKlB,KAAK,IAAI,IAAI;IAiBb,IAAI,IAAI,IAAI;IAQZ,MAAM,IAAI,IAAI;IAcd,OAAO,IAAI,IAAI;IAef,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIjC,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI;IAStD,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IA8DjC,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI;IAuB5C,cAAc,IAAI,WAAW;IAUvB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAmCjC,WAAW,IAAI,cAAc;IAe7B,OAAO,CAAC,YAAY;IAuCpB,OAAO,CAAC,WAAW;IAyBnB,OAAO,CAAC,aAAa;CAKtB"}
|
|
@@ -27,6 +27,41 @@ export class ViewerEngine {
|
|
|
27
27
|
lastWidth;
|
|
28
28
|
lastHeight;
|
|
29
29
|
maxPixelRatio;
|
|
30
|
+
hasDominantGroundPlane(root, bounds) {
|
|
31
|
+
if (!bounds || bounds.isEmpty())
|
|
32
|
+
return false;
|
|
33
|
+
const size = new THREE.Vector3();
|
|
34
|
+
bounds.getSize(size);
|
|
35
|
+
const planSpan = Math.max(size.x, size.z);
|
|
36
|
+
const minY = bounds.min.y;
|
|
37
|
+
const heightThreshold = Math.max(0.05, size.y * 0.02);
|
|
38
|
+
const planThreshold = planSpan * 0.7;
|
|
39
|
+
let detected = false;
|
|
40
|
+
root.updateMatrixWorld(true);
|
|
41
|
+
root.traverse((object) => {
|
|
42
|
+
if (detected)
|
|
43
|
+
return;
|
|
44
|
+
const mesh = object;
|
|
45
|
+
if (!mesh.isMesh || !mesh.geometry)
|
|
46
|
+
return;
|
|
47
|
+
const geometry = mesh.geometry;
|
|
48
|
+
geometry.computeBoundingBox();
|
|
49
|
+
const bbox = geometry.boundingBox?.clone();
|
|
50
|
+
if (!bbox)
|
|
51
|
+
return;
|
|
52
|
+
bbox.applyMatrix4(mesh.matrixWorld);
|
|
53
|
+
const spanX = bbox.max.x - bbox.min.x;
|
|
54
|
+
const spanZ = bbox.max.z - bbox.min.z;
|
|
55
|
+
const spanY = bbox.max.y - bbox.min.y;
|
|
56
|
+
const nearFloor = Math.abs(bbox.min.y - minY) <= heightThreshold * 1.5;
|
|
57
|
+
const flat = spanY <= heightThreshold;
|
|
58
|
+
const large = spanX >= planThreshold && spanZ >= planThreshold;
|
|
59
|
+
if (nearFloor && flat && large) {
|
|
60
|
+
detected = true;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
return detected;
|
|
64
|
+
}
|
|
30
65
|
constructor(options) {
|
|
31
66
|
this.container = options.container;
|
|
32
67
|
const basePresets = options.presets ?? DEFAULT_PRESETS;
|
|
@@ -205,7 +240,17 @@ export class ViewerEngine {
|
|
|
205
240
|
// Re-apply scene extras (ground/grid) to match updated bounds.
|
|
206
241
|
try {
|
|
207
242
|
const preset = this.resolvePreset(this.presetId);
|
|
208
|
-
this.
|
|
243
|
+
const disableGround = this.hasDominantGroundPlane(this.rootGroup, this.sceneBounds);
|
|
244
|
+
const debugPreset = disableGround
|
|
245
|
+
? {
|
|
246
|
+
...preset,
|
|
247
|
+
sceneExtras: {
|
|
248
|
+
...(preset.sceneExtras ?? {}),
|
|
249
|
+
ground: false,
|
|
250
|
+
},
|
|
251
|
+
}
|
|
252
|
+
: preset;
|
|
253
|
+
this.debugSystem.apply(debugPreset, this.sceneBounds);
|
|
209
254
|
}
|
|
210
255
|
catch {
|
|
211
256
|
// ignore debug system failures
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ export type { ViewerCreateOptions, ViewerHandle, ViewerRuntime, ViewerSnapshot,
|
|
|
2
2
|
export type { CameraFrameConfig, CameraFrameMode, CameraNormalizationConfig, CameraNormalizationResult, } from "./camera";
|
|
3
3
|
export { createViewer } from "./engine/createViewer";
|
|
4
4
|
export { computeCameraFrame, normalizeObject3d } from "./camera";
|
|
5
|
+
export type { CameraRigConfig, SceneStats, ApplyGroupToViewerOptions, ApplyGroupToViewerResult, RoomHeights, } from "./scene";
|
|
6
|
+
export { DEFAULT_CAMERA_RIG, applyGroupToViewer, computeSceneStats, resolveRoomHeights, setCameraToBounds, setCameraTopDown, } from "./scene";
|
|
5
7
|
export { DEFAULT_PRESET_ID, DEFAULT_PRESETS } from "./presets/defaults";
|
|
6
8
|
export { SCIENCE_PRESETS, SCIENCE_PRESET_SUMMARIES, SCIENCE_DEFAULT_PRESET_ID, buildViewerPresets, buildSciencePresets, } from "./presets/sciencePresets";
|
|
7
9
|
export { listScienceSkyOptions, getScienceSkyOption } from "./sky/scienceSky";
|
|
@@ -10,6 +12,8 @@ export type { MaterialCatalogue, MaterialDefinition, MaterialId, MaterialColor,
|
|
|
10
12
|
export { getMaterialCatalogue, findMaterial, listMaterialsByCategory } from "./materials/catalogue";
|
|
11
13
|
export { getRenderMaterialMetadata } from "./materials/renderMetadata";
|
|
12
14
|
export { BASELINE_MATERIAL_PRESET_ID, MATERIAL_PRESET_DATA, listMaterialPresets, getMaterialPreset, resolveMaterialSlot, resolveMaterialPresetMaterials, } from "./materials/presets";
|
|
15
|
+
export type { MaterialOverrides, MaterialResolveOptions } from "./materials/resolve";
|
|
16
|
+
export { resolveMaterialConfig } from "./materials/resolve";
|
|
13
17
|
export { applyMaterialsToGroup, buildSurfaceMaterial, buildCatalogMaterial, setTextureBaseUrl, } from "./materials/architectural";
|
|
14
18
|
export { EnvironmentSystem } from "./systems/environmentSystem";
|
|
15
19
|
export { LightingSystem } from "./systems/lightingSystem";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,WAAW,EACX,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,aAAa,EACb,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,qBAAqB,EACrB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACpG,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,8BAA8B,GAC/B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACnE,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,WAAW,EACX,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,aAAa,EACb,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACjE,YAAY,EACV,eAAe,EACf,UAAU,EACV,yBAAyB,EACzB,wBAAwB,EACxB,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EACL,eAAe,EACf,wBAAwB,EACxB,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,qBAAqB,EACrB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACpG,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,8BAA8B,GAC/B,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACnE,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
export { createViewer } from "./engine/createViewer";
|
|
2
2
|
export { computeCameraFrame, normalizeObject3d } from "./camera";
|
|
3
|
+
export { DEFAULT_CAMERA_RIG, applyGroupToViewer, computeSceneStats, resolveRoomHeights, setCameraToBounds, setCameraTopDown, } from "./scene";
|
|
3
4
|
export { DEFAULT_PRESET_ID, DEFAULT_PRESETS } from "./presets/defaults";
|
|
4
5
|
export { SCIENCE_PRESETS, SCIENCE_PRESET_SUMMARIES, SCIENCE_DEFAULT_PRESET_ID, buildViewerPresets, buildSciencePresets, } from "./presets/sciencePresets";
|
|
5
6
|
export { listScienceSkyOptions, getScienceSkyOption } from "./sky/scienceSky";
|
|
6
7
|
export { getMaterialCatalogue, findMaterial, listMaterialsByCategory } from "./materials/catalogue";
|
|
7
8
|
export { getRenderMaterialMetadata } from "./materials/renderMetadata";
|
|
8
9
|
export { BASELINE_MATERIAL_PRESET_ID, MATERIAL_PRESET_DATA, listMaterialPresets, getMaterialPreset, resolveMaterialSlot, resolveMaterialPresetMaterials, } from "./materials/presets";
|
|
10
|
+
export { resolveMaterialConfig } from "./materials/resolve";
|
|
9
11
|
export { applyMaterialsToGroup, buildSurfaceMaterial, buildCatalogMaterial, setTextureBaseUrl, } from "./materials/architectural";
|
|
10
12
|
export { EnvironmentSystem } from "./systems/environmentSystem";
|
|
11
13
|
export { LightingSystem } from "./systems/lightingSystem";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { MaterialsConfig, SurfaceMaterialConfig } from "./types";
|
|
2
|
+
export type MaterialOverrides = {
|
|
3
|
+
walls?: Partial<SurfaceMaterialConfig>;
|
|
4
|
+
floor?: Partial<SurfaceMaterialConfig>;
|
|
5
|
+
ceiling?: Partial<SurfaceMaterialConfig>;
|
|
6
|
+
};
|
|
7
|
+
export type MaterialResolveOptions = {
|
|
8
|
+
payload?: Record<string, unknown> | null;
|
|
9
|
+
presetId?: string | null;
|
|
10
|
+
overrides?: MaterialOverrides | null;
|
|
11
|
+
};
|
|
12
|
+
export declare function resolveMaterialConfig(options: MaterialResolveOptions): MaterialsConfig | null;
|
|
13
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/materials/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAGtE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACvC,KAAK,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACvC,OAAO,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;CACtC,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,eAAe,GAAG,IAAI,CAyB7F"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getMaterialPreset, resolveMaterialPresetMaterials } from "./presets";
|
|
2
|
+
export function resolveMaterialConfig(options) {
|
|
3
|
+
const { payload, presetId, overrides } = options;
|
|
4
|
+
if (presetId) {
|
|
5
|
+
try {
|
|
6
|
+
const preset = getMaterialPreset(presetId);
|
|
7
|
+
const base = resolveMaterialPresetMaterials(preset);
|
|
8
|
+
return {
|
|
9
|
+
walls: { ...base.walls, ...(overrides?.walls ?? {}) },
|
|
10
|
+
floor: { ...base.floor, ...(overrides?.floor ?? {}) },
|
|
11
|
+
ceiling: { ...base.ceiling, ...(overrides?.ceiling ?? {}) },
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const record = payload;
|
|
19
|
+
const directMaterials = record?.materials ?? record?.room?.materials;
|
|
20
|
+
if (directMaterials?.walls && directMaterials?.floor && directMaterials?.ceiling) {
|
|
21
|
+
return {
|
|
22
|
+
walls: { ...directMaterials.walls, ...(overrides?.walls ?? {}) },
|
|
23
|
+
floor: { ...directMaterials.floor, ...(overrides?.floor ?? {}) },
|
|
24
|
+
ceiling: { ...directMaterials.ceiling, ...(overrides?.ceiling ?? {}) },
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
package/dist/scene.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as THREE from "three";
|
|
2
|
+
import type { ViewerHandle } from "./engine/types";
|
|
3
|
+
import type { CameraFrameConfig, CameraNormalizationConfig, CameraNormalizationResult } from "./camera";
|
|
4
|
+
import type { MaterialsConfig } from "./materials/types";
|
|
5
|
+
export type CameraRigConfig = CameraFrameConfig & CameraNormalizationConfig;
|
|
6
|
+
export declare const DEFAULT_CAMERA_RIG: CameraRigConfig;
|
|
7
|
+
export type SceneStats = {
|
|
8
|
+
meshCount: number;
|
|
9
|
+
vertexCount: number;
|
|
10
|
+
triangleCount: number;
|
|
11
|
+
size: {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
z: number;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export declare function computeSceneStats(root?: THREE.Object3D | null): SceneStats;
|
|
18
|
+
export declare const setCameraToBounds: (handle: ViewerHandle, bounds: THREE.Box3, config?: CameraFrameConfig) => void;
|
|
19
|
+
export declare const setCameraTopDown: (handle: ViewerHandle, bounds: THREE.Box3) => void;
|
|
20
|
+
export type ApplyGroupToViewerOptions = {
|
|
21
|
+
viewer?: ViewerHandle | null;
|
|
22
|
+
group: THREE.Group;
|
|
23
|
+
cameraRig?: CameraRigConfig;
|
|
24
|
+
viewMode?: "2d" | "3d" | "auto";
|
|
25
|
+
frameConfig?: CameraFrameConfig;
|
|
26
|
+
materialsConfig?: MaterialsConfig | null;
|
|
27
|
+
floorLevel?: number;
|
|
28
|
+
ceilingHeight?: number;
|
|
29
|
+
};
|
|
30
|
+
export type ApplyGroupToViewerResult = {
|
|
31
|
+
bounds: THREE.Box3;
|
|
32
|
+
stats: SceneStats;
|
|
33
|
+
normalization: CameraNormalizationResult;
|
|
34
|
+
resolvedFloor: number;
|
|
35
|
+
resolvedHeight: number;
|
|
36
|
+
};
|
|
37
|
+
export type RoomHeights = {
|
|
38
|
+
floorLevel?: number;
|
|
39
|
+
ceilingHeight?: number;
|
|
40
|
+
};
|
|
41
|
+
export declare const resolveRoomHeights: (payload: Record<string, unknown>) => RoomHeights;
|
|
42
|
+
export declare function applyGroupToViewer(options: ApplyGroupToViewerOptions): ApplyGroupToViewerResult | null;
|
|
43
|
+
//# sourceMappingURL=scene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../src/scene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAExG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzD,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,yBAAyB,CAAC;AAE5E,eAAO,MAAM,kBAAkB,EAAE,eAMhC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3C,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,QAAQ,GAAG,IAAI,GAAG,UAAU,CA0C1E;AAED,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,YAAY,EACpB,QAAQ,KAAK,CAAC,IAAI,EAClB,SAAS,iBAAiB,SA0B3B,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,QAAQ,YAAY,EAAE,QAAQ,KAAK,CAAC,IAAI,SA0BxE,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC;IACnB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;IAChC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC;IACnB,KAAK,EAAE,UAAU,CAAC;IAClB,aAAa,EAAE,yBAAyB,CAAC;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1E,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,WAYrE,CAAC;AAEF,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,yBAAyB,GACjC,wBAAwB,GAAG,IAAI,CA2CjC"}
|
package/dist/scene.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import * as THREE from "three";
|
|
2
|
+
import { computeCameraFrame, normalizeObject3d } from "./camera";
|
|
3
|
+
import { applyMaterialsToGroup } from "./materials/architectural";
|
|
4
|
+
export const DEFAULT_CAMERA_RIG = {
|
|
5
|
+
recenter: true,
|
|
6
|
+
floorToZero: true,
|
|
7
|
+
padding: 1.22,
|
|
8
|
+
direction: [1, 0.7, 1],
|
|
9
|
+
mode: "iso",
|
|
10
|
+
};
|
|
11
|
+
export function computeSceneStats(root) {
|
|
12
|
+
let meshCount = 0;
|
|
13
|
+
let vertexCount = 0;
|
|
14
|
+
let triangleCount = 0;
|
|
15
|
+
if (!root || typeof root.traverse !== "function") {
|
|
16
|
+
return {
|
|
17
|
+
meshCount,
|
|
18
|
+
vertexCount,
|
|
19
|
+
triangleCount,
|
|
20
|
+
size: { x: 0, y: 0, z: 0 },
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
root.traverse((child) => {
|
|
24
|
+
const mesh = child;
|
|
25
|
+
if (mesh.isMesh) {
|
|
26
|
+
meshCount += 1;
|
|
27
|
+
const geometry = mesh.geometry;
|
|
28
|
+
const position = geometry.getAttribute("position");
|
|
29
|
+
if (position) {
|
|
30
|
+
vertexCount += position.count;
|
|
31
|
+
}
|
|
32
|
+
const index = geometry.getIndex();
|
|
33
|
+
if (index) {
|
|
34
|
+
triangleCount += index.count / 3;
|
|
35
|
+
}
|
|
36
|
+
else if (position) {
|
|
37
|
+
triangleCount += position.count / 3;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const bounds = new THREE.Box3().setFromObject(root);
|
|
42
|
+
const size = new THREE.Vector3();
|
|
43
|
+
bounds.getSize(size);
|
|
44
|
+
return {
|
|
45
|
+
meshCount,
|
|
46
|
+
vertexCount,
|
|
47
|
+
triangleCount: Math.round(triangleCount),
|
|
48
|
+
size: { x: size.x, y: size.y, z: size.z },
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export const setCameraToBounds = (handle, bounds, config) => {
|
|
52
|
+
if (bounds.isEmpty())
|
|
53
|
+
return;
|
|
54
|
+
const fov = handle.getCameraState().fov ?? 60;
|
|
55
|
+
const { position, target } = computeCameraFrame(bounds, fov, config);
|
|
56
|
+
if (![position.x, position.y, position.z, target.x, target.y, target.z].every(Number.isFinite)) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const sphere = new THREE.Sphere();
|
|
60
|
+
bounds.getBoundingSphere(sphere);
|
|
61
|
+
const distance = position.distanceTo(target);
|
|
62
|
+
const safetyFar = 1.15;
|
|
63
|
+
const safetyNear = 1.6;
|
|
64
|
+
let near = Math.max(0.01, distance - sphere.radius * safetyNear);
|
|
65
|
+
const maxNear = distance * 0.1;
|
|
66
|
+
if (Number.isFinite(maxNear) && maxNear > 0) {
|
|
67
|
+
near = Math.min(near, maxNear);
|
|
68
|
+
}
|
|
69
|
+
const minSkyFar = 350;
|
|
70
|
+
const far = Math.max(distance + sphere.radius * safetyFar, near + sphere.radius * 2, minSkyFar);
|
|
71
|
+
handle.setCamera({
|
|
72
|
+
position: [position.x, position.y, position.z],
|
|
73
|
+
target: [target.x, target.y, target.z],
|
|
74
|
+
near,
|
|
75
|
+
far,
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
export const setCameraTopDown = (handle, bounds) => {
|
|
79
|
+
if (bounds.isEmpty())
|
|
80
|
+
return;
|
|
81
|
+
const center = bounds.getCenter(new THREE.Vector3());
|
|
82
|
+
const size = bounds.getSize(new THREE.Vector3());
|
|
83
|
+
const span = Math.max(size.x, size.z, 1);
|
|
84
|
+
const height = span * 1.5;
|
|
85
|
+
const position = new THREE.Vector3(center.x, center.y + height, center.z);
|
|
86
|
+
const target = center.clone();
|
|
87
|
+
const sphere = new THREE.Sphere();
|
|
88
|
+
bounds.getBoundingSphere(sphere);
|
|
89
|
+
const distance = position.distanceTo(target);
|
|
90
|
+
const safetyFar = 1.2;
|
|
91
|
+
const safetyNear = 1.8;
|
|
92
|
+
let near = Math.max(0.01, distance - sphere.radius * safetyNear);
|
|
93
|
+
const maxNear = distance * 0.1;
|
|
94
|
+
if (Number.isFinite(maxNear) && maxNear > 0) {
|
|
95
|
+
near = Math.min(near, maxNear);
|
|
96
|
+
}
|
|
97
|
+
const minSkyFar = 350;
|
|
98
|
+
const far = Math.max(distance + sphere.radius * safetyFar, near + sphere.radius * 2, minSkyFar);
|
|
99
|
+
handle.setCamera({
|
|
100
|
+
position: [position.x, position.y, position.z],
|
|
101
|
+
target: [target.x, target.y, target.z],
|
|
102
|
+
near,
|
|
103
|
+
far,
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
export const resolveRoomHeights = (payload) => {
|
|
107
|
+
const record = payload;
|
|
108
|
+
const floorLevel = typeof record?.floorLevel === "number" ? record.floorLevel : undefined;
|
|
109
|
+
const roomHeight = typeof record?.roomHeight === "number"
|
|
110
|
+
? record.roomHeight
|
|
111
|
+
: typeof record?.room?.rectilinear?.height === "number"
|
|
112
|
+
? record.room.rectilinear.height
|
|
113
|
+
: typeof record?.room?.curvilinear?.height === "number"
|
|
114
|
+
? record.room.curvilinear.height
|
|
115
|
+
: undefined;
|
|
116
|
+
return { floorLevel, ceilingHeight: roomHeight };
|
|
117
|
+
};
|
|
118
|
+
export function applyGroupToViewer(options) {
|
|
119
|
+
const { viewer, group, cameraRig, viewMode = "auto", frameConfig, materialsConfig, floorLevel, ceilingHeight, } = options;
|
|
120
|
+
if (!group)
|
|
121
|
+
return null;
|
|
122
|
+
const normalization = normalizeObject3d(group, cameraRig);
|
|
123
|
+
const bounds = normalization.bounds;
|
|
124
|
+
const resolvedFloor = cameraRig?.floorToZero
|
|
125
|
+
? 0
|
|
126
|
+
: typeof floorLevel === "number"
|
|
127
|
+
? floorLevel * normalization.scale + normalization.offset.y
|
|
128
|
+
: bounds.min.y;
|
|
129
|
+
const resolvedHeight = typeof ceilingHeight === "number"
|
|
130
|
+
? ceilingHeight * normalization.scale
|
|
131
|
+
: Math.max(0.1, bounds.max.y - bounds.min.y);
|
|
132
|
+
if (materialsConfig) {
|
|
133
|
+
applyMaterialsToGroup(group, materialsConfig, resolvedFloor, resolvedHeight);
|
|
134
|
+
viewer?.invalidate?.();
|
|
135
|
+
}
|
|
136
|
+
const stats = computeSceneStats(group);
|
|
137
|
+
if (viewer) {
|
|
138
|
+
viewer.setSceneRoot(group);
|
|
139
|
+
const shouldTopDown = viewMode === "2d" || (viewMode === "auto" && stats.meshCount === 0);
|
|
140
|
+
if (shouldTopDown) {
|
|
141
|
+
setCameraTopDown(viewer, bounds);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
setCameraToBounds(viewer, bounds, frameConfig);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return { bounds, stats, normalization, resolvedFloor, resolvedHeight };
|
|
148
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@treasuryspatial/viewer-kit",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.41",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"dist"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@treasuryspatial/rhino-bridge": "^0.1.
|
|
18
|
+
"@treasuryspatial/rhino-bridge": "^0.1.7"
|
|
19
19
|
},
|
|
20
20
|
"publishConfig": {
|
|
21
21
|
"access": "public"
|