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