babylon.quarks 0.27.0 → 0.28.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 (52) hide show
  1. package/CHANGELOG.md +425 -0
  2. package/README.md +3 -1
  3. package/dist/babylon.quarks.cjs +1 -1
  4. package/dist/babylon.quarks.cjs.map +1 -1
  5. package/dist/babylon.quarks.esm.js +1 -1
  6. package/dist/babylon.quarks.esm.js.map +1 -1
  7. package/dist/babylon.quarks.umd.min.js +1 -1
  8. package/dist/babylon.quarks.umd.min.js.map +1 -1
  9. package/dist/types/index.d.cts +4256 -831
  10. package/dist/types/index.d.ts +4256 -831
  11. package/package.json +7 -2
  12. package/src/BatchedRenderer.ts +93 -78
  13. package/src/EffectPool.ts +91 -12
  14. package/src/MeshSurfaceEmitter.ts +24 -13
  15. package/src/ParticleEmitter.ts +31 -3
  16. package/src/ParticleSystem.ts +92 -25
  17. package/src/QuarksLoader.ts +289 -171
  18. package/src/QuarksPrefab.ts +301 -94
  19. package/src/QuarksSerializer.ts +43 -15
  20. package/src/QuarksUtil.ts +64 -9
  21. package/src/SpriteBatch.ts +21 -6
  22. package/src/TrailBatch.ts +12 -6
  23. package/src/VFXBatch.ts +70 -528
  24. package/src/batchKey.ts +4 -2
  25. package/src/batchSettings.ts +546 -0
  26. package/src/effectDocumentJSON.ts +261 -0
  27. package/src/effectResources.ts +21 -24
  28. package/src/envAtlas.ts +8 -2
  29. package/src/geometryUtil.ts +1 -1
  30. package/src/index.ts +39 -4
  31. package/src/nodeId.ts +25 -2
  32. package/src/shaderProgram.ts +110 -16
  33. package/src/shaderVariants.ts +24 -4
  34. package/src/shaders/chunks/blend.ts +31 -0
  35. package/src/shaders/chunks/fog.ts +8 -3
  36. package/src/shaders/chunks/soft.ts +6 -5
  37. package/src/shaders/chunks/surface.ts +2 -2
  38. package/src/shaders/particle_frag.glsl.ts +3 -1
  39. package/src/shaders/particle_frag.wgsl.ts +2 -0
  40. package/src/shaders/particle_physics_frag.glsl.ts +5 -2
  41. package/src/shaders/particle_physics_frag.wgsl.ts +2 -0
  42. package/src/shaders/trail_frag.glsl.ts +4 -1
  43. package/src/shaders/trail_frag.wgsl.ts +2 -0
  44. package/src/system/EmissionController.ts +2 -4
  45. package/src/system/EventDispatcher.ts +26 -10
  46. package/src/system/geometry.ts +22 -29
  47. package/src/system/materialResolve.ts +56 -7
  48. package/src/system/normalize.ts +6 -1
  49. package/src/system/serialization.ts +54 -33
  50. package/src/system/settingsSchema.ts +32 -10
  51. package/src/system/types.ts +67 -28
  52. package/src/trailSettings.ts +9 -6
