@needle-tools/engine 2.42.0-pre → 2.44.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.
- package/CHANGELOG.md +22 -0
- package/dist/needle-engine.d.ts +224 -81
- package/dist/needle-engine.js +3836 -422
- package/dist/needle-engine.js.map +4 -4
- package/dist/needle-engine.min.js +40 -40
- package/dist/needle-engine.min.js.map +4 -4
- package/lib/engine/engine_element_loading.js +22 -6
- package/lib/engine/engine_element_loading.js.map +1 -1
- package/lib/engine/engine_input.js +17 -6
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_serialization_builtin_serializer.js +60 -58
- package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
- package/lib/engine/engine_three_utils.d.ts +1 -0
- package/lib/engine/engine_three_utils.js +10 -0
- package/lib/engine/engine_three_utils.js.map +1 -1
- package/lib/engine/engine_time.js +2 -0
- package/lib/engine/engine_time.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_techniques_webgl.js +42 -0
- package/lib/engine/extensions/NEEDLE_techniques_webgl.js.map +1 -1
- package/lib/engine-components/Animation.d.ts +3 -1
- package/lib/engine-components/Animation.js +25 -1
- package/lib/engine-components/Animation.js.map +1 -1
- package/lib/engine-components/AnimatorController.js +4 -1
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/Camera.d.ts +3 -0
- package/lib/engine-components/Camera.js +17 -9
- package/lib/engine-components/Camera.js.map +1 -1
- package/lib/engine-components/ParticleSystem.d.ts +33 -7
- package/lib/engine-components/ParticleSystem.js +464 -249
- package/lib/engine-components/ParticleSystem.js.map +1 -1
- package/lib/engine-components/ParticleSystemBehaviours.d.ts +0 -0
- package/lib/engine-components/ParticleSystemBehaviours.js +2 -0
- package/lib/engine-components/ParticleSystemBehaviours.js.map +1 -0
- package/lib/engine-components/ParticleSystemModules.d.ts +123 -20
- package/lib/engine-components/ParticleSystemModules.js +461 -63
- package/lib/engine-components/ParticleSystemModules.js.map +1 -1
- package/lib/engine-components/WebXRController.d.ts +1 -0
- package/lib/engine-components/WebXRController.js +2 -1
- package/lib/engine-components/WebXRController.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +6 -0
- package/lib/engine-components/codegen/components.js +6 -0
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/js-extensions/RGBAColor.d.ts +1 -0
- package/lib/engine-components/js-extensions/RGBAColor.js +7 -0
- package/lib/engine-components/js-extensions/RGBAColor.js.map +1 -1
- package/package.json +2 -1
- package/src/engine/codegen/register_types.js +24 -0
- package/src/engine/engine_element_loading.ts +22 -5
- package/src/engine/engine_input.ts +16 -7
- package/src/engine/engine_serialization_builtin_serializer.ts +59 -57
- package/src/engine/engine_three_utils.ts +11 -2
- package/src/engine/engine_time.ts +1 -0
- package/src/engine/extensions/NEEDLE_techniques_webgl.ts +43 -1
- package/src/engine-components/Animation.ts +18 -2
- package/src/engine-components/AnimatorController.ts +5 -1
- package/src/engine-components/Camera.ts +17 -10
- package/src/engine-components/ParticleSystem.ts +526 -303
- package/src/engine-components/ParticleSystemBehaviours.ts +0 -0
- package/src/engine-components/ParticleSystemModules.ts +408 -66
- package/src/engine-components/WebXRController.ts +2 -1
- package/src/engine-components/codegen/components.ts +6 -0
- package/src/engine-components/js-extensions/RGBAColor.ts +7 -0
|
File without changes
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { init } from "@dimforge/rapier3d-compat";
|
|
2
2
|
import * as THREE from "three";
|
|
3
|
-
import { Color, Matrix4, Object3D, Vector3 } from "three";
|
|
3
|
+
import { Color, Matrix4, Object3D, PointLightShadow, Quaternion, Vector3 } from "three";
|
|
4
4
|
import { Mathf } from "../engine/engine_math";
|
|
5
5
|
import { serializeable } from "../engine/engine_serialization";
|
|
6
6
|
import { RGBAColor } from "./js-extensions/RGBAColor";
|
|
7
7
|
import { AnimationCurve } from "./AnimationCurve";
|
|
8
|
-
import { Vec3 } from "../engine/engine_types";
|
|
8
|
+
import { Vec2, Vec3 } from "../engine/engine_types";
|
|
9
|
+
import { EmitterShape, FrameOverLife, Particle, ShapeJSON } from "three.quarks";
|
|
9
10
|
|
|
10
11
|
declare type Color4 = { r: number, g: number, b: number, a: number };
|
|
11
12
|
declare type ColorKey = { time: number, color: Color4 };
|
|
@@ -17,6 +18,10 @@ export interface IParticleSystem {
|
|
|
17
18
|
get time(): number;
|
|
18
19
|
get duration(): number;
|
|
19
20
|
readonly main: MainModule;
|
|
21
|
+
get container(): Object3D;
|
|
22
|
+
get worldQuaternion(): Quaternion;
|
|
23
|
+
get worldQuaternionInverted(): Quaternion;
|
|
24
|
+
get worldScale() : Vector3;
|
|
20
25
|
}
|
|
21
26
|
|
|
22
27
|
export enum ParticleSystemRenderMode {
|
|
@@ -165,14 +170,14 @@ export class MinMaxCurve {
|
|
|
165
170
|
case ParticleSystemCurveMode.Constant:
|
|
166
171
|
return this.constant;
|
|
167
172
|
case ParticleSystemCurveMode.Curve:
|
|
168
|
-
t01
|
|
169
|
-
return this.curve!.evaluate(t01)
|
|
173
|
+
t01 = Mathf.clamp01(t01);
|
|
174
|
+
return this.curve!.evaluate(t01) * this.curveMultiplier!;
|
|
170
175
|
case ParticleSystemCurveMode.TwoCurves:
|
|
171
176
|
const t1 = t01 * this.curveMin!.duration;
|
|
172
177
|
const t2 = t01 * this.curveMax!.duration;
|
|
173
|
-
return Mathf.lerp(this.curveMin!.evaluate(t1), this.curveMax!.evaluate(t2), t % 1)
|
|
178
|
+
return Mathf.lerp(this.curveMin!.evaluate(t1), this.curveMax!.evaluate(t2), t % 1) * this.curveMultiplier!;
|
|
174
179
|
case ParticleSystemCurveMode.TwoConstants:
|
|
175
|
-
return Mathf.lerp(this.constantMin, this.constantMax, t % 1)
|
|
180
|
+
return Mathf.lerp(this.constantMin, this.constantMax, t % 1)
|
|
176
181
|
default:
|
|
177
182
|
this.curveMax!.evaluate(t01) * this.curveMultiplier!;
|
|
178
183
|
break;
|
|
@@ -208,7 +213,8 @@ export class MinMaxGradient {
|
|
|
208
213
|
this.gradient.evaluate(t01, MinMaxGradient._temp);
|
|
209
214
|
return MinMaxGradient._temp
|
|
210
215
|
case ParticleSystemGradientMode.TwoColors:
|
|
211
|
-
|
|
216
|
+
const col1 = MinMaxGradient._temp.lerpColors(this.colorMin, this.colorMax, t);
|
|
217
|
+
return col1;
|
|
212
218
|
case ParticleSystemGradientMode.TwoGradients:
|
|
213
219
|
const t2 = Math.random();
|
|
214
220
|
this.gradientMin.evaluate(t2, MinMaxGradient._temp);
|
|
@@ -372,38 +378,23 @@ export class EmissionModule {
|
|
|
372
378
|
|
|
373
379
|
/** set from system */
|
|
374
380
|
system!: IParticleSystem;
|
|
375
|
-
get time() { return this.system.time; }
|
|
376
381
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
/** called by nebula */
|
|
381
|
-
init() {
|
|
382
|
+
reset() {
|
|
383
|
+
this.bursts?.forEach(b => b.reset());
|
|
382
384
|
}
|
|
383
385
|
|
|
384
|
-
|
|
385
|
-
|
|
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
|
-
|
|
386
|
+
getBurst() {
|
|
387
|
+
let amount = 0;
|
|
394
388
|
if (this.burstCount > 0) {
|
|
395
389
|
for (let i = 0; i < this.burstCount; i++) {
|
|
396
390
|
const burst = this.bursts[i];
|
|
397
|
-
if (burst.time >= this.time) {
|
|
391
|
+
if (burst.time >= this.system.time) {
|
|
398
392
|
burst.reset();
|
|
399
|
-
continue;
|
|
400
393
|
}
|
|
401
|
-
amount += Math.round(burst.run(this.time));
|
|
394
|
+
amount += Math.round(burst.run(this.system.time));
|
|
402
395
|
}
|
|
403
396
|
}
|
|
404
|
-
|
|
405
|
-
// dont emit more than we are allowed to
|
|
406
|
-
return amount;//Mathf.clamp(amount, 0, this.system.maxParticles - this.system.currentParticles);
|
|
397
|
+
return amount;
|
|
407
398
|
}
|
|
408
399
|
}
|
|
409
400
|
|
|
@@ -420,18 +411,26 @@ export class SizeOverLifetimeModule {
|
|
|
420
411
|
size!: MinMaxCurve;
|
|
421
412
|
sizeMultiplier!: number;
|
|
422
413
|
@serializeable(MinMaxCurve)
|
|
423
|
-
|
|
424
|
-
|
|
414
|
+
x!: MinMaxCurve;
|
|
415
|
+
xMultiplier!: number;
|
|
425
416
|
@serializeable(MinMaxCurve)
|
|
426
|
-
|
|
427
|
-
|
|
417
|
+
y!: MinMaxCurve;
|
|
418
|
+
yMultiplier!: number;
|
|
428
419
|
@serializeable(MinMaxCurve)
|
|
429
|
-
|
|
430
|
-
|
|
420
|
+
z!: MinMaxCurve;
|
|
421
|
+
zMultiplier!: number;
|
|
431
422
|
|
|
432
423
|
private _time: number = 0;
|
|
424
|
+
private _temp = new Vector3();
|
|
425
|
+
|
|
426
|
+
evaluate(t01: number, target?: Vec3) {
|
|
427
|
+
if (!target) target = this._temp;
|
|
428
|
+
|
|
429
|
+
if (!this.enabled) {
|
|
430
|
+
target.x = target.y = target.z = 1;
|
|
431
|
+
return target;
|
|
432
|
+
}
|
|
433
433
|
|
|
434
|
-
evaluate(t01: number, target: Vec3) {
|
|
435
434
|
if (!this.separateAxes) {
|
|
436
435
|
const scale = this.size.evaluate(t01) * this.sizeMultiplier;
|
|
437
436
|
target.x = scale;
|
|
@@ -439,15 +438,31 @@ export class SizeOverLifetimeModule {
|
|
|
439
438
|
// target.z = scale;
|
|
440
439
|
}
|
|
441
440
|
else {
|
|
442
|
-
target.x = this.
|
|
443
|
-
|
|
444
|
-
|
|
441
|
+
target.x = this.x.evaluate(t01) * this.xMultiplier;
|
|
442
|
+
target.y = this.y.evaluate(t01) * this.yMultiplier;
|
|
443
|
+
target.z = this.z.evaluate(t01) * this.zMultiplier;
|
|
445
444
|
}
|
|
446
445
|
return target;
|
|
447
446
|
}
|
|
448
447
|
}
|
|
449
448
|
|
|
450
|
-
export class ShapeModule {
|
|
449
|
+
export class ShapeModule implements EmitterShape {
|
|
450
|
+
|
|
451
|
+
get type(): string {
|
|
452
|
+
return ParticleSystemShapeType[this.shapeType];
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
initialize(particle: Particle): void {
|
|
456
|
+
this.getPosition();
|
|
457
|
+
particle.position.copy(this._vector);
|
|
458
|
+
}
|
|
459
|
+
toJSON(): ShapeJSON {
|
|
460
|
+
return this;
|
|
461
|
+
}
|
|
462
|
+
clone(): EmitterShape {
|
|
463
|
+
return new ShapeModule();
|
|
464
|
+
}
|
|
465
|
+
|
|
451
466
|
@serializeable()
|
|
452
467
|
shapeType: ParticleSystemShapeType = ParticleSystemShapeType.Box;
|
|
453
468
|
@serializeable()
|
|
@@ -479,17 +494,21 @@ export class ShapeModule {
|
|
|
479
494
|
@serializeable()
|
|
480
495
|
sphericalDirectionAmount!: number;
|
|
481
496
|
|
|
497
|
+
private system! : IParticleSystem;
|
|
482
498
|
private _space?: ParticleSystemSimulationSpace;
|
|
483
|
-
private readonly
|
|
499
|
+
private readonly _worldSpaceMatrix: Matrix4 = new Matrix4();
|
|
500
|
+
private readonly _worldSpaceMatrixInverse: Matrix4 = new Matrix4();
|
|
484
501
|
|
|
485
|
-
update(_context: Context, simulationSpace: ParticleSystemSimulationSpace, obj: Object3D) {
|
|
502
|
+
update(system : IParticleSystem, _context: Context, simulationSpace: ParticleSystemSimulationSpace, obj: Object3D) {
|
|
503
|
+
this.system = system;
|
|
486
504
|
this._space = simulationSpace;
|
|
487
505
|
if (simulationSpace === ParticleSystemSimulationSpace.World) {
|
|
488
|
-
this.
|
|
506
|
+
this._worldSpaceMatrix.copy(obj.matrixWorld);
|
|
489
507
|
// set scale to 1
|
|
490
|
-
this.
|
|
491
|
-
this.
|
|
492
|
-
this.
|
|
508
|
+
this._worldSpaceMatrix.elements[0] = 1;
|
|
509
|
+
this._worldSpaceMatrix.elements[5] = 1;
|
|
510
|
+
this._worldSpaceMatrix.elements[10] = 1;
|
|
511
|
+
this._worldSpaceMatrixInverse.copy(this._worldSpaceMatrix).invert();
|
|
493
512
|
}
|
|
494
513
|
}
|
|
495
514
|
|
|
@@ -502,7 +521,6 @@ export class ShapeModule {
|
|
|
502
521
|
get vector() {
|
|
503
522
|
return this._vector;
|
|
504
523
|
}
|
|
505
|
-
/** called by nebula */
|
|
506
524
|
getPosition(): void {
|
|
507
525
|
switch (this.shapeType) {
|
|
508
526
|
case ParticleSystemShapeType.Box:
|
|
@@ -511,14 +529,18 @@ export class ShapeModule {
|
|
|
511
529
|
this._vector.z = Math.random() * this.scale.z - this.scale.z / 2;
|
|
512
530
|
break;
|
|
513
531
|
case ParticleSystemShapeType.Sphere:
|
|
514
|
-
randomSpherePoint(this.position.x, this.position.y, this.position.z, this.radius, this.radiusThickness, this.arc, this._vector);
|
|
532
|
+
randomSpherePoint(this.position.x, this.position.y, this.position.z, this.radius * this.system.worldScale.x, this.radiusThickness, this.arc, this._vector);
|
|
533
|
+
// this._vector.y += 1;
|
|
534
|
+
break;
|
|
535
|
+
default:
|
|
536
|
+
this._vector.set(0, 0, 0);
|
|
515
537
|
break;
|
|
516
538
|
// case ParticleSystemShapeType.Hemisphere:
|
|
517
539
|
// randomSpherePoint(this.position.x, this.position.y, this.position.z, this.radius, this.radiusThickness, 180, this._vector);
|
|
518
540
|
// break;
|
|
519
541
|
}
|
|
520
542
|
if (this._space === ParticleSystemSimulationSpace.World) {
|
|
521
|
-
this._vector.applyMatrix4(this.
|
|
543
|
+
this._vector.applyMatrix4(this._worldSpaceMatrix);
|
|
522
544
|
}
|
|
523
545
|
}
|
|
524
546
|
|
|
@@ -528,14 +550,24 @@ export class ShapeModule {
|
|
|
528
550
|
getDirection(position): Vector3 {
|
|
529
551
|
switch (this.shapeType) {
|
|
530
552
|
case ParticleSystemShapeType.Box:
|
|
531
|
-
|
|
553
|
+
this._dir.set(0, 0, 1);
|
|
554
|
+
break;
|
|
532
555
|
case ParticleSystemShapeType.Sphere:
|
|
533
556
|
const rx = position.x;
|
|
534
557
|
const ry = position.y;
|
|
535
558
|
const rz = position.z;
|
|
536
|
-
|
|
559
|
+
this._dir.set(rx, ry, rz);
|
|
560
|
+
break;
|
|
561
|
+
default:
|
|
562
|
+
this._dir.set(0, 0, 1);
|
|
563
|
+
break;
|
|
537
564
|
}
|
|
538
|
-
|
|
565
|
+
if (this._space === ParticleSystemSimulationSpace.World) {
|
|
566
|
+
this._dir.applyMatrix4(this._worldSpaceMatrixInverse);
|
|
567
|
+
}
|
|
568
|
+
this._dir.normalize();
|
|
569
|
+
// Gizmos.DrawDirection(position, this._dir, 0xff0000, .5);
|
|
570
|
+
return this._dir;
|
|
539
571
|
}
|
|
540
572
|
}
|
|
541
573
|
|
|
@@ -559,6 +591,8 @@ function randomSpherePoint(x0: number, y0: number, z0: number, radius: number, t
|
|
|
559
591
|
|
|
560
592
|
import { createNoise4D, NoiseFunction4D } from 'simplex-noise';
|
|
561
593
|
import { Context } from "../engine/engine_setup";
|
|
594
|
+
import { getWorldQuaternion } from "../engine/engine_three_utils";
|
|
595
|
+
import { Gizmos } from "../engine/engine_gizmos";
|
|
562
596
|
|
|
563
597
|
export class NoiseModule {
|
|
564
598
|
@serializeable()
|
|
@@ -626,34 +660,342 @@ export class NoiseModule {
|
|
|
626
660
|
|
|
627
661
|
/** nebula implementations: */
|
|
628
662
|
private _temp: Vector3 = new Vector3();
|
|
629
|
-
|
|
663
|
+
apply(_index: number, pos: Vec3, vel: Vec3, _deltaTime: number, age: number, life: number) {
|
|
630
664
|
if (!this.enabled) return;
|
|
631
665
|
if (!this._noise) {
|
|
632
666
|
this._noise = createNoise4D(() => 0);
|
|
633
667
|
}
|
|
634
|
-
const t = age / life;
|
|
635
|
-
const dt = Context.Current.time.deltaTime;
|
|
636
668
|
const temp = this._temp.set(pos.x, pos.y, pos.z).multiplyScalar(this.frequency);
|
|
637
669
|
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 + .
|
|
639
|
-
const nz = this._noise(temp.x, temp.y, temp.z, this._time +
|
|
640
|
-
this._temp.set(nx, ny, nz).normalize()
|
|
670
|
+
const ny = this._noise(temp.x, temp.y, temp.z, this._time + .3);
|
|
671
|
+
const nz = this._noise(temp.x, temp.y, temp.z, this._time + 1);
|
|
672
|
+
this._temp.set(nx, ny, nz).normalize()
|
|
641
673
|
|
|
674
|
+
const t = age / life;
|
|
642
675
|
let strengthFactor = this.positionAmount.evaluate(t);
|
|
643
676
|
if (!this.separateAxes) {
|
|
644
|
-
if (this.strengthX)
|
|
645
|
-
strengthFactor *= this.strengthX.evaluate(t
|
|
646
|
-
|
|
647
|
-
strengthFactor *=
|
|
677
|
+
if (this.strengthX) {
|
|
678
|
+
strengthFactor *= this.strengthX.evaluate(t) * Math.PI;
|
|
679
|
+
}
|
|
680
|
+
// strengthFactor *= this.strengthMultiplier;
|
|
681
|
+
// strengthFactor *= deltaTime;
|
|
648
682
|
this._temp.multiplyScalar(strengthFactor);
|
|
649
683
|
}
|
|
650
|
-
|
|
651
|
-
this._temp.x *= strengthFactor *
|
|
652
|
-
this._temp.y *= strengthFactor *
|
|
653
|
-
this._temp.z *= strengthFactor *
|
|
684
|
+
else {
|
|
685
|
+
this._temp.x *= strengthFactor * this.strengthXMultiplier
|
|
686
|
+
this._temp.y *= strengthFactor * this.strengthYMultiplier;
|
|
687
|
+
this._temp.z *= strengthFactor * this.strengthZMultiplier;
|
|
688
|
+
}
|
|
689
|
+
// this._temp.setLength(strengthFactor * deltaTime);
|
|
690
|
+
vel.x += this._temp.x;
|
|
691
|
+
vel.y += this._temp.y;
|
|
692
|
+
vel.z += this._temp.z;
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
export class TrailModule {
|
|
697
|
+
|
|
698
|
+
@serializeable()
|
|
699
|
+
enabled!: boolean;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
export class VelocityOverLifetimeModule {
|
|
703
|
+
@serializeable()
|
|
704
|
+
enabled!: boolean;
|
|
705
|
+
|
|
706
|
+
/* orbital settings */
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
@serializeable()
|
|
710
|
+
space: ParticleSystemSimulationSpace = ParticleSystemSimulationSpace.Local;
|
|
711
|
+
|
|
712
|
+
@serializeable(MinMaxCurve)
|
|
713
|
+
speedModifier!: MinMaxCurve;
|
|
714
|
+
@serializeable()
|
|
715
|
+
speedModifierMultiplier!: number;
|
|
716
|
+
@serializeable(MinMaxCurve)
|
|
717
|
+
x!: MinMaxCurve;
|
|
718
|
+
@serializeable()
|
|
719
|
+
xMultiplier!: number;
|
|
720
|
+
@serializeable(MinMaxCurve)
|
|
721
|
+
y!: MinMaxCurve;
|
|
722
|
+
@serializeable()
|
|
723
|
+
yMultiplier!: number;
|
|
724
|
+
@serializeable(MinMaxCurve)
|
|
725
|
+
z!: MinMaxCurve;
|
|
726
|
+
@serializeable()
|
|
727
|
+
zMultiplier!: number;
|
|
728
|
+
|
|
729
|
+
private _system?: IParticleSystem;
|
|
730
|
+
// private _worldRotation: Quaternion = new Quaternion();
|
|
731
|
+
|
|
732
|
+
update(system: IParticleSystem) {
|
|
733
|
+
this._system = system;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
private _temp: Vector3 = new Vector3();
|
|
737
|
+
|
|
738
|
+
apply(_index: number, _pos: Vec3, vel: Vec3, _dt: number, age: number, life: number) {
|
|
739
|
+
if (!this.enabled) return;
|
|
740
|
+
const t = age / life;
|
|
741
|
+
|
|
742
|
+
const speed = this.speedModifier.evaluate(t) * this.speedModifierMultiplier;
|
|
743
|
+
const x = this.x.evaluate(t) * speed;
|
|
744
|
+
const y = this.y.evaluate(t) * speed;
|
|
745
|
+
const z = this.z.evaluate(t) * speed;
|
|
746
|
+
this._temp.set(-x, y, z);
|
|
747
|
+
if (this._system) {
|
|
748
|
+
if (this.space === ParticleSystemSimulationSpace.World) {
|
|
749
|
+
this._temp.applyQuaternion(this._system.worldQuaternionInverted);
|
|
750
|
+
}
|
|
751
|
+
if (this._system.main.simulationSpace === ParticleSystemSimulationSpace.World) {
|
|
752
|
+
this._temp.applyQuaternion(this._system.worldQuaternion);
|
|
753
|
+
}
|
|
654
754
|
}
|
|
655
755
|
vel.x += this._temp.x;
|
|
656
756
|
vel.y += this._temp.y;
|
|
657
757
|
vel.z += this._temp.z;
|
|
658
758
|
}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
enum ParticleSystemAnimationTimeMode {
|
|
764
|
+
Lifetime,
|
|
765
|
+
Speed,
|
|
766
|
+
FPS,
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
enum ParticleSystemAnimationMode {
|
|
770
|
+
Grid,
|
|
771
|
+
Sprites,
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
enum ParticleSystemAnimationRowMode {
|
|
775
|
+
Custom,
|
|
776
|
+
Random,
|
|
777
|
+
MeshIndex,
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
enum ParticleSystemAnimationType {
|
|
781
|
+
WholeSheet,
|
|
782
|
+
SingleRow,
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
export class TextureSheetAnimationModule {
|
|
786
|
+
|
|
787
|
+
@serializeable()
|
|
788
|
+
animation!: ParticleSystemAnimationType;
|
|
789
|
+
|
|
790
|
+
@serializeable()
|
|
791
|
+
enabled!: boolean;
|
|
792
|
+
|
|
793
|
+
@serializeable()
|
|
794
|
+
cycleCount!: number;
|
|
795
|
+
|
|
796
|
+
@serializeable(MinMaxCurve)
|
|
797
|
+
frameOverTime!: MinMaxCurve;
|
|
798
|
+
@serializeable()
|
|
799
|
+
frameOverTimeMultiplier!: number;
|
|
800
|
+
|
|
801
|
+
@serializeable()
|
|
802
|
+
numTilesX!: number;
|
|
803
|
+
@serializeable()
|
|
804
|
+
numTilesY!: number;
|
|
805
|
+
|
|
806
|
+
@serializeable(MinMaxCurve)
|
|
807
|
+
startFrame!: MinMaxCurve;
|
|
808
|
+
@serializeable()
|
|
809
|
+
startFrameMultiplier!: number;
|
|
810
|
+
|
|
811
|
+
@serializeable()
|
|
812
|
+
rowMode!: ParticleSystemAnimationRowMode;
|
|
813
|
+
@serializeable()
|
|
814
|
+
rowIndex!: number;
|
|
815
|
+
|
|
816
|
+
@serializeable()
|
|
817
|
+
spriteCount!: number;
|
|
818
|
+
|
|
819
|
+
@serializeable()
|
|
820
|
+
timeMode!: ParticleSystemAnimationTimeMode;
|
|
821
|
+
|
|
822
|
+
private sampleOnceAtStart(): boolean {
|
|
823
|
+
if (this.timeMode === ParticleSystemAnimationTimeMode.Lifetime) {
|
|
824
|
+
switch (this.frameOverTime.mode) {
|
|
825
|
+
case ParticleSystemCurveMode.Constant:
|
|
826
|
+
case ParticleSystemCurveMode.TwoConstants:
|
|
827
|
+
return true;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
return false;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
getStartIndex(): number {
|
|
834
|
+
if (this.sampleOnceAtStart()) {
|
|
835
|
+
return this.frameOverTime.evaluate(Math.random())
|
|
836
|
+
}
|
|
837
|
+
return 0;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
evaluate(t01: number): number | undefined {
|
|
841
|
+
if (this.sampleOnceAtStart()) {
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
return this.getIndex(t01);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
private getIndex(t01: number): number {
|
|
848
|
+
const tiles = this.numTilesX * this.numTilesY;
|
|
849
|
+
// let pos = t01 * this.cycleCount;
|
|
850
|
+
let index = this.frameOverTime.evaluate(t01 % 1);
|
|
851
|
+
index *= this.frameOverTimeMultiplier;
|
|
852
|
+
index *= tiles;
|
|
853
|
+
index = index % tiles;
|
|
854
|
+
index = Math.floor(index);
|
|
855
|
+
// console.log(index);
|
|
856
|
+
return index;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
|
|
861
|
+
export class RotationOverLifetimeModule {
|
|
862
|
+
@serializeable()
|
|
863
|
+
enabled!: boolean;
|
|
864
|
+
|
|
865
|
+
@serializeable()
|
|
866
|
+
separateAxes!: boolean;
|
|
867
|
+
|
|
868
|
+
@serializeable(MinMaxCurve)
|
|
869
|
+
x!: MinMaxCurve;
|
|
870
|
+
@serializeable()
|
|
871
|
+
xMultiplier!: number;
|
|
872
|
+
@serializeable(MinMaxCurve)
|
|
873
|
+
y!: MinMaxCurve;
|
|
874
|
+
@serializeable()
|
|
875
|
+
yMultiplier!: number;
|
|
876
|
+
@serializeable(MinMaxCurve)
|
|
877
|
+
z!: MinMaxCurve;
|
|
878
|
+
@serializeable()
|
|
879
|
+
zMultiplier!: number;
|
|
880
|
+
|
|
881
|
+
evaluate(t01: number): number {
|
|
882
|
+
if (!this.enabled) return 0;
|
|
883
|
+
if (!this.separateAxes) {
|
|
884
|
+
const rot = this.z.evaluate(t01) * -1;
|
|
885
|
+
return rot;
|
|
886
|
+
}
|
|
887
|
+
return 0;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
export class RotationBySpeedModule {
|
|
892
|
+
@serializeable()
|
|
893
|
+
enabled!: boolean;
|
|
894
|
+
|
|
895
|
+
@serializeable()
|
|
896
|
+
range!: Vec2;
|
|
897
|
+
|
|
898
|
+
@serializeable()
|
|
899
|
+
separateAxes!: boolean;
|
|
900
|
+
|
|
901
|
+
@serializeable(MinMaxCurve)
|
|
902
|
+
x!: MinMaxCurve;
|
|
903
|
+
@serializeable()
|
|
904
|
+
xMultiplier!: number;
|
|
905
|
+
@serializeable(MinMaxCurve)
|
|
906
|
+
y!: MinMaxCurve;
|
|
907
|
+
@serializeable()
|
|
908
|
+
yMultiplier!: number;
|
|
909
|
+
@serializeable(MinMaxCurve)
|
|
910
|
+
z!: MinMaxCurve;
|
|
911
|
+
@serializeable()
|
|
912
|
+
zMultiplier!: number;
|
|
913
|
+
|
|
914
|
+
evaluate(_t01: number, speed: number): number {
|
|
915
|
+
if (!this.enabled) return 0;
|
|
916
|
+
if (!this.separateAxes) {
|
|
917
|
+
const t = Mathf.lerp(this.range.x, this.range.y, speed);
|
|
918
|
+
const rot = this.z.evaluate(t) * -1;
|
|
919
|
+
return rot;
|
|
920
|
+
}
|
|
921
|
+
return 0;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
|
|
926
|
+
export class LimitVelocityOverLifetimeModule {
|
|
927
|
+
@serializeable()
|
|
928
|
+
enabled!: boolean;
|
|
929
|
+
|
|
930
|
+
@serializeable()
|
|
931
|
+
dampen!: number;
|
|
932
|
+
|
|
933
|
+
@serializeable(MinMaxCurve)
|
|
934
|
+
drag!: MinMaxCurve;
|
|
935
|
+
@serializeable()
|
|
936
|
+
dragMultiplier!: number;
|
|
937
|
+
|
|
938
|
+
@serializeable(MinMaxCurve)
|
|
939
|
+
limit!: MinMaxCurve;
|
|
940
|
+
@serializeable()
|
|
941
|
+
limitMultiplier!: number;
|
|
942
|
+
|
|
943
|
+
@serializeable()
|
|
944
|
+
separateAxes!: boolean;
|
|
945
|
+
|
|
946
|
+
@serializeable(MinMaxCurve)
|
|
947
|
+
limitX!: MinMaxCurve;
|
|
948
|
+
@serializeable()
|
|
949
|
+
limitXMultiplier!: number;
|
|
950
|
+
@serializeable(MinMaxCurve)
|
|
951
|
+
limitY!: MinMaxCurve;
|
|
952
|
+
@serializeable()
|
|
953
|
+
limitYMultiplier!: number;
|
|
954
|
+
@serializeable(MinMaxCurve)
|
|
955
|
+
limitZ!: MinMaxCurve;
|
|
956
|
+
@serializeable()
|
|
957
|
+
limitZMultiplier!: number;
|
|
958
|
+
|
|
959
|
+
@serializeable()
|
|
960
|
+
multiplyDragByParticleSize: boolean = false;
|
|
961
|
+
@serializeable()
|
|
962
|
+
multiplyDragByParticleVelocity: boolean = false;
|
|
963
|
+
|
|
964
|
+
@serializeable()
|
|
965
|
+
space!: ParticleSystemSimulationSpace;
|
|
966
|
+
|
|
967
|
+
private _temp: Vector3 = new Vector3();
|
|
968
|
+
private _temp2: Vector3 = new Vector3();
|
|
969
|
+
|
|
970
|
+
apply(_position: Vec3, baseVelocity: Vector3, currentVelocity: Vector3, _size: number, t01: number, _dt: number, _scale: number) {
|
|
971
|
+
if (!this.enabled) return;
|
|
972
|
+
// if (this.separateAxes) {
|
|
973
|
+
// // const maxX = this.limitX.evaluate(t01) * this.limitXMultiplier;
|
|
974
|
+
// // const maxY = this.limitY.evaluate(t01) * this.limitYMultiplier;
|
|
975
|
+
// // const maxZ = this.limitZ.evaluate(t01) * this.limitZMultiplier;
|
|
976
|
+
|
|
977
|
+
// }
|
|
978
|
+
// else
|
|
979
|
+
{
|
|
980
|
+
const max = this.limit.evaluate(t01) * this.limitMultiplier;
|
|
981
|
+
const speed = baseVelocity.length();
|
|
982
|
+
if (speed > max) {
|
|
983
|
+
this._temp.copy(baseVelocity).normalize().multiplyScalar(max);
|
|
984
|
+
let t = this.dampen * .5;
|
|
985
|
+
// t *= scale;
|
|
986
|
+
baseVelocity.x = Mathf.lerp(baseVelocity.x, this._temp.x, t);
|
|
987
|
+
baseVelocity.y = Mathf.lerp(baseVelocity.y, this._temp.y, t);
|
|
988
|
+
baseVelocity.z = Mathf.lerp(baseVelocity.z, this._temp.z, t);
|
|
989
|
+
|
|
990
|
+
// this._temp2.set(0, 0, 0);
|
|
991
|
+
currentVelocity.x = Mathf.lerp(currentVelocity.x, this._temp.x, t);
|
|
992
|
+
currentVelocity.y = Mathf.lerp(currentVelocity.y, this._temp.y, t);
|
|
993
|
+
currentVelocity.z = Mathf.lerp(currentVelocity.z, this._temp.z, t);
|
|
994
|
+
}
|
|
995
|
+
// vel.multiplyScalar(dragFactor);
|
|
996
|
+
}
|
|
997
|
+
// vel.x *= 0.3;
|
|
998
|
+
// vel.y *= 0.3;
|
|
999
|
+
// vel.z *= 0.3;
|
|
1000
|
+
}
|
|
659
1001
|
}
|
|
@@ -162,6 +162,7 @@ export class WebXRController extends Behaviour {
|
|
|
162
162
|
public grabbed: AttachedObject | null = null;
|
|
163
163
|
public input: XRInputSource | null = null;
|
|
164
164
|
public type: ControllerType = ControllerType.PhysicalDevice;
|
|
165
|
+
public showRaycastLine : boolean = true;
|
|
165
166
|
|
|
166
167
|
get isUsingHands(): boolean {
|
|
167
168
|
const r = this.input?.hand;
|
|
@@ -396,7 +397,7 @@ export class WebXRController extends Behaviour {
|
|
|
396
397
|
setWorldQuaternion(this.raycastLine, this.rayRotation);
|
|
397
398
|
}
|
|
398
399
|
else {
|
|
399
|
-
this.raycastLine.visible =
|
|
400
|
+
this.raycastLine.visible = this.showRaycastLine;
|
|
400
401
|
setWorldQuaternion(this.raycastLine, this.rayRotation);
|
|
401
402
|
setWorldPosition(this.raycastLine, wp);
|
|
402
403
|
}
|
|
@@ -60,6 +60,12 @@ export { ColorOverLifetimeModule } from "../ParticleSystemModules";
|
|
|
60
60
|
export { SizeOverLifetimeModule } from "../ParticleSystemModules";
|
|
61
61
|
export { ShapeModule } from "../ParticleSystemModules";
|
|
62
62
|
export { NoiseModule } from "../ParticleSystemModules";
|
|
63
|
+
export { TrailModule } from "../ParticleSystemModules";
|
|
64
|
+
export { VelocityOverLifetimeModule } from "../ParticleSystemModules";
|
|
65
|
+
export { TextureSheetAnimationModule } from "../ParticleSystemModules";
|
|
66
|
+
export { RotationOverLifetimeModule } from "../ParticleSystemModules";
|
|
67
|
+
export { RotationBySpeedModule } from "../ParticleSystemModules";
|
|
68
|
+
export { LimitVelocityOverLifetimeModule } from "../ParticleSystemModules";
|
|
63
69
|
export { PlayerColor } from "../PlayerColor";
|
|
64
70
|
export { ReflectionProbe } from "../ReflectionProbe";
|
|
65
71
|
export { FieldWithDefault } from "../Renderer";
|
|
@@ -32,6 +32,13 @@ export class RGBAColor extends Color {
|
|
|
32
32
|
return super.lerp(color, alpha);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
lerpColors(color1: Color, color2: Color, alpha: number): this {
|
|
36
|
+
const rgba1 = color1 as RGBAColor;
|
|
37
|
+
const rgba2 = color2 as RGBAColor;
|
|
38
|
+
if(rgba1.alpha && rgba2.alpha) this.alpha = Mathf.lerp(rgba1.alpha, rgba2.alpha, alpha);
|
|
39
|
+
return super.lerpColors(color1, color2, alpha);
|
|
40
|
+
}
|
|
41
|
+
|
|
35
42
|
multiply(color: Color): this {
|
|
36
43
|
const rgba = color as RGBAColor;
|
|
37
44
|
if(rgba.alpha) this.alpha = this.alpha * rgba.alpha;
|