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.
Files changed (58) hide show
  1. package/Readme.md +12 -5
  2. package/dist/camera/camera.d.ts +14 -2
  3. package/dist/core/studio-manager.d.ts +91 -0
  4. package/dist/core/types.d.ts +260 -9
  5. package/dist/core/viewer-state.d.ts +28 -2
  6. package/dist/core/viewer.d.ts +200 -6
  7. package/dist/index.d.ts +7 -2
  8. package/dist/rendering/environment.d.ts +239 -0
  9. package/dist/rendering/light-detection.d.ts +44 -0
  10. package/dist/rendering/material-factory.d.ts +77 -2
  11. package/dist/rendering/material-presets.d.ts +32 -0
  12. package/dist/rendering/room-environment.d.ts +13 -0
  13. package/dist/rendering/studio-composer.d.ts +130 -0
  14. package/dist/rendering/studio-floor.d.ts +53 -0
  15. package/dist/rendering/texture-cache.d.ts +142 -0
  16. package/dist/rendering/triplanar.d.ts +37 -0
  17. package/dist/scene/animation.d.ts +1 -1
  18. package/dist/scene/clipping.d.ts +31 -0
  19. package/dist/scene/nestedgroup.d.ts +64 -27
  20. package/dist/scene/objectgroup.d.ts +47 -0
  21. package/dist/three-cad-viewer.css +339 -29
  22. package/dist/three-cad-viewer.esm.js +27567 -11874
  23. package/dist/three-cad-viewer.esm.js.map +1 -1
  24. package/dist/three-cad-viewer.esm.min.js +10 -4
  25. package/dist/three-cad-viewer.js +27486 -11787
  26. package/dist/three-cad-viewer.min.js +10 -4
  27. package/dist/ui/display.d.ts +147 -0
  28. package/dist/utils/decode-instances.d.ts +60 -0
  29. package/dist/utils/utils.d.ts +10 -0
  30. package/package.json +4 -2
  31. package/src/_version.ts +1 -1
  32. package/src/camera/camera.ts +27 -10
  33. package/src/core/studio-manager.ts +682 -0
  34. package/src/core/types.ts +328 -9
  35. package/src/core/viewer-state.ts +84 -4
  36. package/src/core/viewer.ts +453 -22
  37. package/src/index.ts +25 -1
  38. package/src/rendering/environment.ts +840 -0
  39. package/src/rendering/light-detection.ts +327 -0
  40. package/src/rendering/material-factory.ts +456 -2
  41. package/src/rendering/material-presets.ts +303 -0
  42. package/src/rendering/raycast.ts +2 -2
  43. package/src/rendering/room-environment.ts +192 -0
  44. package/src/rendering/studio-composer.ts +577 -0
  45. package/src/rendering/studio-floor.ts +108 -0
  46. package/src/rendering/texture-cache.ts +1020 -0
  47. package/src/rendering/triplanar.ts +329 -0
  48. package/src/scene/animation.ts +3 -2
  49. package/src/scene/clipping.ts +59 -0
  50. package/src/scene/nestedgroup.ts +399 -0
  51. package/src/scene/objectgroup.ts +186 -11
  52. package/src/scene/orientation.ts +12 -0
  53. package/src/scene/render-shape.ts +55 -21
  54. package/src/types/n8ao.d.ts +28 -0
  55. package/src/ui/display.ts +1032 -27
  56. package/src/ui/index.html +181 -44
  57. package/src/utils/decode-instances.ts +233 -0
  58. package/src/utils/utils.ts +33 -20
@@ -1,6 +1,6 @@
1
1
  import * as THREE from "three";
2
2
  import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";
3
- import type { ColorValue } from "../core/types.js";
3
+ import type { ColorValue, MaterialAppearance } from "../core/types.js";
4
4
  /**
5
5
  * Options for MaterialFactory constructor
6
6
  */
