@needle-tools/engine 2.40.0-pre → 2.42.0-pre

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 (80) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/needle-engine.d.ts +332 -126
  3. package/dist/needle-engine.js +401 -401
  4. package/dist/needle-engine.js.map +4 -4
  5. package/dist/needle-engine.min.js +53 -53
  6. package/dist/needle-engine.min.js.map +4 -4
  7. package/lib/engine/engine_element.js +1 -1
  8. package/lib/engine/engine_element.js.map +1 -1
  9. package/lib/engine/engine_element_loading.js +6 -1
  10. package/lib/engine/engine_element_loading.js.map +1 -1
  11. package/lib/engine/engine_gizmos.d.ts +8 -21
  12. package/lib/engine/engine_gizmos.js +51 -5
  13. package/lib/engine/engine_gizmos.js.map +1 -1
  14. package/lib/engine/engine_math.d.ts +9 -6
  15. package/lib/engine/engine_math.js +9 -0
  16. package/lib/engine/engine_math.js.map +1 -1
  17. package/lib/engine/engine_physics.js +14 -6
  18. package/lib/engine/engine_physics.js.map +1 -1
  19. package/lib/engine/engine_serialization_core.js +2 -0
  20. package/lib/engine/engine_serialization_core.js.map +1 -1
  21. package/lib/engine/engine_setup.d.ts +3 -0
  22. package/lib/engine/engine_setup.js +15 -0
  23. package/lib/engine/engine_setup.js.map +1 -1
  24. package/lib/engine/engine_three_utils.d.ts +16 -1
  25. package/lib/engine/engine_three_utils.js +94 -54
  26. package/lib/engine/engine_three_utils.js.map +1 -1
  27. package/lib/engine/engine_types.d.ts +6 -0
  28. package/lib/engine/engine_types.js.map +1 -1
  29. package/lib/engine/engine_utils.d.ts +1 -0
  30. package/lib/engine/engine_utils.js +3 -0
  31. package/lib/engine/engine_utils.js.map +1 -1
  32. package/lib/engine-components/AnimationCurve.js +20 -5
  33. package/lib/engine-components/AnimationCurve.js.map +1 -1
  34. package/lib/engine-components/BoxHelperComponent.js +9 -10
  35. package/lib/engine-components/BoxHelperComponent.js.map +1 -1
  36. package/lib/engine-components/Light.d.ts +2 -0
  37. package/lib/engine-components/Light.js +33 -9
  38. package/lib/engine-components/Light.js.map +1 -1
  39. package/lib/engine-components/ParticleSystem.d.ts +29 -26
  40. package/lib/engine-components/ParticleSystem.js +349 -187
  41. package/lib/engine-components/ParticleSystem.js.map +1 -1
  42. package/lib/engine-components/ParticleSystemModules.d.ts +243 -64
  43. package/lib/engine-components/ParticleSystemModules.js +722 -153
  44. package/lib/engine-components/ParticleSystemModules.js.map +1 -1
  45. package/lib/engine-components/ReflectionProbe.js +29 -11
  46. package/lib/engine-components/ReflectionProbe.js.map +1 -1
  47. package/lib/engine-components/Renderer.d.ts +1 -0
  48. package/lib/engine-components/Renderer.js +4 -2
  49. package/lib/engine-components/Renderer.js.map +1 -1
  50. package/lib/engine-components/WebXR.js +8 -3
  51. package/lib/engine-components/WebXR.js.map +1 -1
  52. package/lib/engine-components/codegen/components.d.ts +7 -0
  53. package/lib/engine-components/codegen/components.js +7 -0
  54. package/lib/engine-components/codegen/components.js.map +1 -1
  55. package/package.json +4 -2
  56. package/src/engine/codegen/register_types.js +28 -0
  57. package/src/engine/dist/engine_three_utils.js +279 -0
  58. package/src/engine/engine_element.ts +1 -1
  59. package/src/engine/engine_element_loading.ts +5 -1
  60. package/src/engine/engine_gizmos.ts +58 -6
  61. package/src/engine/engine_math.ts +19 -6
  62. package/src/engine/engine_physics.ts +17 -7
  63. package/src/engine/engine_serialization_core.ts +1 -0
  64. package/src/engine/engine_setup.ts +25 -2
  65. package/src/engine/engine_three_utils.ts +103 -62
  66. package/src/engine/engine_types.ts +8 -1
  67. package/src/engine/engine_utils.ts +5 -0
  68. package/src/engine-components/AnimationCurve.ts +25 -11
  69. package/src/engine-components/BoxHelperComponent.ts +12 -15
  70. package/src/engine-components/Light.ts +39 -8
  71. package/src/engine-components/ParticleSystem.ts +395 -199
  72. package/src/engine-components/ParticleSystemModules.ts +638 -152
  73. package/src/engine-components/ReflectionProbe.ts +37 -13
  74. package/src/engine-components/Renderer.ts +4 -2
  75. package/src/engine-components/WebXR.ts +11 -8
  76. package/src/engine-components/codegen/components.ts +7 -0
  77. package/src/engine/dist/engine_physics.js +0 -739
  78. package/src/engine/dist/engine_setup.js +0 -777
  79. package/src/engine-components/dist/CharacterController.js +0 -123
  80. package/src/engine-components/dist/RigidBody.js +0 -458