@@ -0,0 +1,261 @@
1
+ import type {BaseTexture} from '@babylonjs/core/Materials/Textures/baseTexture';
2
+ import type {
3
+ MeshLighting,
4
+ MeshRim,
5
+ ParticleErosionOptions,
6
+ ParticleGradientMap,
7
+ ParticleUVDistortionOptions,
8
+ TextureUV,
9
+ } from './batchSettings';
10
+ import type {QuarksEffectJSON, QuarksNodeJSON, QuarksTextureJSON} from './QuarksSerializer';
11
+ import type {ParticleMaterialSource} from './system/materialResolve';
12
+
13
+ // The parts of an effect document `QuarksLoader` reads: what `serializeEffect` writes, and the
14
+ // three.js object format three.quarks files use. Every field a file may leave out is optional; the
15
+ // loader checks what it reads, so a field of the wrong kind warns or is skipped, never throws.
16
+
17
+ /** Mesh data as typed arrays, the form a loaded geometry takes. */
18
+ export interface GeometryArrays {
19
+ /** `x, y, z` per vertex. */
20
+ positions: Float32Array;
21
+ /** Three per triangle. */
22
+ indices: Uint32Array | Uint16Array;
23
+ /** First UV set, `u, v` per vertex. */
24
+ uvs?: Float32Array;
25
+ /** Second UV set, `u, v` per vertex. */
26
+ uvs2?: Float32Array;
27
+ /** `x, y, z` per vertex. */
28
+ normals?: Float32Array;
29
+ }
30
+
31
+ /** A three.js `BufferAttribute`, inline or as a view into an interleaved buffer. */
32
+ export interface BufferAttributeJSON {
33
+ /** The values, when the attribute holds its own. */
34
+ array?: number[];
35
+ /** Components per vertex. */
36
+ itemSize?: number;
37
+ /** The typed array type, e.g. `'Float32Array'` or `'Uint16Array'`. */
38
+ type?: string;
39
+ /** Set when the attribute reads an interleaved buffer. */
40
+ isInterleavedBufferAttribute?: boolean;
41
+ /** The interleaved buffer's uuid. */
42
+ data?: string;
43
+ /** Where the attribute starts in each interleaved vertex. */
44
+ offset?: number;
45
+ }
46
+
47
+ /** A three.js interleaved buffer: a stride over one of the geometry's array buffers. */
48
+ export interface InterleavedBufferJSON {
49
+ /** The array buffer's uuid. */
50
+ buffer: string;
51
+ /** Floats per vertex. */
52
+ stride: number;
53
+ }
54
+
55
+ /** The vertex attributes of a three.js `BufferGeometry` that quarks reads. */
56
+ export interface BufferGeometryAttributesJSON {
57
+ /** Positions, `x, y, z` per vertex. */
58
+ position?: BufferAttributeJSON;
59
+ /** The first UV set. */
60
+ uv?: BufferAttributeJSON;
61
+ /** The second UV set, as three.js r151 on names it. */
62
+ uv1?: BufferAttributeJSON;
63
+ /** The second UV set, as three.js before r151 names it. */
64
+ uv2?: BufferAttributeJSON;
65
+ /** Normals, `x, y, z` per vertex. */
66
+ normal?: BufferAttributeJSON;
67
+ }
68
+
69
+ /** The index of a three.js `BufferGeometry`. */
70
+ export interface BufferIndexJSON {
71
+ /** `'Uint16Array'` or `'Uint32Array'`; 32-bit when absent. */
72
+ type?: string;
73
+ /** Three per triangle. */
74
+ array: number[];
75
+ }
76
+
77
+ /** The `data` of a three.js `BufferGeometry`. */
78
+ export interface BufferGeometryDataJSON {
79
+ /** The vertex attributes. */
80
+ attributes?: BufferGeometryAttributesJSON;
81
+ /** The triangle indices. */
82
+ index?: BufferIndexJSON;
83
+ /** Interleaved buffers by uuid. */
84
+ interleavedBuffers?: {[uuid: string]: InterleavedBufferJSON};
85
+ /** The bytes of the interleaved buffers by uuid, as 32-bit words. */
86
+ arrayBuffers?: {[uuid: string]: number[] | ArrayBuffer};
87
+ }
88
+
89
+ /** A three.js `BufferGeometry`. */
90
+ export interface BufferGeometryJSON {
91
+ /** Unique within the file. */
92
+ uuid: string;
93
+ /** Always `'BufferGeometry'`. */
94
+ type: 'BufferGeometry';
95
+ /** The vertex data. */
96
+ data?: BufferGeometryDataJSON;
97
+ }
98
+
99
+ /** A three.js `PlaneGeometry`: a quad in XY. */
100
+ export interface PlaneGeometryJSON {
101
+ /** Unique within the file. */
102
+ uuid: string;
103
+ /** Always `'PlaneGeometry'`. */
104
+ type: 'PlaneGeometry';
105
+ /** Default 1. */
106
+ width?: number;
107
+ /** Default 1. */
108
+ height?: number;
109
+ }
110
+
111
+ /** A three.js `SphereGeometry`. */
112
+ export interface SphereGeometryJSON {
113
+ /** Unique within the file. */
114
+ uuid: string;
115
+ /** Always `'SphereGeometry'`. */
116
+ type: 'SphereGeometry';
117
+ /** Default 0.5. */
118
+ radius?: number;
119
+ /** Default 16, at least 3. */
120
+ widthSegments?: number;
121
+ /** Default 8, at least 2. */
122
+ heightSegments?: number;
123
+ /** Default 0. */
124
+ phiStart?: number;
125
+ /** Default 2π. */
126
+ phiLength?: number;
127
+ /** Default 0. */
128
+ thetaStart?: number;
129
+ /** Default π. */
130
+ thetaLength?: number;
131
+ }
132
+
133
+ /**
134
+ * Quarks' own mesh data, inline (see `QuarksGeometryJSON`) or in its own file at `url`, which
135
+ * `QuarksLoader.resolveResources` inlines before parsing.
136
+ */
137
+ export interface QuarksGeometryEntryJSON {
138
+ /** Unique within the file. */
139
+ uuid: string;
140
+ /** Always `'QuarksGeometry'`. */
141
+ type: 'QuarksGeometry';
142
+ /** The file that holds the data, until it is inlined. */
143
+ url?: string;
144
+ /** `x, y, z` per vertex. */
145
+ positions?: number[];
146
+ /** Three per triangle. */
147
+ indices?: number[];
148
+ /** First UV set. */
149
+ uvs?: number[];
150
+ /** Second UV set. */
151
+ uvs2?: number[];
152
+ /** `x, y, z` per vertex. */
153
+ normals?: number[];
154
+ }
155
+
156
+ /** A geometry entry of an effect document. */
157
+ export type EffectGeometryJSON = QuarksGeometryEntryJSON | BufferGeometryJSON | PlaneGeometryJSON | SphereGeometryJSON;
158
+
159
+ /** An image entry of an effect document. */
160
+ export interface EffectImageJSON {
161
+ /** Unique within the file. */
162
+ uuid: string;
163
+ /** Relative to the file's base url, absolute, or a `data:` url; absent for an image with no file. */
164
+ url?: string;
165
+ }
166
+
167
+ /**
168
+ * A texture slot of a {@link QuarksMaterialJSON}: a texture uuid in a file, the texture itself once
169
+ * a loader resolved it, or null for a texture that could not be made.
170
+ */
171
+ export type MaterialTextureRef = string | BaseTexture | null;
172
+
173
+ /** The gradient mapping of a {@link QuarksMaterialJSON}; see `ParticleSystem.gradientMap`. */
174
+ export interface GradientMapJSON extends Omit<Partial<ParticleGradientMap>, 'ramp'> {
175
+ /** The ramp texture. */
176
+ ramp?: MaterialTextureRef;
177
+ }
178
+
179
+ /** The erosion of a {@link QuarksMaterialJSON}; see `ParticleSystem.erosion`. */
180
+ export type ErosionJSON = Omit<ParticleErosionOptions, 'mask'> & {
181
+ /** The mask texture. */
182
+ mask?: MaterialTextureRef;
183
+ };
184
+
185
+ /** The UV distortion of a {@link QuarksMaterialJSON}; see `ParticleSystem.uvDistortion`. */
186
+ export type UVDistortionJSON = Omit<ParticleUVDistortionOptions, 'map'> & {
187
+ /** The distortion texture. */
188
+ map?: MaterialTextureRef;
189
+ };
190
+
191
+ /**
192
+ * A material entry of an effect document: what a particle system's material writes (`type`
193
+ * `'QuarksMaterial'`), or a three.js material, whose `map` and `blending` the loader reads too.
194
+ */
195
+ export interface QuarksMaterialJSON {
196
+ /** Unique within the file. */
197
+ uuid: string;
198
+ /** `'QuarksMaterial'`, or the three.js material type. */
199
+ type?: string;
200
+ /** Whether the particles blend. Default true. */
201
+ transparent?: boolean;
202
+ /** A Babylon alpha mode constant. */
203
+ alphaMode?: number;
204
+ /** A three.js blending code (1 normal, 2 additive, 3 subtractive, 4 multiply), read without `alphaMode`. */
205
+ blending?: number;
206
+ /** A three.js side code; 2 draws both faces. */
207
+ side?: number;
208
+ /** Default true. */
209
+ depthTest?: boolean;
210
+ /** Default false. */
211
+ depthWrite?: boolean;
212
+ /** Default 0. */
213
+ alphaTest?: number;
214
+ /** The particle texture. */
215
+ texture?: MaterialTextureRef;
216
+ /** A three.js material's texture, read when there is no `texture`. */
217
+ map?: string;
218
+ /** A 3×2 environment atlas for reflections. */
219
+ reflectionAtlas?: MaterialTextureRef;
220
+ /** How strong the reflection is. */
221
+ reflectionLevel?: number;
222
+ /** Mesh particle lighting; `'fixed'` when absent. */
223
+ lighting?: MeshLighting;
224
+ /** Mesh particle rim. */
225
+ rim?: Partial<MeshRim>;
226
+ /** The particle texture's UV transform. */
227
+ mapUV?: Partial<TextureUV>;
228
+ /** Gradient mapping. */
229
+ gradientMap?: GradientMapJSON;
230
+ /** Erosion. */
231
+ erosion?: ErosionJSON;
232
+ /** UV distortion. */
233
+ uvDistortion?: UVDistortionJSON;
234
+ /** While writing: the material the system read its settings from. Never written to a file. */
235
+ sourceMaterial?: ParticleMaterialSource;
236
+ }
237
+
238
+ /**
239
+ * A geometry as an effect's resources hold it: an entry of the document, or, once loaded, its
240
+ * typed arrays.
241
+ */
242
+ export type GeometryEntry = EffectGeometryJSON | GeometryArrays;
243
+
244
+ /**
245
+ * An effect document as `QuarksLoader` reads it: what `serializeEffect` writes
246
+ * (`QuarksEffectJSON`), or a three.quarks / three.js object file. Only `object` is required.
247
+ */
248
+ export interface EffectDocumentJSON {
249
+ /** What wrote the file. */
250
+ metadata?: Partial<QuarksEffectJSON['metadata']>;
251
+ /** Meshes the nodes and particle systems use. */
252
+ geometries?: EffectGeometryJSON[];
253
+ /** Materials, referred to by uuid. */
254
+ materials?: QuarksMaterialJSON[];
255
+ /** Textures, referred to by uuid. */
256
+ textures?: QuarksTextureJSON[];
257
+ /** Image files the textures load. */
258
+ images?: EffectImageJSON[];
259
+ /** The effect's root node. */
260
+ object: QuarksNodeJSON;
261
+ }
@@ -3,46 +3,46 @@ import type {BaseTexture} from '@babylonjs/core/Materials/Textures/baseTexture';
3
3
  import type {TransformNode} from '@babylonjs/core/Meshes/transformNode';