@@ -60,6 +60,27 @@ interface TextureMaterialOptions {
60
60
  texture: THREE.Texture;
61
61
  visible?: boolean;
62
62
  }
63
+ /**
64
+ * Interface for the TextureCache dependency.
65
+ * The actual TextureCache class is defined in texture-cache.ts.
66
+ * We depend only on its get() method for loose coupling.
67
+ */
68
+ interface TextureCacheInterface {
69
+ get(ref: string, textureRole: string): Promise<THREE.Texture | null>;
70
+ }
71
+ /**
72
+ * Options for Studio mode materials.
73
+ */
74
+ interface StudioMaterialOptions {
75
+ /** Resolved MaterialAppearance definition (already looked up from materials table / presets) */
76
+ materialDef: MaterialAppearance;
77
+ /** Fallback CSS hex color from the leaf node (e.g., "#cc0000") */
78
+ fallbackColor: ColorValue;
79
+ /** Fallback alpha from the leaf node (0-1) */
80
+ fallbackAlpha: number;
81
+ /** TextureCache for resolving texture references */
82
+ textureCache: TextureCacheInterface | null;
83
+ }
63
84
  /**
64
85
  * Options for updating factory settings
65
86
  */
@@ -122,10 +143,64 @@ declare class MaterialFactory {
122
143
  * Create a basic material for texture-mapped surfaces.
123
144
  */
124
145
  createTextureMaterial({ texture, visible }: TextureMaterialOptions, label?: string): THREE.MeshBasicMaterial;
146
+ /**
147
+ * Create a Studio mode material from a resolved MaterialAppearance.
148
+ *
149
+ * Always creates MeshPhysicalMaterial (except when `unlit: true`, which
150
+ * uses MeshBasicMaterial). MeshPhysicalMaterial is a superset of
151
+ * MeshStandardMaterial; when advanced features are off (transmission=0,
152
+ * clearcoat=0, sheen=0, etc.), the shader compiles to essentially the
153
+ * same cost.
154
+ *
155
+ * @param options - Studio material options
156
+ * @param label - Optional label for GPU tracking
157
+ * @returns Configured MeshPhysicalMaterial (or MeshBasicMaterial if unlit)
158
+ */
159
+ createStudioMaterial({ materialDef, fallbackColor, fallbackAlpha, textureCache }: StudioMaterialOptions, label?: string): Promise<THREE.MeshPhysicalMaterial | THREE.MeshBasicMaterial>;
160
+ /**
161
+ * Create a Studio mode material from a threejs-materials format entry.
162
+ *
163
+ * threejs-materials `properties` uses simplified property names (e.g., "color",
164
+ * "roughness", "normal") where each entry has an optional `value` (scalar or
165
+ * [r,g,b] array in **linear RGB**) and/or `texture` (inline data URI).
166
+ *
167
+ * @param properties - Material properties from threejs-materials
168
+ * @param textureRepeat - Optional [u, v] texture tiling applied to all loaded textures
169
+ * @param textureCache - TextureCache for resolving data URI textures
170
+ * @param label - Optional label for GPU tracking
171
+ * @returns Configured MeshPhysicalMaterial
172
+ */
173
+ createStudioMaterialFromMaterialX(properties: Record<string, {
174
+ value?: unknown;
175
+ texture?: string;
176
+ }>, textureRepeat: [number, number] | undefined, textureCache: TextureCacheInterface | null, label?: string): Promise<THREE.MeshPhysicalMaterial>;
177
+ /**
178
+ * Apply alpha mode settings to a material.
179
+ *
180
+ * - OPAQUE: fully opaque, no transparency
181
+ * - MASK: alpha testing with cutoff threshold
182
+ * - BLEND: standard alpha blending
183
+ * - Default (no alphaMode): transparent: true (current viewer behavior)
184
+ */
185
+ private _applyAlphaMode;
186
+ /**
187
+ * Resolve and apply texture references from a MaterialAppearance onto a
188
+ * MeshPhysicalMaterial via the TextureCache.
189
+ *
190
+ * Color-data textures (base color, emissive, sheen color, specular color)
191
+ * are requested with SRGBColorSpace. All other textures (normal, metallic-
192
+ * roughness, occlusion, roughness maps, transmission, thickness) are
193
+ * requested with LinearSRGBColorSpace (the default).
194
+ *
195
+ * The metallicRoughnessTexture is a single combined texture where
196
+ * B channel = metalness and G channel = roughness. It is assigned to
197
+ * both metalnessMap and roughnessMap on the material.
198
+ */
199
+ private _applyStudioTextures;
125
200
  /**
126
201
  * Update global settings.
127
202
  */
128
203
  update(options: UpdateOptions): void;
129
204
  }