@@ -1,173 +1,659 @@
1
+ import { init } from "@dimforge/rapier3d-compat";
1
2
  import * as THREE from "three";
3
+ import { Color, Matrix4, Object3D, Vector3 } from "three";
4
+ import { Mathf } from "../engine/engine_math";
5
+ import { serializeable } from "../engine/engine_serialization";
6
+ import { RGBAColor } from "./js-extensions/RGBAColor";
7
+ import { AnimationCurve } from "./AnimationCurve";
8
+ import { Vec3 } from "../engine/engine_types";
9
+
10
+ declare type Color4 = { r: number, g: number, b: number, a: number };
11
+ declare type ColorKey = { time: number, color: Color4 };
12
+ declare type AlphaKey = { time: number, alpha: number };
13
+
14
+ export interface IParticleSystem {
15
+ get currentParticles(): number;
16
+ get maxParticles(): number;
17
+ get time(): number;
18
+ get duration(): number;
19
+ readonly main: MainModule;
20
+ }
21
+
22
+ export enum ParticleSystemRenderMode {
23
+ Billboard = 0,
24
+ // Stretch = 1,
25
+ // HorizontalBillboard = 2,
26
+ // VerticalBillboard = 3,
27
+ Mesh = 4,
28
+ // None = 5,
29
+ }
30
+
31
+
32
+ export class Gradient {
33
+ @serializeable()
34
+ alphaKeys!: Array<AlphaKey>;
35
+ @serializeable()
36
+ colorKeys!: Array<ColorKey>;
37
+
38
+ get duration(): number {
39
+ return 1;
40
+ }
41
+
42
+ evaluate(time: number, target: RGBAColor) {
43
+
44
+ // target.r = this.colorKeys[0].color.r;
45
+ // target.g = this.colorKeys[0].color.g;
46
+ // target.b = this.colorKeys[0].color.b;
47
+ // target.alpha = this.alphaKeys[0].alpha;
48
+ // return;
49
+
50
+ let closestAlpha: AlphaKey | undefined = undefined;
51
+ let closestAlphaIndex = 0;
52
+ let closestColor: ColorKey | null = null;
53
+ let closestColorIndex = 0;
54
+ for (let i = 0; i < this.alphaKeys.length; i++) {
55
+ const key = this.alphaKeys[i];
56
+ if (key.time < time || !closestAlpha) {
57
+ closestAlpha = key;
58
+ closestAlphaIndex = i;
59
+ }
60
+ }
61
+ for (let i = 0; i < this.colorKeys.length; i++) {
62
+ const key = this.colorKeys[i];
63
+ if (key.time < time || !closestColor) {
64
+ closestColor = key;
65
+ closestColorIndex = i;
66
+ }
67
+ }
68
+ if (closestColor) {
69
+ const hasNextColor = closestColorIndex + 1 < this.colorKeys.length;
70
+ if (hasNextColor) {
71
+ const nextColor = this.colorKeys[closestColorIndex + 1];
72
+ const t = Mathf.remap(time, closestColor.time, nextColor.time, 0, 1);
73
+ target.r = Mathf.lerp(closestColor.color.r, nextColor.color.r, t);
74
+ target.g = Mathf.lerp(closestColor.color.g, nextColor.color.g, t);
75
+ target.b = Mathf.lerp(closestColor.color.b, nextColor.color.b, t);
76
+ }
77
+ else {
78
+ target.r = closestColor.color.r;
79
+ target.g = closestColor.color.g;
80
+ target.b = closestColor.color.b;
81
+ }
82
+ }
83
+ if (closestAlpha) {
84
+ const hasNextAlpha = closestAlphaIndex + 1 < this.alphaKeys.length;
85
+ if (hasNextAlpha) {
86
+ const nextAlpha = this.alphaKeys[closestAlphaIndex + 1];
87
+ const t = Mathf.remap(time, closestAlpha.time, nextAlpha.time, 0, 1);
88
+ target.alpha = Mathf.lerp(closestAlpha.alpha, nextAlpha.alpha, t);
89
+ }
90
+ else {
91
+ target.alpha = closestAlpha.alpha;
92
+ }
93
+ }
94
+ return target;
95
+ }
96
+ }
97
+
98
+ export enum ParticleSystemCurveMode {
99
+ Constant = 0,
100
+ Curve = 1,
101
+ TwoCurves = 2,
102
+ TwoConstants = 3
103
+ }
104
+
105
+ export enum ParticleSystemGradientMode {
106
+ Color = 0,
107
+ Gradient = 1,
108
+ TwoColors = 2,
109
+ TwoGradients = 3,
110
+ RandomColor = 4,
111
+ }
112
+
113
+ export enum ParticleSystemSimulationSpace {
114
+ Local = 0,
115
+ World = 1,
116
+ Custom = 2
117
+ }
118
+
119
+ export enum ParticleSystemShapeType {
120
+ Sphere = 0,
121
+ SphereShell = 1,
122
+ Hemisphere = 2,
123
+ HemisphereShell = 3,
124
+ Cone = 4,
125
+ Box = 5,
126
+ Mesh = 6,
127
+ ConeShell = 7,
128
+ ConeVolume = 8,
129
+ ConeVolumeShell = 9,
130
+ Circle = 10,
131
+ CircleEdge = 11,
132
+ SingleSidedEdge = 12,
133
+ MeshRenderer = 13,
134
+ SkinnedMeshRenderer = 14,
135
+ BoxShell = 15,
136
+ BoxEdge = 16,
137
+ Donut = 17,
138
+ Rectangle = 18,
139
+ Sprite = 19,
140
+ SpriteRenderer = 20
141
+ }
142
+
143
+
144
+ export class MinMaxCurve {
145
+ @serializeable()
146
+ mode!: ParticleSystemCurveMode;
147
+ @serializeable()
148
+ constant!: number;
149
+ @serializeable()
150
+ constantMin!: number;
151
+ @serializeable()
152
+ constantMax!: number;
153
+ @serializeable(AnimationCurve)
154
+ curve?: AnimationCurve;
155
+ @serializeable(AnimationCurve)
156
+ curveMin?: AnimationCurve;
157
+ @serializeable(AnimationCurve)
158
+ curveMax?: AnimationCurve;
159
+ @serializeable()
160
+ curveMultiplier?: number;
161
+
162
+ evaluate(t01: number, lerpFactor?: number): number {
163
+ const t = lerpFactor === undefined ? Math.random() : lerpFactor;
164
+ switch (this.mode) {
165
+ case ParticleSystemCurveMode.Constant:
166
+ return this.constant;
167
+ case ParticleSystemCurveMode.Curve:
168
+ t01 %= this.curve!.duration;
169
+ return this.curve!.evaluate(t01);
170
+ case ParticleSystemCurveMode.TwoCurves:
171
+ const t1 = t01 * this.curveMin!.duration;
172
+ const t2 = t01 * this.curveMax!.duration;
173
+ return Mathf.lerp(this.curveMin!.evaluate(t1), this.curveMax!.evaluate(t2), t % 1);
174
+ case ParticleSystemCurveMode.TwoConstants:
175
+ return Mathf.lerp(this.constantMin, this.constantMax, t % 1);
176
+ default:
177
+ this.curveMax!.evaluate(t01) * this.curveMultiplier!;
178
+ break;
179
+ }
180
+ return 0;
181
+ }
182
+ }
183
+
184
+ export class MinMaxGradient {
185
+ mode!: ParticleSystemGradientMode;
186
+ @serializeable(RGBAColor)
187
+ color!: RGBAColor;
188
+ @serializeable(RGBAColor)
189
+ colorMin!: RGBAColor;
190
+ @serializeable(RGBAColor)
191
+ colorMax!: RGBAColor;
192
+ @serializeable(Gradient)
193
+ gradient!: Gradient;
194
+ @serializeable(Gradient)
195
+ gradientMin!: Gradient;
196
+ @serializeable(Gradient)
197
+ gradientMax!: Gradient;
198
+
199
+ private static _temp: RGBAColor = new RGBAColor(0, 0, 0, 1);
200
+ private static _temp2: RGBAColor = new RGBAColor(0, 0, 0, 1);
201
+
202
+ evaluate(t01: number, lerpFactor?: number): RGBAColor {
203
+ const t = lerpFactor === undefined ? Math.random() : lerpFactor;
204
+ switch (this.mode) {
205
+ case ParticleSystemGradientMode.Color:
206
+ return this.color;
207
+ case ParticleSystemGradientMode.Gradient:
208
+ this.gradient.evaluate(t01, MinMaxGradient._temp);
209
+ return MinMaxGradient._temp
210
+ case ParticleSystemGradientMode.TwoColors:
211
+ return MinMaxGradient._temp.lerpColors(this.colorMin, this.colorMax, t);
212
+ case ParticleSystemGradientMode.TwoGradients:
213
+ const t2 = Math.random();
214
+ this.gradientMin.evaluate(t2, MinMaxGradient._temp);
215
+ this.gradientMax.evaluate(t2, MinMaxGradient._temp2);
216
+ return MinMaxGradient._temp.lerp(MinMaxGradient._temp2, t);
217
+
218
+ }
219
+ // console.warn("Not implemented", ParticleSystemGradientMode[this.mode]);
220
+ MinMaxGradient._temp.set(0xff00ff)
221
+ MinMaxGradient._temp.alpha = 1;
222
+ return MinMaxGradient._temp;
223
+ }
224
+ }
225
+
226
+ declare type ParticleSystemScalingMode = {
227
+ Hierarchy: number;
228
+ Local: number;
229
+ Shape: number;
230
+ }
2
231
 