4
4
  import type {Node} from '@babylonjs/core/node';
5
5
 
6
- /** What an effect root owns: the textures it holds a count on, and the materials made for it alone. */
6
+ /** What an effect root holds a count on: the textures it draws with and the materials made for the effect. */
7
7
  interface EffectResources {
8
8
  textures: Set<BaseTexture>;
9
- materials: Material[];
9
+ materials: Set<Material>;
10
10
  }
11
11
 
12
12
  const owned = new WeakMap<Node, EffectResources>();
13
- /** How many effect roots hold each texture. */
14
- const holders = new WeakMap<BaseTexture, number>();
13
+ /** How many effect roots hold each texture and material. */
14
+ const holders = new WeakMap<BaseTexture | Material, number>();
15
15
 
16
16
  /**
17
- * Records that `root` uses `textures` and owns `materials`. They are freed when the root is
18
- * disposed, however that happens: {@link disposeEffect}, `root.dispose()`, a parent's dispose or
19
- * the scene's.
17
+ * Records that `root` uses `textures` and the `materials` made for the effect. Each is freed once
18
+ * the last root holding it is disposed, however that happens: {@link disposeEffect},
19
+ * `root.dispose()`, a parent's dispose or the scene's.
20
20
  */
21
21
  export function retainEffectResources(
22
22
  root: TransformNode,
23
23
  textures: Iterable<BaseTexture>,
24
- materials: Material[]
24
+ materials: Iterable<Material>
25
25
  ): void {
26
26
  if (owned.has(root)) {
27
27
  return;
28
28
  }
29
- const resources: EffectResources = {textures: new Set(textures), materials};
30
- for (const texture of resources.textures) {
31
- holders.set(texture, (holders.get(texture) ?? 0) + 1);
29
+ const resources: EffectResources = {textures: new Set(textures), materials: new Set(materials)};
30
+ for (const resource of [...resources.textures, ...resources.materials]) {
31
+ holders.set(resource, (holders.get(resource) ?? 0) + 1);
32
32
  }
33
33
  owned.set(root, resources);
34
34
  root.onDisposeObservable.addOnce(() => releaseEffectResources(root));
35
35
  }
36
36
 
37
37
  /**
38
- * Gives `copy` a hold on the textures the effect `source` belongs to holds, as a copy of the
39
- * effect, or of a node in it, draws with them too.
38
+ * Gives `copy` a hold on the textures and materials the effect `source` belongs to holds, as a
39
+ * copy of the effect, or of a node in it, draws with them too.
40
40
  */
41
41
  export function shareEffectResources(source: TransformNode, copy: TransformNode): void {
42
42
  for (let node: Node | null = source; node !== null; node = node.parent) {
43
43
  const resources = owned.get(node);
44
44
  if (resources !== undefined) {
45
- retainEffectResources(copy, resources.textures, []);
45
+ retainEffectResources(copy, resources.textures, resources.materials);
46
46
  return;
47
47
  }
48
48
  }
@@ -54,23 +54,20 @@ function releaseEffectResources(root: Node): void {
54
54
  return;
55
55
  }
56
56
  owned.delete(root);
57
- for (const material of resources.materials) {
58
- material.dispose();
59
- }
60
- for (const texture of resources.textures) {
61
- const count = (holders.get(texture) ?? 1) - 1;
57
+ for (const resource of [...resources.materials, ...resources.textures]) {
58
+ const count = (holders.get(resource) ?? 1) - 1;
62
59
  if (count > 0) {
63
- holders.set(texture, count);
60
+ holders.set(resource, count);
64
61
  } else {
65
- holders.delete(texture);
66
- texture.dispose();
62
+ holders.delete(resource);
63
+ resource.dispose();
67
64
  }
68
65
  }
69
66
  }
70
67
 
71
68
  /**
72
- * Disposes an effect root and its nodes and systems, the materials made for it, and each texture it
73
- * holds once no other effect root holds it. A root nothing was recorded for is only disposed.
69
+ * Disposes an effect root and its nodes and systems, and each material and texture it holds once no
70
+ * other effect root holds it. A root nothing was recorded for is only disposed.
74
71
  */
75
72
  export function disposeEffect(root: TransformNode): void {
76
73
  root.dispose();
package/src/envAtlas.ts CHANGED
@@ -10,6 +10,8 @@ const atlasesByCube = new WeakMap<BaseTexture, Map<Scene, Texture>>();
10
10
  const pendingByCube = new WeakMap<BaseTexture, Map<Scene, Promise<Texture | null>>>();
11
11
  /** Atlases this module built, which it disposes; an atlas given to {@link cacheEnvAtlas} stays the caller's. */
12
12
  const builtAtlases = new WeakSet<Texture>();
13
+ /** The faces each cube's atlas failed to build from: not tried, or warned about, again. */
14
+ const failedFaces = new WeakMap<BaseTexture, string>();
13
15
  /** Atlases whose dispose this module already listens to. */
14
16
  const watchedAtlases = new WeakSet<Texture>();
15
17
  /** Cubes whose dispose this module already listens to. */
@@ -66,6 +68,7 @@ export function cacheEnvAtlas(cube: BaseTexture, atlas: Texture): void {
66
68
  * @param scene - Only the atlas for this scene. Defaults to every scene.
67
69
  */
68
70
  export function disposeEnvAtlas(cube: BaseTexture, scene?: Scene): void {
71
+ failedFaces.delete(cube);
69
72
  const atlases = atlasesByCube.get(cube);
70
73
  if (!atlases) {
71
74
  return;
@@ -146,7 +149,9 @@ export const envAtlasBuilder = {
146
149
  /**
147
150
  * Ensures a 3×2 env atlas exists for a CubeTexture in `scene`. Returns a cached atlas
148
151
  * synchronously when available; otherwise starts (or joins) an async build and invokes onReady
149
- * when the atlas is usable. A cube disposed before its build finishes gets no atlas.
152
+ * when the atlas is usable. A cube disposed before its build finishes gets no atlas. A build that
153
+ * fails warns once and is not tried again until the cube's faces change or
154
+ * {@link disposeEnvAtlas} is called for it; {@link cacheEnvAtlas} still supplies an atlas.
150
155
  */
151
156
  export function ensureEnvAtlasFromCube(
152
157
  cube: BaseTexture,
@@ -178,7 +183,7 @@ export function ensureEnvAtlasFromCube(
178
183
  }
179
184
 
180
185
  const urls = cubeFaceUrls(cube);
181
- if (!urls) {
186
+ if (!urls || failedFaces.get(cube) === urls.join('\n')) {
182
187
  return;
183
188
  }
184
189
 
@@ -206,6 +211,7 @@ export function ensureEnvAtlasFromCube(
206
211
  })
207
212
  .catch((err) => {
208
213
  settle();
214
+ failedFaces.set(cube, urls.join('\n'));
209
215
  console.warn('[babylon.quarks] Failed to build env atlas from cubemap faces', err);
210
216
  return null;
211
217
  });
@@ -1,4 +1,4 @@
1
- /** Sequential 0..N-1 indices for non-indexed triangle-list BufferGeometry (Three.js drawArrays). */
1
+ /** `indices` when there are some, else `0..N-1`: each three vertices of `positions` one triangle. */
2
2
  export function ensureTriangleIndices(
3
3
  positions: Float32Array,
4
4
  indices?: Uint32Array | Uint16Array
package/src/index.ts CHANGED
@@ -4,8 +4,29 @@ import {MeshSurfaceEmitterPlugin} from './MeshSurfaceEmitter';
4
4
  export * from 'quarks.core';
5
5
  export {BatchedRenderer} from './BatchedRenderer';
6
6
  export type {AdaptivePerformanceOptions, AdaptivePerformanceState, VFXBatchSettings} from './BatchedRenderer';
7
+ export type {
8
+ BufferAttributeJSON,
9
+ BufferGeometryAttributesJSON,
10
+ BufferGeometryDataJSON,
11
+ BufferGeometryJSON,
12
+ BufferIndexJSON,
13
+ EffectDocumentJSON,
14
+ EffectGeometryJSON,
15
+ EffectImageJSON,
16
+ ErosionJSON,
17
+ GeometryArrays,
18
+ GeometryEntry,
19
+ GradientMapJSON,
20
+ InterleavedBufferJSON,
21
+ MaterialTextureRef,
22
+ PlaneGeometryJSON,
23
+ QuarksGeometryEntryJSON,
24
+ QuarksMaterialJSON,
25
+ SphereGeometryJSON,
26
+ UVDistortionJSON,
27
+ } from './effectDocumentJSON';
7
28
  export {EffectPool} from './EffectPool';
8
- export type {EffectPoolOptions} from './EffectPool';
29
+ export type {EffectPlacement, EffectPoolOptions} from './EffectPool';
9
30
  export {
10
31
  cacheEnvAtlas,
11
32
  createEnvAtlasFromFaceUrls,
@@ -17,6 +38,7 @@ export {
17
38
  export {MeshSurfaceEmitter, MeshSurfaceEmitterPlugin} from './MeshSurfaceEmitter';
18
39
  export {quarksNodeId} from './nodeId';
19
40
  export {ParticleEmitter} from './ParticleEmitter';
41
+ export type {ParticleEmitterJSON} from './ParticleEmitter';
20
42
  export {ParticleSystem} from './ParticleSystem';
21
43
  export type {
22
44
  BabylonMetaData,
@@ -34,11 +56,12 @@ export type {
34
56
  QuarksJSONLoadEntry,
35
57
  QuarksLoaderOptions,
36
58
  QuarksLoadOptions,
59
+ QuarksResolveOptions,
37
60
  QuarksResourceKind,
38
61
  QuarksResourceResolver,
39
62
  } from './QuarksLoader';
40
63
  export {QuarksPrefab} from './QuarksPrefab';
41
- export type {AnimationData, QuarksTimelineClip} from './QuarksPrefab';
64
+ export type {AnimationData, AnimationJSON, QuarksPrefabJSON, QuarksTimelineClip} from './QuarksPrefab';
42
65
  export {QUARKS_FORMAT_VERSION, serializeEffect} from './QuarksSerializer';
43
66
  export type {
44
67
  QuarksEffectJSON,
@@ -49,13 +72,23 @@ export type {
49
72
  SerializeEffectOptions,
50
73
  } from './QuarksSerializer';
51
74
  export {QuarksUtil} from './QuarksUtil';
52
- export {shaderProgram} from './shaderProgram';
53
- export type {ShaderContext, ShaderDepth, ShaderProgram, ShaderSettings} from './shaderProgram';
75
+ export {blendCategory, shaderProgram} from './shaderProgram';
76
+ export type {
77
+ BlendCategory,
78
+ BlendOutput,
79
+ FogTarget,
80
+ ShaderContext,
81
+ ShaderDepth,
82
+ ShaderProgram,
83
+ ShaderSettings,
84
+ } from './shaderProgram';
54
85
  export type {ShaderSources} from './shaders/shaderLanguageSupport';
55
86
  export {shaderVariants} from './shaderVariants';
56
87
  export type {ShaderVariant} from './shaderVariants';
57
88
  export {decodeSoftDepth, softDepthParams} from './softDepth';
58
89
  export type {DepthTextureOptions, SoftDepthEncoding} from './softDepth';
90
+ export type {ParticleMaterialSource} from './system/materialResolve';
91
+ export type {RendererEmitterSettingsJSON, TrailSettingsJSON} from './system/types';
59
92
  export {textureSourceUrl} from './textureSource';
60
93
  export {
61
94
  MAX_TRAIL_TESSELLATION,
@@ -65,6 +98,7 @@ export {
65
98
  trailTessellation,
66
99
  trailTextureMode,
67
100
  trailTextureScale,
101
+ type TrailOptions,
68
102
  } from './trailSettings';
69
103
  export {
70
104
  defaultMeshLighting,
@@ -99,6 +133,7 @@ export type {
99
133
  ParticleGradientMap,
100
134
  ParticleUVDistortion,
101
135
  ParticleUVDistortionOptions,
136
+ RenderFace,
102
137
  SortMode,
103
138
  StoredBatchSettings,
104
139
  TextureUV,
package/src/nodeId.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import {RandomGUID} from '@babylonjs/core/Misc/guid';
2
2
 
3
+ /** The id each node is known by in effect files, set when it is loaded or first asked for. */
4
+ const nodeIds = new WeakMap<object, string>();
5
+
3
6
  /**
4
7
  * The id an effect file knows a node by: the uuid it was loaded under, or, for a node made in code,
5
8
  * a GUID given to it the first time it is asked for and kept from then on. Every link written into
@@ -8,6 +11,26 @@ import {RandomGUID} from '@babylonjs/core/Misc/guid';
8
11
  * and a node made in code never takes the id of one loaded from a file.
9
12
  */
10
13
  export function quarksNodeId(node: object): string {
11
- const ided = node as {_quarksUUID?: string};
12
- return (ided._quarksUUID ??= RandomGUID());
14
+ let id = nodeIds.get(node);
15
+ if (id === undefined) {
16
+ id = RandomGUID();
17
+ nodeIds.set(node, id);
18
+ }
19
+ return id;
20
+ }
21
+
22
+ /**
23
+ * The uuid `node` was loaded under or was given, or undefined for a node no file or save has named.
24
+ * @internal
25
+ */
26
+ export function fileNodeId(node: object): string | undefined {
27
+ return nodeIds.get(node);
28
+ }
29
+
30
+ /**
31
+ * Names `node` with `id`, the uuid a file gave it.
32
+ * @internal
33
+ */
34
+ export function setQuarksNodeId(node: object, id: string): void {
35
+ nodeIds.set(node, id);
13
36
  }