@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
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { Behaviour, GameObject } from "./Component";
|
|
2
2
|
import * as THREE from "three";
|
|
3
|
-
import { MainModule, EmissionModule, ShapeModule, ParticleSystemShapeType, MinMaxCurve, MinMaxGradient, ColorOverLifetimeModule, SizeOverLifetimeModule, NoiseModule, ParticleSystemSimulationSpace, ParticleBurst, IParticleSystem, ParticleSystemRenderMode } from "./ParticleSystemModules"
|
|
3
|
+
import { MainModule, EmissionModule, ShapeModule, ParticleSystemShapeType, MinMaxCurve, MinMaxGradient, ColorOverLifetimeModule, SizeOverLifetimeModule, NoiseModule, ParticleSystemSimulationSpace, ParticleBurst, IParticleSystem, ParticleSystemRenderMode, TrailModule, VelocityOverLifetimeModule, TextureSheetAnimationModule, RotationOverLifetimeModule, LimitVelocityOverLifetimeModule, RotationBySpeedModule } from "./ParticleSystemModules"
|
|
4
4
|
import { getParam } from "../engine/engine_utils";
|
|
5
5
|
|
|
6
6
|
// https://github.dev/creativelifeform/three-nebula
|
|
7
|
-
import System, { Emitter, Position, Life, SpriteRenderer, Particle, Body, MeshRenderer, } from 'three-nebula';
|
|
7
|
+
// import System, { Emitter, Position, Life, SpriteRenderer, Particle, Body, MeshRenderer, } from 'three-nebula';
|
|
8
8
|
|
|
9
9
|
import { serializeable } from "../engine/engine_serialization";
|
|
10
|
-
import { Time } from "../engine/engine_time";
|
|
11
|
-
import { Context } from "../engine/engine_setup";
|
|
12
10
|
import { RGBAColor } from "./js-extensions/RGBAColor";
|
|
13
|
-
import { AxesHelper, BufferGeometry, Material, Mesh, Object3D, Sprite, SpriteMaterial, Vector3 } from "three";
|
|
14
|
-
import { getWorldQuaternion, getWorldScale } from "../engine/engine_three_utils";
|
|
11
|
+
import { AxesHelper, BufferGeometry, Color, Material, Mesh, MeshStandardMaterial, Object3D, OneMinusDstAlphaFactor, Quaternion, Sprite, SpriteMaterial, Vector3, Vector4 } from "three";
|
|
12
|
+
import { getWorldPosition, getWorldQuaternion, getWorldScale } from "../engine/engine_three_utils";
|
|
15
13
|
import { assign } from "../engine/engine_serialization_core";
|
|
14
|
+
import { BatchedParticleRenderer, Behavior, BillBoardSettings, BurstParameters, ColorGenerator, ConstantColor, ConstantValue, EmissionState, EmitterShape, FunctionColorGenerator, FunctionJSON, FunctionValueGenerator, MeshSettings, Particle, ParticleEmitter, ParticleSystem as _ParticleSystem, ParticleSystemParameters, PointEmitter, RenderMode, RotationGenerator, SizeOverLife, TrailBatch, TrailSettings, ValueGenerator } from "three.quarks";
|
|
15
|
+
import { createFlatTexture } from "../engine/engine_shaders";
|
|
16
|
+
import { Mathf } from "../engine/engine_math";
|
|
16
17
|
|
|
17
18
|
const debug = getParam("debugparticles");
|
|
18
19
|
|
|
@@ -28,6 +29,11 @@ export class ParticleSystemRenderer extends Behaviour {
|
|
|
28
29
|
// @serializeable(Mesh)
|
|
29
30
|
particleMesh?: Mesh | string;
|
|
30
31
|
|
|
32
|
+
get transparent(): boolean {
|
|
33
|
+
const res = this.particleMaterial?.transparent ?? false;
|
|
34
|
+
// console.log(res, this.particleMaterial);
|
|
35
|
+
return res;
|
|
36
|
+
}
|
|
31
37
|
|
|
32
38
|
getMesh() {
|
|
33
39
|
let geo: BufferGeometry | null = null;
|
|
@@ -40,405 +46,622 @@ export class ParticleSystemRenderer extends Behaviour {
|
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
48
|
|
|
43
|
-
|
|
49
|
+
class MinMaxCurveFunction implements FunctionValueGenerator {
|
|
44
50
|
|
|
45
|
-
|
|
46
|
-
readonly colorOverLifetime!: ColorOverLifetimeModule;
|
|
51
|
+
private _curve: MinMaxCurve;
|
|
47
52
|
|
|
48
|
-
|
|
49
|
-
readonly main!: MainModule;
|
|
53
|
+
constructor(curve: MinMaxCurve) { this._curve = curve; }
|
|
50
54
|
|
|
51
|
-
|
|
52
|
-
readonly emission!: EmissionModule;
|
|
55
|
+
type: "function" = "function";
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
57
|
+
genValue(t: number): number {
|
|
58
|
+
return this._curve.evaluate(t, Math.random());
|
|
59
|
+
}
|
|
60
|
+
toJSON(): FunctionJSON {
|
|
61
|
+
throw new Error("Method not implemented.");
|
|
62
|
+
}
|
|
63
|
+
clone(): FunctionValueGenerator {
|
|
64
|
+
throw new Error("Method not implemented.");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
56
67
|
|
|
57
|
-
|
|
58
|
-
readonly shape!: ShapeModule;
|
|
68
|
+
class MinMaxGradientFunction implements FunctionColorGenerator {
|
|
59
69
|
|
|
60
|
-
|
|
61
|
-
readonly noise!: NoiseModule;
|
|
70
|
+
private _curve: MinMaxGradient;
|
|
62
71
|
|
|
63
|
-
|
|
64
|
-
|
|
72
|
+
constructor(curve: MinMaxGradient) { this._curve = curve; }
|
|
73
|
+
|
|
74
|
+
type: "function" = "function";
|
|
75
|
+
|
|
76
|
+
genColor(color: THREE.Vector4, t: number): THREE.Vector4 {
|
|
77
|
+
const col = this._curve.evaluate(t, Math.random());
|
|
78
|
+
// TODO: incoming color should probably be blended?
|
|
79
|
+
color.set(col.r, col.g, col.b, col.alpha);
|
|
80
|
+
return color;
|
|
81
|
+
}
|
|
82
|
+
toJSON(): FunctionJSON {
|
|
83
|
+
throw new Error("Method not implemented.");
|
|
84
|
+
}
|
|
85
|
+
clone(): FunctionColorGenerator {
|
|
86
|
+
throw new Error("Method not implemented.");
|
|
65
87
|
}
|
|
66
88
|
|
|
67
|
-
|
|
68
|
-
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
abstract class BaseValueGenerator implements ValueGenerator {
|
|
92
|
+
|
|
93
|
+
type: "value" = "value";
|
|
94
|
+
toJSON(): FunctionJSON {
|
|
95
|
+
throw new Error("Method not implemented.");
|
|
69
96
|
}
|
|
70
|
-
|
|
71
|
-
|
|
97
|
+
clone(): ValueGenerator {
|
|
98
|
+
throw new Error("Method not implemented.");
|
|
72
99
|
}
|
|
73
|
-
|
|
74
|
-
|
|
100
|
+
|
|
101
|
+
abstract genValue(): number;
|
|
102
|
+
|
|
103
|
+
readonly system: ParticleSystem;
|
|
104
|
+
|
|
105
|
+
constructor(system: ParticleSystem) {
|
|
106
|
+
this.system = system;
|
|
75
107
|
}
|
|
76
|
-
|
|
77
|
-
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
class TextureSheetStartFrameGenerator extends BaseValueGenerator {
|
|
111
|
+
genValue(): number {
|
|
112
|
+
return this.system.textureSheetAnimation.getStartIndex();
|
|
78
113
|
}
|
|
79
114
|
|
|
80
|
-
|
|
81
|
-
private _system!: System;
|
|
82
|
-
private _emitter: Emitter;
|
|
83
|
-
private _size!: SizeBehaviour;
|
|
84
|
-
private _container?: Object3D;
|
|
85
|
-
private _time: number = 0;
|
|
115
|
+
}
|
|
86
116
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
117
|
+
class ParticleSystemEmissionOverTime extends BaseValueGenerator {
|
|
118
|
+
|
|
119
|
+
private _lastPosition: Vector3 = new Vector3();
|
|
120
|
+
private _lastDistance: number = 0;
|
|
121
|
+
|
|
122
|
+
update() {
|
|
123
|
+
const currentPosition = getWorldPosition(this.system.gameObject);
|
|
124
|
+
this._lastDistance = this._lastPosition.distanceTo(currentPosition)
|
|
125
|
+
this._lastPosition.copy(currentPosition);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
genValue(): number {
|
|
129
|
+
if (this.system.currentParticles >= this.system.maxParticles) return 0;
|
|
130
|
+
// emission over time
|
|
131
|
+
let emission = this.system.emission.rateOverTime.evaluate(this.system.time / this.system.duration, Math.random());
|
|
132
|
+
// if(this.system.currentParticles + emission > this.system.maxParticles)
|
|
133
|
+
// emission = (this.system.maxParticles - this.system.currentParticles);
|
|
134
|
+
// const res = Mathf.clamp(emission, 0, this.system.maxParticles - this.system.currentParticles);
|
|
135
|
+
|
|
136
|
+
if (this.system.deltaTime > 0) {
|
|
137
|
+
const distanceEmission = this.system.emission.rateOverDistance.evaluate(this.system.time / this.system.duration, Math.random());
|
|
138
|
+
const meterPerSecond = this._lastDistance / this.system.deltaTime;
|
|
139
|
+
let distanceEmissionValue = meterPerSecond * distanceEmission;
|
|
140
|
+
if (!Number.isFinite(distanceEmissionValue)) distanceEmissionValue = 0;
|
|
141
|
+
emission += distanceEmissionValue;
|
|
96
142
|
}
|
|
97
|
-
|
|
143
|
+
const burst = this.system.emission.getBurst();
|
|
144
|
+
if (burst > 0)
|
|
145
|
+
emission += burst / this.system.deltaTime;
|
|
146
|
+
|
|
147
|
+
const maxEmission = (this.system.maxParticles - this.system.currentParticles);
|
|
148
|
+
return Mathf.clamp(emission, 0, maxEmission / this.system.deltaTime);
|
|
98
149
|
}
|
|
99
|
-
|
|
150
|
+
}
|
|
100
151
|
|
|
101
|
-
|
|
102
|
-
this._renderer = this.gameObject.getComponent(ParticleSystemRenderer) as ParticleSystemRenderer;
|
|
103
|
-
this._system = new System();
|
|
152
|
+
class ParticleSystemEmissionOverDistance extends BaseValueGenerator {
|
|
104
153
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
154
|
+
genValue(): number {
|
|
155
|
+
// this seems not be called yet
|
|
156
|
+
return 0;
|
|
157
|
+
// if (this.system.currentParticles >= this.system.maxParticles) return 0;
|
|
158
|
+
// const emission = this.system.emission.rateOverDistance.evaluate(this.system.time / this.system.duration, Math.random());
|
|
159
|
+
// return emission;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
110
162
|
|
|
111
|
-
|
|
163
|
+
abstract class ParticleSystemBaseBehaviour implements Behavior {
|
|
164
|
+
readonly system: ParticleSystem;
|
|
112
165
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
166
|
+
get scaleFactorDiff(): number {
|
|
167
|
+
return this.system.worldScale.x - this.system.scale;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
constructor(ps: ParticleSystem) {
|
|
171
|
+
this.system = ps;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
abstract type: string;
|
|
175
|
+
|
|
176
|
+
initialize(_particle: Particle): void {
|
|
177
|
+
}
|
|
178
|
+
update(_particle: Particle, _delta: number): void {
|
|
179
|
+
}
|
|
180
|
+
frameUpdate(_delta: number): void {
|
|
181
|
+
}
|
|
182
|
+
toJSON() { throw new Error("Method not implemented."); }
|
|
183
|
+
clone(): Behavior { throw new Error("Method not implemented."); }
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
class TextureSheetAnimationBehaviour extends ParticleSystemBaseBehaviour {
|
|
187
|
+
type: string = "NeedleTextureSheet"
|
|
188
|
+
|
|
189
|
+
update(particle: Particle, _delta: number) {
|
|
190
|
+
const sheet = this.system.textureSheetAnimation;
|
|
191
|
+
if (sheet.enabled) {
|
|
192
|
+
const t01 = particle.age / particle.life;
|
|
193
|
+
const index = sheet.evaluate(t01);;
|
|
194
|
+
if (index !== undefined)
|
|
195
|
+
particle.uvTile = index;
|
|
129
196
|
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
class RotationBehaviour extends ParticleSystemBaseBehaviour {
|
|
202
|
+
type: string = "NeedleRotation"
|
|
203
|
+
|
|
204
|
+
update(particle: Particle, delta: number) {
|
|
205
|
+
if (particle.rotation === undefined) return;
|
|
206
|
+
if (particle.rotation instanceof Quaternion) {
|
|
130
207
|
|
|
131
|
-
if (!renderer) {
|
|
132
|
-
console.error("No renderer for particle system");
|
|
133
|
-
return;
|
|
134
208
|
}
|
|
209
|
+
else {
|
|
210
|
+
if (this.system.rotationOverLifetime.enabled) {
|
|
211
|
+
particle.rotation += this.system.rotationOverLifetime.evaluate(particle.age / particle.life) * delta;
|
|
212
|
+
}
|
|
213
|
+
// HACK flip y
|
|
214
|
+
else particle.rotation = Math.PI;
|
|
135
215
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const sprite = renderer._body as Sprite;
|
|
140
|
-
sprite.layers.disableAll();
|
|
141
|
-
sprite.layers.set(2); // ignore raycasting particles
|
|
142
|
-
sprite.renderOrder = 1;
|
|
143
|
-
sprite.material.map = this.renderer.particleMaterial.map;
|
|
144
|
-
sprite.material.transparent = true;
|
|
145
|
-
// sprite.material.sizeAttenuation = false;
|
|
146
|
-
sprite.material.blending = this.renderer.particleMaterial.blending;
|
|
147
|
-
sprite.material.blendDst = this.renderer.particleMaterial.blendDst;
|
|
148
|
-
sprite.material.blendDstAlpha = this.renderer.particleMaterial.blendDstAlpha;
|
|
149
|
-
sprite.material.blendEquation = this.renderer.particleMaterial.blendEquation;
|
|
150
|
-
sprite.material.blendEquationAlpha = this.renderer.particleMaterial.blendEquationAlpha;
|
|
151
|
-
sprite.material.blendSrc = this.renderer.particleMaterial.blendSrc;
|
|
152
|
-
sprite.material.blendSrcAlpha = this.renderer.particleMaterial.blendSrcAlpha;
|
|
153
|
-
sprite.material.premultipliedAlpha = this.renderer.particleMaterial.premultipliedAlpha;
|
|
154
|
-
sprite.material.depthWrite = false;
|
|
155
|
-
sprite.material.depthTest = true;
|
|
156
|
-
if (debug) console.log(sprite);
|
|
216
|
+
if (this.system.rotationBySpeed.enabled) {
|
|
217
|
+
const speed = particle.velocity.length();
|
|
218
|
+
particle.rotation += this.system.rotationBySpeed.evaluate(particle.age / particle.life, speed) * delta;
|
|
157
219
|
}
|
|
158
220
|
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
159
223
|
|
|
160
|
-
|
|
224
|
+
class SizeBehaviour extends ParticleSystemBaseBehaviour {
|
|
161
225
|
|
|
162
|
-
|
|
163
|
-
const behaviours: Array<any> = [];
|
|
226
|
+
type: string = "NeedleSize";
|
|
164
227
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
228
|
+
update(particle: Particle, _delta: number): void {
|
|
229
|
+
const t = particle.age / particle.life;
|
|
230
|
+
let size = 1;
|
|
231
|
+
if (this.system.sizeOverLifetime.enabled)
|
|
232
|
+
size *= this.system.sizeOverLifetime.evaluate(t).x;
|
|
233
|
+
const scaleFactor = this.system.worldScale.x / this.system.cameraScale;
|
|
234
|
+
particle.size = particle.startSize * size * scaleFactor;
|
|
235
|
+
// console.log(particle.startSize, size, this.system.scale, this.system.cameraScale);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
168
238
|
|
|
169
|
-
|
|
170
|
-
|
|
239
|
+
const $startVelocity = Symbol("startVelocity");
|
|
240
|
+
const $gravityFactor = Symbol("gravityModifier");
|
|
241
|
+
const temp3 = new Vector3();
|
|
242
|
+
const temp4 = new Quaternion();
|
|
171
243
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
behaviours.push(size);
|
|
244
|
+
class VelocityBehaviour extends ParticleSystemBaseBehaviour {
|
|
245
|
+
type: string = "NeedleVelocity";
|
|
175
246
|
|
|
176
|
-
|
|
177
|
-
behaviours.push(color);
|
|
247
|
+
private _gravityDirection = new Vector3();
|
|
178
248
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
velocity.gravityModifierMultiplier = this.main.gravityModifierMultiplier;
|
|
182
|
-
behaviours.push(velocity);
|
|
249
|
+
initialize(particle: Particle): void {
|
|
250
|
+
const factor = 1 + this.scaleFactorDiff;
|
|
183
251
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
252
|
+
particle.startSpeed = this.system.main.startSpeed.evaluate(Math.random(), Math.random()) * factor;
|
|
253
|
+
particle.velocity.copy(this.system.shape.getDirection(particle.position)).multiplyScalar(particle.startSpeed);
|
|
254
|
+
if (!particle[$startVelocity]) particle[$startVelocity] = particle.velocity.clone();
|
|
255
|
+
else particle[$startVelocity].copy(particle.velocity);
|
|
187
256
|
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
emitter.setBehaviours(behaviours);
|
|
191
|
-
emitter.setRate(this.emission);
|
|
192
|
-
emitter.damping = 0;
|
|
193
|
-
}
|
|
257
|
+
const gravityFactor = this.system.main.gravityModifier.evaluate(Math.random(), Math.random());// * factor;
|
|
258
|
+
particle[$gravityFactor] = gravityFactor;
|
|
194
259
|
|
|
195
|
-
|
|
196
|
-
this.
|
|
197
|
-
|
|
198
|
-
this._system.emit({ onStart: () => { }, onUpdate: () => { }, onEnd: () => { }, });
|
|
199
|
-
this._time = 0;
|
|
200
|
-
}
|
|
260
|
+
this._gravityDirection.set(0, -1, 0);
|
|
261
|
+
if (this.system.main.simulationSpace === ParticleSystemSimulationSpace.Local)
|
|
262
|
+
this._gravityDirection.applyQuaternion(this.system.worldQuaternionInverted);
|
|
201
263
|
|
|
202
|
-
onDisable() {
|
|
203
|
-
this._system.removeEmitter(this._emitter);
|
|
204
264
|
}
|
|
205
265
|
|
|
206
|
-
|
|
207
|
-
if (this._bursts) {
|
|
208
|
-
this.emission.bursts = this._bursts;
|
|
209
|
-
}
|
|
266
|
+
update(particle: Particle, delta: number): void {
|
|
210
267
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
if (
|
|
214
|
-
|
|
215
|
-
this.
|
|
268
|
+
const baseVelocity = particle[$startVelocity];
|
|
269
|
+
let gravityFactor = particle[$gravityFactor];
|
|
270
|
+
if (gravityFactor !== 0) {
|
|
271
|
+
// gravityFactor *= -1;
|
|
272
|
+
temp3.copy(this._gravityDirection).multiplyScalar(gravityFactor * delta * Math.PI);
|
|
273
|
+
// Gizmos.DrawDirection(particle.position, temp3, 0xff0000, 0, false, 10);
|
|
274
|
+
baseVelocity.add(temp3);
|
|
216
275
|
}
|
|
276
|
+
particle.velocity.copy(baseVelocity);
|
|
217
277
|
|
|
218
|
-
|
|
219
|
-
// this._container.matrix.copy(this.gameObject.matrixWorld);
|
|
220
|
-
// this._container.matrixWorld.copy(this.gameObject.matrixWorld);
|
|
278
|
+
const t01 = particle.age / particle.life;
|
|
221
279
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
scale.z = 1 / scale.z;
|
|
226
|
-
// console.log(scale);
|
|
227
|
-
// this._container.scale.copy(scale);
|
|
228
|
-
// // this._container.updateMatrix();
|
|
229
|
-
// // this._container.updateMatrixWorld();
|
|
230
|
-
// // // set scale to 1
|
|
231
|
-
this._container.matrix.identity();
|
|
232
|
-
this._container.matrix.scale(scale);
|
|
233
|
-
// this._container.matrixWorld.copy(this._container.matrix);
|
|
280
|
+
const noise = this.system.noise;
|
|
281
|
+
if (noise.enabled) {
|
|
282
|
+
noise.apply(0, particle.position, particle.velocity, delta, particle.age, particle.life);
|
|
234
283
|
}
|
|
235
|
-
// this._system.time
|
|
236
|
-
// this._system.duration = this.main.duration;
|
|
237
|
-
this.emission.system = this;
|
|
238
|
-
this.shape.update(this.context, this.main.simulationSpace, this.gameObject);
|
|
239
|
-
this.noise.update(this.context);
|
|
240
|
-
this._system.update(this.context.time.deltaTime * this.main.simulationSpeed);
|
|
241
|
-
this._time += this.context.time.deltaTime;
|
|
242
|
-
if (this._time > this.duration) this._time = 0;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
}
|
|
246
284
|
|
|
285
|
+
const velocity = this.system.velocityOverLifetime;
|
|
286
|
+
if (velocity.enabled) {
|
|
287
|
+
velocity.apply(0, particle.position, particle.velocity, delta, particle.age, particle.life);
|
|
288
|
+
}
|
|
247
289
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
290
|
+
const limitVelocityOverLifetime = this.system.limitVelocityOverLifetime;
|
|
291
|
+
if (limitVelocityOverLifetime.enabled) {
|
|
292
|
+
// const factor = this.system.worldScale.x;
|
|
293
|
+
limitVelocityOverLifetime.apply(particle.position, baseVelocity, particle.velocity, particle.size, t01, delta, 1);
|
|
294
|
+
}
|
|
253
295
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
this.curve = minMaxCurve;
|
|
257
|
-
this.multiplier = multiplier;
|
|
258
|
-
}
|
|
296
|
+
// const speed = particle.velocity.length();
|
|
297
|
+
// particle.velocity.multiplyScalar(1-delta);
|
|
259
298
|
|
|
260
|
-
|
|
261
|
-
getValue(lerp?: number) {
|
|
262
|
-
const res = this.curve.evaluate(this.time.time, lerp) * this.multiplier;
|
|
263
|
-
return res;
|
|
299
|
+
// const vel = this.system.velocityOverLifetime.evaluate(particle.age / particle.life);
|
|
264
300
|
}
|
|
265
301
|
}
|
|
266
302
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
abstract initialize(particle: Particle);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
abstract class MinMaxCurveBehaviour extends CustomBehaviour {
|
|
303
|
+
class ColorBehaviour extends ParticleSystemBaseBehaviour {
|
|
304
|
+
type: string = "NeedleColor";
|
|
273
305
|
|
|
274
|
-
|
|
275
|
-
|
|
306
|
+
initialize(particle: Particle): void {
|
|
307
|
+
const col = this.system.main.startColor.evaluate(particle.age / particle.life, Math.random());
|
|
308
|
+
particle.startColor.set(col.r, col.g, col.b, col.alpha);
|
|
309
|
+
particle.color.copy(particle.startColor);
|
|
310
|
+
}
|
|
276
311
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
312
|
+
update(particle: Particle, _delta: number): void {
|
|
313
|
+
if (this.system.colorOverLifetime.enabled) {
|
|
314
|
+
const t = particle.age / particle.life;
|
|
315
|
+
const col = this.system.colorOverLifetime.color.evaluate(t);
|
|
316
|
+
particle.color.set(col.r, col.g, col.b, col.alpha).multiply(particle.startColor);
|
|
317
|
+
}
|
|
281
318
|
}
|
|
282
319
|
}
|
|
283
320
|
|
|
284
|
-
|
|
321
|
+
class ParticleSystemInterface implements ParticleSystemParameters {
|
|
285
322
|
|
|
286
|
-
|
|
323
|
+
private readonly system: ParticleSystem;
|
|
324
|
+
private readonly emission: ParticleSystemEmissionOverTime;
|
|
325
|
+
private get anim(): TextureSheetAnimationModule {
|
|
326
|
+
return this.system.textureSheetAnimation;
|
|
327
|
+
}
|
|
287
328
|
|
|
288
|
-
|
|
329
|
+
constructor(system: ParticleSystem) {
|
|
330
|
+
this.system = system;
|
|
331
|
+
this.emission = new ParticleSystemEmissionOverTime(this.system);
|
|
332
|
+
}
|
|
289
333
|
|
|
290
|
-
|
|
334
|
+
update() {
|
|
335
|
+
this.emission.update();
|
|
336
|
+
}
|
|
291
337
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
338
|
+
autoDestroy?: boolean | undefined;
|
|
339
|
+
get looping() { return this.system.main.loop; }
|
|
340
|
+
get duration() { return this.system.duration; }
|
|
341
|
+
get shape(): EmitterShape { return this.system.shape; }
|
|
342
|
+
get startLife() { return new MinMaxCurveFunction(this.system.main.startLifetime); }
|
|
343
|
+
get startSpeed() { return new MinMaxCurveFunction(this.system.main.startSpeed); }
|
|
344
|
+
get startRotation() { return new MinMaxCurveFunction(this.system.main.startRotation); }
|
|
345
|
+
get startSize() { return new MinMaxCurveFunction(this.system.main.startSize); }
|
|
346
|
+
startLength?: ValueGenerator | FunctionValueGenerator | undefined; /** start length is for trails */
|
|
347
|
+
get startColor() { return new ConstantColor(new Vector4(1, 1, 1, 1)); }
|
|
348
|
+
get emissionOverTime() { return this.emission; }
|
|
349
|
+
/** this is not supported yet */
|
|
350
|
+
get emissionOverDistance() { return new ParticleSystemEmissionOverDistance(this.system); }
|
|
351
|
+
/** not used - burst is controled via emissionOverTime */
|
|
352
|
+
emissionBursts?: BurstParameters[] | undefined;
|
|
353
|
+
onlyUsedByOther?: boolean | undefined;
|
|
354
|
+
readonly behaviors: Behavior[] = [];
|
|
355
|
+
get instancingGeometry() {
|
|
356
|
+
return this.system.renderer.getMesh().geometry;
|
|
357
|
+
}
|
|
358
|
+
get renderMode() {
|
|
359
|
+
if (this.system.trails["enabled"] === true) {
|
|
360
|
+
return RenderMode.Trail;
|
|
295
361
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
this.sizeOverLifetimeModule.evaluate?.call(this.sizeOverLifetimeModule, time, scaleVector);
|
|
303
|
-
// scaleVector.set(.1, .1, .1)
|
|
304
|
-
particle.scale = particle.start_scale * scaleVector.x;
|
|
305
|
-
// console.log(time, particle.scale);
|
|
362
|
+
switch (this.system.renderer.renderMode) {
|
|
363
|
+
case ParticleSystemRenderMode.Billboard: return RenderMode.BillBoard;
|
|
364
|
+
// case ParticleSystemRenderMode.Stretch: return RenderMode.Stretch;
|
|
365
|
+
// case ParticleSystemRenderMode.HorizontalBillboard: return RenderMode.HorizontalBillboard;
|
|
366
|
+
// case ParticleSystemRenderMode.VerticalBillboard: return RenderMode.VerticalBillboard;
|
|
367
|
+
case ParticleSystemRenderMode.Mesh: return RenderMode.LocalSpace;
|
|
306
368
|
}
|
|
369
|
+
return RenderMode.BillBoard;
|
|
307
370
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
371
|
+
rendererEmitterSettings: TrailSettings = {
|
|
372
|
+
startLength: new ConstantValue(220),
|
|
373
|
+
followLocalOrigin: false,
|
|
374
|
+
};
|
|
375
|
+
get speedFactor() { return this.system.main.simulationSpeed; }
|
|
376
|
+
get texture(): THREE.Texture {
|
|
377
|
+
const mat = this.system.renderer.particleMaterial;
|
|
378
|
+
if (mat && mat["map"]) {
|
|
379
|
+
const tex = mat["map"]!;
|
|
380
|
+
tex.premultiplyAlpha = false;
|
|
381
|
+
tex.encoding = THREE.LinearEncoding;
|
|
382
|
+
return tex;
|
|
383
|
+
}
|
|
384
|
+
return createFlatTexture(new RGBAColor(1, 1, 1, 1), 1)
|
|
312
385
|
}
|
|
386
|
+
get startTileIndex() { return new TextureSheetStartFrameGenerator(this.system); }
|
|
387
|
+
get uTileCount() { return this.anim.enabled ? this.anim?.numTilesX : undefined }
|
|
388
|
+
get vTileCount() { return this.anim.enabled ? this.anim?.numTilesY : undefined }
|
|
389
|
+
get renderOrder() { return 1; }
|
|
390
|
+
get blending(): THREE.Blending { return this.system.renderer.particleMaterial?.blending ?? THREE.NormalBlending; }
|
|
391
|
+
get transparent() { return this.system.renderer.transparent; }
|
|
392
|
+
get worldSpace() { return this.system.main.simulationSpace === ParticleSystemSimulationSpace.World; }
|
|
393
|
+
|
|
313
394
|
}
|
|
314
395
|
|
|
315
|
-
|
|
396
|
+
class ParticlesEmissionState implements EmissionState {
|
|
397
|
+
|
|
398
|
+
burstIndex: number = 0;
|
|
399
|
+
burstWaveIndex: number = 0;
|
|
400
|
+
time: number = 0;
|
|
401
|
+
waitEmiting: number = 0;
|
|
402
|
+
}
|
|
316
403
|
|
|
317
|
-
class
|
|
404
|
+
export class ParticleSystem extends Behaviour implements IParticleSystem {
|
|
318
405
|
|
|
319
|
-
|
|
320
|
-
|
|
406
|
+
play(includeChildren: boolean = false) {
|
|
407
|
+
if (includeChildren) {
|
|
408
|
+
GameObject.foreachComponent(this.gameObject, comp => {
|
|
409
|
+
if (comp instanceof ParticleSystem && comp !== this) {
|
|
410
|
+
comp.play(false);
|
|
411
|
+
}
|
|
412
|
+
}, true)
|
|
413
|
+
}
|
|
414
|
+
this._isPlaying = true;
|
|
415
|
+
this._time = 0;
|
|
321
416
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
417
|
+
// https://github.com/Alchemist0823/three.quarks/pull/35
|
|
418
|
+
if (this._particleSystem) {
|
|
419
|
+
this._particleSystem["emissionState"].time = 0;
|
|
420
|
+
this._particleSystem["emitEnded"] = false;
|
|
421
|
+
}
|
|
422
|
+
this.emission?.reset();
|
|
326
423
|
}
|
|
327
424
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
425
|
+
pause() {
|
|
426
|
+
this._isPlaying = false;
|
|
427
|
+
}
|
|
428
|
+
stop() {
|
|
429
|
+
this._isPlaying = false;
|
|
430
|
+
this._time = 0;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
private _state?: ParticlesEmissionState;
|
|
434
|
+
emit(count: number) {
|
|
435
|
+
if (this._particleSystem) {
|
|
436
|
+
count = Math.min(count, this.maxParticles - this.currentParticles);
|
|
437
|
+
if (!this._state) this._state = new ParticlesEmissionState();
|
|
438
|
+
this._state.waitEmiting = count;
|
|
439
|
+
this._state.time = 0;
|
|
440
|
+
const emitEndedState = this._particleSystem["emitEnded"];
|
|
441
|
+
this._particleSystem["emitEnded"] = false;
|
|
442
|
+
this._particleSystem.emit(this.deltaTime, this._state, this._particleSystem.emitter.matrixWorld);
|
|
443
|
+
this._particleSystem["emitEnded"] = emitEndedState;
|
|
341
444
|
}
|
|
342
445
|
}
|
|
343
446
|
|
|
344
|
-
|
|
345
|
-
|
|
447
|
+
@serializeable(ColorOverLifetimeModule)
|
|
448
|
+
readonly colorOverLifetime!: ColorOverLifetimeModule;
|
|
346
449
|
|
|
347
|
-
|
|
348
|
-
|
|
450
|
+
@serializeable(MainModule)
|
|
451
|
+
readonly main!: MainModule;
|
|
349
452
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
// const time = context.time.time;
|
|
353
|
-
const ev = this.startGradient.evaluate(Math.random()) as RGBAColor;
|
|
354
|
-
particle.color.r = ev.r;
|
|
355
|
-
particle.color.g = ev.g;
|
|
356
|
-
particle.color.b = ev.b;
|
|
357
|
-
particle.alpha = ev.alpha
|
|
453
|
+
@serializeable(EmissionModule)
|
|
454
|
+
readonly emission!: EmissionModule;
|
|
358
455
|
|
|
359
|
-
|
|
456
|
+
@serializeable(SizeOverLifetimeModule)
|
|
457
|
+
readonly sizeOverLifetime!: SizeOverLifetimeModule;
|
|
360
458
|
|
|
361
|
-
|
|
362
|
-
|
|
459
|
+
@serializeable(ShapeModule)
|
|
460
|
+
readonly shape!: ShapeModule;
|
|
363
461
|
|
|
364
|
-
|
|
365
|
-
|
|
462
|
+
@serializeable(NoiseModule)
|
|
463
|
+
readonly noise!: NoiseModule;
|
|
366
464
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}
|
|
370
|
-
}
|
|
465
|
+
// @serializeable(TrailModule)
|
|
466
|
+
readonly trails!: TrailModule;
|
|
371
467
|
|
|
468
|
+
@serializeable(VelocityOverLifetimeModule)
|
|
469
|
+
readonly velocityOverLifetime!: VelocityOverLifetimeModule;
|
|
372
470
|
|
|
373
|
-
|
|
471
|
+
@serializeable(LimitVelocityOverLifetimeModule)
|
|
472
|
+
readonly limitVelocityOverLifetime!: LimitVelocityOverLifetimeModule;
|
|
374
473
|
|
|
375
|
-
|
|
474
|
+
@serializeable(TextureSheetAnimationModule)
|
|
475
|
+
readonly textureSheetAnimation!: TextureSheetAnimationModule;
|
|
376
476
|
|
|
377
|
-
|
|
477
|
+
@serializeable(RotationOverLifetimeModule)
|
|
478
|
+
readonly rotationOverLifetime!: RotationOverLifetimeModule;
|
|
378
479
|
|
|
379
|
-
|
|
380
|
-
|
|
480
|
+
@serializeable(RotationBySpeedModule)
|
|
481
|
+
readonly rotationBySpeed!: RotationBySpeedModule;
|
|
381
482
|
|
|
382
|
-
|
|
383
|
-
|
|
483
|
+
get renderer(): ParticleSystemRenderer {
|
|
484
|
+
return this._renderer;
|
|
485
|
+
}
|
|
384
486
|
|
|
385
|
-
|
|
386
|
-
gravityModifierMultiplier: number = 1;
|
|
487
|
+
get isPlaying() { return this.isPlaying; }
|
|
387
488
|
|
|
388
|
-
|
|
389
|
-
|
|
489
|
+
get currentParticles() {
|
|
490
|
+
return this._particleSystem?.particleNum ?? 0;
|
|
491
|
+
}
|
|
492
|
+
get maxParticles() {
|
|
493
|
+
return this.main.maxParticles;
|
|
494
|
+
}
|
|
495
|
+
get time() {
|
|
496
|
+
return this._time;
|
|
497
|
+
}
|
|
498
|
+
get duration() {
|
|
499
|
+
return this.main.duration;
|
|
500
|
+
}
|
|
501
|
+
get deltaTime() {
|
|
502
|
+
return this.context.time.deltaTime * this.main.simulationSpeed;
|
|
503
|
+
}
|
|
504
|
+
get scale() {
|
|
505
|
+
return this.gameObject.scale.x;
|
|
506
|
+
}
|
|
507
|
+
get cameraScale(): number {
|
|
508
|
+
return this._cameraScale;
|
|
509
|
+
}
|
|
510
|
+
private _cameraScale: number = 1;
|
|
390
511
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
this.shape = shape;
|
|
395
|
-
this.noise = noise;
|
|
396
|
-
this.startSpeed = startCurve;
|
|
397
|
-
this.startMultiplier = startMultiplier;
|
|
512
|
+
get container(): Object3D {
|
|
513
|
+
return this._container!;
|
|
514
|
+
}
|
|
398
515
|
|
|
516
|
+
get worldspace() {
|
|
517
|
+
return this.main.simulationSpace === ParticleSystemSimulationSpace.World;
|
|
399
518
|
}
|
|
400
519
|
|
|
401
|
-
|
|
520
|
+
private __worldQuaternion = new Quaternion();
|
|
521
|
+
get worldQuaternion(): Quaternion {
|
|
522
|
+
return this.__worldQuaternion;
|
|
523
|
+
}
|
|
524
|
+
private _worldQuaternionInverted = new Quaternion();
|
|
525
|
+
get worldQuaternionInverted(): Quaternion {
|
|
526
|
+
return this._worldQuaternionInverted;
|
|
527
|
+
}
|
|
528
|
+
private _worldScale = new Vector3();
|
|
529
|
+
get worldScale(): Vector3 {
|
|
530
|
+
return this._worldScale;
|
|
531
|
+
}
|
|
402
532
|
|
|
403
|
-
|
|
404
|
-
// target.velocity.x = target.velocity_start.x;
|
|
405
|
-
// target.velocity.y = target.velocity_start.y;
|
|
406
|
-
// target.velocity.z = target.velocity_start.z;
|
|
407
|
-
if (target.gravity !== 0 && this.gravity) {
|
|
408
|
-
// get world down vector
|
|
409
|
-
this._temp.copy(this.downDirection);
|
|
410
|
-
this._temp.multiplyScalar(target.gravity * deltaTime);
|
|
411
|
-
target.velocity.add(this._temp);
|
|
412
|
-
}
|
|
533
|
+
private _renderer!: ParticleSystemRenderer;
|
|
413
534
|
|
|
414
|
-
|
|
415
|
-
|
|
535
|
+
private _batchSystem?: BatchedParticleRenderer;
|
|
536
|
+
private _particleSystem?: _ParticleSystem;
|
|
537
|
+
private _interface!: ParticleSystemInterface;
|
|
538
|
+
|
|
539
|
+
// private _system!: System;
|
|
540
|
+
// private _emitter: Emitter;
|
|
541
|
+
// private _size!: SizeBehaviour;
|
|
542
|
+
private _container!: Object3D;
|
|
543
|
+
private _time: number = 0;
|
|
544
|
+
private _isPlaying: boolean = true;
|
|
545
|
+
|
|
546
|
+
/** called from deserialization */
|
|
547
|
+
private set bursts(arr: ParticleBurst[]) {
|
|
548
|
+
for (let i = 0; i < arr.length; i++) {
|
|
549
|
+
const burst = arr[i];
|
|
550
|
+
if ((burst instanceof ParticleBurst) === false) {
|
|
551
|
+
const instance = new ParticleBurst();
|
|
552
|
+
assign(instance, burst);
|
|
553
|
+
arr[i] = instance;
|
|
416
554
|
}
|
|
417
555
|
}
|
|
556
|
+
this._bursts = arr;
|
|
418
557
|
}
|
|
558
|
+
private _bursts?: ParticleBurst[];
|
|
559
|
+
|
|
560
|
+
awake(): void {
|
|
561
|
+
this._renderer = this.gameObject.getComponent(ParticleSystemRenderer) as ParticleSystemRenderer;
|
|
419
562
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
particle.velocity.x = dir.x * speed;
|
|
425
|
-
particle.velocity.y = dir.y * speed;
|
|
426
|
-
particle.velocity.z = dir.z * speed;
|
|
427
|
-
if (!particle.velocity_start)
|
|
428
|
-
particle.velocity_start = {};
|
|
429
|
-
particle.velocity_start.x = particle.velocity.x;
|
|
430
|
-
particle.velocity_start.y = particle.velocity.y;
|
|
431
|
-
particle.velocity_start.z = particle.velocity.z;
|
|
432
|
-
|
|
433
|
-
if (this.gravity) {
|
|
434
|
-
particle.gravity = this.gravity.evaluate(Math.random(), Math.random()) * 9.81;
|
|
563
|
+
this._container = new Object3D();
|
|
564
|
+
this._container.matrixAutoUpdate = false;
|
|
565
|
+
if (this.main.simulationSpace == ParticleSystemSimulationSpace.Local) {
|
|
566
|
+
this.gameObject.add(this._container);
|
|
435
567
|
}
|
|
436
568
|
else {
|
|
437
|
-
|
|
569
|
+
this.context.scene.add(this._container);
|
|
438
570
|
}
|
|
571
|
+
// else this._container = this.context.scene;
|
|
572
|
+
|
|
573
|
+
this._batchSystem = new BatchedParticleRenderer();
|
|
574
|
+
this._container.add(this._batchSystem);
|
|
575
|
+
this._interface = new ParticleSystemInterface(this);
|
|
576
|
+
this._particleSystem = new _ParticleSystem(this._batchSystem, this._interface);
|
|
577
|
+
this._particleSystem.addBehavior(new SizeBehaviour(this));
|
|
578
|
+
this._particleSystem.addBehavior(new VelocityBehaviour(this));
|
|
579
|
+
this._particleSystem.addBehavior(new ColorBehaviour(this));
|
|
580
|
+
this._particleSystem.addBehavior(new TextureSheetAnimationBehaviour(this));
|
|
581
|
+
this._particleSystem.addBehavior(new RotationBehaviour(this));
|
|
582
|
+
const emitter = this._particleSystem.emitter;
|
|
583
|
+
this.context.scene.add(emitter);
|
|
439
584
|
|
|
440
|
-
|
|
441
|
-
|
|
585
|
+
if (debug) {
|
|
586
|
+
console.log(this);
|
|
587
|
+
this.gameObject.add(new AxesHelper(1))
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// renderer.logRendererType = () => { };
|
|
591
|
+
// if (renderMode === ParticleSystemRenderMode.Billboard) {
|
|
592
|
+
// if (this.renderer.particleMaterial) {
|
|
593
|
+
// const sprite = renderer._body as Sprite;
|
|
594
|
+
// sprite.layers.disableAll();
|
|
595
|
+
// sprite.layers.set(2); // ignore raycasting particles
|
|
596
|
+
// sprite.renderOrder = 1;
|
|
597
|
+
// sprite.material.map = this.renderer.particleMaterial.map;
|
|
598
|
+
// sprite.material.transparent = true;
|
|
599
|
+
// // sprite.material.sizeAttenuation = false;
|
|
600
|
+
// sprite.material.blending = this.renderer.particleMaterial.blending;
|
|
601
|
+
// sprite.material.blendDst = this.renderer.particleMaterial.blendDst;
|
|
602
|
+
// sprite.material.blendDstAlpha = this.renderer.particleMaterial.blendDstAlpha;
|
|
603
|
+
// sprite.material.blendEquation = this.renderer.particleMaterial.blendEquation;
|
|
604
|
+
// sprite.material.blendEquationAlpha = this.renderer.particleMaterial.blendEquationAlpha;
|
|
605
|
+
// sprite.material.blendSrc = this.renderer.particleMaterial.blendSrc;
|
|
606
|
+
// sprite.material.blendSrcAlpha = this.renderer.particleMaterial.blendSrcAlpha;
|
|
607
|
+
// sprite.material.premultipliedAlpha = this.renderer.particleMaterial.premultipliedAlpha;
|
|
608
|
+
// sprite.material.depthWrite = false;
|
|
609
|
+
// sprite.material.depthTest = true;
|
|
610
|
+
// if (debug) console.log(sprite);
|
|
611
|
+
// }
|
|
612
|
+
// }
|
|
613
|
+
|
|
614
|
+
// setInterval(()=>{
|
|
615
|
+
// this.emit(100);
|
|
616
|
+
// }, 1000)
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
onEnable() {
|
|
620
|
+
this.play();
|
|
442
621
|
}
|
|
443
622
|
|
|
444
|
-
|
|
623
|
+
onDisable() {
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
onBeforeRender() {
|
|
627
|
+
if (this._bursts) {
|
|
628
|
+
this.emission.bursts = this._bursts;
|
|
629
|
+
delete this._bursts;
|
|
630
|
+
}
|
|
631
|
+
if (!this._isPlaying) return;
|
|
632
|
+
|
|
633
|
+
// sprite materials must be scaled in AR
|
|
634
|
+
const cam = this.context.mainCamera;
|
|
635
|
+
if (cam) {
|
|
636
|
+
const scale = getWorldScale(cam);
|
|
637
|
+
this._cameraScale = scale.x;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
let source = this._container;
|
|
641
|
+
if (this.worldspace)
|
|
642
|
+
source = this.gameObject;
|
|
643
|
+
getWorldQuaternion(source, this.__worldQuaternion)
|
|
644
|
+
this._worldQuaternionInverted.copy(this.__worldQuaternion).invert();
|
|
645
|
+
getWorldScale(this.gameObject, this._worldScale);
|
|
646
|
+
|
|
647
|
+
if (!this.worldspace && this._container && this.gameObject?.parent) {
|
|
648
|
+
const scale = getWorldScale(this.gameObject.parent);
|
|
649
|
+
scale.x = 1 / scale.x;
|
|
650
|
+
scale.y = 1 / scale.y;
|
|
651
|
+
scale.z = 1 / scale.z;
|
|
652
|
+
this._container.matrix.identity();
|
|
653
|
+
this._container.matrix.scale(scale);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
this.emission.system = this;
|
|
657
|
+
const dt = this.deltaTime;
|
|
658
|
+
this._interface.update();
|
|
659
|
+
this.shape.update(this, this.context, this.main.simulationSpace, this.gameObject);
|
|
660
|
+
this.noise.update(this.context);
|
|
661
|
+
this.velocityOverLifetime.update(this);
|
|
662
|
+
this._batchSystem?.update(dt);
|
|
663
|
+
this._time += dt;
|
|
664
|
+
if (this._time > this.duration) this._time = 0;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
}
|