130
205
  export { MaterialFactory };
131
- export type { MaterialFactoryOptions, UpdateOptions };
206
+ export type { MaterialFactoryOptions, UpdateOptions, StudioMaterialOptions, TextureCacheInterface };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Built-in material presets for Studio mode.
3
+ *
4
+ * 31 presets organized by category: metals (polished & matte/brushed),
5
+ * plastics, glass & transparent, rubber & elastomers, painted surfaces,
6
+ * and natural/other materials.
7
+ *
8
+ * These are pure data definitions — no textures, no runtime cost.
9
+ * The `builtin` field is intentionally omitted; it is used by user-defined
10
+ * materials to reference these presets, not by presets themselves.
11
+ *
12
+ * All color values are in sRGB color space (0-1 per channel).
13
+ * The material factory converts sRGB to linear when creating Three.js materials.
14
+ * Presets with neutral color (plastics, paints) rely on the leaf node's
15
+ * color field for the actual tint via fallback in the material factory.
16
+ *
17
+ */
18
+ import type { MaterialAppearance } from "../core/types.js";
19
+ /**
20
+ * Built-in material presets keyed by preset name.
21
+ *
22
+ * Usage: look up a preset by the `material` tag on a leaf node, or via
23
+ * `"builtin:<name>"` strings in the materials table.
24
+ */
25
+ export declare const MATERIAL_PRESETS: Record<string, MaterialAppearance>;
26
+ /**
27
+ * Sorted list of all built-in material preset names.
28
+ *
29
+ * Useful for UI dropdowns, validation, and programmatic enumeration.
30
+ * Derived from MATERIAL_PRESETS keys at module load time.
31
+ */
32
+ export declare const MATERIAL_PRESET_NAMES: string[];
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Clean room environment for Studio mode PMREM generation.
3
+ *
4
+ * Based on Three.js RoomEnvironment (which is based on Google model-viewer's
5
+ * EnvironmentScene), but with the 6 decorative boxes removed and an infinity
6
+ * cove (quarter-cylinder) at all wall-floor junctions for a clean cyclorama.
7
+ */
8
+ import { Scene } from "three";
9
+ declare class CleanRoomEnvironment extends Scene {
10
+ constructor();
11
+ dispose(): void;
12
+ }
13
+ export { CleanRoomEnvironment };
@@ -0,0 +1,130 @@
1
+ /**
2
+ * StudioComposer -- postprocessing pipeline for Studio mode.
3
+ *
4
+ * Wraps the pmndrs EffectComposer to provide:
5
+ * - Scene rendering (RenderPass)
6
+ * - Screen-space ambient occlusion (N8AOPostPass)
7
+ * - Screen-space shadow mask (BasicShadowMap + KawaseBlurPass)
8
+ * - Tone mapping + sRGB output + antialiasing (ToneMappingEffect + SMAAEffect)
9
+ *
10
+ * Tone mapping is handled by the postprocessing ToneMappingEffect, which uses
11
+ * Three.js's own GLSL tone mapping functions (via #include <tonemapping_pars_fragment>).
12
+ * The renderer's toneMapping must be set to NoToneMapping (the postprocessing
13
+ * library's documented requirement). Exposure is controlled via
14
+ * renderer.toneMappingExposure, which the GLSL functions read automatically.
15
+ *
16
+ * Background protection: solid-color backgrounds are excluded from tone mapping.
17
+ * The RenderPass skips the background (ignoreBackground), the FBO is cleared to
18
+ * transparent, and the EffectPass alpha-blends its output onto a pre-cleared
19
+ * canvas that already has the correct background color.
20
+ *
21
+ * Shadow mask: BasicShadowMap produces sharp shadow boundaries at 4096×4096.
22
+ * A half-resolution ShadowMaterial override pass captures the mask, which is
23
+ * then blurred via KawaseBlurPass and composited by ShadowMaskEffect before
24
+ * tone mapping. The floor keeps its own ShadowMaterial reading the shadow map
25
+ * directly (sharp but clean).
26
+ *
27
+ * Only instantiated when Studio mode is active. Non-Studio rendering
28
+ * bypasses this entirely and uses direct `renderer.render()`.
29
+ */
30
+ import * as THREE from "three";
31
+ import type { StudioToneMapping } from "../core/types.js";
32
+ declare class StudioComposer {
33
+ private _composer;
34
+ private _renderPass;
35
+ private _n8aoPass;
36
+ private _toneMappingEffect;
37
+ private _effectPass;
38
+ private _renderer;
39
+ private _scene;
40
+ private _camera;
41
+ /** Solid background color to protect from tone mapping, or null. */
42
+ private _bgProtectColor;
43
+ private _shadowMaskRT;
44
+ private _blurredObjectMaskRT;
45
+ private _blurredFloorMaskRT;
46
+ private _blurPass;
47
+ private _shadowMaskMaterial;
48
+ private _shadowMaskEffect;
49
+ private _shadowMaskEnabled;
50
+ private _width;
51
+ private _height;
52
+ private _receiveShadowState;
53
+ private _savedIntensities;
54
+ private _savedVisibility;
55
+ /**
56
+ * Create the postprocessing pipeline.
57
+ *
58
+ * @param renderer - WebGL renderer
59
+ * @param scene - Scene to render
60
+ * @param camera - Active camera (perspective or orthographic)
61
+ * @param width - Canvas width in pixels
62
+ * @param height - Canvas height in pixels
63
+ */
64
+ constructor(renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, width: number, height: number);
65
+ /**
66
+ * Enable or disable solid-background protection.
67
+ *
68
+ * When a solid color is set, the RenderPass skips the scene background
69
+ * (ignoreBackground=true), the FBO is cleared to transparent, and the
70
+ * canvas is pre-cleared with the correct color. The EffectPass then
71
+ * alpha-blends its output so background pixels (alpha=0) show the
72
+ * canvas clear color underneath.
73
+ *
74
+ * Pass null to disable protection (for gradient/environment backgrounds).
75
+ */
76
+ setBackgroundProtect(color: THREE.Color | null): void;
77
+ setAOEnabled(flag: boolean): void;
78
+ setAOIntensity(value: number): void;
79
+ /**
80
+ * Set the tone mapping algorithm and exposure.
81
+ *
82
+ * @param mode - One of "neutral", "ACES", "none"
83
+ * @param exposure - Exposure multiplier (0 to 2, default 1.0)
84
+ */
85
+ setToneMapping(mode: StudioToneMapping, exposure: number): void;
86
+ /**
87
+ * Enable or disable the screen-space shadow mask pipeline.
88
+ *
89
+ * When enabled, creates half-resolution render targets and a KawaseBlurPass.
90
+ * When disabled, disposes those resources and disables the mask effect.
91
+ */
92
+ setShadowMaskEnabled(enabled: boolean): void;
93
+ /**
94
+ * Set shadow blur softness. Uses a fixed HUGE kernel with continuous scale.
95
+ *
96
+ * @param softness - 0 (sharpest) to 1 (softest)
97
+ */
98
+ setShadowSoftness(softness: number): void;
99
+ /**
100
+ * Set the intensity of the object shadow mask overlay.
101
+ *
102
+ * @param intensity - 0 (no shadow) to 1 (full shadow)
103
+ */
104
+ setShadowMaskIntensity(intensity: number): void;
105
+ setCamera(camera: THREE.Camera): void;
106
+ setSize(width: number, height: number): void;
107
+ /**
108
+ * Render one frame through the postprocessing pipeline.
109
+ *
110
+ * When shadow mask is enabled, runs a 3-phase pipeline:
111
+ * 1. Render shadow mask (ShadowMaterial override) to half-res RT
112
+ * 2. Blur via KawaseBlurPass
113
+ * 3. Composite via ShadowMaskEffect in the main EffectPass
114
+ *
115
+ * When background protection is active, pre-clears the canvas with the
116
+ * solid background color before compositing the tone-mapped scene on top
117
+ * via alpha blending.
118
+ */
119
+ render(deltaTime?: number): void;
120
+ /**
121
+ * Render a shadow mask to the half-resolution render target.
122
+ *
123
+ * @param mode - "objects" renders only objects (floor hidden),
124
+ * "floor" renders only the floor (objects hidden)
125
+ * @internal
126
+ */
127
+ private _renderShadowMask;
128
+ dispose(): void;
129
+ }
130
+ export { StudioComposer };
@@ -0,0 +1,53 @@
1
+ import * as THREE from "three";
2
+ /**
3
+ * Studio floor — shadow-catching ground plane for Studio mode.
4
+ *
5
+ * Uses ShadowMaterial which is fully transparent except where shadows
6
+ * are cast, providing a natural grounding effect without obscuring
7
+ * the background (like KeyShot's Ground material or Fusion 360's
8
+ * ground plane).
9
+ *
10
+ * The floor is added to the scene via its `group` property.
11
+ * Shadow plane visibility is toggled via `setShadowsEnabled()`.
12
+ */
13
+ declare class StudioFloor {
14
+ /** The Group to add to the scene. Contains the shadow plane. */
15
+ readonly group: THREE.Group;
16
+ /** Shadow-receiving plane (ShadowMaterial) */
17
+ private _shadowPlane;
18
+ /** Whether shadows are currently enabled */
19
+ private _shadowsEnabled;
20
+ constructor();
21
+ /**
22
+ * Create or recreate the floor for the given scene bounds.
23
+ *
24
+ * Call this when the bounding box changes (new shapes loaded).
25
+ *
26
+ * @param zPosition - Z coordinate for the floor (typically bbox.min.z)
27
+ * @param sceneSize - Approximate scene size (max extent) for sizing the floor
28
+ */
29
+ configure(zPosition: number, sceneSize: number): void;
30
+ /**
31
+ * Toggle shadow plane visibility.
32
+ *
33
+ * @param enabled - Whether to show the shadow plane
34
+ */
35
+ setShadowsEnabled(enabled: boolean): void;
36
+ /**
37
+ * Set the ground shadow opacity (how dark the shadow appears on the floor).
38
+ * This supplements `light.shadow.intensity` which controls shadow darkness
39
+ * on lit materials; the ground plane ShadowMaterial needs its own opacity.
40
+ *
41
+ * @param intensity - Shadow intensity 0-1
42
+ */
43
+ setShadowIntensity(intensity: number): void;
44
+ /** Dispose all GPU resources. */
45
+ dispose(): void;
46
+ /**
47
+ * Create a shadow-receiving plane at the floor position.
48
+ */
49
+ private _createShadowPlane;
50
+ /** Remove and dispose the current shadow plane. */
51
+ private _clearCurrent;
52
+ }
53
+ export { StudioFloor };
@@ -0,0 +1,142 @@
1
+ import * as THREE from "three";
2
+ import type { TextureEntry } from "../core/types.js";
3
+ /** Names of all supported builtin procedural textures */
4
+ declare const BUILTIN_NAMES: readonly ["brushed", "knurled", "sandblasted", "hammered", "checker", "wood-dark", "leather", "fabric-weave"];
5
+ /**
6
+ * Texture fields that carry sRGB color data.
7
+ *
8
+ * When a texture is used for one of these roles, its `colorSpace` must be set
9
+ * to `SRGBColorSpace` so Three.js applies the sRGB-to-linear decode on
10
+ * sampling. All other texture roles (normal, metallic-roughness, occlusion,
11
+ * thickness, transmission, roughness maps) remain `LinearSRGBColorSpace`.
12
+ */
13
+ declare const SRGB_TEXTURE_ROLES: Set<string>;
14
+ /**
15
+ * Manages loading, caching, and lifecycle of all Studio mode textures.
16
+ *
17
+ * The TextureCache is the **sole owner** of all THREE.Texture objects used by
18
+ * Studio mode. Materials reference textures but never dispose them directly.
19
+ * Only TextureCache.dispose() / disposeFull() disposes GPU texture resources.
20
+ *
21
+ * Resolution order for texture reference strings:
22
+ * 1. `builtin:` prefix -- procedural texture from the persistent builtin cache
23
+ * 2. Key in the root-level `textures` table -- embedded data or URL
24
+ * 3. `data:` prefix -- treat as data URI, load directly
25
+ * 4. Otherwise -- treat as URL, resolve relative to HTML page
26
+ *
27
+ * Features:
28
+ * - Two-tier caching: user textures (disposed on clear) + builtin textures
29
+ * (persistent, only disposed on viewer teardown)
30
+ * - In-flight promise deduplication (no duplicate loads for the same key)
31
+ * - Correct colorSpace assignment per texture semantic role
32
+ * - GPU resource tracking via gpuTracker
33
+ */
34
+ declare class TextureCache {
35
+ /** User textures cache (disposed on clear/dispose, rebuilt per shape data) */
36
+ private _cache;
37
+ /** Built-in procedural textures (persistent, only disposed via disposeFull) */
38
+ private _builtinCache;
39
+ /** In-flight load promises keyed by cache key */
40
+ private _inflight;
41
+ /** Root-level textures table from shape data */
42
+ private _texturesTable;
43
+ /** THREE.TextureLoader instance (created lazily) */
44
+ private _textureLoader;
45
+ /** Whether this cache has been fully disposed */
46
+ private _disposed;
47
+ /**
48
+ * Set or update the root-level textures table.
49
+ *
50
+ * Called when new shape data is loaded. The table maps string keys to
51
+ * TextureEntry objects (embedded base64 data or URL references).
52
+ *
53
+ * @param table - The textures table from root Shapes node, or undefined to clear
54
+ */
55
+ setTexturesTable(table: Record<string, TextureEntry> | undefined): void;
56
+ /**
57
+ * Resolve a texture reference string and return a cached or newly loaded
58
+ * THREE.Texture with the correct colorSpace set.
59
+ *
60
+ * @param ref - Texture reference string (builtin name, table key, data URI, or URL)
61
+ * @param textureRole - The texture role name (MaterialAppearance field name or proxy role)
62
+ * (e.g. "baseColorTexture", "normalTexture"). Used to determine colorSpace.
63
+ * @returns The resolved THREE.Texture, or null if the reference is invalid
64
+ * or loading fails
65
+ */
66
+ get(ref: string, textureRole: string): Promise<THREE.Texture | null>;
67
+ /**
68
+ * Check whether a texture reference string would resolve to a builtin texture.
69
+ */
70
+ isBuiltin(ref: string): boolean;
71
+ /**
72
+ * Dispose user textures (called on viewer.clear() when shape data is replaced).
73
+ *
74
+ * Disposes all textures in the user cache and clears in-flight promises.
75
+ * The builtin procedural texture cache is preserved.
76
+ */
77
+ dispose(): void;
78
+ /**
79
+ * Dispose all textures including builtin procedural textures.
80
+ *
81
+ * Called on viewer.dispose() when the viewer is fully torn down.
82
+ * After this call, the TextureCache cannot be used again.
83
+ */
84
+ disposeFull(): void;
85
+ /**
86
+ * Get or generate a builtin procedural texture.
87
+ *
88
+ * Builtin textures are cached in the persistent `_builtinCache` and survive
89
+ * `dispose()` calls. They are only freed via `disposeFull()`.
90
+ */
91
+ private _getBuiltin;
92
+ /**
93
+ * Load a texture from the root-level textures table entry.
94
+ *
95
+ * Handles both embedded (base64 data) and URL-referenced entries.
96
+ */
97
+ private _getFromTable;
98
+ /**
99
+ * Load a texture from a data URI string.
100
+ */
101
+ private _getFromDataUri;
102
+ /**
103
+ * Load a texture from a URL (resolved relative to the HTML page).
104
+ */
105
+ private _getFromUrl;
106
+ /**
107
+ * Load a texture from a source (URL or data URI), cache it, and return it.
108
+ *
109
+ * Deduplicates in-flight loads for the same cache key.
110
+ *
111
+ * @param cacheKey - Key for the user cache
112
+ * @param source - URL or data URI to load from
113
+ * @param colorSpace - Color space to assign to the loaded texture
114
+ * @returns The loaded texture, or null on failure
115
+ */
116
+ private _loadAndCache;
117
+ /**
118
+ * Perform the actual texture load via THREE.TextureLoader.
119
+ *
120
+ * THREE.TextureLoader handles both URLs and data URIs.
121
+ */
122
+ private _doLoad;
123
+ /**
124
+ * Get or create the THREE.TextureLoader (lazy initialization).
125
+ */
126
+ private _ensureTextureLoader;
127
+ /**
128
+ * Convert a format string (e.g. "png", "jpg", "webp") to a MIME type.
129
+ */
130
+ private _formatToMime;
131
+ }
132
+ /**
133
+ * Get the correct color space for a Three.js material map property name.
134
+ *
135
+ * sRGB maps (color data): map, emissiveMap, sheenColorMap, specularColorMap
136
+ * Linear maps (non-color data): everything else (normalMap, roughnessMap, etc.)
137
+ *
138
+ * @param mapName - Three.js material property name (e.g., "map", "normalMap")
139
+ * @returns THREE.SRGBColorSpace or THREE.LinearSRGBColorSpace
140
+ */
141
+ declare function getColorSpaceForMap(mapName: string): THREE.ColorSpace;
142
+ export { TextureCache, SRGB_TEXTURE_ROLES, BUILTIN_NAMES, getColorSpaceForMap };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Triplanar texture mapping for MeshPhysicalMaterial.
3
+ *
4
+ * Replaces standard UV-based texture sampling with model-space triplanar
5
+ * projection via `material.onBeforeCompile`. Eliminates seams on curved
6
+ * surfaces (cylinders, cones, etc.) and maintains uniform texture scale
7
+ * regardless of object proportions.
8
+ *
9
+ * All coordinates are in **model space** to match the geometry's bounding box.
10
+ * `transformed` (model-space position) and `objectNormal` (model-space normal)
11
+ * are used — NOT the view-space `transformedNormal`.
12
+ *
13
+ * NOTE: `onBeforeCompile` receives shaders BEFORE `#include` resolution.
14
+ * Therefore we replace `#include <chunk_name>` directives with inline GLSL
15
+ * that uses triplanar sampling, rather than replacing expanded texture2D calls.
16
+ *
17
+ * Handles: map, normalMap, roughnessMap, metalnessMap, emissiveMap, aoMap,
18
+ * clearcoatNormalMap, alphaMap.
19
+ */
20
+ import * as THREE from "three";
21
+ /**
22
+ * Apply triplanar texture mapping to a MeshPhysicalMaterial.
23
+ *
24
+ * Modifies the material's shader via `onBeforeCompile` so that all texture
25
+ * lookups use model-space triplanar projection instead of UV coordinates.
26
+ * The material should be a **clone** (not shared) because `onBeforeCompile`
27
+ * and `customProgramCacheKey` are set on it.
28
+ *
29
+ * Bounding box of the geometry determines coordinate normalization: the
30
+ * texture tiles once across the largest dimension with uniform scale,
31
+ * preserving aspect ratio. `textureRepeat` on the material's textures
32
+ * (if set) is respected via the triplanarRepeat uniform.
33
+ *
34
+ * @param material - Material clone to modify
35
+ * @param geometry - Geometry for bounding box computation
36
+ */
37
+ export declare function applyTriplanarMapping(material: THREE.MeshPhysicalMaterial, geometry: THREE.BufferGeometry): void;
@@ -17,7 +17,7 @@ declare class Animation {
17
17
  mixer: THREE.AnimationMixer | null;
18
18
  clip: THREE.AnimationClip | null;
19
19
  clipAction: THREE.AnimationAction | null;
20
- clock: THREE.Clock;
20
+ clock: THREE.Timer;
21
21
  duration: number | null;
22
22
  speed: number | null;
23
23
  repeat: boolean | null;
@@ -68,6 +68,19 @@ interface NestedGroupLike {
68
68
  interface ClippingOptions {
69
69
  onNormalChange?: (index: ClipIndex, normalArray: Vector3Tuple) => void;
70
70
  }
71
+ /**
72
+ * Saved clipping state for mode transitions (e.g., entering/leaving Studio mode).
73
+ * Captures only Clipping-internal state; renderer flags and ViewerState keys
74
+ * are managed by the caller.
75
+ */
76
+ interface ClippingState {
77
+ /** Centered constant (position) for each of the 3 clip planes */
78
+ planeConstants: [number, number, number];
79
+ /** Whether the plane helper meshes (translucent colored rectangles) are visible */
80
+ helperVisible: boolean;
81
+ /** Whether the stencil plane meshes (solid colored caps) are visible */
82
+ planesVisible: boolean;
83
+ }
71
84
  /**
72
85
  * Manages clipping planes, stencil rendering, and plane visualization.
73
86
  */
@@ -149,6 +162,23 @@ declare class Clipping extends THREE.Group {
149
162
  * @param flag - True to show, false to hide.
150
163
  */
151
164
  setVisible: (flag: boolean) => void;
165
+ /**
166
+ * Save the current clipping state for later restoration.
167
+ * Captures plane positions, helper visibility, and stencil plane visibility.
168
+ * Used by Studio mode to snapshot clipping state before disabling clipping.
169
+ *
170
+ * Note: `renderer.localClippingEnabled` and `clipPlaneHelpers` ViewerState
171
+ * are managed by the caller (Display/Viewer layer), not captured here.
172
+ */
173
+ saveState(): ClippingState;
174
+ /**
175
+ * Restore a previously saved clipping state.
176
+ * Re-applies plane positions, helper visibility, and stencil plane visibility.
177
+ * Used by Studio mode when leaving to restore the clipping configuration.
178
+ *
179
+ * @param state - The state previously captured by `saveState()`.
180
+ */
181
+ restoreState(state: ClippingState): void;
152
182
  /**
153
183
  * Clean up resources.
154
184
  * Note: We don't null out arrays/references as GC handles cleanup when the Clipping object is collected.
@@ -156,3 +186,4 @@ declare class Clipping extends THREE.Group {
156
186
  dispose(): void;
157
187
  }
158
188
  export { Clipping };
189
+ export type { ClippingState };