three-cad-viewer 4.1.2 → 4.2.0
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/Readme.md +12 -5
- package/dist/camera/camera.d.ts +14 -2
- package/dist/core/studio-manager.d.ts +91 -0
- package/dist/core/types.d.ts +260 -9
- package/dist/core/viewer-state.d.ts +28 -2
- package/dist/core/viewer.d.ts +200 -6
- package/dist/index.d.ts +7 -2
- package/dist/rendering/environment.d.ts +239 -0
- package/dist/rendering/light-detection.d.ts +44 -0
- package/dist/rendering/material-factory.d.ts +77 -2
- package/dist/rendering/material-presets.d.ts +32 -0
- package/dist/rendering/room-environment.d.ts +13 -0
- package/dist/rendering/studio-composer.d.ts +130 -0
- package/dist/rendering/studio-floor.d.ts +53 -0
- package/dist/rendering/texture-cache.d.ts +142 -0
- package/dist/rendering/triplanar.d.ts +37 -0
- package/dist/scene/animation.d.ts +1 -1
- package/dist/scene/clipping.d.ts +31 -0
- package/dist/scene/nestedgroup.d.ts +64 -27
- package/dist/scene/objectgroup.d.ts +47 -0
- package/dist/three-cad-viewer.css +339 -29
- package/dist/three-cad-viewer.esm.js +27567 -11874
- package/dist/three-cad-viewer.esm.js.map +1 -1
- package/dist/three-cad-viewer.esm.min.js +10 -4
- package/dist/three-cad-viewer.js +27486 -11787
- package/dist/three-cad-viewer.min.js +10 -4
- package/dist/ui/display.d.ts +147 -0
- package/dist/utils/decode-instances.d.ts +60 -0
- package/dist/utils/utils.d.ts +10 -0
- package/package.json +4 -2
- package/src/_version.ts +1 -1
- package/src/camera/camera.ts +27 -10
- package/src/core/studio-manager.ts +682 -0
- package/src/core/types.ts +328 -9
- package/src/core/viewer-state.ts +84 -4
- package/src/core/viewer.ts +453 -22
- package/src/index.ts +25 -1
- package/src/rendering/environment.ts +840 -0
- package/src/rendering/light-detection.ts +327 -0
- package/src/rendering/material-factory.ts +456 -2
- package/src/rendering/material-presets.ts +303 -0
- package/src/rendering/raycast.ts +2 -2
- package/src/rendering/room-environment.ts +192 -0
- package/src/rendering/studio-composer.ts +577 -0
- package/src/rendering/studio-floor.ts +108 -0
- package/src/rendering/texture-cache.ts +1020 -0
- package/src/rendering/triplanar.ts +329 -0
- package/src/scene/animation.ts +3 -2
- package/src/scene/clipping.ts +59 -0
- package/src/scene/nestedgroup.ts +399 -0
- package/src/scene/objectgroup.ts +186 -11
- package/src/scene/orientation.ts +12 -0
- package/src/scene/render-shape.ts +55 -21
- package/src/types/n8ao.d.ts +28 -0
- package/src/ui/display.ts +1032 -27
- package/src/ui/index.html +181 -44
- package/src/utils/decode-instances.ts +233 -0
- package/src/utils/utils.ts +33 -20
package/dist/core/viewer.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ declare global {
|
|
|
4
4
|
THREE?: typeof THREE;
|
|
5
5
|
}
|
|
6
6
|
}
|
|
7
|
-
import { NestedGroup } from "../scene/nestedgroup.js";
|
|
7
|
+
import { NestedGroup, ObjectGroup } from "../scene/nestedgroup.js";
|
|
8
8
|
import { Grid } from "../scene/grid.js";
|
|
9
9
|
import { AxesHelper } from "../scene/axes.js";
|
|
10
10
|
import { OrientationMarker } from "../scene/orientation.js";
|
|
@@ -23,7 +23,7 @@ import { PickedObject, Raycaster } from "../rendering/raycast.js";
|
|
|
23
23
|
import { ViewerState } from "./viewer-state.js";
|
|
24
24
|
import type { Display } from "../ui/display.js";
|
|
25
25
|
import type { Vector3Tuple, QuaternionTuple } from "three";
|
|
26
|
-
import { CollapseState, type ZebraColorScheme, type ZebraMappingMode, type NotificationCallback, type RenderOptions, type ViewerOptions, type Shapes, type VisibilityState, type ActiveTab, type Axis, type ClipIndex, type ThemeInput, type BoundingBoxFlat, type Keymap } from "./types.js";
|
|
26
|
+
import { CollapseState, type ZebraColorScheme, type ZebraMappingMode, type StudioToneMapping, type StudioTextureMapping, type StudioBackground, type NotificationCallback, type RenderOptions, type ViewerOptions, type Shapes, type VisibilityState, type ActiveTab, type Axis, type ClipIndex, type ThemeInput, type BoundingBoxFlat, type Keymap } from "./types.js";
|
|
27
27
|
/**
|
|
28
28
|
* Material settings for the viewer.
|
|
29
29
|
*/
|
|
@@ -97,6 +97,8 @@ interface DisplayOptionsInternal {
|
|
|
97
97
|
zebraTool?: boolean;
|
|
98
98
|
glass?: boolean;
|
|
99
99
|
tools?: boolean;
|
|
100
|
+
canvas?: HTMLCanvasElement;
|
|
101
|
+
gl?: WebGLRenderingContext | WebGL2RenderingContext;
|
|
100
102
|
keymap?: KeymapConfig;
|
|
101
103
|
[key: string]: unknown;
|
|
102
104
|
}
|
|
@@ -161,6 +163,8 @@ declare class Viewer {
|
|
|
161
163
|
ready: boolean;
|
|
162
164
|
display: Display;
|
|
163
165
|
renderer: THREE.WebGLRenderer;
|
|
166
|
+
private _externalGl;
|
|
167
|
+
onAfterRender: (() => void) | null;
|
|
164
168
|
mouse: THREE.Vector2;
|
|
165
169
|
cadTools: Tools;
|
|
166
170
|
animation: Animation;
|
|
@@ -199,6 +203,9 @@ declare class Viewer {
|
|
|
199
203
|
expandedNestedGroup: NestedGroup | null;
|
|
200
204
|
compactNestedGroup: NestedGroup | null;
|
|
201
205
|
raycaster: Raycaster | null;
|
|
206
|
+
private _studioManager;
|
|
207
|
+
/** Environment manager — proxied from StudioManager for display.ts access. */
|
|
208
|
+
get envManager(): import("../index.js").EnvironmentManager;
|
|
202
209
|
zScale: number;
|
|
203
210
|
clipNormal0: Vector3Tuple | null;
|
|
204
211
|
clipNormal1: Vector3Tuple | null;
|
|
@@ -379,7 +386,7 @@ declare class Viewer {
|
|
|
379
386
|
toggleGroup(expanded: boolean): void;
|
|
380
387
|
/**
|
|
381
388
|
* Set the active sidebar tab.
|
|
382
|
-
* @param tabName - Tab name: "tree", "clip", "material", or "
|
|
389
|
+
* @param tabName - Tab name: "tree", "clip", "material", "zebra", or "studio"
|
|
383
390
|
* @param notify - whether to send notification or not.
|
|
384
391
|
*/
|
|
385
392
|
setActiveTab(tabName: ActiveTab, notify?: boolean): void;
|
|
@@ -525,7 +532,7 @@ declare class Viewer {
|
|
|
525
532
|
* @param nodeType - node type
|
|
526
533
|
* @param tree - whether from tree
|
|
527
534
|
*/
|
|
528
|
-
handlePick: (path: string, name: string, meta: boolean, shift: boolean,
|
|
535
|
+
handlePick: (path: string, name: string, meta: boolean, shift: boolean, alt: boolean, point: THREE.Vector3 | null, nodeType?: string | null, tree?: boolean) => void;
|
|
529
536
|
setPickHandler(flag: boolean): void;
|
|
530
537
|
/**
|
|
531
538
|
* Find the shape that was double clicked and send notification
|
|
@@ -749,6 +756,11 @@ declare class Viewer {
|
|
|
749
756
|
* @param value - The mapping mode ("reflection", "normal").
|
|
750
757
|
*/
|
|
751
758
|
setZebraMappingMode: (value: ZebraMappingMode) => void;
|
|
759
|
+
/**
|
|
760
|
+
* Resets zebra tool settings to defaults: count=9, opacity=1, direction=0,
|
|
761
|
+
* colorScheme=blackwhite, mappingMode=reflection.
|
|
762
|
+
*/
|
|
763
|
+
resetZebra: () => void;
|
|
752
764
|
/**
|
|
753
765
|
* Gets the current stripe count value.
|
|
754
766
|
* @returns The stripe count (2-50).
|
|
@@ -774,6 +786,173 @@ declare class Viewer {
|
|
|
774
786
|
* @returns The mapping mode ("reflection", "normal").
|
|
775
787
|
*/
|
|
776
788
|
getZebraMappingMode: () => ZebraMappingMode;
|
|
789
|
+
/**
|
|
790
|
+
* Sets the studio environment preset.
|
|
791
|
+
* @param value - The environment name ("studio", "neutral", "outdoor", "none", or custom HDR URL).
|
|
792
|
+
* @param notify - Whether to notify about the changes.
|
|
793
|
+
* @public
|
|
794
|
+
*/
|
|
795
|
+
setStudioEnvironment: (value: string, notify?: boolean) => void;
|
|
796
|
+
/**
|
|
797
|
+
* Sets the studio environment intensity.
|
|
798
|
+
* @param value - The environment intensity (0-3).
|
|
799
|
+
* @param notify - Whether to notify about the changes.
|
|
800
|
+
* @public
|
|
801
|
+
*/
|
|
802
|
+
setStudioEnvIntensity: (value: number, notify?: boolean) => void;
|
|
803
|
+
/**
|
|
804
|
+
* Sets the background mode for Studio mode.
|
|
805
|
+
* @param value - The background mode ("grey", "white", "gradient", "environment", or "transparent").
|
|
806
|
+
* @param notify - Whether to notify about the changes.
|
|
807
|
+
* @public
|
|
808
|
+
*/
|
|
809
|
+
setStudioBackground: (value: StudioBackground, notify?: boolean) => void;
|
|
810
|
+
/**
|
|
811
|
+
* Sets the tone mapping mode for Studio mode.
|
|
812
|
+
* @param value - The tone mapping mode ("neutral", "ACES", or "none").
|
|
813
|
+
* @param notify - Whether to notify about the changes.
|
|
814
|
+
* @public
|
|
815
|
+
*/
|
|
816
|
+
setStudioToneMapping: (value: StudioToneMapping, notify?: boolean) => void;
|
|
817
|
+
/**
|
|
818
|
+
* Sets the exposure value for Studio mode.
|
|
819
|
+
* @param value - The exposure value (0-2).
|
|
820
|
+
* @param notify - Whether to notify about the changes.
|
|
821
|
+
* @public
|
|
822
|
+
*/
|
|
823
|
+
setStudioExposure: (value: number, notify?: boolean) => void;
|
|
824
|
+
/**
|
|
825
|
+
* Sets whether 4K environment maps are used (default: 2K).
|
|
826
|
+
* @param value - True for 4K, false for 2K.
|
|
827
|
+
* @param notify - Whether to notify about the changes.
|
|
828
|
+
* @public
|
|
829
|
+
*/
|
|
830
|
+
setStudio4kEnvMaps: (value: boolean, notify?: boolean) => void;
|
|
831
|
+
/**
|
|
832
|
+
* Gets whether 4K environment maps are enabled.
|
|
833
|
+
* @returns True for 4K, false for 2K.
|
|
834
|
+
* @public
|
|
835
|
+
*/
|
|
836
|
+
getStudio4kEnvMaps: () => boolean;
|
|
837
|
+
/**
|
|
838
|
+
* Sets the environment rotation for Studio mode.
|
|
839
|
+
* @param value - The rotation in degrees (0-360).
|
|
840
|
+
* @param notify - Whether to notify about the changes.
|
|
841
|
+
* @public
|
|
842
|
+
*/
|
|
843
|
+
setStudioEnvRotation: (value: number, notify?: boolean) => void;
|
|
844
|
+
/**
|
|
845
|
+
* Gets the current environment rotation for Studio mode.
|
|
846
|
+
* @returns The rotation in degrees (0-360).
|
|
847
|
+
* @public
|
|
848
|
+
*/
|
|
849
|
+
getStudioEnvRotation: () => number;
|
|
850
|
+
/**
|
|
851
|
+
* Sets the texture mapping mode for Studio mode.
|
|
852
|
+
* @param value - The texture mapping mode ("triplanar" or "parametric").
|
|
853
|
+
* @param notify - Whether to notify about the changes.
|
|
854
|
+
* @public
|
|
855
|
+
*/
|
|
856
|
+
setStudioTextureMapping: (value: StudioTextureMapping, notify?: boolean) => void;
|
|
857
|
+
/**
|
|
858
|
+
* Gets the current texture mapping mode for Studio mode.
|
|
859
|
+
* @returns The texture mapping mode ("triplanar" or "parametric").
|
|
860
|
+
* @public
|
|
861
|
+
*/
|
|
862
|
+
getStudioTextureMapping: () => StudioTextureMapping;
|
|
863
|
+
/**
|
|
864
|
+
* Gets the current studio environment preset.
|
|
865
|
+
* @returns The environment name ("studio", "neutral", "outdoor", "none", or custom HDR URL).
|
|
866
|
+
* @public
|
|
867
|
+
*/
|
|
868
|
+
getStudioEnvironment: () => string;
|
|
869
|
+
/**
|
|
870
|
+
* Gets the current studio environment intensity.
|
|
871
|
+
* @returns The environment intensity (0-3).
|
|
872
|
+
* @public
|
|
873
|
+
*/
|
|
874
|
+
getStudioEnvIntensity: () => number;
|
|
875
|
+
/**
|
|
876
|
+
* Gets the current background mode for Studio mode.
|
|
877
|
+
* @returns The background mode ("grey", "white", "gradient", "environment", or "transparent").
|
|
878
|
+
* @public
|
|
879
|
+
*/
|
|
880
|
+
getStudioBackground: () => StudioBackground;
|
|
881
|
+
/**
|
|
882
|
+
* Gets the current tone mapping mode for Studio mode.
|
|
883
|
+
* @returns The tone mapping mode ("neutral", "ACES", or "none").
|
|
884
|
+
* @public
|
|
885
|
+
*/
|
|
886
|
+
getStudioToneMapping: () => StudioToneMapping;
|
|
887
|
+
/**
|
|
888
|
+
* Gets the current exposure value for Studio mode.
|
|
889
|
+
* @returns The exposure value (0-3).
|
|
890
|
+
* @public
|
|
891
|
+
*/
|
|
892
|
+
getStudioExposure: () => number;
|
|
893
|
+
/**
|
|
894
|
+
* Sets the shadow intensity in Studio mode.
|
|
895
|
+
* A value of 0 disables shadows; values > 0 enable them at that darkness.
|
|
896
|
+
* @param value - The shadow intensity (0-1).
|
|
897
|
+
* @param notify - Whether to notify about the changes.
|
|
898
|
+
* @public
|
|
899
|
+
*/
|
|
900
|
+
setStudioShadowIntensity: (value: number, notify?: boolean) => void;
|
|
901
|
+
/**
|
|
902
|
+
* Gets the current shadow intensity in Studio mode.
|
|
903
|
+
* @returns The shadow intensity (0-1). 0 means shadows are off.
|
|
904
|
+
* @public
|
|
905
|
+
*/
|
|
906
|
+
getStudioShadowIntensity: () => number;
|
|
907
|
+
/**
|
|
908
|
+
* Sets the shadow softness in Studio mode.
|
|
909
|
+
* Controls PCSS penumbra width (virtual light source size).
|
|
910
|
+
* @param value - The shadow softness (0-1).
|
|
911
|
+
* @param notify - Whether to notify about the changes.
|
|
912
|
+
* @public
|
|
913
|
+
*/
|
|
914
|
+
setStudioShadowSoftness: (value: number, notify?: boolean) => void;
|
|
915
|
+
/**
|
|
916
|
+
* Gets the current shadow softness in Studio mode.
|
|
917
|
+
* @returns The shadow softness (0-1).
|
|
918
|
+
* @public
|
|
919
|
+
*/
|
|
920
|
+
getStudioShadowSoftness: () => number;
|
|
921
|
+
/**
|
|
922
|
+
* Sets the ambient occlusion intensity in Studio mode.
|
|
923
|
+
* A value of 0 disables AO; values > 0 enable it at that intensity.
|
|
924
|
+
* @param value - The AO intensity (0-3.0).
|
|
925
|
+
* @param notify - Whether to notify about the changes.
|
|
926
|
+
* @public
|
|
927
|
+
*/
|
|
928
|
+
setStudioAOIntensity: (value: number, notify?: boolean) => void;
|
|
929
|
+
/**
|
|
930
|
+
* Gets the current ambient occlusion intensity in Studio mode.
|
|
931
|
+
* @returns The AO intensity value (0.5-3.0).
|
|
932
|
+
* @public
|
|
933
|
+
*/
|
|
934
|
+
getStudioAOIntensity: () => number;
|
|
935
|
+
/**
|
|
936
|
+
* Returns whether Studio mode is currently active.
|
|
937
|
+
* @returns True if Studio mode is active and the viewer has rendered content.
|
|
938
|
+
* @public
|
|
939
|
+
*/
|
|
940
|
+
get isStudioActive(): boolean;
|
|
941
|
+
/**
|
|
942
|
+
* Get the ObjectGroup and path for the currently selected object in Studio mode.
|
|
943
|
+
* Returns null if nothing is selected, Studio mode is inactive, or the
|
|
944
|
+
* selection is a CompoundGroup (assembly node) rather than a leaf object.
|
|
945
|
+
*/
|
|
946
|
+
getSelectedObjectGroup(): {
|
|
947
|
+
object: ObjectGroup;
|
|
948
|
+
path: string;
|
|
949
|
+
} | null;
|
|
950
|
+
/** Enter Studio mode. Called by display.ts switchToTab(). @internal */
|
|
951
|
+
enterStudioMode: () => Promise<void>;
|
|
952
|
+
/** Leave Studio mode. Called by display.ts switchToTab(). @internal */
|
|
953
|
+
leaveStudioMode: () => void;
|
|
954
|
+
/** Reset Studio settings to defaults. @public */
|
|
955
|
+
resetStudio: () => void;
|
|
777
956
|
/**
|
|
778
957
|
* Get ortho value as property (for ViewerLike interface compatibility).
|
|
779
958
|
*/
|
|
@@ -1157,6 +1336,11 @@ declare class Viewer {
|
|
|
1157
1336
|
* @param notify - whether to send notification or not.
|
|
1158
1337
|
*/
|
|
1159
1338
|
setClipSlider: (index: 0 | 1 | 2, value: number, notify?: boolean) => void;
|
|
1339
|
+
/**
|
|
1340
|
+
* Resets clip planes to default normals and slider positions.
|
|
1341
|
+
* Normals reset to -X, -Y, -Z; sliders to gridSize/2; checkboxes unchecked.
|
|
1342
|
+
*/
|
|
1343
|
+
resetClip: () => void;
|
|
1160
1344
|
/**
|
|
1161
1345
|
* Replace CadView with an inline png image of the canvas.
|
|
1162
1346
|
*
|
|
@@ -1266,11 +1450,21 @@ declare class Viewer {
|
|
|
1266
1450
|
*/
|
|
1267
1451
|
showHelp: (flag: boolean) => void;
|
|
1268
1452
|
/**
|
|
1269
|
-
*
|
|
1270
|
-
* @param flag -
|
|
1453
|
+
* Collapse or expand the info panel in glass mode.
|
|
1454
|
+
* @param flag - true to show, false to collapse
|
|
1271
1455
|
* @public
|
|
1272
1456
|
*/
|
|
1457
|
+
showInfoPanel: (flag: boolean) => void;
|
|
1458
|
+
/**
|
|
1459
|
+
* @deprecated Use showInfoPanel() instead.
|
|
1460
|
+
*/
|
|
1273
1461
|
showInfo: (flag: boolean) => void;
|
|
1462
|
+
/**
|
|
1463
|
+
* Collapse or expand the tools panel (tabs + content) in glass mode.
|
|
1464
|
+
* @param flag - true to show, false to collapse
|
|
1465
|
+
* @public
|
|
1466
|
+
*/
|
|
1467
|
+
showToolsPanel: (flag: boolean) => void;
|
|
1274
1468
|
/**
|
|
1275
1469
|
* Show/hide the pinning button.
|
|
1276
1470
|
* @param flag - whether to show the pinning button
|
package/dist/index.d.ts
CHANGED
|
@@ -10,15 +10,17 @@ import "../css/treeview.css";
|
|
|
10
10
|
import "../css/tools.css";
|
|
11
11
|
import { Viewer } from "./core/viewer.js";
|
|
12
12
|
import { Display } from "./ui/display.js";
|
|
13
|
+
import { EnvironmentManager } from "./rendering/environment.js";
|
|
13
14
|
import { Timer } from "./utils/timer.js";
|
|
14
15
|
import { logger } from "./utils/logger.js";
|
|
15
16
|
import { gpuTracker } from "./utils/gpu-tracker.js";
|
|
16
17
|
import { version } from "./_version.js";
|
|
17
|
-
export { Viewer, Display, Timer, logger, gpuTracker, version };
|
|
18
|
+
export { Viewer, Display, EnvironmentManager, Timer, logger, gpuTracker, version };
|
|
19
|
+
export { MATERIAL_PRESETS, MATERIAL_PRESET_NAMES } from "./rendering/material-presets.js";
|
|
18
20
|
export type { LogLevel } from "./utils/logger.js";
|
|
19
21
|
export type { ResourceType, TrackedResource, ResourceSummary } from "./utils/gpu-tracker.js";
|
|
20
22
|
export type { Vector3Tuple, QuaternionTuple } from "three";
|
|
21
|
-
export type { ThemeInput, Theme, ControlType, UpDirection, AnimationMode, ActiveTab, ZebraColorScheme, ZebraMappingMode, ShapeType, ShapeSubtype, Axis, ClipIndex, ColorValue, RGBColor, AxisColors, AxisColorsFlatArray, } from "./core/types.js";
|
|
23
|
+
export type { ThemeInput, Theme, ControlType, UpDirection, AnimationMode, ActiveTab, ZebraColorScheme, ZebraMappingMode, ShapeType, ShapeSubtype, Axis, ClipIndex, ColorValue, RGBColor, RGBAColor, AxisColors, AxisColorsFlatArray, } from "./core/types.js";
|
|
22
24
|
export { CLIP_INDICES, isClipIndex, CollapseState } from "./core/types.js";
|
|
23
25
|
export type { StateChange, StateSubscriber, GlobalStateSubscriber, } from "./core/types.js";
|
|
24
26
|
export type { BoundingBox, BoundingSphere, BoundingBoxFlat, } from "./core/types.js";
|
|
@@ -30,4 +32,7 @@ export type { Texture, Shape, ShapeBinary, ShapeNested, Location, VisibilityValu
|
|
|
30
32
|
export { isShapeBinaryFormat, hasTrianglesPerFace, hasSegmentsPerEdge, } from "./core/types.js";
|
|
31
33
|
export type { DomEventCallback } from "./core/types.js";
|
|
32
34
|
export type { ColoredMaterial } from "./core/types.js";
|
|
35
|
+
export type { MaterialAppearance, MaterialXMaterial, TextureEntry, StudioOptions, StudioBackground, StudioModeOptions, StudioEnvironment, StudioToneMapping, StudioTextureMapping, } from "./core/types.js";
|
|
36
|
+
export { isMaterialXMaterial } from "./core/types.js";
|
|
37
|
+
export { isInstancedFormat, decodeInstancedFormat } from "./utils/decode-instances.js";
|
|
33
38
|
export type { SubscribeOptions } from "./core/types.js";
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import * as THREE from "three";
|
|
2
|
+
import type { StudioEnvironment, StudioBackground } from "../core/types.js";
|
|
3
|
+
import { type LightDetectionResult } from "./light-detection.js";
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for EnvironmentManager.
|
|
6
|
+
*/
|
|
7
|
+
interface EnvironmentManagerOptions {
|
|
8
|
+
/** Override URLs for the "neutral" and "outdoor" HDR presets */
|
|
9
|
+
presetUrls?: Partial<Record<string, string>>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Manages environment maps for Studio mode.
|
|
13
|
+
*
|
|
14
|
+
* Handles three tiers of environment sources:
|
|
15
|
+
* - **Tier 1 "studio"**: Procedural RoomEnvironment (bundled, zero network)
|
|
16
|
+
* - **Tier 2 "neutral"/"outdoor"**: HDR presets loaded from configurable CDN URLs
|
|
17
|
+
* - **Tier 3 custom URL**: User-provided HDR URL (same loading path as Tier 2)
|
|
18
|
+
*
|
|
19
|
+
* The environment map is used for IBL (image-based lighting) via
|
|
20
|
+
* `scene.environment`. The scene background is configurable via the
|
|
21
|
+
* `backgroundMode` parameter in `apply()` (grey, white, gradient,
|
|
22
|
+
* blurred environment, or transparent).
|
|
23
|
+
*
|
|
24
|
+
* Features:
|
|
25
|
+
* - PMREM generation and caching for all tiers
|
|
26
|
+
* - In-flight promise deduplication (prevents duplicate loads on rapid switching)
|
|
27
|
+
* - Lazy PMREMGenerator creation
|
|
28
|
+
* - Fallback to "studio" on HDR load failure
|
|
29
|
+
* - GPU resource tracking via gpuTracker
|
|
30
|
+
*/
|
|
31
|
+
declare class EnvironmentManager {
|
|
32
|
+
/** Cached PMREM render targets keyed by environment name or URL */
|
|
33
|
+
private _cache;
|
|
34
|
+
/** Cached light detection results keyed by environment name or URL */
|
|
35
|
+
private _lightDetectionCache;
|
|
36
|
+
/** In-flight load promises keyed by environment name or URL */
|
|
37
|
+
private _inflight;
|
|
38
|
+
/** Lazily-created PMREMGenerator instance */
|
|
39
|
+
private _pmremGenerator;
|
|
40
|
+
/** Resolved preset URLs (defaults merged with user overrides) */
|
|
41
|
+
private _presetUrls;
|
|
42
|
+
/** Whether 4K env maps are enabled (default false = 2K) */
|
|
43
|
+
private _use4k;
|
|
44
|
+
/** User-provided URL overrides from constructor */
|
|
45
|
+
private _userOverrides;
|
|
46
|
+
/** HDRLoader instance (created lazily on first HDR load) */
|
|
47
|
+
private _hdrLoader;
|
|
48
|
+
/** The last loaded PMREM texture (stateful — used by apply() for IBL) */
|
|
49
|
+
private _currentTexture;
|
|
50
|
+
/** Whether this manager has been disposed */
|
|
51
|
+
private _disposed;
|
|
52
|
+
/**
|
|
53
|
+
* Ortho env background workaround.
|
|
54
|
+
*
|
|
55
|
+
* Three.js cannot render PMREM/cubemap textures as scene.background with
|
|
56
|
+
* orthographic cameras (renders as a tiny rectangle). We work around this by
|
|
57
|
+
* rendering the env map to a render target using a virtual perspective camera,
|
|
58
|
+
* then setting that 2D texture as scene.background. A 2D texture background
|
|
59
|
+
* renders as a fullscreen quad regardless of camera projection, and the
|
|
60
|
+
* transmission pass (glass refraction) also sees it correctly.
|
|
61
|
+
*/
|
|
62
|
+
private _bgScene;
|
|
63
|
+
private _bgCamera;
|
|
64
|
+
private _bgRenderTarget;
|
|
65
|
+
private _orthoEnvMainScene;
|
|
66
|
+
/** Whether the env background feature is active (ortho + environment background). */
|
|
67
|
+
private _envBackgroundActive;
|
|
68
|
+
/**
|
|
69
|
+
* Deferred-apply state: if apply() was called with backgroundMode "environment"
|
|
70
|
+
* while _currentTexture was null, store the arguments so loadEnvironment() can
|
|
71
|
+
* re-apply once the texture is ready.
|
|
72
|
+
*/
|
|
73
|
+
private _deferredApply;
|
|
74
|
+
constructor(options?: EnvironmentManagerOptions);
|
|
75
|
+
/**
|
|
76
|
+
* Load or retrieve an environment map.
|
|
77
|
+
*
|
|
78
|
+
* Resolves the environment name to a loading strategy:
|
|
79
|
+
* - `"studio"` -- procedural RoomEnvironment via PMREMGenerator.fromScene()
|
|
80
|
+
* - `"neutral"` / `"outdoor"` -- HDR preset from configured CDN URL
|
|
81
|
+
* - `"none"` -- returns null (caller should call `remove()` instead)
|
|
82
|
+
* - Any other string -- treated as a custom HDR URL
|
|
83
|
+
*
|
|
84
|
+
* Results are cached. If a load is already in flight for the same key,
|
|
85
|
+
* the existing promise is returned (no duplicate loads).
|
|
86
|
+
*
|
|
87
|
+
* @param name - Environment preset name or custom HDR URL
|
|
88
|
+
* @param renderer - WebGL renderer (needed for PMREMGenerator)
|
|
89
|
+
* @returns PMREM texture, or null for "none"
|
|
90
|
+
*/
|
|
91
|
+
loadEnvironment(name: StudioEnvironment | string, renderer: THREE.WebGLRenderer): Promise<THREE.Texture | null>;
|
|
92
|
+
/**
|
|
93
|
+
* Apply the current environment map to the scene.
|
|
94
|
+
*
|
|
95
|
+
* Sets `scene.environment` for PBR/IBL reflections and configures
|
|
96
|
+
* `scene.background` according to the selected background mode:
|
|
97
|
+
* - `"grey"`: Neutral grey color (default, clean product-shot look)
|
|
98
|
+
* - `"white"`: Pure white background (e-commerce / documentation style)
|
|
99
|
+
* - `"gradient"`: Radial vignette gradient (light grey center → darker edges)
|
|
100
|
+
* - `"environment"`: Blurred, dimmed PMREM environment as backdrop
|
|
101
|
+
* (color-matched to IBL, eliminates edge-glow artifacts on reflective objects)
|
|
102
|
+
* - `"transparent"`: No background (canvas alpha shows through)
|
|
103
|
+
*
|
|
104
|
+
* @param scene - The Three.js scene to apply the environment to
|
|
105
|
+
* @param envIntensity - Environment intensity multiplier (0-3, default 1.0)
|
|
106
|
+
* @param backgroundMode - Background mode
|
|
107
|
+
* @param upIsZ - Whether the scene uses Z-up coordinates (default true)
|
|
108
|
+
* @param ortho - Whether the camera is orthographic (env background falls back to gradient)
|
|
109
|
+
* @param envRotationDeg - Environment map rotation in degrees (default 0)
|
|
110
|
+
*/
|
|
111
|
+
apply(scene: THREE.Scene, envIntensity: number, backgroundMode?: StudioBackground, upIsZ?: boolean, ortho?: boolean, envRotationDeg?: number): void;
|
|
112
|
+
/**
|
|
113
|
+
* Remove environment map from the scene.
|
|
114
|
+
*
|
|
115
|
+
* Clears `scene.environment`, `scene.background`, and resets
|
|
116
|
+
* environment/background properties to defaults.
|
|
117
|
+
*
|
|
118
|
+
* @param scene - The Three.js scene to clear
|
|
119
|
+
*/
|
|
120
|
+
remove(scene: THREE.Scene): void;
|
|
121
|
+
/**
|
|
122
|
+
* Switch between 2K and 4K environment map resolution.
|
|
123
|
+
*
|
|
124
|
+
* Rebuilds preset URLs, evicts cached HDR presets (so they reload at
|
|
125
|
+
* the new resolution), and reloads the current environment if one is
|
|
126
|
+
* active.
|
|
127
|
+
*
|
|
128
|
+
* @param use4k - True for 4K, false for 2K
|
|
129
|
+
* @param currentEnvName - The currently active environment name (to reload)
|
|
130
|
+
* @param renderer - WebGL renderer (needed for reload)
|
|
131
|
+
* @returns Promise that resolves when the new texture is ready
|
|
132
|
+
*/
|
|
133
|
+
setUse4kEnvMaps(use4k: boolean, currentEnvName: string, renderer: THREE.WebGLRenderer): Promise<THREE.Texture | null>;
|
|
134
|
+
/** Whether 4K env maps are currently enabled. */
|
|
135
|
+
get use4kEnvMaps(): boolean;
|
|
136
|
+
/**
|
|
137
|
+
* Whether an environment name is a Poly Haven preset (resolution-switchable).
|
|
138
|
+
* Returns false for "studio", "none", and custom URLs.
|
|
139
|
+
*/
|
|
140
|
+
isPreset(name: string): boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Whether the render-to-texture env background path is currently active.
|
|
143
|
+
* When true, the caller must call updateEnvBackground() each frame.
|
|
144
|
+
*/
|
|
145
|
+
get isEnvBackgroundActive(): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Get cached light detection result for an environment.
|
|
148
|
+
*
|
|
149
|
+
* @param envName - Environment name or URL (same key used in loadEnvironment)
|
|
150
|
+
* @returns Detection result, or null if not yet analyzed
|
|
151
|
+
*/
|
|
152
|
+
getLightDetection(envName: string): LightDetectionResult | null;
|
|
153
|
+
/**
|
|
154
|
+
* Update the env background render target (ortho camera workaround).
|
|
155
|
+
*
|
|
156
|
+
* Renders the PMREM env map to a 2D render target using a fixed-FOV virtual
|
|
157
|
+
* perspective camera whose quaternion is synced with the main camera. The
|
|
158
|
+
* resulting 2D texture is set as the main scene's background, giving a
|
|
159
|
+
* world-space environment that tracks camera orbit — matching how
|
|
160
|
+
* scene.environment (IBL reflections) already behaves.
|
|
161
|
+
*
|
|
162
|
+
* Called every frame from the render loop when isEnvBackgroundActive is true.
|
|
163
|
+
* Only active in ortho mode (perspective uses native cubemap background).
|
|
164
|
+
*
|
|
165
|
+
* @param renderer - WebGL renderer
|
|
166
|
+
* @param mainCamera - The active camera whose orientation to match
|
|
167
|
+
*/
|
|
168
|
+
updateEnvBackground(renderer: THREE.WebGLRenderer, mainCamera?: THREE.Camera): void;
|
|
169
|
+
/**
|
|
170
|
+
* Dispose all cached resources.
|
|
171
|
+
*
|
|
172
|
+
* Disposes all cached PMREM render targets (and their textures) and
|
|
173
|
+
* the PMREMGenerator. After disposal, this manager cannot be used again.
|
|
174
|
+
*
|
|
175
|
+
* Call this on `viewer.dispose()`, NOT on `viewer.clear()` --
|
|
176
|
+
* the EnvironmentManager survives shape data clearing because
|
|
177
|
+
* environments are independent of shape data.
|
|
178
|
+
*/
|
|
179
|
+
dispose(): void;
|
|
180
|
+
/**
|
|
181
|
+
* Set up the env background: a separate scene with the PMREM texture
|
|
182
|
+
* as background and a fixed-FOV virtual perspective camera for rendering
|
|
183
|
+
* to a 2D target. Used only for ortho cameras (perspective uses native
|
|
184
|
+
* cubemap background).
|
|
185
|
+
*/
|
|
186
|
+
private _setupEnvBackground;
|
|
187
|
+
/**
|
|
188
|
+
* Tear down the env background state.
|
|
189
|
+
*/
|
|
190
|
+
private _teardownEnvBackground;
|
|
191
|
+
/**
|
|
192
|
+
* Resolve environment name to an HDR URL, if applicable.
|
|
193
|
+
*
|
|
194
|
+
* Returns null for "studio" (uses RoomEnvironment, no URL).
|
|
195
|
+
* Returns the preset URL for "neutral"/"outdoor".
|
|
196
|
+
* Returns the name itself for custom URLs.
|
|
197
|
+
*/
|
|
198
|
+
private _resolveUrl;
|
|
199
|
+
/**
|
|
200
|
+
* Get or create the PMREMGenerator (lazy initialization).
|
|
201
|
+
*/
|
|
202
|
+
private _ensurePmremGenerator;
|
|
203
|
+
/**
|
|
204
|
+
* Get or create the HDRLoader (lazy initialization).
|
|
205
|
+
*/
|
|
206
|
+
private _ensureHdrLoader;
|
|
207
|
+
/**
|
|
208
|
+
* Internal load dispatcher.
|
|
209
|
+
*
|
|
210
|
+
* Routes to RoomEnvironment generation or HDR loading based on the name.
|
|
211
|
+
* On HDR failure, falls back to "studio" (RoomEnvironment).
|
|
212
|
+
*/
|
|
213
|
+
private _load;
|
|
214
|
+
/**
|
|
215
|
+
* Generate PMREM texture from the procedural RoomEnvironment.
|
|
216
|
+
*
|
|
217
|
+
* This is synchronous (no network), fast (~70ms), and always available.
|
|
218
|
+
*/
|
|
219
|
+
private _loadRoomEnvironment;
|
|
220
|
+
/**
|
|
221
|
+
* Load an HDR file and generate a PMREM texture from it.
|
|
222
|
+
*
|
|
223
|
+
* Uses HDRLoader to fetch the .hdr file, then PMREMGenerator.fromEquirectangular()
|
|
224
|
+
* to create the PMREM cubemap. The source equirectangular texture is disposed
|
|
225
|
+
* after PMREM generation. The PMREM texture itself serves as both the IBL
|
|
226
|
+
* environment and the background (in "environment" mode).
|
|
227
|
+
*
|
|
228
|
+
* @param url - URL of the .hdr file
|
|
229
|
+
* @param cacheKey - Cache key for the resulting PMREM render target
|
|
230
|
+
* @param renderer - WebGL renderer for PMREMGenerator
|
|
231
|
+
* @returns PMREM texture
|
|
232
|
+
* @throws If the HDR file cannot be loaded
|
|
233
|
+
*/
|
|
234
|
+
private _loadHdr;
|
|
235
|
+
}
|
|
236
|
+
/** Dispose lazy-cached gradient textures (called from EnvironmentManager.dispose). */
|
|
237
|
+
declare function disposeGradientTextures(): void;
|
|
238
|
+
export { EnvironmentManager, disposeGradientTextures };
|
|
239
|
+
export type { EnvironmentManagerOptions };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HDR environment map light source detection.
|
|
3
|
+
*
|
|
4
|
+
* Analyzes equirectangular HDR pixel data to find dominant light sources
|
|
5
|
+
* (softboxes in studio HDRs, sun in outdoor HDRs). Returns direction,
|
|
6
|
+
* intensity, and color for up to 2 lights, used to create shadow-casting
|
|
7
|
+
* DirectionalLights in Studio mode.
|
|
8
|
+
*
|
|
9
|
+
* Algorithm: downsample to 128x64 luminance grid → threshold at 10x median
|
|
10
|
+
* → flood-fill cluster → convert centroids to 3D direction vectors.
|
|
11
|
+
* Runs ~5-10ms on CPU, no GPU readback needed.
|
|
12
|
+
*/
|
|
13
|
+
/** A detected dominant light source from HDR analysis. */
|
|
14
|
+
export interface DetectedLight {
|
|
15
|
+
/** Unit direction vector toward the light source (Y-up, before Z-up rotation). */
|
|
16
|
+
direction: [number, number, number];
|
|
17
|
+
/** Relative intensity (normalized, 0-1 range). */
|
|
18
|
+
intensity: number;
|
|
19
|
+
/** Linear RGB color of the light source (0-1 range). */
|
|
20
|
+
color: [number, number, number];
|
|
21
|
+
}
|
|
22
|
+
/** Result of light detection analysis. */
|
|
23
|
+
export interface LightDetectionResult {
|
|
24
|
+
/** Detected light sources (0-2 entries). */
|
|
25
|
+
lights: DetectedLight[];
|
|
26
|
+
/** Whether the result came from actual HDR analysis (true) or a fallback (false). */
|
|
27
|
+
wasAnalyzed: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Detect dominant light sources from equirectangular HDR pixel data.
|
|
31
|
+
*
|
|
32
|
+
* @param data - Raw pixel data (Uint16Array for HalfFloat, or Float32Array)
|
|
33
|
+
* @param width - HDR image width in pixels
|
|
34
|
+
* @param height - HDR image height in pixels
|
|
35
|
+
* @returns Detection result with up to 2 lights
|
|
36
|
+
*/
|
|
37
|
+
export declare function detectDominantLights(data: Uint16Array | Float32Array, width: number, height: number): LightDetectionResult;
|
|
38
|
+
/**
|
|
39
|
+
* Return hardcoded fallback lights for procedural RoomEnvironment.
|
|
40
|
+
*
|
|
41
|
+
* The RoomEnvironment has no raw HDR data to analyze. A single top-front
|
|
42
|
+
* light direction approximates its primary illumination.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getDefaultLights(): LightDetectionResult;
|