@sw-file-lib/three 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Teinishi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,536 @@
1
+ import * as THREE from "three";
2
+ import { BufferGeometry } from "three";
3
+ import { Color } from "@sw-file-lib/core/color";
4
+ import { BinaryReaderInput, MeshData, PhysData, PhysGroup } from "@sw-file-lib/core";
5
+ import { ComponentDefinitionImmutable, ComponentDefinitionSchemas, VehicleSchemas } from "@sw-file-lib/xml";
6
+ import { BuildSurfaceGeometryOptions, GeometryBuilder } from "@sw-file-lib/geometry";
7
+ //#region src/geometry.d.ts
8
+ /**
9
+ * Transfers the contents of a {@link GeometryBuilder} into a `THREE.BufferGeometry`.
10
+ *
11
+ * This function clears the existing attributes and groups of the buffer geometry,
12
+ * then copies the position, normal, color, index, and group data from the builder.
13
+ *
14
+ * @param builder The source geometry builder.
15
+ * @param buffer The target buffer geometry.
16
+ */
17
+ declare function applyBuilderOnBufferGeometry(builder: GeometryBuilder, buffer: BufferGeometry): void;
18
+ /**
19
+ * Creates a new `THREE.BufferGeometry` from a {@link GeometryBuilder}.
20
+ */
21
+ declare function bufferGeometryFromBuilder(builder: GeometryBuilder): BufferGeometry;
22
+ //#endregion
23
+ //#region src/lights.d.ts
24
+ /** Options used when creating the default Stormworks-style lights. */
25
+ interface CreateSwLightsOptions {
26
+ /** Intensity of the hemisphere light. Defaults to `1.6`. */
27
+ readonly hemisphereIntensity?: number;
28
+ /** Intensity of the directional light. Defaults to `1.0`. */
29
+ readonly directionalIntensity?: number;
30
+ }
31
+ /**
32
+ * Create the default Stormworks-style light objects.
33
+ *
34
+ * The returned array contains a hemisphere light and a directional light.
35
+ */
36
+ declare function createSwLights(options?: CreateSwLightsOptions): [THREE.HemisphereLight, THREE.DirectionalLight];
37
+ /** Create a group containing the default Stormworks-style lights. */
38
+ declare function createSwLightGroup(options?: CreateSwLightsOptions): THREE.Group;
39
+ //#endregion
40
+ //#region src/material/uniformController.d.ts
41
+ declare const CREATE: unique symbol;
42
+ declare const ATTACH: unique symbol;
43
+ type UniformTransformer<T> = {
44
+ toUniform(value: T): any;
45
+ fromUniform(value: any): T | undefined;
46
+ };
47
+ type UniformTransformerMap<T> = { [K in keyof T]: UniformTransformer<T[K]>; };
48
+ /**
49
+ * Manages shader uniforms for a material.
50
+ */
51
+ declare class UniformController<T extends object> {
52
+ private transformers;
53
+ private pending;
54
+ private shaderUniforms?;
55
+ /** @hidden */
56
+ static [CREATE]<T extends object>(transformers: UniformTransformerMap<T>): UniformController<T>;
57
+ private constructor();
58
+ /** @hidden */
59
+ [ATTACH](shader: Record<string, THREE.IUniform>): void;
60
+ /** Gets the value of a uniform. */
61
+ get<K extends keyof T>(key: K): T[K] | undefined;
62
+ /** Sets the value of a uniform. */
63
+ set<K extends keyof T>(key: K, value: T[K]): void;
64
+ /** Patches multiple uniforms at once. */
65
+ patch(values: Partial<T>): void;
66
+ }
67
+ //#endregion
68
+ //#region src/material/additive.d.ts
69
+ /** Uniforms used by the additive material. */
70
+ interface AdditiveUniforms {
71
+ /**
72
+ * Whether to override the vertex colors with a single color.
73
+ *
74
+ * When enabled, the `overrideColor` uniform is used instead of the vertex colors.
75
+ */
76
+ overrideColorEnabled: boolean;
77
+ /** The color to use when `overrideColorEnabled` is true. */
78
+ overrideColor: Color;
79
+ }
80
+ /**
81
+ * Manages shader uniforms for the additive material.
82
+ *
83
+ * This can be created using {@link createAdditiveUniforms} and attached to a material using {@link createAdditiveMaterial}.
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * const additiveUniforms: AdditiveUniformController = createAdditiveUniforms();
88
+ *
89
+ * additiveUniforms.set("overrideColorEnabled", true);
90
+ * additiveUniforms.set("overrideColor", { r: 255, g: 0, b: 0 });
91
+ * ```
92
+ */
93
+ type AdditiveUniformController = UniformController<AdditiveUniforms>;
94
+ /**
95
+ * Create the default uniforms used for additive materials.
96
+ *
97
+ * An additive material can be created using {@link createAdditiveMaterial}.
98
+ *
99
+ * The default uniforms are:
100
+ * - `overrideColorEnabled`: true
101
+ * - `overrideColor`: white
102
+ *
103
+ * @example
104
+ * ```ts
105
+ * const additiveUniforms = createAdditiveUniforms({
106
+ * overrideColorEnabled: false
107
+ * });
108
+ *
109
+ * const additiveMaterial = createAdditiveMaterial(additiveUniforms);
110
+ * ```
111
+ */
112
+ declare function createAdditiveUniforms(defaults?: Partial<AdditiveUniforms>): AdditiveUniformController;
113
+ /**
114
+ * Create an additive material used for materialIndex 2 groups.
115
+ *
116
+ * If you want to use custom uniforms, you can create them using {@link createAdditiveUniforms} and pass them to this function.
117
+ *
118
+ * You can override the material parameters by passing a `THREE.MeshBasicMaterialParameters` object as the second argument.
119
+ *
120
+ * @returns A new `THREE.MeshBasicMaterial` with the specified uniforms, or a default one if not provided.
121
+ */
122
+ declare function createAdditiveMaterial(uniforms?: AdditiveUniformController | undefined | null, materialParameters?: THREE.MeshBasicMaterialParameters): THREE.MeshBasicMaterial;
123
+ //#endregion
124
+ //#region src/material/glass.d.ts
125
+ /** Uniforms used by the glass material. */
126
+ interface GlassUniforms {
127
+ /** The color of the reflection of the sky when looking up. */
128
+ skyColorUp: Color;
129
+ /** The color of the reflection of the sky when looking down. */
130
+ skyColorDown: Color;
131
+ }
132
+ /**
133
+ * Manages shader uniforms for the glass material.
134
+ *
135
+ * This can be created using {@link createGlassUniforms} and attached to a material using {@link createGlassMaterial}.
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * const glassUniforms: GlassUniformController = createGlassUniforms();
140
+ *
141
+ * glassUniforms.set("skyColorUp", { r: 0, g: 61, b: 182 });
142
+ * glassUniforms.set("skyColorDown", { r: 139, g: 210, b: 207 });
143
+ * ```
144
+ */
145
+ type GlassUniformController = UniformController<GlassUniforms>;
146
+ /**
147
+ * Create the default uniforms used for glass materials.
148
+ *
149
+ * A glass material can be created using {@link createGlassMaterial}.
150
+ *
151
+ * The default uniforms are:
152
+ * - `skyColorUp`: { r: 0, g: 61, b: 182 }
153
+ * - `skyColorDown`: { r: 139, g: 210, b: 207 }
154
+ *
155
+ * @example
156
+ * ```ts
157
+ * const glassUniforms = createGlassUniforms({
158
+ * skyColorUp: { r: 0, g: 61, b: 182 },
159
+ * skyColorDown: { r: 139, g: 210, b: 207 }
160
+ * });
161
+ *
162
+ * const glassMaterial = createGlassMaterial(glassUniforms);
163
+ * ```
164
+ */
165
+ declare function createGlassUniforms(defaults?: Partial<GlassUniforms>): GlassUniformController;
166
+ /**
167
+ * Create the default glass material used for materialIndex 1 groups.
168
+ *
169
+ * If you want to use custom uniforms, you can create them using {@link createGlassUniforms} and pass them to this function.
170
+ *
171
+ * You can override the material parameters by passing a `THREE.ShaderMaterialParameters` object as the second argument.
172
+ *
173
+ * @returns A new `THREE.ShaderMaterial` with the specified uniforms, or a default one if not provided.
174
+ */
175
+ declare function createGlassMaterial(uniforms?: GlassUniformController, materialParameters?: THREE.ShaderMaterialParameters): THREE.ShaderMaterial;
176
+ //#endregion
177
+ //#region src/material/opaque.d.ts
178
+ /** Uniforms used by the opaque material. */
179
+ interface OpaqueUniforms {
180
+ /**
181
+ * Whether to override the vertex colors.
182
+ *
183
+ * When enabled, the `overrideColor1`, `overrideColor2`, and `overrideColor3` uniforms are used instead of certain vertex colors.
184
+ */
185
+ overrideColorEnabled: boolean;
186
+ /** The color to override vertex colors that is close to `(255, 126, 0)` with when `overrideColorEnabled` is true. */
187
+ overrideColor1: Color;
188
+ /** The color to override vertex colors that is close to `(155, 126, 0)` with when `overrideColorEnabled` is true. */
189
+ overrideColor2: Color;
190
+ /** The color to override vertex colors that is close to `(55, 126, 0)` with when `overrideColorEnabled` is true. */
191
+ overrideColor3: Color;
192
+ }
193
+ /**
194
+ * Manages shader uniforms for the opaque material.
195
+ *
196
+ * This can be created using {@link createOpaqueUniforms} and attached to a material using {@link createOpaqueMaterial}.
197
+ *
198
+ * @example
199
+ * ```ts
200
+ * const opaqueUniforms: OpaqueUniformController = createOpaqueUniforms();
201
+ *
202
+ * opaqueUniforms.set("overrideColorEnabled", true);
203
+ * opaqueUniforms.set("overrideColor1", { r: 255, g: 0, b: 0 });
204
+ * opaqueUniforms.set("overrideColor2", { r: 0, g: 255, b: 0 });
205
+ * opaqueUniforms.set("overrideColor3", { r: 0, g: 0, b: 255 });
206
+ * ```
207
+ */
208
+ type OpaqueUniformController = UniformController<OpaqueUniforms>;
209
+ /**
210
+ * Create the default uniforms used for opaque materials.
211
+ *
212
+ * An opaque material can be created using {@link createOpaqueMaterial}.
213
+ *
214
+ * The default uniforms are:
215
+ * - `overrideColorEnabled`: true
216
+ * - `overrideColor1`: white
217
+ * - `overrideColor2`: white
218
+ * - `overrideColor3`: white
219
+ *
220
+ * @example
221
+ * ```ts
222
+ * const opaqueUniforms = createOpaqueUniforms({
223
+ * overrideColorEnabled: false
224
+ * });
225
+ *
226
+ * const opaqueMaterial = createOpaqueMaterial(opaqueUniforms);
227
+ * ```
228
+ */
229
+ declare function createOpaqueUniforms(defaults?: Partial<OpaqueUniforms>): OpaqueUniformController;
230
+ /**
231
+ * Create the default opaque material used for materialIndex 0 groups.
232
+ *
233
+ * If you want to use custom uniforms, you can create them using {@link createOpaqueUniforms} and pass them to this function.
234
+ *
235
+ * You can override the material parameters by passing a `THREE.MeshStandardMaterialParameters` object as the second argument.
236
+ *
237
+ * @returns A new `THREE.MeshStandardMaterial` with the specified uniforms, or a default one if not provided.
238
+ */
239
+ declare function createOpaqueMaterial(uniforms?: OpaqueUniformController, materialParameters?: THREE.MeshStandardMaterialParameters): THREE.MeshStandardMaterial;
240
+ //#endregion
241
+ //#region src/material/materials.d.ts
242
+ /** Material families for Stormworks mesh. */
243
+ type SwMaterialKind = "opaque" | "glass" | "additive";
244
+ /** Mutable Three.js uniform stores owned by a Stormworks material set. */
245
+ interface SwUniformControllers {
246
+ /** Uniforms used by the opaque render material. */
247
+ opaque: OpaqueUniformController;
248
+ /** Uniforms used by the glass render material. */
249
+ glass: GlassUniformController;
250
+ /** Uniforms used by the additive render material. */
251
+ additive: AdditiveUniformController;
252
+ }
253
+ /** Materials and their uniform stores used by Stormworks object creation helpers. */
254
+ interface SwMaterialSet {
255
+ /** Material used for shader id `0` groups. */
256
+ opaque: THREE.MeshStandardMaterial;
257
+ /** Material used for shader id `1` groups. */
258
+ glass: THREE.ShaderMaterial;
259
+ /** Material used for shader id `2` groups. */
260
+ additive: THREE.MeshBasicMaterial;
261
+ /** Uniform stores attached to this material set. */
262
+ uniforms: SwUniformControllers;
263
+ }
264
+ /** Options used when creating the default Stormworks material set. */
265
+ interface CreateSwMaterialsOptions {
266
+ /** Initial uniforms applied after each material family's defaults are created. */
267
+ readonly uniforms?: {
268
+ opaque?: Partial<OpaqueUniforms>;
269
+ glass?: Partial<GlassUniforms>;
270
+ additive?: Partial<AdditiveUniforms>;
271
+ };
272
+ }
273
+ /**
274
+ * Create the default materials used by Stormworks object helpers.
275
+ *
276
+ * A new material set has independent uniform stores, making it suitable for
277
+ * object-local color and shader state. Share the returned set only when objects
278
+ * should intentionally share uniform updates.
279
+ */
280
+ declare function createSwMaterials(options?: CreateSwMaterialsOptions): SwMaterialSet;
281
+ //#endregion
282
+ //#region src/mesh.d.ts
283
+ /** Options used when creating a render mesh object from parsed `mesh` data. */
284
+ interface CreateSwMeshOptions {
285
+ /** Optional display name assigned to the created mesh. */
286
+ readonly name?: string;
287
+ /** Materials used for opaque, glass, and additive groups. */
288
+ readonly materials?: Readonly<SwMaterialSet>;
289
+ }
290
+ /** Options used when creating a physics mesh group from parsed `phys` data. */
291
+ interface CreateSwPhysMeshOptions {
292
+ /** Optional display name assigned to the created group. */
293
+ readonly name?: string;
294
+ }
295
+ /**
296
+ * Create a renderable Three.js mesh from parsed Stormworks `mesh` data.
297
+ *
298
+ * The returned mesh owns its geometry. It uses material groups mapped from the
299
+ * file's group shader ids: opaque, glass, and additive.
300
+ */
301
+ declare function createSwMesh(mesh: MeshData, options?: CreateSwMeshOptions): THREE.Mesh<THREE.BufferGeometry, THREE.Material[]>;
302
+ /**
303
+ * Create a Three.js group from parsed Stormworks `phys` data.
304
+ *
305
+ * Each physics section becomes a child mesh using the `phys` material from the
306
+ * supplied material set.
307
+ */
308
+ declare function createSwPhysMeshGroup(mesh: PhysData, material: THREE.Material, options?: CreateSwPhysMeshOptions): THREE.Group;
309
+ /**
310
+ * Create buffer geometry for parsed Stormworks render mesh data.
311
+ *
312
+ * The geometry includes `position`, `normal`, and `color` attributes, and material groups derived from group shader ids.
313
+ */
314
+ declare function createSwMeshGeometry(mesh: MeshData): THREE.BufferGeometry;
315
+ /**
316
+ * Create buffer geometry for parsed Stormworks phys group.
317
+ *
318
+ * The geometry includes `position` attributes.
319
+ */
320
+ declare function createSwPhysGroupGeometry(physGroup: PhysGroup): THREE.BufferGeometry;
321
+ //#endregion
322
+ //#region src/vehicleAssembler/assetResolver.d.ts
323
+ /**
324
+ * Resolves a component definition from its component ID.
325
+ *
326
+ * Returns `undefined` if the component definition cannot be found.
327
+ */
328
+ type ComponentDefinitionResolver = (componentId: string | undefined) => Promise<ComponentDefinitionImmutable | undefined>;
329
+ /**
330
+ * Resolves a Three.js geometry from a Stormworks mesh path.
331
+ *
332
+ * Returns `undefined` if the mesh asset cannot be found.
333
+ */
334
+ type MeshResolver = (meshPath: string) => Promise<THREE.BufferGeometry | undefined>;
335
+ /**
336
+ * Asset resolver used by {@link VehicleBodyAssembler}.
337
+ *
338
+ * This interface provides parsed component definitions and mesh geometries,
339
+ * allowing applications to load assets from any source such as the local
340
+ * filesystem, HTTP, IndexedDB, or an in-memory cache.
341
+ */
342
+ interface VehicleAssetResolver {
343
+ /** Resolves a parsed component definition. */
344
+ resolveComponentDefinition: ComponentDefinitionResolver;
345
+ /** Resolves a parsed mesh geometry. */
346
+ resolveMesh: MeshResolver;
347
+ }
348
+ /**
349
+ * Creates a {@link VehicleAssetResolver} from raw asset providers.
350
+ *
351
+ * The returned resolver automatically parses XML component definitions,
352
+ * converts Stormworks mesh files into `THREE.BufferGeometry`, and
353
+ * caches the results so each asset is loaded and parsed at most once.
354
+ *
355
+ * This is the recommended way to construct a resolver for {@link VehicleBodyAssembler}.
356
+ *
357
+ * @param getComponentDefinitionFile Returns the XML source of a component
358
+ * definition.
359
+ * @param getMeshFile Returns the binary contents of a Stormworks mesh file.
360
+ * @returns A cached asset resolver.
361
+ */
362
+ declare function createVehicleAssetResolver(getComponentDefinitionFile: (componentId: string) => Promise<string | Uint8Array<ArrayBuffer> | undefined> | string | Uint8Array<ArrayBuffer> | undefined, getMeshFile: (meshPath: string) => Promise<BinaryReaderInput | undefined> | BinaryReaderInput | undefined): VehicleAssetResolver;
363
+ /**
364
+ * Wraps an asynchronous resolver with memoization.
365
+ *
366
+ * The returned function caches both completed results and in-flight promises,
367
+ * ensuring that concurrent requests for the same key share a single operation.
368
+ *
369
+ * @param resolver The resolver to memoize.
370
+ * @returns A cached resolver.
371
+ */
372
+ declare function withCache<K, V>(resolver: (key: K) => Promise<V>): (key: K) => Promise<V>;
373
+ //#endregion
374
+ //#region src/vehicleAssembler/bodyAssembler.d.ts
375
+ /** The names of the mesh reference attributes in the component definition XML. */
376
+ declare const MESH_ATTRIBUTE_NAMES: readonly ["mesh_data_name", "mesh_0_name", "mesh_1_name", "mesh_2_name"];
377
+ /** The type for the mesh reference attributes in the component definition XML. */
378
+ type MeshAttributeName = (typeof MESH_ATTRIBUTE_NAMES)[number];
379
+ /**
380
+ * Options for {@link VehicleBodyAssembler.build}.
381
+ */
382
+ interface VehicleBodyBuildOptions {
383
+ /**
384
+ * Generates border of surfaces.
385
+ *
386
+ * @default false
387
+ */
388
+ readonly edge?: boolean;
389
+ /**
390
+ * Generates only the surface border.
391
+ *
392
+ * Implies `edge=true`.
393
+ *
394
+ * @default false
395
+ */
396
+ readonly hollow?: boolean;
397
+ /**
398
+ * Removes hidden internal surfaces before generating geometry.
399
+ *
400
+ * @default true
401
+ */
402
+ readonly cull?: boolean;
403
+ }
404
+ /**
405
+ * Assembles a single Stormworks vehicle body into Three.js objects.
406
+ *
407
+ * The assembler collects component geometry and meshes, then produces one
408
+ * `THREE.Group` containing a culled surface mesh and any additional meshes.
409
+ *
410
+ * A single instance should be used for one vehicle body.
411
+ *
412
+ * The primary methods most applications should call are {@link appendComponent} and {@link build}.
413
+ *
414
+ * @example
415
+ * ```ts
416
+ * import * as THREE from "three";
417
+ * import { parseVehicleXml } from "@sw-file-lib/xml";
418
+ * import { createVehicleAssetResolver, VehicleBodyAssembler } from "@sw-file-lib/three";
419
+ *
420
+ * const assetResolver = createVehicleAssetResolver(
421
+ * (componentId) =>
422
+ * fetch(`/rom/data/definitions/${componentId}.xml`)
423
+ * .then((res) => res.ok ? res.text() : undefined),
424
+ * (meshPath) =>
425
+ * fetch(`/rom/${meshPath}`)
426
+ * .then((res) => res.ok ? res.arrayBuffer() : undefined)
427
+ * );
428
+ *
429
+ * const vehicle = parseVehicleXml(text);
430
+ * const vehicleGroup = new THREE.Group();
431
+ *
432
+ * for (const body of vehicle.bodies ?? []) {
433
+ * const assembler = new VehicleBodyAssembler(assetResolver);
434
+ * for (const component of body.components ?? []) {
435
+ * await assembler.appendComponent(component);
436
+ * }
437
+ *
438
+ * const obj = assembler.build();
439
+ * vehicleGroup.add(obj);
440
+ * }
441
+ *
442
+ * scene.add(vehicleGroup);
443
+ * ```
444
+ */
445
+ declare class VehicleBodyAssembler {
446
+ private assets;
447
+ private surfaces;
448
+ private groups;
449
+ /**
450
+ * Creates a new body assembler.
451
+ *
452
+ * @param assets Callbacks used to resolve component definitions and mesh assets.
453
+ * Create a resolver with {@link createVehicleAssetResolver}, or make your own.
454
+ * Wrapping them with a cache is recommended when loading from disk or over the network.
455
+ */
456
+ constructor(assets: VehicleAssetResolver);
457
+ /**
458
+ * Appends a component to the body.
459
+ *
460
+ * The component type is detected automatically, and the appropriate builder
461
+ * is used internally. This is the primary method most applications should call.
462
+ *
463
+ * @param componentInstance The component instance from the vehicle body.
464
+ * Represented by a `<c>` element in the vehicle XML.
465
+ */
466
+ appendComponent(componentInstance: VehicleSchemas.ComponentImmutable): Promise<void>;
467
+ /**
468
+ * Appends surfaces and prebuilt objects to the body.
469
+ *
470
+ * This is a low-level API intended for custom or unsupported components.
471
+ * All surfaces and objects must be provided in the component's local
472
+ * coordinate system; they will be transformed into body space automatically.
473
+ *
474
+ * @param componentInstance The component instance from the vehicle body.
475
+ * Represented by a `<c>` element in the vehicle XML.
476
+ * @param surfaceDefinitions Surface definitions in local space.
477
+ * @param objects Additional Three.js objects in local space.
478
+ */
479
+ appendRawComponent(componentInstance: VehicleSchemas.ComponentImmutable, surfaceDefinitions?: readonly ComponentDefinitionSchemas.SurfaceImmutable[] | undefined, objects?: readonly THREE.Object3D[] | undefined): void;
480
+ /**
481
+ * Appends a standard component using its component definition.
482
+ *
483
+ * This resolves surface definitions and any required mesh assets, transforms
484
+ * them into world space, and adds them to the current body.
485
+ *
486
+ * Most users should prefer {@link appendComponent}, which performs type
487
+ * detection automatically.
488
+ *
489
+ * @param componentInstance The component instance from the vehicle body.
490
+ * Represented by a `<c>` element in the vehicle XML.
491
+ * @param definition The component definition for the component instance.
492
+ * @param meshesToExclude Optional list of mesh attributes to ignore.
493
+ */
494
+ appendStandardComponent(componentInstance: VehicleSchemas.ComponentImmutable, definition?: ComponentDefinitionImmutable, meshesToExclude?: readonly MeshAttributeName[]): Promise<void>;
495
+ /**
496
+ * Appends a paintable sign component.
497
+ *
498
+ * Paintable signs generate their geometry dynamically from the component
499
+ * properties and do not use a predefined mesh asset.
500
+ *
501
+ * @param componentInstance The component instance from the vehicle body.
502
+ * Represented by a `<c>` element in the vehicle XML.
503
+ * @param definition The component definition for the component instance.
504
+ */
505
+ appendPaintableSign(componentInstance: VehicleSchemas.ComponentImmutable, definition: ComponentDefinitionImmutable): Promise<void>;
506
+ /**
507
+ * Appends a microcontroller component.
508
+ *
509
+ * Microcontrollers have variable dimensions and therefore generate their
510
+ * surfaces and meshes procedurally instead of using a fixed definition.
511
+ *
512
+ * @param componentInstance The component instance from the vehicle body.
513
+ * Represented by a `<c>` element in the vehicle XML.
514
+ */
515
+ appendMicrocontroller(componentInstance: VehicleSchemas.ComponentImmutable): Promise<void>;
516
+ /**
517
+ * Builds the merged surface mesh for this body using {@link GeometryBuilder}.
518
+ *
519
+ * Surface culling is performed before constructing geometry unless explicitly disabled by the options.
520
+ * The returned geometry does not include any additional meshes.
521
+ *
522
+ * @see {@link build} for the complete object including additional meshes.
523
+ */
524
+ buildSurfaceMesh(options?: BuildSurfaceGeometryOptions): GeometryBuilder;
525
+ /**
526
+ * Builds the final Three.js object representing this vehicle body.
527
+ *
528
+ * The returned group contains the merged surface mesh together with every
529
+ * additional mesh appended during assembly.
530
+ *
531
+ * @returns A complete Three.js group for the body.
532
+ */
533
+ build(surfaceOptions?: VehicleBodyBuildOptions): THREE.Group;
534
+ }
535
+ //#endregion
536
+ export { AdditiveUniformController, AdditiveUniforms, ComponentDefinitionResolver, CreateSwLightsOptions, CreateSwMaterialsOptions, CreateSwMeshOptions, CreateSwPhysMeshOptions, GlassUniformController, GlassUniforms, MESH_ATTRIBUTE_NAMES, MeshAttributeName, MeshResolver, OpaqueUniformController, OpaqueUniforms, SwMaterialKind, SwMaterialSet, SwUniformControllers, UniformController, VehicleAssetResolver, VehicleBodyAssembler, VehicleBodyBuildOptions, applyBuilderOnBufferGeometry, bufferGeometryFromBuilder, createAdditiveMaterial, createAdditiveUniforms, createGlassMaterial, createGlassUniforms, createOpaqueMaterial, createOpaqueUniforms, createSwLightGroup, createSwLights, createSwMaterials, createSwMesh, createSwMeshGeometry, createSwPhysGroupGeometry, createSwPhysMeshGroup, createVehicleAssetResolver, withCache };