3
232
  export class MainModule {
4
- randomizeRotationDirection: number = 0;
5
- duration: number = 5;
6
- loop: boolean = true;
7
- prewarm: boolean = false;
8
- startDelay = undefined; // UnityEngine.ParticleSystem+MinMaxCurve
9
- startDelayMultiplier: number = 0;
10
- startLifetime = undefined; // UnityEngine.ParticleSystem+MinMaxCurve
11
- startLifetimeMultiplier: number = 5;
12
- startSpeed = undefined; // UnityEngine.ParticleSystem+MinMaxCurve
13
- startSpeedMultiplier: number = 5;
14
- startSize3D: boolean = false;
15
- startSize = undefined; // UnityEngine.ParticleSystem+MinMaxCurve
16
- startSizeMultiplier: number = 1;
17
- startSizeX = undefined; // UnityEngine.ParticleSystem+MinMaxCurve
18
- startSizeXMultiplier: number = 1;
19
- startSizeY = undefined; // UnityEngine.ParticleSystem+MinMaxCurve
20
- startSizeYMultiplier: number = 1;
21
- startSizeZ = undefined; // UnityEngine.ParticleSystem+MinMaxCurve
22
- startSizeZMultiplier: number = 1;
23
- startRotation3D: boolean = false;
24
- startRotation = undefined; // UnityEngine.ParticleSystem+MinMaxCurve
25
- startRotationMultiplier: number = 0;
26
- startRotationX = undefined; // UnityEngine.ParticleSystem+MinMaxCurve
27
- startRotationXMultiplier: number = 0;
28
- startRotationY = undefined; // UnityEngine.ParticleSystem+MinMaxCurve
29
- startRotationYMultiplier: number = 0;
30
- startRotationZ = undefined; // UnityEngine.ParticleSystem+MinMaxCurve
31
- startRotationZMultiplier: number = 0;
32
- flipRotation: number = 0;
33
- startColor : THREE.Color = new THREE.Color(1, 1, 1);
34
- startColor1 : THREE.Color | undefined = new THREE.Color(0, 0, 0); // this only exists in gradient mode
35
- gravityModifier = undefined; // UnityEngine.ParticleSystem+MinMaxCurve
36
- gravityModifierMultiplier: number = 0;
37
- simulationSpace: number = 0;
38
- customSimulationSpace = null;
39
- simulationSpeed: number = 1;
40
- useUnscaledTime: boolean = false;
41
- scalingMode: number = 1;
42
- playOnAwake: boolean = true;
43
- maxParticles: number = 1000;
44
- emitterVelocityMode: number = 1;
45
- stopAction: number = 0;
46
- ringBufferMode: number = 0;
47
- ringBufferLoopRange: THREE.Vector2 = new THREE.Vector2(0, 1);
48
- cullingMode: number = 0;
233
+ cullingMode!: number;
234
+ duration!: number;
235
+ emitterVelocityMode!: number;
236
+ flipRotation!: number;
237
+ @serializeable(MinMaxCurve)
238
+ gravityModifier!: MinMaxCurve;
239
+ gravityModifierMultiplier!: number;
240
+ loop!: boolean;
241
+ maxParticles!: number;
242
+ playOnAwake!: boolean;
243
+ prewarm!: boolean;
244
+ ringBufferLoopRange!: { x: number, y: number };
245
+ ringBufferMode!: boolean;
246
+ scalingMode!: ParticleSystemScalingMode;
247
+ simulationSpace!: ParticleSystemSimulationSpace;
248
+ simulationSpeed!: number;
249
+ @serializeable(MinMaxGradient)
250
+ startColor!: MinMaxGradient;
251
+ @serializeable(MinMaxCurve)
252
+ startDelay!: MinMaxCurve;
253
+ startDelayMultiplier!: number;
254
+ @serializeable(MinMaxCurve)
255
+ startLifetime!: MinMaxCurve;
256
+ startLifetimeMultiplier!: number;
257
+ @serializeable(MinMaxCurve)
258
+ startRotation!: MinMaxCurve;
259
+ startRotationMultiplier!: number;
260
+ startRotation3D!: boolean;
261
+ @serializeable(MinMaxCurve)
262
+ startRotationX!: MinMaxCurve;
263
+ startRotationXMultiplier!: number;
264
+ @serializeable(MinMaxCurve)
265
+ startRotationY!: MinMaxCurve;
266
+ startRotationYMultiplier!: number;
267
+ @serializeable(MinMaxCurve)
268
+ startRotationZ!: MinMaxCurve;
269
+ startRotationZMultiplier!: number;
270
+ @serializeable(MinMaxCurve)
271
+ startSize!: MinMaxCurve;
272
+ startSize3D!: boolean;
273
+ startSizeMultiplier!: number;
274
+ @serializeable(MinMaxCurve)
275
+ startSizeX!: MinMaxCurve;
276
+ startSizeXMultiplier!: number;
277
+ @serializeable(MinMaxCurve)
278
+ startSizeY!: MinMaxCurve;
279
+ startSizeYMultiplier!: number;
280
+ @serializeable(MinMaxCurve)
281
+ startSizeZ!: MinMaxCurve;
282
+ startSizeZMultiplier!: number;
283
+ @serializeable(MinMaxCurve)
284
+ startSpeed!: MinMaxCurve;
285
+ startSpeedMultiplier!: number;
286
+ stopAction!: number;
287
+ useUnscaledTime!: boolean;
49
288
  }
