soonspacejs 3.0.0-alpha.12 → 3.0.0-alpha.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "soonspacejs",
3
- "version": "3.0.0-alpha.12",
3
+ "version": "3.0.0-alpha.14",
4
4
  "homepage": "https://www.xwbuilders.com/soonspacejs/",
5
5
  "description": "SoonSpace.js 3.0 alpha",
6
6
  "module": "./dist/index.esm.js",
@@ -0,0 +1,9 @@
1
+ /** Shared per-origin validation admission. Work must own its complete HTTP body. */
2
+ export declare class ModelValidationScheduler {
3
+ private readonly concurrency;
4
+ private pools;
5
+ private sequence;
6
+ constructor(concurrency?: number);
7
+ schedule<T>(origin: string, bytes: number, signal: AbortSignal | undefined, work: () => Promise<T>): Promise<T>;
8
+ private drain;
9
+ }
@@ -2,6 +2,7 @@ import { BufferGeometry, Material, Matrix4, Texture } from 'three';
2
2
  import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
3
3
  import { ModelBufferCache } from '../Cache/ModelBufferCache';
4
4
  import { ParsedModelCacheOptions } from '../Cache/ParsedModelCache';
5
+ import { ParametricOpeningModelDescription, ParametricOpeningLoadOptions } from '../Geometry/ParametricOpenings/opening-model';
5
6
  export interface ModelPart {
6
7
  /** Omitted for triangle meshes. Basic line segments share the Entity lifecycle. */
7
8
  kind?: 'mesh' | 'line-segments';
@@ -67,6 +68,9 @@ export declare class ModelResources {
67
68
  private urls;
68
69
  private gltfLoader;
69
70
  private bufferCache;
71
+ private openingTextures;
72
+ private openingMaterials;
73
+ private openingMaterialKeys;
70
74
  private parsedCacheOptions;
71
75
  private parsedCache;
72
76
  /** Borrow a host-configured loader; its decoder workers remain host-owned. */
@@ -84,6 +88,10 @@ export declare class ModelResources {
84
88
  ownership: 'transfer';
85
89
  }): ModelLease;
86
90
  load(url: string, options?: ModelLoadOptions): Promise<ModelLease>;
91
+ /** Procedural geometry and materials with the same Entity lease/ownership contract as load(). */
92
+ loadOpening(description: ParametricOpeningModelDescription, options?: ParametricOpeningLoadOptions): Promise<ModelLease>;
93
+ private resolveOpening;
94
+ private acquireOpeningMaterial;
87
95
  private resolveLoad;
88
96
  private create;
89
97
  lease<T>(record: ResourceRecord<T>): ResourceLease<T>;
@@ -0,0 +1,55 @@
1
+ import { ParametricWindowType, ParametricOpeningKind, ParametricOpeningMaterialLayout } from './types';
2
+ /** Builder generator defaults. Lengths are metres; angles are radians. */
3
+ export declare const OPENING_GENERATOR_CONSTANTS: Readonly<{
4
+ door: Readonly<{
5
+ frameThick: 0.05;
6
+ glassThick: 0.01;
7
+ leftThick: 0.03;
8
+ rightThick: 0.03;
9
+ glassFrameThick: 0.1;
10
+ openAngle: number;
11
+ doubleDoorRatio: 0.5;
12
+ asymmetricDoorRatio: readonly [0.7, 0.3];
13
+ }>;
14
+ window: Readonly<{
15
+ frameThick: 0.05;
16
+ glassThick: 0.01;
17
+ openAngle: number;
18
+ byType: readonly [Readonly<{
19
+ type: ParametricWindowType.Sliding;
20
+ layerCount: 2;
21
+ windowThick: 0.05;
22
+ }>, Readonly<{
23
+ type: ParametricWindowType.FixedTopSlidingBottom;
24
+ layerCount: 2;
25
+ windowThick: 0.05;
26
+ }>, Readonly<{
27
+ type: ParametricWindowType.Fixed;
28
+ layerCount: 1;
29
+ windowThick: 0.06;
30
+ }>, Readonly<{
31
+ type: ParametricWindowType.Hinged;
32
+ layerCount: 1;
33
+ windowThick: 0.06;
34
+ }>, Readonly<{
35
+ type: ParametricWindowType.Circular;
36
+ layerCount: 1;
37
+ windowThick: 0.06;
38
+ }>, Readonly<{
39
+ type: ParametricWindowType.Vent;
40
+ layerCount: 1;
41
+ windowThick: 0.06;
42
+ }>];
43
+ topWindowRate: number;
44
+ roundSegments: 40;
45
+ }>;
46
+ elevatorDoor: Readonly<{
47
+ gap: 0.01;
48
+ leafWidthExtra: 0.05;
49
+ /** Caller applies this offset when placing a floor's door. */
50
+ floorHeightOffset: 0.01;
51
+ uvTileLength: 1;
52
+ }>;
53
+ }>;
54
+ /** Original Builder slots, including reserved defaults and unused materials. */
55
+ export declare function getOpeningMaterialLayout(kind: ParametricOpeningKind, type?: number): ParametricOpeningMaterialLayout;
@@ -0,0 +1,6 @@
1
+ import { ParametricDoorGeometryOptions, ParametricOpeningGeometryPart } from './types';
2
+ /**
3
+ * Ordinary Builder door geometry, in metres. No scene, materials or animation
4
+ * objects are created. Every call returns new caller-owned geometry and poses.
5
+ */
6
+ export declare function createDoorGeometryParts(options: ParametricDoorGeometryOptions): ParametricOpeningGeometryPart[];
@@ -0,0 +1,3 @@
1
+ import { ParametricElevatorDoorGeometryOptions, ParametricOpeningGeometryPart } from './types';
2
+ /** Two closed floor leaves in local coordinates; caller owns floor placement. */
3
+ export declare function createElevatorDoorGeometryParts(options: ParametricElevatorDoorGeometryOptions): ParametricOpeningGeometryPart[];
@@ -0,0 +1,8 @@
1
+ export { createDoorGeometryParts, } from './door';
2
+ export { createWindowGeometryParts, } from './window';
3
+ export { createElevatorDoorGeometryParts, } from './elevator';
4
+ export { OPENING_GENERATOR_CONSTANTS, getOpeningMaterialLayout, } from './constants';
5
+ export * from './types';
6
+ export { DEFAULT_OPENING_MATERIALS, resolveOpeningMaterialDescription, applyOpeningTextureTransform, createOpeningMaterial, } from './materials';
7
+ export type { OpeningMaterialDescription, } from './materials';
8
+ export type { ParametricOpeningModelDescription, ParametricOpeningLoadOptions, } from './opening-model';
@@ -0,0 +1,33 @@
1
+ import { MeshPhongMaterial, MeshStandardMaterial, Texture } from 'three';
2
+ /** Builder material values. Rotation is in degrees; SCALE is inverse UV scale. */
3
+ export interface OpeningMaterialDescription {
4
+ textureFile?: string | null;
5
+ ambient?: readonly number[];
6
+ diffuse?: readonly number[];
7
+ opacity?: number;
8
+ scale?: readonly number[];
9
+ scroll?: readonly number[];
10
+ rotation?: number;
11
+ full?: number | boolean;
12
+ cullingMode?: number;
13
+ alphaBlendMode?: number;
14
+ depthBias?: readonly number[];
15
+ metalness?: number;
16
+ roughness?: number;
17
+ emissive?: readonly number[];
18
+ /** Explicit Builder specular lighting selects Phong, including custom material names. */
19
+ shininess?: number;
20
+ specular?: readonly number[];
21
+ }
22
+ type NormalizedOpeningMaterialDescription = Required<Omit<OpeningMaterialDescription, 'shininess' | 'specular'>> & Pick<OpeningMaterialDescription, 'shininess' | 'specular'> & {
23
+ full: boolean;
24
+ };
25
+ /** Opening entries from Builder's DefaultMaterial.ini, plus its fixed elevator material. */
26
+ export declare const DEFAULT_OPENING_MATERIALS: Readonly<Record<string, Readonly<NormalizedOpeningMaterialDescription>>>;
27
+ /** Returns copied RGB tuples and explicit opacity; omitted fields retain their preset. */
28
+ export declare function resolveOpeningMaterialDescription(name: string, input?: OpeningMaterialDescription): NormalizedOpeningMaterialDescription;
29
+ /** Configures only the supplied, caller-owned sampler; this helper never fetches images. */
30
+ export declare function applyOpeningTextureTransform(texture: Texture, description: OpeningMaterialDescription): void;
31
+ /** Creates an independent material. The caller provides and owns any fresh texture sampler. */
32
+ export declare function createOpeningMaterial(name: string, description?: OpeningMaterialDescription, texture?: Texture, textureAlpha?: 'opaque' | 'cutout' | 'blend'): MeshStandardMaterial | MeshPhongMaterial;
33
+ export {};
@@ -0,0 +1,42 @@
1
+ import { Matrix4 } from 'three';
2
+ import { ParametricOpeningGeometryOptions, ParametricOpeningGeometryPart, ParametricOpeningPartRole } from './types';
3
+ export type Point = readonly [number, number, number];
4
+ export interface Rect {
5
+ left: number;
6
+ right: number;
7
+ bottom: number;
8
+ top: number;
9
+ }
10
+ export interface Solid extends Rect {
11
+ front: number;
12
+ back: number;
13
+ }
14
+ export declare const FRAME: 0.05;
15
+ export declare const GLASS: 0.01;
16
+ /** Semantic face writer: every emitted face owns its normals and UV seam. */
17
+ export declare class OpeningMesh {
18
+ readonly name: string;
19
+ readonly materialSlot: number;
20
+ readonly role: ParametricOpeningPartRole;
21
+ readonly matrix: Matrix4;
22
+ private positions;
23
+ private normals;
24
+ private uvs;
25
+ private indices;
26
+ constructor(name: string, materialSlot: number, role: ParametricOpeningPartRole, matrix?: Matrix4);
27
+ quad(points: readonly Point[], normal: Point, uvs?: readonly number[]): void;
28
+ triangle(points: readonly Point[], normal: Point, uv: readonly number[]): void;
29
+ compile(): ParametricOpeningGeometryPart | null;
30
+ }
31
+ export declare function compileParts(writers: OpeningMesh[]): ParametricOpeningGeometryPart[];
32
+ export declare function validateOptions(options: ParametricOpeningGeometryOptions, maximumType: number): void;
33
+ export declare function assertRect(rect: Rect): void;
34
+ /** UVs follow the reference's top-left origin; back faces mirror U. */
35
+ export declare function faceXY(writer: OpeningMesh, rect: Rect, z: number, front: boolean, uvRect?: Rect, mirrorU?: boolean): void;
36
+ export declare function boxSides(writer: OpeningMesh, box: Solid): void;
37
+ /** One continuous extruded frame with vertically stacked real apertures. */
38
+ export declare function shell(writer: OpeningMesh, outer: Solid, holes: Rect[]): void;
39
+ export declare function glass(writer: OpeningMesh, rect: Rect, back?: number, front?: number): void;
40
+ export declare function pose(x: number, y: number, z: number, angle?: number): Matrix4;
41
+ export declare function sash(writers: OpeningMesh[], name: string, outer: Solid, matrix: Matrix4): void;
42
+ export declare function slidingLeaves(writers: OpeningMesh[], inner: Solid, open: boolean): void;
@@ -0,0 +1,50 @@
1
+ import { resolveOpeningMaterialDescription, OpeningMaterialDescription } from './materials';
2
+ import { MaterialLease, ModelPart } from '../../Entity/ModelResources';
3
+ import { ParametricDoorGeometryOptions, ParametricWindowGeometryOptions, ParametricElevatorDoorGeometryOptions, ParametricOpeningGeometryPart } from './types';
4
+ interface MaterialBindings {
5
+ partMaterials?: readonly {
6
+ slot: number;
7
+ material: string;
8
+ }[];
9
+ /** Partial material overrides. Explicit null/empty textureFile means no texture. */
10
+ materials?: Readonly<Record<string, OpeningMaterialDescription>>;
11
+ }
12
+ export type ParametricOpeningModelDescription = MaterialBindings & ({
13
+ kind: 'door';
14
+ parameters: ParametricDoorGeometryOptions;
15
+ } | {
16
+ kind: 'window';
17
+ parameters: ParametricWindowGeometryOptions;
18
+ } | {
19
+ kind: 'elevator-door';
20
+ parameters: ParametricElevatorDoorGeometryOptions;
21
+ });
22
+ export interface ParametricOpeningLoadOptions {
23
+ signal?: AbortSignal;
24
+ /** Resolve metadata references/default image names into a URL. No filesystem assumptions. */
25
+ resolveTexture?: (reference: string, materialName: string) => string | null | undefined;
26
+ headers?: HeadersInit;
27
+ credentials?: RequestCredentials;
28
+ }
29
+ export interface OpeningMaterialBinding {
30
+ name: string;
31
+ description: ReturnType<typeof resolveOpeningMaterialDescription>;
32
+ url?: string;
33
+ headers: Headers;
34
+ }
35
+ export interface PreparedOpening {
36
+ key: string;
37
+ geometry: () => ParametricOpeningGeometryPart[];
38
+ bindings: Map<number, OpeningMaterialBinding>;
39
+ credentials: RequestCredentials;
40
+ }
41
+ /** Snapshot caller data and resolved/authenticated image identities before awaiting. */
42
+ export declare function prepareOpening(input: ParametricOpeningModelDescription, options: ParametricOpeningLoadOptions, managerResolve?: (url: string) => string): PreparedOpening;
43
+ /** Candidate is either transferred atomically to ModelResources or disposed once. */
44
+ export declare function openingMaterialKey(binding: OpeningMaterialBinding, credentials: RequestCredentials): string;
45
+ export declare function buildOpening(prepared: PreparedOpening, acquire: (binding: OpeningMaterialBinding, credentials: RequestCredentials, signal: AbortSignal) => Promise<MaterialLease>, signal: AbortSignal): Promise<{
46
+ parts: ModelPart[];
47
+ releaseMaterials: () => void;
48
+ dispose: () => void;
49
+ }>;
50
+ export {};
@@ -0,0 +1,22 @@
1
+ import { Texture } from 'three';
2
+ import { ModelBufferCache } from '../../Cache/ModelBufferCache';
3
+ export type OpeningTextureAlpha = 'opaque' | 'cutout' | 'blend';
4
+ export declare const openingAbort: () => DOMException;
5
+ export declare function openingHeaderPairs(headers: Headers): [string, string][];
6
+ /** Image classification is cached with the live decoded pixels, never scanned per frame. */
7
+ export declare function classifyOpeningAlpha(rgba: Uint8ClampedArray, name?: string): OpeningTextureAlpha;
8
+ /** Registry-owned image pool. Texture objects/sources stay independent per material. */
9
+ export declare class OpeningTexturePool {
10
+ private cache;
11
+ private pixels;
12
+ private pending;
13
+ private disposed;
14
+ constructor(cache: () => ModelBufferCache);
15
+ private sampler;
16
+ acquire(url: string, headers: Headers, credentials: RequestCredentials, signal: AbortSignal): Promise<{
17
+ texture: Texture;
18
+ alpha: OpeningTextureAlpha;
19
+ }>;
20
+ private read;
21
+ dispose(): void;
22
+ }
@@ -0,0 +1,73 @@
1
+ import { BufferGeometry, Matrix4 } from 'three';
2
+ /** Builder's door type IDs. These IDs are not shared with window types. */
3
+ export declare enum ParametricDoorType {
4
+ SingleHinged = 0,
5
+ SingleHingedGlass = 1,
6
+ DoubleSwing = 2,
7
+ AsymmetricDoubleHinged = 3,
8
+ DoubleSwingGlass = 4,
9
+ DoubleSwingTwoGlass = 5,
10
+ DoubleHinged = 6,
11
+ Opening = 7,
12
+ Sliding = 8,
13
+ RollUp = 9
14
+ }
15
+ export declare enum ParametricWindowType {
16
+ Sliding = 0,
17
+ FixedTopSlidingBottom = 1,
18
+ Fixed = 2,
19
+ Hinged = 3,
20
+ Opening = 4,
21
+ Circular = 5,
22
+ Vent = 6
23
+ }
24
+ export type ParametricOpeningKind = 'door' | 'window' | 'elevator-door';
25
+ export interface ParametricOpeningMaterialSlot {
26
+ readonly materialSlot: number;
27
+ readonly defaultMaterialTitle: string;
28
+ readonly userAssignable: boolean;
29
+ }
30
+ export interface ParametricOpeningMaterialLayout {
31
+ readonly frameSlotIndex: number;
32
+ readonly faceSlotIndex: number;
33
+ readonly slots: readonly ParametricOpeningMaterialSlot[];
34
+ }
35
+ export interface ParametricOpeningGeometryOptions {
36
+ /** Metres. Local X is width, Y is up; the opening bottom is Y=0. */
37
+ width: number;
38
+ height: number;
39
+ /** 0: pivot at local -X; 1: pivot at +X. Default 0. */
40
+ hingePosition?: 0 | 1;
41
+ /** Static pose, default false. No animation or frame listener is installed. */
42
+ open?: boolean;
43
+ }
44
+ export interface ParametricDoorGeometryOptions extends ParametricOpeningGeometryOptions {
45
+ type: ParametricDoorType;
46
+ /** Actual additional height in metres, default 0. Not the legacy 0/1 flag. */
47
+ topWindowHeight?: number;
48
+ }
49
+ export interface ParametricWindowGeometryOptions extends ParametricOpeningGeometryOptions {
50
+ type: ParametricWindowType;
51
+ }
52
+ /** One floor's closed outer elevator leaves. Dimensions are metres. */
53
+ export interface ParametricElevatorDoorGeometryOptions {
54
+ doorWidth: number;
55
+ /** Combined two-layer door depth, greater than the generator's depth gap. */
56
+ doorDepth: number;
57
+ /** Exterior elevator depth; zero is allowed. */
58
+ outDepth: number;
59
+ outHeight: number;
60
+ /** Shaft wall thickness; zero is allowed. */
61
+ wallThick: number;
62
+ }
63
+ export type ParametricOpeningPartRole = 'frame' | 'panel' | 'glass' | 'transom-glass' | 'vent';
64
+ /** Caller owns the geometry. Transfer it to ModelResources or dispose it once. */
65
+ export interface ParametricOpeningGeometryPart {
66
+ name: string;
67
+ geometry: BufferGeometry;
68
+ /** Local part pose, independent from the scene node's transform. */
69
+ matrix: Matrix4;
70
+ /** Builder slot: door 0/1/2, window 1/2/3, elevator 0. -1 is untagged transom glass. */
71
+ materialSlot: number;
72
+ role: ParametricOpeningPartRole;
73
+ }
@@ -0,0 +1,3 @@
1
+ import { ParametricWindowGeometryOptions, ParametricOpeningGeometryPart } from './types';
2
+ /** Builder window geometry (types 0–6), with metre dimensions and local poses. */
3
+ export declare function createWindowGeometryParts(options: ParametricWindowGeometryOptions): ParametricOpeningGeometryPart[];
package/types/index.d.ts CHANGED
@@ -880,6 +880,9 @@ export declare interface AnimationOptions {
880
880
  */
881
881
  declare type AnimationPath = IVector3[] | Curve<Vector3> | Topology;
882
882
 
883
+ /** Configures only the supplied, caller-owned sampler; this helper never fetches images. */
884
+ export declare function applyOpeningTextureTransform(texture: Texture, description: OpeningMaterialDescription): void;
885
+
883
886
  declare function approxEquals(a: number, b: number, error?: number): boolean;
884
887
 
885
888
  declare function approxZero(number: number, error?: number): boolean;
@@ -1706,6 +1709,15 @@ export declare interface CreateCurveAnimationClipReturn {
1706
1709
  lengths: number[] | undefined;
1707
1710
  }
1708
1711
 
1712
+ /**
1713
+ * Ordinary Builder door geometry, in metres. No scene, materials or animation
1714
+ * objects are created. Every call returns new caller-owned geometry and poses.
1715
+ */
1716
+ export declare function createDoorGeometryParts(options: ParametricDoorGeometryOptions): ParametricOpeningGeometryPart[];
1717
+
1718
+ /** Two closed floor leaves in local coordinates; caller owns floor placement. */
1719
+ export declare function createElevatorDoorGeometryParts(options: ParametricElevatorDoorGeometryOptions): ParametricOpeningGeometryPart[];
1720
+
1709
1721
  /**
1710
1722
  * 创建等分链式骨骼
1711
1723
  * @param boneOpts - 等分链式骨骼的选项
@@ -1835,6 +1847,9 @@ export declare function createKeyframeTracksOfCurveAnimationByPolyline(options:
1835
1847
  curveLength: number;
1836
1848
  };
1837
1849
 
1850
+ /** Creates an independent material. The caller provides and owns any fresh texture sampler. */
1851
+ export declare function createOpeningMaterial(name: string, description?: OpeningMaterialDescription, texture?: Texture, textureAlpha?: 'opaque' | 'cutout' | 'blend'): MeshStandardMaterial | MeshPhongMaterial;
1852
+
1838
1853
  declare type CreatePathAnimationActionForCameraOptions = CreatePathAnimationActionForCameraOptions_Base & CreatePathAnimationOptions;
1839
1854
 
1840
1855
  declare interface CreatePathAnimationActionForCameraOptions_Base {
@@ -1865,6 +1880,9 @@ declare function createTextureLoader(manager?: LoadingManager): TextureLoader;
1865
1880
  */
1866
1881
  export declare function createUVMatrix(box: Box2): Matrix3;
1867
1882
 
1883
+ /** Builder window geometry (types 0–6), with metre dimensions and local poses. */
1884
+ export declare function createWindowGeometryParts(options: ParametricWindowGeometryOptions): ParametricOpeningGeometryPart[];
1885
+
1868
1886
  declare class CSS2DRenderer {
1869
1887
  readonly viewport: Viewport;
1870
1888
  domElement: HTMLElement;
@@ -1980,6 +1998,9 @@ export declare enum DecalUVMapType {
1980
1998
  Original = 5
1981
1999
  }
1982
2000
 
2001
+ /** Opening entries from Builder's DefaultMaterial.ini, plus its fixed elevator material. */
2002
+ export declare const DEFAULT_OPENING_MATERIALS: Readonly<Record<string, Readonly<NormalizedOpeningMaterialDescription>>>;
2003
+
1983
2004
  declare class DefaultManage {
1984
2005
  readonly type: string;
1985
2006
  readonly viewport: Viewport;
@@ -2695,6 +2716,9 @@ export declare interface GetKeyframeTransformDatasOptionsByCurve_Base extends Ge
2695
2716
  us?: number[];
2696
2717
  }
2697
2718
 
2719
+ /** Original Builder slots, including reserved defaults and unused materials. */
2720
+ export declare function getOpeningMaterialLayout(kind: ParametricOpeningKind, type?: number): ParametricOpeningMaterialLayout;
2721
+
2698
2722
  export declare function getPolygonGeometryInfo(points: Vector3[]): {
2699
2723
  geometry: ShapeGeometry;
2700
2724
  polygonBox: Box2;
@@ -3455,6 +3479,15 @@ declare interface ManagerStore {
3455
3479
  pluginObjectManager: PluginManage;
3456
3480
  }
3457
3481
 
3482
+ declare interface MaterialBindings {
3483
+ partMaterials?: readonly {
3484
+ slot: number;
3485
+ material: string;
3486
+ }[];
3487
+ /** Partial material overrides. Explicit null/empty textureFile means no texture. */
3488
+ materials?: Readonly<Record<string, OpeningMaterialDescription>>;
3489
+ }
3490
+
3458
3491
  export declare interface MaterialEffectOptionItem {
3459
3492
  type: keyof MaterialEffectOptions;
3460
3493
  option: MaterialEffectOptions[keyof MaterialEffectOptions] | null;
@@ -3734,6 +3767,9 @@ export declare class ModelResources {
3734
3767
  private urls;
3735
3768
  private gltfLoader;
3736
3769
  private bufferCache;
3770
+ private openingTextures;
3771
+ private openingMaterials;
3772
+ private openingMaterialKeys;
3737
3773
  private parsedCacheOptions;
3738
3774
  private parsedCache;
3739
3775
  /** Borrow a host-configured loader; its decoder workers remain host-owned. */
@@ -3751,6 +3787,10 @@ export declare class ModelResources {
3751
3787
  ownership: 'transfer';
3752
3788
  }): ModelLease;
3753
3789
  load(url: string, options?: ModelLoadOptions): Promise<ModelLease>;
3790
+ /** Procedural geometry and materials with the same Entity lease/ownership contract as load(). */
3791
+ loadOpening(description: ParametricOpeningModelDescription, options?: ParametricOpeningLoadOptions): Promise<ModelLease>;
3792
+ private resolveOpening;
3793
+ private acquireOpeningMaterial;
3754
3794
  private resolveLoad;
3755
3795
  private create;
3756
3796
  lease<T>(record: ResourceRecord<T>): ResourceLease<T>;
@@ -3797,6 +3837,10 @@ export declare interface NodeInfo extends PointInfo {
3797
3837
  graphs: TopologyNodeGraph[];
3798
3838
  }
3799
3839
 
3840
+ declare type NormalizedOpeningMaterialDescription = Required<Omit<OpeningMaterialDescription, 'shininess' | 'specular'>> & Pick<OpeningMaterialDescription, 'shininess' | 'specular'> & {
3841
+ full: boolean;
3842
+ };
3843
+
3800
3844
  /**
3801
3845
  * 通用对象事件参数
3802
3846
  */
@@ -3854,6 +3898,80 @@ export declare interface OffsetPoint {
3854
3898
 
3855
3899
  export declare type OpacitySelectOptions = BaseSelectOptions;
3856
3900
 
3901
+ /** Builder generator defaults. Lengths are metres; angles are radians. */
3902
+ export declare const OPENING_GENERATOR_CONSTANTS: Readonly<{
3903
+ door: Readonly<{
3904
+ frameThick: 0.05;
3905
+ glassThick: 0.01;
3906
+ leftThick: 0.03;
3907
+ rightThick: 0.03;
3908
+ glassFrameThick: 0.1;
3909
+ openAngle: number;
3910
+ doubleDoorRatio: 0.5;
3911
+ asymmetricDoorRatio: readonly [0.7, 0.3];
3912
+ }>;
3913
+ window: Readonly<{
3914
+ frameThick: 0.05;
3915
+ glassThick: 0.01;
3916
+ openAngle: number;
3917
+ byType: readonly [Readonly<{
3918
+ type: ParametricWindowType.Sliding;
3919
+ layerCount: 2;
3920
+ windowThick: 0.05;
3921
+ }>, Readonly<{
3922
+ type: ParametricWindowType.FixedTopSlidingBottom;
3923
+ layerCount: 2;
3924
+ windowThick: 0.05;
3925
+ }>, Readonly<{
3926
+ type: ParametricWindowType.Fixed;
3927
+ layerCount: 1;
3928
+ windowThick: 0.06;
3929
+ }>, Readonly<{
3930
+ type: ParametricWindowType.Hinged;
3931
+ layerCount: 1;
3932
+ windowThick: 0.06;
3933
+ }>, Readonly<{
3934
+ type: ParametricWindowType.Circular;
3935
+ layerCount: 1;
3936
+ windowThick: 0.06;
3937
+ }>, Readonly<{
3938
+ type: ParametricWindowType.Vent;
3939
+ layerCount: 1;
3940
+ windowThick: 0.06;
3941
+ }>];
3942
+ topWindowRate: number;
3943
+ roundSegments: 40;
3944
+ }>;
3945
+ elevatorDoor: Readonly<{
3946
+ gap: 0.01;
3947
+ leafWidthExtra: 0.05;
3948
+ /** Caller applies this offset when placing a floor's door. */
3949
+ floorHeightOffset: 0.01;
3950
+ uvTileLength: 1;
3951
+ }>;
3952
+ }>;
3953
+
3954
+ /** Builder material values. Rotation is in degrees; SCALE is inverse UV scale. */
3955
+ export declare interface OpeningMaterialDescription {
3956
+ textureFile?: string | null;
3957
+ ambient?: readonly number[];
3958
+ diffuse?: readonly number[];
3959
+ opacity?: number;
3960
+ scale?: readonly number[];
3961
+ scroll?: readonly number[];
3962
+ rotation?: number;
3963
+ full?: number | boolean;
3964
+ cullingMode?: number;
3965
+ alphaBlendMode?: number;
3966
+ depthBias?: readonly number[];
3967
+ metalness?: number;
3968
+ roughness?: number;
3969
+ emissive?: readonly number[];
3970
+ /** Explicit Builder specular lighting selects Phong, including custom material names. */
3971
+ shininess?: number;
3972
+ specular?: readonly number[];
3973
+ }
3974
+
3857
3975
  export declare interface OrbitControlsOptions {
3858
3976
  type: OrbitControlsType;
3859
3977
  enableAutoRotate?: boolean;
@@ -3883,6 +4001,108 @@ export declare type OrbitControlsProperties = Required<Omit<OrbitControlsOptions
3883
4001
 
3884
4002
  export declare type OrbitControlsType = 'orbit';
3885
4003
 
4004
+ export declare interface ParametricDoorGeometryOptions extends ParametricOpeningGeometryOptions {
4005
+ type: ParametricDoorType;
4006
+ /** Actual additional height in metres, default 0. Not the legacy 0/1 flag. */
4007
+ topWindowHeight?: number;
4008
+ }
4009
+
4010
+ /** Builder's door type IDs. These IDs are not shared with window types. */
4011
+ export declare enum ParametricDoorType {
4012
+ SingleHinged = 0,
4013
+ SingleHingedGlass = 1,
4014
+ DoubleSwing = 2,
4015
+ AsymmetricDoubleHinged = 3,
4016
+ DoubleSwingGlass = 4,
4017
+ DoubleSwingTwoGlass = 5,
4018
+ DoubleHinged = 6,
4019
+ Opening = 7,
4020
+ Sliding = 8,
4021
+ RollUp = 9
4022
+ }
4023
+
4024
+ /** One floor's closed outer elevator leaves. Dimensions are metres. */
4025
+ export declare interface ParametricElevatorDoorGeometryOptions {
4026
+ doorWidth: number;
4027
+ /** Combined two-layer door depth, greater than the generator's depth gap. */
4028
+ doorDepth: number;
4029
+ /** Exterior elevator depth; zero is allowed. */
4030
+ outDepth: number;
4031
+ outHeight: number;
4032
+ /** Shaft wall thickness; zero is allowed. */
4033
+ wallThick: number;
4034
+ }
4035
+
4036
+ export declare interface ParametricOpeningGeometryOptions {
4037
+ /** Metres. Local X is width, Y is up; the opening bottom is Y=0. */
4038
+ width: number;
4039
+ height: number;
4040
+ /** 0: pivot at local -X; 1: pivot at +X. Default 0. */
4041
+ hingePosition?: 0 | 1;
4042
+ /** Static pose, default false. No animation or frame listener is installed. */
4043
+ open?: boolean;
4044
+ }
4045
+
4046
+ /** Caller owns the geometry. Transfer it to ModelResources or dispose it once. */
4047
+ export declare interface ParametricOpeningGeometryPart {
4048
+ name: string;
4049
+ geometry: BufferGeometry;
4050
+ /** Local part pose, independent from the scene node's transform. */
4051
+ matrix: Matrix4;
4052
+ /** Builder slot: door 0/1/2, window 1/2/3, elevator 0. -1 is untagged transom glass. */
4053
+ materialSlot: number;
4054
+ role: ParametricOpeningPartRole;
4055
+ }
4056
+
4057
+ export declare type ParametricOpeningKind = 'door' | 'window' | 'elevator-door';
4058
+
4059
+ export declare interface ParametricOpeningLoadOptions {
4060
+ signal?: AbortSignal;
4061
+ /** Resolve metadata references/default image names into a URL. No filesystem assumptions. */
4062
+ resolveTexture?: (reference: string, materialName: string) => string | null | undefined;
4063
+ headers?: HeadersInit;
4064
+ credentials?: RequestCredentials;
4065
+ }
4066
+
4067
+ export declare interface ParametricOpeningMaterialLayout {
4068
+ readonly frameSlotIndex: number;
4069
+ readonly faceSlotIndex: number;
4070
+ readonly slots: readonly ParametricOpeningMaterialSlot[];
4071
+ }
4072
+
4073
+ export declare interface ParametricOpeningMaterialSlot {
4074
+ readonly materialSlot: number;
4075
+ readonly defaultMaterialTitle: string;
4076
+ readonly userAssignable: boolean;
4077
+ }
4078
+
4079
+ export declare type ParametricOpeningModelDescription = MaterialBindings & ({
4080
+ kind: 'door';
4081
+ parameters: ParametricDoorGeometryOptions;
4082
+ } | {
4083
+ kind: 'window';
4084
+ parameters: ParametricWindowGeometryOptions;
4085
+ } | {
4086
+ kind: 'elevator-door';
4087
+ parameters: ParametricElevatorDoorGeometryOptions;
4088
+ });
4089
+
4090
+ export declare type ParametricOpeningPartRole = 'frame' | 'panel' | 'glass' | 'transom-glass' | 'vent';
4091
+
4092
+ export declare interface ParametricWindowGeometryOptions extends ParametricOpeningGeometryOptions {
4093
+ type: ParametricWindowType;
4094
+ }
4095
+
4096
+ export declare enum ParametricWindowType {
4097
+ Sliding = 0,
4098
+ FixedTopSlidingBottom = 1,
4099
+ Fixed = 2,
4100
+ Hinged = 3,
4101
+ Opening = 4,
4102
+ Circular = 5,
4103
+ Vent = 6
4104
+ }
4105
+
3886
4106
  /** Parsed-cache evidence is bounded and contains no URLs, headers or exception text. */
3887
4107
  export declare interface ParsedModelCacheDiagnostic {
3888
4108
  key: string;
@@ -4327,6 +4547,9 @@ declare type RequestInit_2 = {
4327
4547
  redirect?: RequestRedirect;
4328
4548
  };
4329
4549
 
4550
+ /** Returns copied RGB tuples and explicit opacity; omitted fields retain their preset. */
4551
+ export declare function resolveOpeningMaterialDescription(name: string, input?: OpeningMaterialDescription): NormalizedOpeningMaterialDescription;
4552
+
4330
4553
  export declare class ResourceLease<T> {
4331
4554
  readonly registry: ModelResources;
4332
4555
  private record;