babylon.quarks 0.27.0 → 0.29.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/CHANGELOG.md +585 -0
- package/README.md +3 -1
- package/dist/babylon.quarks.cjs +1 -1
- package/dist/babylon.quarks.cjs.map +1 -1
- package/dist/babylon.quarks.esm.js +1 -1
- package/dist/babylon.quarks.esm.js.map +1 -1
- package/dist/babylon.quarks.umd.min.js +1 -1
- package/dist/babylon.quarks.umd.min.js.map +1 -1
- package/dist/types/index.d.cts +4811 -974
- package/dist/types/index.d.ts +4811 -974
- package/package.json +7 -2
- package/src/BatchedRenderer.ts +106 -79
- package/src/EffectPool.ts +96 -16
- package/src/MeshSurfaceEmitter.ts +24 -13
- package/src/ParticleEmitter.ts +119 -26
- package/src/ParticleSystem.ts +305 -55
- package/src/QuarksLoader.ts +298 -171
- package/src/QuarksPrefab.ts +301 -94
- package/src/QuarksSerializer.ts +44 -16
- package/src/QuarksUtil.ts +88 -11
- package/src/SpriteBatch.ts +24 -6
- package/src/TrailBatch.ts +20 -7
- package/src/VFXBatch.ts +182 -528
- package/src/batchKey.ts +6 -2
- package/src/batchSettings.ts +548 -0
- package/src/effectDocumentJSON.ts +261 -0
- package/src/effectResources.ts +21 -24
- package/src/envAtlas.ts +8 -2
- package/src/geometryUtil.ts +1 -1
- package/src/index.ts +41 -4
- package/src/nodeId.ts +25 -2
- package/src/shaderProgram.ts +213 -16
- package/src/shaderVariants.ts +124 -7
- package/src/shaders/chunks/blend.ts +39 -0
- package/src/shaders/chunks/fog.ts +8 -3
- package/src/shaders/chunks/imageProcessing.ts +143 -0
- package/src/shaders/chunks/soft.ts +6 -5
- package/src/shaders/chunks/surface.ts +2 -2
- package/src/shaders/particle_frag.glsl.ts +5 -1
- package/src/shaders/particle_frag.wgsl.ts +4 -0
- package/src/shaders/particle_physics_frag.glsl.ts +7 -2
- package/src/shaders/particle_physics_frag.wgsl.ts +4 -0
- package/src/shaders/trail_frag.glsl.ts +6 -1
- package/src/shaders/trail_frag.wgsl.ts +4 -0
- package/src/system/EmissionController.ts +23 -20
- package/src/system/EventDispatcher.ts +26 -10
- package/src/system/ParticleSpawner.ts +96 -19
- package/src/system/geometry.ts +22 -29
- package/src/system/integrate.ts +61 -4
- package/src/system/materialResolve.ts +56 -7
- package/src/system/normalize.ts +34 -2
- package/src/system/serialization.ts +54 -33
- package/src/system/settingsSchema.ts +57 -17
- package/src/system/types.ts +150 -42
- package/src/trailSettings.ts +9 -6
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {Constants} from '@babylonjs/core/Engines/constants';
|
|
2
|
+
import type {ColorGeneratorJSON, RotationGeneratorJSON, ValueGeneratorJSON, Vector3GeneratorJSON} from 'quarks.core';
|
|
2
3
|
import {
|
|
3
4
|
ColorGenerator,
|
|
4
5
|
ColorGeneratorFromJSON,
|
|
@@ -7,6 +8,7 @@ import {
|
|
|
7
8
|
FunctionColorGenerator,
|
|
8
9
|
FunctionValueGenerator,
|
|
9
10
|
GeneratorFromJSON,
|
|
11
|
+
readFormatPart,
|
|
10
12
|
RotationGenerator,
|
|
11
13
|
ValueGenerator,
|
|
12
14
|
ValueGeneratorFromJSON,
|
|
@@ -17,8 +19,24 @@ import {
|
|
|
17
19
|
} from 'quarks.core';
|
|
18
20
|
import type {ParticleSystem} from '../ParticleSystem';
|
|
19
21
|
import {RenderMode} from '../VFXBatch';
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
+
import {
|
|
23
|
+
DEFAULT_SOFT_FAR_FADE,
|
|
24
|
+
normalizeBursts,
|
|
25
|
+
validCullingMode,
|
|
26
|
+
validLoopRange,
|
|
27
|
+
validRenderFace,
|
|
28
|
+
validRingBufferMode,
|
|
29
|
+
validScalingMode,
|
|
30
|
+
validSortMode,
|
|
31
|
+
validStopAction,
|
|
32
|
+
validTileCount,
|
|
33
|
+
} from './normalize';
|
|
34
|
+
import type {
|
|
35
|
+
BurstParameters,
|
|
36
|
+
BurstParametersJSON,
|
|
37
|
+
ParticleSystemJSONParameters,
|
|
38
|
+
ParticleSystemParameters,
|
|
39
|
+
} from './types';
|
|
22
40
|
|
|
23
41
|
/**
|
|
24
42
|
* One setting of a {@link ParticleSystem} that is a plain value or a generator: how to read it
|
|
@@ -54,6 +72,9 @@ export interface SettingDescriptor {
|
|
|
54
72
|
|
|
55
73
|
type Generator = {toJSON(): unknown; clone(): unknown};
|
|
56
74
|
|
|
75
|
+
/** A burst as files hold it, any field left out. */
|
|
76
|
+
type BurstJSON = Partial<BurstParametersJSON>;
|
|
77
|
+
|
|
57
78
|
/** A number, boolean or string compared by value. */
|
|
58
79
|
function plain<T>(
|
|
59
80
|
param: keyof ParticleSystemParameters,
|
|
@@ -97,11 +118,11 @@ function boolean(json: unknown): boolean | undefined {
|
|
|
97
118
|
* A generator, compared with its default through its JSON. `read` turns the JSON back into one;
|
|
98
119
|
* a bare number is read as a constant.
|
|
99
120
|
*/
|
|
100
|
-
function generator(
|
|
121
|
+
function generator<J>(
|
|
101
122
|
param: keyof ParticleSystemParameters,
|
|
102
123
|
get: (system: ParticleSystem) => Generator,
|
|
103
124
|
defaultValue: () => Generator,
|
|
104
|
-
read: (json:
|
|
125
|
+
read: (json: J) => unknown,
|
|
105
126
|
always = true
|
|
106
127
|
): SettingDescriptor {
|
|
107
128
|
const defaultJSON = JSON.stringify(defaultValue().toJSON());
|
|
@@ -111,7 +132,8 @@ function generator(
|
|
|
111
132
|
get,
|
|
112
133
|
isDefault: (value) => JSON.stringify((value as Generator).toJSON()) === defaultJSON,
|
|
113
134
|
toJSON: (value) => (value as Generator).toJSON(),
|
|
114
|
-
|
|
135
|
+
// The generator readers check the JSON they are given, and warn about what they cannot read.
|
|
136
|
+
fromJSON: (json) => (typeof json === 'number' ? new ConstantValue(json) : read(json as J)),
|
|
115
137
|
clone: (value) => (value as Generator).clone(),
|
|
116
138
|
};
|
|
117
139
|
}
|
|
@@ -124,7 +146,7 @@ function vectorJSON(value: unknown): number[] | undefined {
|
|
|
124
146
|
|
|
125
147
|
/** Every plain and generator setting, in the order `toJSON` writes them. */
|
|
126
148
|
export const SETTINGS: ReadonlyArray<SettingDescriptor> = [
|
|
127
|
-
plain('
|
|
149
|
+
plain('stopAction', (s) => s.stopAction, 'none', validStopAction),
|
|
128
150
|
plain('looping', (s) => s.looping, true, boolean),
|
|
129
151
|
plain('prewarm', (s) => s.prewarm, false, boolean),
|
|
130
152
|
plain('prewarmTime', (s) => s.prewarmTime, 0, number),
|
|
@@ -152,19 +174,21 @@ export const SETTINGS: ReadonlyArray<SettingDescriptor> = [
|
|
|
152
174
|
'startRotation',
|
|
153
175
|
(s) => s.startRotation,
|
|
154
176
|
() => new ConstantValue(0),
|
|
155
|
-
(json
|
|
177
|
+
(json: ValueGeneratorJSON | RotationGeneratorJSON) =>
|
|
178
|
+
GeneratorFromJSON(json) as RotationGenerator | ValueGenerator | FunctionValueGenerator
|
|
156
179
|
),
|
|
157
180
|
generator(
|
|
158
181
|
'startSize',
|
|
159
182
|
(s) => s.startSize,
|
|
160
183
|
() => new ConstantValue(1),
|
|
161
|
-
(json
|
|
184
|
+
(json: ValueGeneratorJSON | Vector3GeneratorJSON) =>
|
|
185
|
+
GeneratorFromJSON(json) as Vector3Generator | ValueGenerator | FunctionValueGenerator
|
|
162
186
|
),
|
|
163
187
|
generator(
|
|
164
188
|
'startColor',
|
|
165
189
|
(s) => s.startColor,
|
|
166
190
|
() => new ConstantColor(new Vector4(1, 1, 1, 1)),
|
|
167
|
-
(json) => ColorGeneratorFromJSON(json) as ColorGenerator | FunctionColorGenerator
|
|
191
|
+
(json: ColorGeneratorJSON) => ColorGeneratorFromJSON(json) as ColorGenerator | FunctionColorGenerator
|
|
168
192
|
),
|
|
169
193
|
generator(
|
|
170
194
|
'emissionOverTime',
|
|
@@ -193,7 +217,7 @@ export const SETTINGS: ReadonlyArray<SettingDescriptor> = [
|
|
|
193
217
|
fromJSON: (json) =>
|
|
194
218
|
Array.isArray(json)
|
|
195
219
|
? normalizeBursts(
|
|
196
|
-
json.map((burst:
|
|
220
|
+
json.map((burst: BurstJSON) => ({
|
|
197
221
|
time: burst.time,
|
|
198
222
|
count:
|
|
199
223
|
typeof burst.count === 'number'
|
|
@@ -208,6 +232,15 @@ export const SETTINGS: ReadonlyArray<SettingDescriptor> = [
|
|
|
208
232
|
clone: (value) => (value as BurstParameters[]).map((burst) => ({...burst, count: burst.count.clone()})),
|
|
209
233
|
},
|
|
210
234
|
plain('maxParticles', (s) => s.maxParticles, undefined, number),
|
|
235
|
+
plain('ringBufferMode', (s) => s.ringBufferMode, 'disabled', validRingBufferMode),
|
|
236
|
+
{
|
|
237
|
+
param: 'ringBufferLoopRange',
|
|
238
|
+
get: (s) => s.ringBufferLoopRange,
|
|
239
|
+
isDefault: (value) => (value as Vector2).x === 0 && (value as Vector2).y === 1,
|
|
240
|
+
toJSON: vectorJSON,
|
|
241
|
+
fromJSON: (json) => (Array.isArray(json) ? validLoopRange(new Vector2(json[0], json[1])) : undefined),
|
|
242
|
+
clone: (value) => (value as Vector2).clone(),
|
|
243
|
+
},
|
|
211
244
|
plain('onlyUsedByOther', (s) => s.onlyUsedByOther, false, boolean),
|
|
212
245
|
plain('renderMode', (s) => s.renderMode, RenderMode.BillBoard, number),
|
|
213
246
|
plain('renderOrder', (s) => s.renderOrder, 0, number),
|
|
@@ -218,16 +251,18 @@ export const SETTINGS: ReadonlyArray<SettingDescriptor> = [
|
|
|
218
251
|
true,
|
|
219
252
|
(json) => json !== false
|
|
220
253
|
),
|
|
221
|
-
plain('playbackSpeed', (s) => s.playbackSpeed, 1, number),
|
|
222
|
-
plain('cullingMode', (s) => s.cullingMode, 'always', validCullingMode),
|
|
223
254
|
plain(
|
|
224
|
-
'
|
|
225
|
-
(s) => s.
|
|
226
|
-
|
|
227
|
-
(json) =>
|
|
255
|
+
'applyImageProcessing',
|
|
256
|
+
(s) => s.applyImageProcessing,
|
|
257
|
+
true,
|
|
258
|
+
(json) => json !== false
|
|
228
259
|
),
|
|
260
|
+
plain('playbackSpeed', (s) => s.playbackSpeed, 1, number),
|
|
261
|
+
plain('cullingMode', (s) => s.cullingMode, 'always', validCullingMode),
|
|
262
|
+
plain('scalingMode', (s) => s.scalingMode, 'local', validScalingMode),
|
|
229
263
|
plain('seed', (s) => s.seed, undefined, number),
|
|
230
264
|
plain('sortMode', (s) => s.sortMode, 'none', validSortMode),
|
|
265
|
+
plain('renderFace', (s) => s.renderFace, 'both', validRenderFace),
|
|
231
266
|
plain(
|
|
232
267
|
'alignToDirection',
|
|
233
268
|
(s) => s.alignToDirection,
|
|
@@ -299,11 +334,16 @@ export function settingsFromJSON(json: ParticleSystemJSONParameters): Partial<Pa
|
|
|
299
334
|
if (value === undefined || value === null) {
|
|
300
335
|
continue;
|
|
301
336
|
}
|
|
302
|
-
const
|
|
337
|
+
const key = settingJSONKey(setting);
|
|
338
|
+
const read = readFormatPart(key, () => setting.fromJSON(value));
|
|
303
339
|
if (read !== undefined) {
|
|
304
340
|
parameters[setting.param] = read;
|
|
305
341
|
}
|
|
306
342
|
}
|
|
343
|
+
// Files before 0.29 wrote the stop action as `autoDestroy`.
|
|
344
|
+
if (parameters.stopAction === undefined && fields.autoDestroy === true) {
|
|
345
|
+
parameters.stopAction = 'destroy';
|
|
346
|
+
}
|
|
307
347
|
return parameters as Partial<ParticleSystemParameters>;
|
|
308
348
|
}
|
|
309
349
|
|
package/src/system/types.ts
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
|
+
import type {BaseTexture} from '@babylonjs/core/Materials/Textures/baseTexture';
|
|
1
2
|
import type {Texture} from '@babylonjs/core/Materials/Textures/texture';
|
|
2
3
|
import type {Scene} from '@babylonjs/core/scene';
|
|
3
4
|
import type {
|
|
4
5
|
Behavior,
|
|
6
|
+
BehaviorJSON,
|
|
5
7
|
ColorGenerator,
|
|
8
|
+
ColorGeneratorJSON,
|
|
6
9
|
EmitterShape,
|
|
7
10
|
FunctionColorGenerator,
|
|
8
|
-
FunctionJSON,
|
|
9
11
|
FunctionValueGenerator,
|
|
10
12
|
RendererEmitterSettings,
|
|
11
13
|
RotationGenerator,
|
|
14
|
+
RotationGeneratorJSON,
|
|
15
|
+
ShapeJSON,
|
|
16
|
+
StretchedBillBoardSettings,
|
|
12
17
|
ValueGenerator,
|
|
18
|
+
ValueGeneratorJSON,
|
|
13
19
|
Vector2,
|
|
14
20
|
Vector3,
|
|
21
|
+
Vector3ArrayJSON,
|
|
15
22
|
Vector3Generator,
|
|
23
|
+
Vector3GeneratorJSON,
|
|
24
|
+
Vector3JSON,
|
|
16
25
|
} from 'quarks.core';
|
|
17
26
|
import type {
|
|
18
27
|
MeshLighting,
|
|
@@ -20,10 +29,28 @@ import type {
|
|
|
20
29
|
ParticleErosionOptions,
|
|
21
30
|
ParticleGradientMap,
|
|
22
31
|
ParticleUVDistortionOptions,
|
|
32
|
+
RenderFace,
|
|
23
33
|
RenderMode,
|
|
24
34
|
SortMode,
|
|
25
35
|
TextureUV,
|
|
26
36
|
} from '../VFXBatch';
|
|
37
|
+
import type {GeometryEntry, QuarksMaterialJSON} from '../effectDocumentJSON';
|
|
38
|
+
import type {TrailOptions} from '../trailSettings';
|
|
39
|
+
import type {ParticleMaterialSource} from './materialResolve';
|
|
40
|
+
|
|
41
|
+
/** A trail's settings in JSON, each only when not its default: the start length as a generator's JSON, the side axis as `[x, y, z]`. */
|
|
42
|
+
export type TrailSettingsJSON = Partial<TrailOptions> & {
|
|
43
|
+
/** See `TrailSettings.startLength`. */
|
|
44
|
+
startLength?: ValueGeneratorJSON;
|
|
45
|
+
/** See `TrailSettings.sideAxis`; files may hold it as `{x, y, z}`. */
|
|
46
|
+
sideAxis?: Vector3ArrayJSON | Vector3JSON;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* A render mode's own settings in JSON, see {@link RendererEmitterSettings}: a trail's or a
|
|
51
|
+
* stretched billboard's. The other render modes have none, and their systems leave the field out.
|
|
52
|
+
*/
|
|
53
|
+
export type RendererEmitterSettingsJSON = TrailSettingsJSON | StretchedBillBoardSettings;
|
|
27
54
|
|
|
28
55
|
/**
|
|
29
56
|
* One burst of a system's emission (Unity's Emission Bursts): `count` particles at `time` seconds
|
|
@@ -64,22 +91,78 @@ export interface BurstParameters {
|
|
|
64
91
|
* An empty system is never culled, so it can start emitting and grow the
|
|
65
92
|
* bounds that decide its visibility. A system another one emits into is never
|
|
66
93
|
* culled either; its parent decides.
|
|
94
|
+
*
|
|
95
|
+
* The cameras tested are the scene's active cameras (`scene.activeCameras`, or
|
|
96
|
+
* `scene.activeCamera`), each only for the systems on a layer it renders
|
|
97
|
+
* (`camera.layerMask & system.layers.mask`). A camera that renders into a
|
|
98
|
+
* render target texture (a mirror, a minimap, a portal) is not one of them: a
|
|
99
|
+
* system seen only through one should keep `'always'`.
|
|
67
100
|
*/
|
|
68
101
|
export type CullingMode = 'always' | 'pause' | 'pauseAndCatchUp';
|
|
69
102
|
|
|
70
103
|
/**
|
|
71
|
-
* What
|
|
72
|
-
*
|
|
73
|
-
*
|
|
104
|
+
* What a system does once it has finished, its emission over and its last particle dead (Unity's
|
|
105
|
+
* Stop Action):
|
|
106
|
+
*
|
|
107
|
+
* - `'none'` (the default): nothing; {@link ParticleSystem.restart} plays it again.
|
|
108
|
+
* - `'disable'`: disables its emitter node (`setEnabled(false)`), and with it the nodes under it.
|
|
109
|
+
* A disabled system is not advanced or drawn; enable the emitter again before playing it.
|
|
110
|
+
* - `'destroy'`: disposes the system and its emitter, as `ParticleSystem.dispose()` does.
|
|
111
|
+
*
|
|
112
|
+
* Unity's Callback is the system's `finished` event, which fires whatever the stop action. The
|
|
113
|
+
* action waits for the system's sub emitters, see {@link ParticleSystem.stopAction}. A disabled
|
|
114
|
+
* emitter is state like any other: saved as not visible, and copied disabled by `clone`.
|
|
115
|
+
*/
|
|
116
|
+
export type StopAction = 'none' | 'disable' | 'destroy';
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* What a full system does with the particles it emits next (Unity's Ring Buffer Mode). It needs
|
|
120
|
+
* {@link ParticleSystemParameters.maxParticles}; without a limit it is ignored.
|
|
121
|
+
*
|
|
122
|
+
* - `'disabled'` (the default): particles die at the end of their life, and a full system drops
|
|
123
|
+
* what it would emit.
|
|
124
|
+
* - `'pauseUntilReplaced'`: a particle at the end of its life stays where and as it is, frozen,
|
|
125
|
+
* until a new particle replaces it, the oldest first. For footprints, decals and bullet holes.
|
|
126
|
+
* - `'loopUntilReplaced'`: a particle at the end of its life goes back to an earlier point of it
|
|
127
|
+
* and plays that part again, over and over, until a new particle replaces it; see
|
|
128
|
+
* {@link ParticleSystem.ringBufferLoopRange}.
|
|
129
|
+
*
|
|
130
|
+
* Particles are never killed by age, so a system in either mode keeps its particles and does not
|
|
131
|
+
* finish while it has any: a non-looping ring effect never fires `finished`, and an
|
|
132
|
+
* `EffectPool` copy of it returns to the pool only when it is released. A replaced particle
|
|
133
|
+
* does not fire `particleDied`, nor Death sub emitters, which never fire in either mode since
|
|
134
|
+
* no particle dies. Lowering `maxParticles` drops the oldest particles over the new limit, also
|
|
135
|
+
* without `particleDied`. Particles are replaced oldest first in the order they were emitted;
|
|
136
|
+
* switching a mode on in a system whose particles have already died in a different order
|
|
137
|
+
* replaces them in row order the first time round. `'oldestInFront'` and `'youngestInFront'`
|
|
138
|
+
* sorting reads age, so a looping particle sorts by its age in the loop. Applies in every
|
|
139
|
+
* render mode but Trail, whose particles always die at the end of their life.
|
|
140
|
+
*/
|
|
141
|
+
export type RingBufferMode = 'disabled' | 'pauseUntilReplaced' | 'loopUntilReplaced';
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* What the emitter's scale does to the system, as Unity's Scaling Mode, in world and local space
|
|
145
|
+
* alike. The scale reaches the emission shape, the particles' size, their start speed and, in world
|
|
146
|
+
* space, `ForceOverLife`, `ApplyForce` and `LimitSpeedOverLife` (by the mean of the axes), so a
|
|
147
|
+
* scaled effect looks and moves like a scaled model, except where a mode leaves it out:
|
|
74
148
|
*
|
|
75
|
-
* - `'
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
* - `'
|
|
79
|
-
*
|
|
80
|
-
*
|
|
149
|
+
* - `'local'` (default, as in Unity): only the emitter's own `scaling`; its parents' scale is left
|
|
150
|
+
* out, so an effect keeps its size under a scaled character or prop.
|
|
151
|
+
* - `'hierarchy'`: the emitter's whole world scale, its parents' included.
|
|
152
|
+
* - `'shape'`: the world scale sizes the emission shape alone; the particles keep their size and
|
|
153
|
+
* speed, so a bigger emitter spreads the same particles over a larger area.
|
|
154
|
+
*
|
|
155
|
+
* Under every mode the emitter's position, rotation and any mirroring come from the whole
|
|
156
|
+
* hierarchy; only the length of each axis changes. A sub emission starts in its parent particle's
|
|
157
|
+
* frame and takes its size and speed from that, not from the sub emitter's scale; `'shape'` still
|
|
158
|
+
* scales its shape by the sub emitter's world scale. With a non-uniform scale `'shape'` stretches
|
|
159
|
+
* where particles start, not the directions the shape sends them.
|
|
160
|
+
*
|
|
161
|
+
* Known differences from Unity: a world force (`ForceOverLife`, `ApplyForce`, and so the gravity
|
|
162
|
+
* the Unity exporter writes) is scaled with the motion in `'local'` and `'hierarchy'`, where
|
|
163
|
+
* Unity's gravity is not.
|
|
81
164
|
*/
|
|
82
|
-
export type ScalingMode = '
|
|
165
|
+
export type ScalingMode = 'local' | 'hierarchy' | 'shape';
|
|
83
166
|
|
|
84
167
|
/**
|
|
85
168
|
* Where a {@link RenderMode.Beam} system's quads end: a point in world space,
|
|
@@ -112,7 +195,12 @@ export type BeamEnd =
|
|
|
112
195
|
* default named on it, the same default `fromJSON` gives a file that leaves it out.
|
|
113
196
|
*/
|
|
114
197
|
export interface ParticleSystemParameters {
|
|
115
|
-
/**
|
|
198
|
+
/** What the system does once it has finished, see {@link StopAction}. Default `'none'`. */
|
|
199
|
+
stopAction?: StopAction;
|
|
200
|
+
/**
|
|
201
|
+
* `true` is `stopAction: 'destroy'`; read only when `stopAction` is left out.
|
|
202
|
+
* @deprecated Use `stopAction: 'destroy'`.
|
|
203
|
+
*/
|
|
116
204
|
autoDestroy?: boolean;
|
|
117
205
|
/** See {@link ParticleSystem.looping}. Default true. */
|
|
118
206
|
looping?: boolean;
|
|
@@ -144,6 +232,10 @@ export interface ParticleSystemParameters {
|
|
|
144
232
|
emissionBursts?: Array<BurstParameters>;
|
|
145
233
|
/** Most particles alive at once; emission past it is dropped. Leave unset for no limit. */
|
|
146
234
|
maxParticles?: number;
|
|
235
|
+
/** What a full system does with new particles, see {@link RingBufferMode}. Default `'disabled'`. */
|
|
236
|
+
ringBufferMode?: RingBufferMode;
|
|
237
|
+
/** See {@link ParticleSystem.ringBufferLoopRange}. Default the whole life, (0, 1). */
|
|
238
|
+
ringBufferLoopRange?: Vector2;
|
|
147
239
|
/** See {@link ParticleSystem.onlyUsedByOther}. Default false. */
|
|
148
240
|
onlyUsedByOther?: boolean;
|
|
149
241
|
/** See {@link ParticleSystem.behaviors}. Default none. */
|
|
@@ -169,7 +261,7 @@ export interface ParticleSystemParameters {
|
|
|
169
261
|
/** @deprecated Set `speedFactor` in {@link rendererEmitterSettings} instead; this one wins when both are set. */
|
|
170
262
|
speedFactor?: number;
|
|
171
263
|
/** See {@link ParticleSystem.material}. Default none. */
|
|
172
|
-
material?:
|
|
264
|
+
material?: ParticleMaterialSource | null;
|
|
173
265
|
/** See {@link ParticleSystem.texture}. Unset takes the material's texture; null draws without one. */
|
|
174
266
|
texture?: Texture | null;
|
|
175
267
|
/** See {@link ParticleSystem.startTileIndex}. Default 0. */
|
|
@@ -230,12 +322,14 @@ export interface ParticleSystemParameters {
|
|
|
230
322
|
playbackSpeed?: number;
|
|
231
323
|
/** What the system does while off screen, see {@link CullingMode}. Default `'always'`. */
|
|
232
324
|
cullingMode?: CullingMode;
|
|
233
|
-
/** What the emitter's scale does to
|
|
325
|
+
/** What the emitter's scale does to the system, see {@link ScalingMode}. Default `'local'`. */
|
|
234
326
|
scalingMode?: ScalingMode;
|
|
235
327
|
/** Seed for this system's own random generator, see {@link ParticleSystem.seed}. Default none. */
|
|
236
328
|
seed?: number;
|
|
237
329
|
/** Draw order within the batch, see {@link ParticleSystem.sortMode}. Default `'none'`. */
|
|
238
330
|
sortMode?: SortMode;
|
|
331
|
+
/** Which faces a mesh particle draws, see {@link ParticleSystem.renderFace}. Default `'both'`. */
|
|
332
|
+
renderFace?: RenderFace;
|
|
239
333
|
/** Whether particles start turned along their direction of travel, see {@link ParticleSystem.alignToDirection}. Default false. */
|
|
240
334
|
alignToDirection?: boolean;
|
|
241
335
|
/** Smallest on-screen size, as a fraction of the viewport height, see {@link ParticleSystem.minParticleSize}. Default 0. */
|
|
@@ -246,6 +340,8 @@ export interface ParticleSystemParameters {
|
|
|
246
340
|
renderingGroupId?: number;
|
|
247
341
|
/** Whether the scene's fog applies, see {@link ParticleSystem.applyFog}. Default true. */
|
|
248
342
|
applyFog?: boolean;
|
|
343
|
+
/** Whether the scene's image processing applies, see {@link ParticleSystem.applyImageProcessing}. Default true. */
|
|
344
|
+
applyImageProcessing?: boolean;
|
|
249
345
|
/** Scene the emitter node is created in. Default Babylon's last created scene. */
|
|
250
346
|
scene?: Scene;
|
|
251
347
|
}
|
|
@@ -255,13 +351,15 @@ export interface BurstParametersJSON {
|
|
|
255
351
|
/** See {@link BurstParameters.time}. */
|
|
256
352
|
time: number;
|
|
257
353
|
/** See {@link BurstParameters.count}. */
|
|
258
|
-
count:
|
|
354
|
+
count: ValueGeneratorJSON | number;
|
|
259
355
|
/** See {@link BurstParameters.cycle}. */
|
|
260
356
|
cycle: number;
|
|
261
357
|
/** See {@link BurstParameters.interval}. */
|
|
262
358
|
interval: number;
|
|
263
359
|
/** See {@link BurstParameters.probability}. */
|
|
264
360
|
probability: number;
|
|
361
|
+
/** `cycle`, as files before it was named wrote it; read when there is no `cycle`. */
|
|
362
|
+
cycleCount?: number;
|
|
265
363
|
}
|
|
266
364
|
|
|
267
365
|
/**
|
|
@@ -277,7 +375,9 @@ export interface BurstParametersJSON {
|
|
|
277
375
|
export interface ParticleSystemJSONParameters {
|
|
278
376
|
/** The quarks.core version line the system was written with. */
|
|
279
377
|
version: string;
|
|
280
|
-
/**
|
|
378
|
+
/** Written only when not `'none'`. */
|
|
379
|
+
stopAction?: StopAction;
|
|
380
|
+
/** Read from older files: `true` is `stopAction: 'destroy'`. No longer written. */
|
|
281
381
|
autoDestroy?: boolean;
|
|
282
382
|
/** See {@link ParticleSystem.looping}. */
|
|
283
383
|
looping?: boolean;
|
|
@@ -288,36 +388,40 @@ export interface ParticleSystemJSONParameters {
|
|
|
288
388
|
/** See {@link ParticleSystem.duration}. */
|
|
289
389
|
duration?: number;
|
|
290
390
|
/** See {@link ParticleSystem.startDelay}. */
|
|
291
|
-
startDelay?:
|
|
391
|
+
startDelay?: ValueGeneratorJSON;
|
|
292
392
|
/** The emitter shape, as its `toJSON` writes it. */
|
|
293
|
-
shape?:
|
|
393
|
+
shape?: ShapeJSON;
|
|
294
394
|
/** See {@link ParticleSystem.startLife}. */
|
|
295
|
-
startLife?:
|
|
395
|
+
startLife?: ValueGeneratorJSON;
|
|
296
396
|
/** See {@link ParticleSystem.startSpeed}. */
|
|
297
|
-
startSpeed?:
|
|
397
|
+
startSpeed?: ValueGeneratorJSON;
|
|
298
398
|
/** See {@link ParticleSystem.startRotation}. */
|
|
299
|
-
startRotation?:
|
|
399
|
+
startRotation?: ValueGeneratorJSON | RotationGeneratorJSON;
|
|
300
400
|
/** See {@link ParticleSystem.startSize}. */
|
|
301
|
-
startSize?:
|
|
401
|
+
startSize?: ValueGeneratorJSON | Vector3GeneratorJSON;
|
|
302
402
|
/** See {@link ParticleSystem.startColor}. */
|
|
303
|
-
startColor?:
|
|
403
|
+
startColor?: ColorGeneratorJSON;
|
|
304
404
|
/** See {@link ParticleSystem.emissionOverTime}. */
|
|
305
|
-
emissionOverTime?:
|
|
405
|
+
emissionOverTime?: ValueGeneratorJSON;
|
|
306
406
|
/** See {@link ParticleSystem.emissionOverDistance}. */
|
|
307
|
-
emissionOverDistance?:
|
|
407
|
+
emissionOverDistance?: ValueGeneratorJSON;
|
|
308
408
|
/** See {@link ParticleSystem.emissionBursts}. */
|
|
309
409
|
emissionBursts?: Array<BurstParametersJSON>;
|
|
310
410
|
/** See {@link ParticleSystem.maxParticles}. */
|
|
311
411
|
maxParticles?: number;
|
|
412
|
+
/** Written only when not `'disabled'`. */
|
|
413
|
+
ringBufferMode?: RingBufferMode;
|
|
414
|
+
/** `[start, end]`; written only when not `[0, 1]`. */
|
|
415
|
+
ringBufferLoopRange?: [number, number];
|
|
312
416
|
/** See {@link ParticleSystem.onlyUsedByOther}. */
|
|
313
417
|
onlyUsedByOther?: boolean;
|
|
314
418
|
/**
|
|
315
|
-
* Trail, stretched or mesh settings; a trail's `startLength` as `
|
|
419
|
+
* Trail, stretched or mesh settings; a trail's `startLength` as `ValueGeneratorJSON`. Left out when
|
|
316
420
|
* the render mode has none.
|
|
317
421
|
*/
|
|
318
|
-
rendererEmitterSettings?:
|
|
319
|
-
/** Uuid of the mesh particles' geometry entry. */
|
|
320
|
-
instancingGeometry?:
|
|
422
|
+
rendererEmitterSettings?: RendererEmitterSettingsJSON;
|
|
423
|
+
/** Uuid of the mesh particles' geometry entry; a document made in code may hold the entry itself. */
|
|
424
|
+
instancingGeometry?: string | GeometryEntry;
|
|
321
425
|
/** A {@link RenderMode} value. */
|
|
322
426
|
renderMode?: number;
|
|
323
427
|
/** See {@link ParticleSystem.renderOrder}. */
|
|
@@ -326,16 +430,20 @@ export interface ParticleSystemJSONParameters {
|
|
|
326
430
|
renderingGroupId?: number;
|
|
327
431
|
/** Written only when false. */
|
|
328
432
|
applyFog?: boolean;
|
|
433
|
+
/** Written only when false. */
|
|
434
|
+
applyImageProcessing?: boolean;
|
|
329
435
|
/** Written only when not 1. */
|
|
330
436
|
playbackSpeed?: number;
|
|
331
437
|
/** Written only when not `'always'`. */
|
|
332
438
|
cullingMode?: CullingMode;
|
|
333
|
-
/** Written only when not `'
|
|
439
|
+
/** Written only when not `'local'`. */
|
|
334
440
|
scalingMode?: ScalingMode;
|
|
335
441
|
/** Written only when set. */
|
|
336
442
|
seed?: number;
|
|
337
443
|
/** Written only when not `'none'`. */
|
|
338
444
|
sortMode?: SortMode;
|
|
445
|
+
/** Written only when not `'both'`. */
|
|
446
|
+
renderFace?: RenderFace;
|
|
339
447
|
/** Written only when true. */
|
|
340
448
|
alignToDirection?: boolean;
|
|
341
449
|
/** Written only when not 0. */
|
|
@@ -351,7 +459,7 @@ export interface ParticleSystemJSONParameters {
|
|
|
351
459
|
/** The camera layer mask. */
|
|
352
460
|
layers?: number;
|
|
353
461
|
/** See {@link ParticleSystem.startTileIndex}. */
|
|
354
|
-
startTileIndex?:
|
|
462
|
+
startTileIndex?: ValueGeneratorJSON | number;
|
|
355
463
|
/** See {@link ParticleSystem.uTileCount}. */
|
|
356
464
|
uTileCount?: number;
|
|
357
465
|
/** See {@link ParticleSystem.vTileCount}. */
|
|
@@ -375,7 +483,7 @@ export interface ParticleSystemJSONParameters {
|
|
|
375
483
|
/** See {@link ParticleSystemParameters.alphaTest}. */
|
|
376
484
|
alphaTest?: number;
|
|
377
485
|
/** Each behavior as its `toJSON` writes it. */
|
|
378
|
-
behaviors?:
|
|
486
|
+
behaviors?: BehaviorJSON[];
|
|
379
487
|
/** See {@link ParticleSystem.worldSpace}. */
|
|
380
488
|
worldSpace?: boolean;
|
|
381
489
|
/** `[x, y, z]`; written only when non-zero. */
|
|
@@ -392,19 +500,19 @@ export interface ParticleSystemJSONParameters {
|
|
|
392
500
|
*/
|
|
393
501
|
export interface BabylonMetaData {
|
|
394
502
|
/** Textures by uuid; null for one that could not be made. */
|
|
395
|
-
textures: {[uuid: string]:
|
|
503
|
+
textures: {[uuid: string]: BaseTexture | null};
|
|
396
504
|
/** Material entries by uuid. */
|
|
397
|
-
materials: {[uuid: string]:
|
|
505
|
+
materials: {[uuid: string]: QuarksMaterialJSON};
|
|
398
506
|
/** Geometry entries by uuid. */
|
|
399
|
-
geometries: {[uuid: string]:
|
|
400
|
-
/**
|
|
401
|
-
images?: {[uuid: string]:
|
|
507
|
+
geometries: {[uuid: string]: GeometryEntry};
|
|
508
|
+
/** Not used by babylon.quarks; kept for three.js-shaped documents. */
|
|
509
|
+
images?: {[uuid: string]: unknown};
|
|
510
|
+
/** Not used by babylon.quarks; kept for three.js-shaped documents. */
|
|
511
|
+
shapes?: {[uuid: string]: unknown};
|
|
402
512
|
/** Not used by babylon.quarks; kept for three.js-shaped documents. */
|
|
403
|
-
|
|
513
|
+
skeletons?: {[uuid: string]: unknown};
|
|
404
514
|
/** Not used by babylon.quarks; kept for three.js-shaped documents. */
|
|
405
|
-
|
|
515
|
+
animations?: {[uuid: string]: unknown};
|
|
406
516
|
/** Not used by babylon.quarks; kept for three.js-shaped documents. */
|
|
407
|
-
|
|
408
|
-
/** Nodes by uuid, which a mesh surface shape links to. */
|
|
409
|
-
nodes?: {[uuid: string]: any};
|
|
517
|
+
nodes?: {[uuid: string]: unknown};
|
|
410
518
|
}
|
package/src/trailSettings.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type {TrailSettings, TrailTextureMode} from 'quarks.core';
|
|
2
2
|
|
|
3
|
+
/** A trail's settings other than its start length and side axis, alike in code and in JSON. */
|
|
4
|
+
export type TrailOptions = Omit<TrailSettings, 'startLength' | 'sideAxis'>;
|
|
5
|
+
|
|
3
6
|
/**
|
|
4
7
|
* The normalised values of a trail's optional settings (`TrailSettings`), each read with its
|
|
5
8
|
* default for a value that is unset or out of range, so the batch, the simulation, JSON and
|
|
@@ -10,13 +13,13 @@ import type {TrailSettings, TrailTextureMode} from 'quarks.core';
|
|
|
10
13
|
export const MAX_TRAIL_TESSELLATION = 16;
|
|
11
14
|
|
|
12
15
|
/** A trail's tessellation, a whole number from 0 (the default: none) to {@link MAX_TRAIL_TESSELLATION}. */
|
|
13
|
-
export function trailTessellation(settings:
|
|
16
|
+
export function trailTessellation(settings: Partial<TrailOptions> | undefined): number {
|
|
14
17
|
const value = Math.round(Number(settings?.tessellation) || 0);
|
|
15
18
|
return Math.min(MAX_TRAIL_TESSELLATION, Math.max(0, value));
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
/** A trail's curve tension, from 0 (the default: Catmull-Rom) to 1 (straight segments). */
|
|
19
|
-
export function trailCurveTension(settings:
|
|
22
|
+
export function trailCurveTension(settings: Partial<TrailOptions> | undefined): number {
|
|
20
23
|
const value = Number(settings?.curveTension) || 0;
|
|
21
24
|
return Math.min(1, Math.max(0, value));
|
|
22
25
|
}
|
|
@@ -24,19 +27,19 @@ export function trailCurveTension(settings: TrailSettings | undefined): number {
|
|
|
24
27
|
const TEXTURE_MODES: readonly TrailTextureMode[] = ['stretch', 'tile', 'distributePerSegment', 'repeatPerSegment'];
|
|
25
28
|
|
|
26
29
|
/** A trail's texture mode, `'stretch'` (the default) unless set to one of the others. */
|
|
27
|
-
export function trailTextureMode(settings:
|
|
30
|
+
export function trailTextureMode(settings: Partial<TrailOptions> | undefined): TrailTextureMode {
|
|
28
31
|
const mode = settings?.textureMode;
|
|
29
32
|
return mode !== undefined && TEXTURE_MODES.includes(mode) ? mode : 'stretch';
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
/** A trail's texture scale: a finite number above 0, else the default 1. */
|
|
33
|
-
export function trailTextureScale(settings:
|
|
36
|
+
export function trailTextureScale(settings: Partial<TrailOptions> | undefined): number {
|
|
34
37
|
const value = Number(settings?.textureScale);
|
|
35
38
|
return Number.isFinite(value) && value > 0 ? value : 1;
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
/** A trail's minimum distance between samples: a finite number of at least 0, else the default 0. */
|
|
39
|
-
export function trailMinVertexDistance(settings:
|
|
42
|
+
export function trailMinVertexDistance(settings: Partial<TrailOptions> | undefined): number {
|
|
40
43
|
const value = Number(settings?.minVertexDistance);
|
|
41
44
|
return Number.isFinite(value) && value > 0 ? value : 0;
|
|
42
45
|
}
|
|
@@ -45,7 +48,7 @@ export function trailMinVertexDistance(settings: TrailSettings | undefined): num
|
|
|
45
48
|
* How long a trail keeps a sample, in seconds: a finite number above 0, else `Infinity` (the
|
|
46
49
|
* default, as 0 is: until the history is full).
|
|
47
50
|
*/
|
|
48
|
-
export function trailLifetime(settings:
|
|
51
|
+
export function trailLifetime(settings: Partial<TrailOptions> | undefined): number {
|
|
49
52
|
const value = Number(settings?.lifetime);
|
|
50
53
|
return Number.isFinite(value) && value > 0 ? value : Infinity;
|
|
51
54
|
}
|