50
289
 
51
290
 
291
+ export class ParticleBurst {
292
+ cycleCount!: number;
293
+ maxCount!: number;
294
+ minCount!: number;
295
+ probability!: number;
296
+ repeatInterval!: number;
297
+ time!: number;
298
+ count!: {
299
+ constant: number;
300
+ constantMax: number;
301
+ constantMin: number;
302
+ curve?: AnimationCurve;
303
+ curveMax?: AnimationCurve;
304
+ curveMin?: AnimationCurve;
305
+ curveMultiplier?: number;
306
+ mode: ParticleSystemCurveMode;
307
+ }
308
+
309
+
310
+ private _performed: number = 0;
311
+
312
+
313
+ reset() {
314
+ this._performed = 0;
315
+ }
316
+ run(time: number): number {
317
+ if (time <= this.time) {
318
+ this.reset();
319
+ return 0;
320
+ }
321
+ let amount = 0;
322
+ if (this.cycleCount === 0 || this._performed < this.cycleCount) {
323
+ const nextTime = this.time + this.repeatInterval * this._performed;
324
+ if (time >= nextTime) {
325
+ this._performed += 1;
326
+ if (Math.random() < this.probability) {
327
+ switch (this.count.mode) {
328
+ case ParticleSystemCurveMode.Constant:
329
+ amount = this.count.constant;
330
+ break;
331
+ case ParticleSystemCurveMode.TwoConstants:
332
+ amount = Mathf.lerp(this.count.constantMin, this.count.constantMax, Math.random());
333
+ break;
334
+ case ParticleSystemCurveMode.Curve:
335
+ amount = this.count.curve!.evaluate(Math.random());
336
+ break;
337
+ case ParticleSystemCurveMode.TwoCurves:
338
+ const t = Math.random();
339
+ amount = Mathf.lerp(this.count.curveMin!.evaluate(t), this.count.curveMax!.evaluate(t), Math.random());
340
+ break;
341
+ }
342
+ }
343
+ }
344
+ }
345
+ return amount;
346
+ }
347
+ }
348
+
52
349
  export class EmissionModule {
53
- burstCount: number = 0;
54
- enabled: boolean = true;
55
- rate: number = 10;
56
- rateMutliplier: number = 1;
57
- rateOverDistance: number = 0;
58
- rateOverDistanceMultiplier: number = 0;
59
- rateOverTime: number = 0;
60
- rateOverTimeMultiplier: number = 0;
61
- // type: number = 0; // is obsolete, time and emission are both active
350
+
351
+ @serializeable()
352
+ enabled!: boolean;
353
+
354
+
355
+ get burstCount() {
356
+ return this.bursts?.length ?? 0;
357
+ }
358
+
359
+ @serializeable()
360
+ bursts!: ParticleBurst[];
361
+
362
+ @serializeable(MinMaxCurve)
363
+ rateOverTime!: MinMaxCurve;
364
+ @serializeable()
365
+ rateOverTimeMultiplier!: number;
366
+
367
+ @serializeable(MinMaxCurve)
368
+ rateOverDistance!: MinMaxCurve;
369
+ @serializeable()
370
+ rateOverDistanceMultiplier!: number;
371
+
372
+
373
+ /** set from system */
374
+ system!: IParticleSystem;
375
+ get time() { return this.system.time; }
376
+
377
+ private _summed: number = 0;
378
+ // private _didEmit: boolean = false;
379
+
380
+ /** called by nebula */
381
+ init() {
382
+ }
383
+
384
+ /** called by nebula */
385
+ getValue(deltaTime: number) {
386
+ if (this.system.currentParticles >= this.system.maxParticles)
387
+ return 0;
388
+ if (!this.enabled) return 0;
389
+ let count = this.rateOverTime.evaluate(this.time / this.system.duration, Math.random());
390
+ this._summed += count * deltaTime;
391
+ let amount = Math.floor(this._summed);
392
+ this._summed -= amount;
393
+
394
+ if (this.burstCount > 0) {
395
+ for (let i = 0; i < this.burstCount; i++) {
396
+ const burst = this.bursts[i];
397
+ if (burst.time >= this.time) {
398
+ burst.reset();
399
+ continue;
400
+ }
401
+ amount += Math.round(burst.run(this.time));
402
+ }
403
+ }
404
+
405
+ // dont emit more than we are allowed to
406
+ return amount;//Mathf.clamp(amount, 0, this.system.maxParticles - this.system.currentParticles);
407
+ }
408
+ }
409
+
410
+ export class ColorOverLifetimeModule {
411
+ enabled!: boolean;
412
+ @serializeable(MinMaxGradient)
413
+ color!: MinMaxGradient;
414
+ }
415
+
416
+ export class SizeOverLifetimeModule {
417
+ enabled!: boolean;
418
+ separateAxes!: boolean;
419
+ @serializeable(MinMaxCurve)
420
+ size!: MinMaxCurve;
421
+ sizeMultiplier!: number;
422
+ @serializeable(MinMaxCurve)
423
+ sizeX!: MinMaxCurve;
424
+ sizeXMultiplier!: number;
425
+ @serializeable(MinMaxCurve)
426
+ sizeY!: MinMaxCurve;
427
+ sizeYMultiplier!: number;
428
+ @serializeable(MinMaxCurve)
429
+ sizeZ!: MinMaxCurve;
430
+ sizeZMultiplier!: number;
431
+
432
+ private _time: number = 0;
433
+
434
+ evaluate(t01: number, target: Vec3) {
435
+ if (!this.separateAxes) {
436
+ const scale = this.size.evaluate(t01) * this.sizeMultiplier;
437
+ target.x = scale;
438
+ // target.y = scale;
439
+ // target.z = scale;
440
+ }
441
+ else {
442
+ target.x = this.sizeX.evaluate(this._time) * this.sizeXMultiplier;
443
+ // target.y = this.sizeY.evaluate(this._time) * this.sizeYMultiplier;
444
+ // target.z = this.sizeZ.evaluate(this._time) * this.sizeZMultiplier;
445
+ }
446
+ return target;
447
+ }
62
448
  }
63
449
 
64
450
  export class ShapeModule {
65
- shapeType : ParticleSystemShapeType = ParticleSystemShapeType.Box;
451
+ @serializeable()
452
+ shapeType: ParticleSystemShapeType = ParticleSystemShapeType.Box;
453
+ @serializeable()
66
454
  enabled: boolean = true;
455
+ @serializeable()
67
456
  alignToDirection: boolean = false;
457
+ @serializeable()
68
458
  angle: number = 0;
459
+ @serializeable()
69
460
  arc: number = 360;
461
+ @serializeable()
70
462
  arcmode: number = 0; // TODO: enum?
71
463
  // arcSpeed, arcSpeedMult, arcSpread
72
- box: THREE.Vector3 = new THREE.Vector3(1, 1, 1);
73
- boxThickness: THREE.Vector3 = new THREE.Vector3(0, 0, 0);
74
- position : THREE.Vector3 = new THREE.Vector3(0, 0, 0);
75
- rotation : THREE.Vector3 = new THREE.Vector3(0, 0, 0);
76
- scale : THREE.Vector3 = new THREE.Vector3(1, 1, 1);
464
+ // @serializeable(Vector3)
465
+ // box!: Vector3;
466
+ @serializeable(Vector3)
467
+ boxThickness!: Vector3;
468
+ @serializeable(Vector3)
469
+ position!: Vector3;
470
+ @serializeable(Vector3)
471
+ rotation!: Vector3;
472
+ @serializeable(Vector3)
473
+ scale!: Vector3;
474
+
475
+ @serializeable()
476
+ radius!: number;
477
+ @serializeable()
478
+ radiusThickness!: number;
479
+ @serializeable()
480
+ sphericalDirectionAmount!: number;
481
+
482
+ private _space?: ParticleSystemSimulationSpace;
483
+ private readonly _worldSpacePosition: Matrix4 = new Matrix4();
484
+
485
+ update(_context: Context, simulationSpace: ParticleSystemSimulationSpace, obj: Object3D) {
486
+ this._space = simulationSpace;
487
+ if (simulationSpace === ParticleSystemSimulationSpace.World) {
488
+ this._worldSpacePosition.copy(obj.matrixWorld);
489
+ // set scale to 1
490
+ this._worldSpacePosition.elements[0] = 1;
491
+ this._worldSpacePosition.elements[5] = 1;
492
+ this._worldSpacePosition.elements[10] = 1;
493
+ }
494
+ }
77
495
 
78
- radius : number = 1;
79
- sphericalDirectionAmount : number = 0;
496
+ /** nebula implementations: */
497
+
498
+ /** initializer implementation */
499
+ private _vector: Vector3 = new Vector3(0, 0, 0);
500
+ private _temp: Vector3 = new Vector3(0, 0, 0);
501
+ /** called by nebula on initialize */
502
+ get vector() {
503
+ return this._vector;
504
+ }
505
+ /** called by nebula */
506
+ getPosition(): void {
507
+ switch (this.shapeType) {
508
+ case ParticleSystemShapeType.Box:
509
+ this._vector.x = Math.random() * this.scale.x - this.scale.x / 2;
510
+ this._vector.y = Math.random() * this.scale.y - this.scale.y / 2;
511
+ this._vector.z = Math.random() * this.scale.z - this.scale.z / 2;
512
+ break;
513
+ case ParticleSystemShapeType.Sphere:
514
+ randomSpherePoint(this.position.x, this.position.y, this.position.z, this.radius, this.radiusThickness, this.arc, this._vector);
515
+ break;
516
+ // case ParticleSystemShapeType.Hemisphere:
517
+ // randomSpherePoint(this.position.x, this.position.y, this.position.z, this.radius, this.radiusThickness, 180, this._vector);
518
+ // break;
519
+ }
520
+ if (this._space === ParticleSystemSimulationSpace.World) {
521
+ this._vector.applyMatrix4(this._worldSpacePosition);
522
+ }
523
+ }
524
+
525
+
526
+
527
+ private _dir: Vector3 = new Vector3();
528
+ getDirection(position): Vector3 {
529
+ switch (this.shapeType) {
530
+ case ParticleSystemShapeType.Box:
531
+ return this._dir.set(0, 0, 1);
532
+ case ParticleSystemShapeType.Sphere:
533
+ const rx = position.x;
534
+ const ry = position.y;
535
+ const rz = position.z;
536
+ return this._dir.set(rx, ry, rz).normalize();
537
+ }
538
+ return this._dir.set(0, 1, 0);
539
+ }
80
540
  }
81
541
 
82
542
 
83
- /// <summary>
84
- /// <para>The emission shape.</para>
85
- /// </summary>
86
- export enum ParticleSystemShapeType {
87
- /// <summary>
88
- /// <para>Emit from a sphere.</para>
89
- /// </summary>
90
- Sphere = 0,
91
- /// <summary>
92
- /// <para>Emit from the surface of a sphere.</para>
93
- /// </summary>
94
- // [Obsolete("SphereShell is deprecated and does nothing. Please use ShapeModule.radiusThickness instead, to control edge emission.", false)] SphereShell,
95
- SphereShell,
96
- /// <summary>
97
- /// <para>Emit from a half-sphere.</para>
98
- /// </summary>
99
- Hemisphere,
100
- // / <summary>
101
- // / <para>Emit from the surface of a half-sphere.</para>
102
- // / </summary>
103
- // [Obsolete("HemisphereShell is deprecated and does nothing. Please use ShapeModule.radiusThickness instead, to control edge emission.", false)] HemisphereShell,
104
- HemisphereShell,
105
- /// <summary>
106
- /// <para>Emit from the base of a cone.</para>
107
- /// </summary>
108
- Cone,
109
- /// <summary>
110
- /// <para>Emit from the volume of a box.</para>
111
- /// </summary>
112
- Box = 5,
113
- /// <summary>
114
- /// <para>Emit from a mesh.</para>
115
- /// </summary>
116
- Mesh,
117
- /// <summary>
118
- /// <para>Emit from the base surface of a cone.</para>
119
- /// </summary>
120
- // [Obsolete("ConeShell is deprecated and does nothing. Please use ShapeModule.radiusThickness instead, to control edge emission.", false)] ConeShell,
121
- // /// <summary>
122
- // /// <para>Emit from a cone.</para>
123
- // /// </summary>
124
- ConeVolume,
125
- /// <summary>
126
- /// <para>Emit from the surface of a cone.</para>
127
- /// </summary>
128
- // [Obsolete("ConeVolumeShell is deprecated and does nothing. Please use ShapeModule.radiusThickness instead, to control edge emission.", false)] ConeVolumeShell,
129
- // /// <summary>
130
- // /// <para>Emit from a circle.</para>
131
- // /// </summary>
132
- Circle = 10,
133
- /// <summary>
134
- /// <para>Emit from the edge of a circle.</para>
135
- /// </summary>
136
- // [Obsolete("CircleEdge is deprecated and does nothing. Please use ShapeModule.radiusThickness instead, to control edge emission.", false)] CircleEdge,
137
- // /// <summary>
138
- // /// <para>Emit from an edge.</para>
139
- // /// </summary>
140
- SingleSidedEdge,
141
- /// <summary>
142
- /// <para>Emit from a mesh renderer.</para>
143
- /// </summary>
144
- MeshRenderer,
145
- /// <summary>
146
- /// <para>Emit from a skinned mesh renderer.</para>
147
- /// </summary>
148
- SkinnedMeshRenderer,
149
- /// <summary>
150
- /// <para>Emit from the surface of a box.</para>
151
- /// </summary>
152
- BoxShell,
153
- /// <summary>
154
- /// <para>Emit from the edges of a box.</para>
155
- /// </summary>
156
- BoxEdge,
157
- /// <summary>
158
- /// <para>Emit from a Donut.</para>
159
- /// </summary>
160
- Donut,
161
- /// <summary>
162
- /// <para>Emit from a rectangle.</para>
163
- /// </summary>
164
- Rectangle,
165
- /// <summary>
166
- /// <para>Emit from a sprite.</para>
167
- /// </summary>
168
- Sprite,
169
- /// <summary>
170
- /// <para>Emit from a sprite renderer.</para>
171
- /// </summary>
172
- SpriteRenderer,
543
+
544
+ function randomSpherePoint(x0: number, y0: number, z0: number, radius: number, thickness: number, arc: number, vec: Vec3) {
545
+ const u = Math.random();
546
+ const v = Math.random();
547
+ const theta = 2 * Math.PI * u * (arc / 360);
548
+ const phi = Math.acos(2 * v - 1);
549
+
550
+ const r = Mathf.lerp(1, 1 - (Math.pow(1 - Math.random(), Math.PI)), thickness) * radius;
551
+ const x = x0 + (-r * Math.sin(phi) * Math.cos(theta));
552
+ const y = y0 + (r * Math.sin(phi) * Math.sin(theta));
553
+ const z = z0 + (r * Math.cos(phi));
554
+ vec.x = x;
555
+ vec.y = y;
556
+ vec.z = z;
557
+ }
558
+
559
+
560
+ import { createNoise4D, NoiseFunction4D } from 'simplex-noise';
561
+ import { Context } from "../engine/engine_setup";
562
+
563
+ export class NoiseModule {
564
+ @serializeable()
565
+ damping!: boolean;
566
+ @serializeable()
567
+ enabled!: boolean;
568
+ @serializeable()
569
+ frequency!: number;
570
+ @serializeable()
571
+ octaveCount!: number;
572
+ @serializeable()
573
+ octaveMultiplier!: number;
574
+ @serializeable()
575
+ octaveScale!: number;
576
+ @serializeable(MinMaxCurve)
577
+ positionAmount!: MinMaxCurve;
578
+ @serializeable()
579
+ quality!: number;
580
+
581
+ @serializeable(MinMaxCurve)
582
+ remap!: MinMaxCurve;
583
+ @serializeable()
584
+ remapEnabled!: boolean;
585
+ @serializeable()
586
+ remapMultiplier!: number;
587
+ @serializeable(MinMaxCurve)
588
+ remapX!: MinMaxCurve;
589
+ @serializeable()
590
+ remapXMultiplier!: number;
591
+ @serializeable(MinMaxCurve)
592
+ remapY!: MinMaxCurve;
593
+ @serializeable()
594
+ remapYMultiplier!: number;
595
+ @serializeable(MinMaxCurve)
596
+ remapZ!: MinMaxCurve;
597
+ @serializeable()
598
+ remapZMultiplier!: number;
599
+
600
+ @serializeable()
601
+ scrollSpeedMultiplier!: number;
602
+ @serializeable()
603
+ separateAxes!: boolean;
604
+ @serializeable()
605
+ strengthMultiplier!: number;
606
+ @serializeable(MinMaxCurve)
607
+ strengthX!: MinMaxCurve;
608
+ @serializeable()
609
+ strengthXMultiplier!: number;
610
+ @serializeable(MinMaxCurve)
611
+ strengthY!: MinMaxCurve;
612
+ @serializeable()
613
+ strengthYMultiplier!: number;
614
+ @serializeable(MinMaxCurve)
615
+ strengthZ!: MinMaxCurve;
616
+ @serializeable()
617
+ strengthZMultiplier!: number;
618
+
619
+
620
+ private _noise?: NoiseFunction4D;
621
+ private _time: number = 0;
622
+
623
+ update(context: Context) {
624
+ this._time += context.time.deltaTime * this.scrollSpeedMultiplier;
625
+ }
626
+
627
+ /** nebula implementations: */
628
+ private _temp: Vector3 = new Vector3();
629
+ applyNoise(index: number, pos: Vec3, vel: Vec3, deltaTime: number, age: number, life: number) {
630
+ if (!this.enabled) return;
631
+ if (!this._noise) {
632
+ this._noise = createNoise4D(() => 0);
633
+ }
634
+ const t = age / life;
635
+ const dt = Context.Current.time.deltaTime;
636
+ const temp = this._temp.set(pos.x, pos.y, pos.z).multiplyScalar(this.frequency);
637
+ const nx = this._noise(temp.x, temp.y, temp.z, this._time);
638
+ const ny = this._noise(temp.x, temp.y, temp.z, this._time + .2);
639
+ const nz = this._noise(temp.x, temp.y, temp.z, this._time + .5);
640
+ this._temp.set(nx, ny, nz).normalize();
641
+
642
+ let strengthFactor = this.positionAmount.evaluate(t);
643
+ if (!this.separateAxes) {
644
+ if (this.strengthX)
645
+ strengthFactor *= this.strengthX.evaluate(t, index * 1.1);
646
+ else strengthFactor *= this.strengthMultiplier;
647
+ strengthFactor *= deltaTime;
648
+ this._temp.multiplyScalar(strengthFactor);
649
+ }
650
+ if (this.separateAxes) {
651
+ this._temp.x *= strengthFactor * deltaTime * this.strengthXMultiplier
652
+ this._temp.y *= strengthFactor * deltaTime * this.strengthYMultiplier;
653
+ this._temp.z *= strengthFactor * deltaTime * this.strengthZMultiplier;
654
+ }
655
+ vel.x += this._temp.x;
656
+ vel.y += this._temp.y;
657
+ vel.z += this._temp.z;
658
+ }
173
659
  }