@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,248 +1,368 @@
1
1
  import { Behaviour, GameObject } from "./Component";
2
2
  import * as THREE from "three";
3
- import * as Modules from "./ParticleSystemModules"
4
- import { Mathf } from "../engine/engine_math";
3
+ import { MainModule, EmissionModule, ShapeModule, ParticleSystemShapeType, MinMaxCurve, MinMaxGradient, ColorOverLifetimeModule, SizeOverLifetimeModule, NoiseModule, ParticleSystemSimulationSpace } from "./ParticleSystemModules"
5
4
  import { getParam } from "../engine/engine_utils";
5
+ import System, {
6
+ Emitter,
7
+ Rate,
8
+ Span,
9
+ Position,
10
+ Mass,
11
+ Radius,
12
+ Life,
13
+ PointZone,
14
+ Vector3D,
15
+ Alpha,
16
+ Scale,
17
+ Color,
18
+ SpriteRenderer,
19
+ RadialVelocity,
20
+ BoxZone,
21
+ Particle,
22
+ Gravity,
23
+ SphereZone,
24
+ } from 'three-nebula';
25
+ // https://github.dev/creativelifeform/three-nebula
26
+
27
+ import { serializeable } from "../engine/engine_serialization";
28
+ import { Time } from "../engine/engine_time";
29
+ import { Context } from "../engine/engine_setup";
30
+ import { RGBAColor } from "./js-extensions/RGBAColor";
31
+ import { Mathf } from "../engine/engine_math";
32
+ import { Vec3 } from "../engine/engine_types";
33
+ import { AxesHelper, Material, Object3D, Sprite, SpriteMaterial, Vector3 } from "three";
34
+ import { Renderer } from "./Renderer";
35
+ import { getWorldQuaternion, getWorldScale } from "../engine/engine_three_utils";
6
36
 
7
37
  const debug = getParam("debugparticles");
8
38
 
9
- class ParticleState {
10
- age: number = 0;
11
- lifetime: number = 0;
12
- position!: THREE.Vector3;
13
- velocity!: THREE.Vector3;
14
- color!: THREE.Color;
15
- }
39
+
16
40
 
17
41
  export class ParticleSystemRenderer extends Behaviour {
18
42
 
19
- get mainTexture(): THREE.Texture | null {
20
- if (this.sharedMaterial) {
21
- const tex = this.context.assets.findTexture(this.sharedMaterial);
22
- if (tex) return tex;
43
+ @serializeable(Material)
44
+ particleMaterial?: SpriteMaterial;
45
+ }
46
+
47
+ export class ParticleSystem extends Behaviour {
48
+
49
+ @serializeable(ColorOverLifetimeModule)
50
+ colorOverLifetime!: ColorOverLifetimeModule;
51
+
52
+ @serializeable(MainModule)
53
+ main!: MainModule;
54
+
55
+ @serializeable(EmissionModule)
56
+ emission!: EmissionModule;
57
+
58
+ @serializeable(SizeOverLifetimeModule)
59
+ sizeOverLifetime!: SizeOverLifetimeModule;
60
+
61
+ @serializeable(ShapeModule)
62
+ shape!: ShapeModule;
63
+
64
+ @serializeable(NoiseModule)
65
+ noise!: NoiseModule;
66
+
67
+ renderer!: ParticleSystemRenderer;
68
+
69
+ private _system!: System;
70
+ private _emitter: Emitter;
71
+ private _size!: SizeBehaviour;
72
+
73
+ awake(): void {
74
+ if (debug) {
75
+ console.log(this);
76
+ this.gameObject.add(new AxesHelper(1))
77
+ }
78
+
79
+ this.renderer = this.gameObject.getComponent(ParticleSystemRenderer) as ParticleSystemRenderer;
80
+ this._system = new System();
81
+ const container = this.main.simulationSpace == ParticleSystemSimulationSpace.Local ? this.gameObject : this.context.scene;
82
+
83
+
84
+ const renderer = new SpriteRenderer(container, THREE);
85
+ renderer.logRendererType = () => { };
86
+ if (this.renderer.particleMaterial) {
87
+ const sprite = renderer._body as Sprite;
88
+ sprite.layers.disableAll();
89
+ sprite.layers.set(2); // ignore raycasting particles
90
+ sprite.renderOrder = 1;
91
+ sprite.material.map = this.renderer.particleMaterial.map;
92
+ sprite.material.transparent = true;
93
+ // sprite.material.sizeAttenuation = false;
94
+ sprite.material.blending = this.renderer.particleMaterial.blending;
95
+ sprite.material.blendDst = this.renderer.particleMaterial.blendDst;
96
+ sprite.material.blendDstAlpha = this.renderer.particleMaterial.blendDstAlpha;
97
+ sprite.material.blendEquation = this.renderer.particleMaterial.blendEquation;
98
+ sprite.material.blendEquationAlpha = this.renderer.particleMaterial.blendEquationAlpha;
99
+ sprite.material.blendSrc = this.renderer.particleMaterial.blendSrc;
100
+ sprite.material.blendSrcAlpha = this.renderer.particleMaterial.blendSrcAlpha;
101
+ sprite.material.premultipliedAlpha = this.renderer.particleMaterial.premultipliedAlpha;
102
+ sprite.material.depthWrite = false;
103
+ sprite.material.depthTest = true;
104
+ if (debug) console.log(sprite);
23
105
  }
24
- return null;
106
+
107
+ this._system.addRenderer(renderer);
108
+
109
+ const initializers: Array<any> = [];
110
+ const behaviours: Array<any> = [];
111
+
112
+
113
+
114
+ const life = new Life();
115
+ life.lifePan = new MinMaxCurveSpan(this.main.startLifetime, 1);
116
+ initializers.push(life);
117
+
118
+ const shape = new Position(this.shape);
119
+ initializers.push(shape);
120
+
121
+ const size = this._size = new SizeBehaviour(this.main.startSize, this.main.startSizeMultiplier);
122
+ size.sizeOverLifetimeModule = this.sizeOverLifetime;
123
+ behaviours.push(size);
124
+
125
+ const color = new GradientBehaviour(this.main.startColor, this.colorOverLifetime?.enabled ? this.colorOverLifetime.color : undefined);
126
+ behaviours.push(color);
127
+
128
+ const velocity = new VelocityBehaviour(renderer.container, this.shape, this.noise, this.main.startSpeed, 1);
129
+ velocity.gravity = this.main.gravityModifier;
130
+ velocity.gravityModifierMultiplier = this.main.gravityModifierMultiplier;
131
+ behaviours.push(velocity);
132
+
133
+
134
+ const emitter = this._emitter = new Emitter({});
135
+ emitter.setInitializers(initializers);
136
+ emitter.setBehaviours(behaviours);
137
+ emitter.setRate(this.emission);
138
+ emitter.damping = 0;
25
139
  }
26
140
 
27
- getMesh(_index: number): THREE.Mesh | null {
28
- if (!this.mesh) return null;
29
- return this.context.assets.findMesh(this.mesh);
141
+ onEnable() {
142
+ this._emitter.emit();
143
+ this._system.addEmitter(this._emitter);
144
+ this._system.emit({ onStart: () => { }, onUpdate: () => { }, onEnd: () => { }, });
30
145
  }
31
146
 
32
- private sharedMaterial?: string;
33
- private mesh?: string;
147
+ onDisable() {
148
+ this._system.removeEmitter(this._emitter);
149
+ }
34
150
 
35
- awake() {
36
- if (debug)
37
- console.log(this);
151
+ onBeforeRender() {
152
+ this.emission.currentParticles = this._system.getCount();
153
+ this.emission.maxParticles = this.main.maxParticles;
154
+ this.shape.update(this.context, this.main.simulationSpace, this.gameObject);
155
+ this.noise.update(this.context);
156
+ this._system.update(this.context.time.deltaTime * this.main.simulationSpeed);
157
+
158
+ // sprite materials must be scaled in AR
159
+ const cam = this.context.mainCamera;
160
+ if (cam) {
161
+ const scale = getWorldScale(cam);
162
+ this._size.cameraScale = scale.x;
163
+ }
38
164
  }
165
+
39
166
  }
40
167
 
41
- export class ParticleSystem extends Behaviour {
42
168
 
43
- main!: Modules.MainModule;
44
- emission!: Modules.EmissionModule;
45
- shape!: Modules.ShapeModule;
46
169
 
47
- private renderer!: ParticleSystemRenderer;
48
170
 
49
- private geometry: THREE.BufferGeometry | undefined;
50
- private material!: THREE.PointsMaterial;
51
- private particlesMesh!: THREE.Points;
171
+ class MinMaxCurveSpan {
52
172
 
53
- private positions!: THREE.Float32BufferAttribute;
54
- private positionsArray!: Float32Array;
55
- private particleStates: Array<ParticleState> = [];
56
- private activeCount: number = 0;
173
+ readonly time: Time;
174
+ readonly curve: MinMaxCurve;
175
+ multiplier: number = 1;
57
176
 
58
- private shapeRotation: THREE.Quaternion = new THREE.Quaternion();
59
- private tempVec3: THREE.Vector3 = new THREE.Vector3();
60
- private tempQuat: THREE.Quaternion = new THREE.Quaternion();
177
+ constructor(minMaxCurve: MinMaxCurve, multiplier: number = 1) {
178
+ this.time = Context.Current.time;
179
+ this.curve = minMaxCurve;
180
+ this.multiplier = multiplier;
181
+ }
61
182
 
62
- awake(): void {
63
- this.renderer = GameObject.getComponent(this.gameObject, ParticleSystemRenderer)!;
64
- // if (debug)
65
- console.log(this);
183
+ /** called by nebula */
184
+ getValue(lerp?: number) {
185
+ const res = this.curve.evaluate(this.time.time, lerp) * this.multiplier;
186
+ return res;
66
187
  }
188
+ }
67
189
 
68
- onEnable() {
69
- // console.trace();
70
- if (this.geometry) {
71
- return;
72
- }
73
- // console.log(this);
190
+ abstract class CustomBehaviour extends Behaviour {
191
+ abstract applyBehaviour(target: Particle | Emitter, time: number, index: number);
192
+ abstract initialize(particle: Particle);
193
+ }
194
+
195
+ abstract class MinMaxCurveBehaviour extends CustomBehaviour {
74
196
 
75
- this.particleStates = [];
76
- this.shapeRotation.setFromEuler(new THREE.Euler(this.shape.rotation.x, this.shape.rotation.y, this.shape.rotation.z));
197
+ readonly startCurve: MinMaxCurve;
198
+ startMultiplier: number = 1;
77
199
 
78
- // TODO: how to render particle mesh
79
- // const assignedMesh = this.renderer?.getMesh(0);
80
- // console.log(assignedMesh);
200
+ constructor(startCurve: MinMaxCurve, startMultiplier: number = 1) {
201
+ super();
202
+ this.startCurve = startCurve;
203
+ this.startMultiplier = startMultiplier;
204
+ }
205
+ }
206
+
207
+ declare type ParticleWithScale = Particle & { target: Object3D, start_scale: number };
81
208
 
82
- this.geometry = new THREE.BufferGeometry();
209
+ class SizeBehaviour extends MinMaxCurveBehaviour {
83
210
 
84
- this.positionsArray = new Float32Array(this.main.maxParticles * 3);
85
- this.positions = new THREE.Float32BufferAttribute(this.positionsArray, 3);
86
- this.geometry.setAttribute('position', this.positions);
211
+ sizeOverLifetimeModule!: SizeOverLifetimeModule;
87
212
 
213
+ cameraScale: number = 1;
88
214
 
89
- // const color = new THREE.Color();
90
- const colorsArray = new Float32Array(this.main.maxParticles * 3);
91
- for (let i = 0; i < colorsArray.length; i++) {
92
- colorsArray[i * 3] = 1;
93
- colorsArray[i * 3 + 1] = 1;
94
- colorsArray[i * 3 + 2] = 1;
215
+ applyBehaviour(particle: ParticleWithScale, _deltaTime: number, _index: number) {
216
+ if (particle.target.type === "Sprite") {
217
+ particle.radius = 1 / this.cameraScale;
218
+ }
219
+ else particle.radius = 1;
220
+
221
+ // particle.target.scale.set(1,1,1);
222
+ if (this.sizeOverLifetimeModule?.enabled) {
223
+ const time = particle.age / particle.life;
224
+ const scaleVector = particle.target.scale;
225
+ this.sizeOverLifetimeModule.evaluate?.call(this.sizeOverLifetimeModule, time, scaleVector);
226
+ // scaleVector.set(.1, .1, .1)
227
+ particle.scale = particle.start_scale * scaleVector.x;
228
+ // console.log(time, particle.scale);
95
229
  }
96
- const colors = new THREE.Float32BufferAttribute(colorsArray, 3);
97
- this.geometry.setAttribute('color', colors);
98
- this.material = new THREE.PointsMaterial({ size: this.main.startSize, color: 0xffffff, vertexColors: true });
99
- this.material.map = this.renderer.mainTexture;
100
- // this.material.onBeforeCompile = (shader) => {
101
- // shader.
102
- // });
103
-
104
- this.particlesMesh = new THREE.Points(this.geometry, this.material);
105
- this.particlesMesh.layers.enable(2);
106
- this.gameObject.add(this.particlesMesh);
107
-
108
- this.activeCount = this.main.prewarm ? this.main.maxParticles : 0;
109
230
  }
231
+ initialize(particle: ParticleWithScale) {
232
+ particle.scale = this.startCurve.evaluate(0, Math.random());// * this.startMultiplier;
233
+ particle.start_scale = particle.scale;
110
234
 
111
- // update() {
112
- // if (!this.geometry) return;
113
-
114
- // const t = this.context.time.deltaTime;
115
- // this.emit(t);
116
-
117
- // for (let i = 0; i < this.activeCount; i += 1) {
118
- // const ps = this.particleStates[i];
119
- // if (!ps) continue;
120
- // const vx = ps.velocity.x * t;
121
- // const vy = ps.velocity.y * t;
122
- // const vz = ps.velocity.z * t;
123
- // ps.position.x += vx;
124
- // ps.position.y += vy;
125
- // ps.position.z += vz;
126
- // this.updateOverLifetime(i, ps);
127
- // this.geometry.attributes.position.setXYZ(i, ps.position.x, ps.position.y, ps.position.z);
128
- // this.geometry.attributes.color.setXYZ(i, ps.color.r, ps.color.g, ps.color.b);
129
- // }
130
- // if (this.geometry) {
131
- // this.geometry.attributes.position.needsUpdate = true;
132
- // this.geometry.setDrawRange(0, this.activeCount);
133
- // }
134
- // }
135
-
136
- emit(deltaTime: number) {
137
- const count = this.activeCount;
138
- for (let i = 0; i < count; i += 1) {
139
-
140
- if (i >= this.particleStates.length) {
141
- const ps = new ParticleState();
142
- ps.lifetime = this.main.startLifetime ?? 1;
143
- ps.position = new THREE.Vector3();
144
- ps.velocity = new THREE.Vector3();
145
- ps.color = new THREE.Color(1, 0, 0);
146
- this.particleStates.push(ps);
147
- this.initializeParticle(i, ps);
148
- ps.age = ps.lifetime * Math.random();
149
- }
150
- const ps = this.particleStates[i];
235
+ }
236
+ }
151
237
 
152
- if (ps.age > ps.lifetime) {
153
- this.activeCount -= 1;
154
- this.activeCount = Math.max(0, this.activeCount);
155
- this.initializeParticle(i, ps);
156
- continue;
157
- }
238
+ declare type ParticleWithColor = Particle & { color_start: { r: number, g: number, b: number }, alpha_start: number };
239
+
240
+ class GradientBehaviour extends CustomBehaviour {
241
+
242
+ private startGradient: MinMaxGradient;
243
+ private gradient?: MinMaxGradient;
158
244
 
159
- ps.age += deltaTime;
160
- this.particleStates[i] = ps;
245
+ constructor(startGradient: MinMaxGradient, gradient?: MinMaxGradient) {
246
+ super();
247
+ this.startGradient = startGradient;
248
+ this.gradient = gradient;
249
+ }
250
+
251
+ /** called from nebula */
252
+ applyBehaviour(target: ParticleWithColor | Emitter, _deltaTime: number, _index: number) {
253
+ // console.log(target, time, index)
254
+ if (target instanceof Particle) {
255
+ if (this.gradient) {
256
+ const t = target.age / target.life;
257
+ const ev = this.gradient.evaluate(t) as RGBAColor;
258
+ const startColor = target.color_start;
259
+ target.color.r = startColor.r * ev.r;
260
+ target.color.g = startColor.g * ev.g;
261
+ target.color.b = startColor.b * ev.b;
262
+ target.alpha = ev.alpha * target.alpha_start;
263
+ }
161
264
  }
162
- this.activeCount += deltaTime * (this.emission.rate);
163
- this.activeCount = Math.min(this.main.maxParticles, this.activeCount);
164
265
  }
165
266
 
166
- private initializeParticle(index: number, particle: ParticleState) {
267
+ private id = Symbol('gradientId');
268
+ private _internalId: number = 0;
269
+
270
+ /** called from nebula */
271
+ initialize(particle: ParticleWithColor) {
272
+
273
+ // console.log(particle);
274
+ // const context = Context.Current;
275
+ // const time = context.time.time;
276
+ const ev = this.startGradient.evaluate(Math.random()) as RGBAColor;
277
+ particle.color.r = ev.r;
278
+ particle.color.g = ev.g;
279
+ particle.color.b = ev.b;
280
+ particle.alpha = ev.alpha
167
281
 
168
- if (!this.geometry) return;
169
282
  particle.age = 0;
170
- particle.color.set(this.main.startColor);
171
- if (this.main.startColor1) {
172
- particle.color.lerp(this.main.startColor1, Math.random());
173
- }
174
- this.geometry.attributes.color.needsUpdate = true;
175
-
176
- this.assignPosition(particle.position);
177
- this.assignVelocity(particle.position, particle.velocity);
178
-
179
- const position = particle.position;
180
- position.multiply(this.shape.scale);
181
- position.applyQuaternion(this.shapeRotation);
182
- position.add(this.shape.position);
183
- // push back
184
- this.particleStates.splice(index, 1);
185
- this.particleStates.push(particle);
283
+
284
+ particle.color_start = { r: ev.r, g: ev.g, b: ev.b };
285
+ particle.alpha_start = ev.alpha;
286
+
287
+ particle.useColor = true;
288
+ particle.useAlpha = true;
289
+
290
+ if (particle[this.id] === undefined)
291
+ particle[this.id] = this._internalId++;
186
292
  }
293
+ }
294
+
295
+
296
+ declare type ParticleWithVelocity = Particle & { velocity_start: { x: number, y: number, u: number }, gravity: number };
297
+
298
+ class VelocityBehaviour extends CustomBehaviour {
299
+
300
+ container: Object3D;
301
+
302
+ shape: ShapeModule;
303
+ noise: NoiseModule;
187
304
 
188
- private updateOverLifetime(_index: number, _particle: ParticleState) {
189
- // particle.position.multiplyScalar()
305
+ startSpeed: MinMaxCurve;
306
+ startMultiplier: number = 1;
307
+
308
+ gravity?: MinMaxCurve;
309
+ gravityModifierMultiplier: number = 1;
310
+
311
+ downDirection = new Vector3(0, -1, 0);
312
+ private _temp: Vector3 = new Vector3();
313
+
314
+ constructor(container: Object3D, shape: ShapeModule, noise: NoiseModule, startCurve: MinMaxCurve, startMultiplier: number) {
315
+ super();
316
+ this.container = container;
317
+ this.shape = shape;
318
+ this.noise = noise;
319
+ this.startSpeed = startCurve;
320
+ this.startMultiplier = startMultiplier;
321
+
322
+ const quat = getWorldQuaternion(container);
323
+ this.downDirection.applyQuaternion(quat);
190
324
  }
191
325
 
192
- private assignPosition(position: THREE.Vector3) {
193
- switch (this.shape.shapeType) {
194
- case Modules.ParticleSystemShapeType.Sphere:
195
- position.set(Math.random() - .5, Math.random() - .5, Math.random() - .5).multiplyScalar(this.shape.radius);
196
- break;
197
- case Modules.ParticleSystemShapeType.Box:
198
- position.set(Math.random() - .5, Math.random() - .5, Math.random() - .5);
199
- break;
200
- default:
201
- position.set(0, 0, 0);
202
- break;
326
+ applyBehaviour(target: ParticleWithVelocity | Emitter, deltaTime: number, index: number) {
327
+
328
+ if (target instanceof Particle) {
329
+ // target.velocity.x = target.velocity_start.x;
330
+ // target.velocity.y = target.velocity_start.y;
331
+ // target.velocity.z = target.velocity_start.z;
332
+ if (target.gravity) {
333
+ // get world down vector
334
+ this._temp.copy(this.downDirection);
335
+ this._temp.multiplyScalar(target.gravity * deltaTime);
336
+ target.velocity.sub(this._temp);
337
+ }
338
+
339
+ if (this.noise) {
340
+ this.noise.applyNoise(index, target.position, target.velocity, deltaTime, target.age, target.life);
341
+ }
203
342
  }
204
343
  }
205
344
 
206
- private assignVelocity(position: THREE.Vector3, velocity: THREE.Vector3) {
207
- switch (this.shape.shapeType) {
208
- case Modules.ParticleSystemShapeType.Sphere:
209
- velocity.set(position.x, position.y, position.z);
210
- break;
211
- case Modules.ParticleSystemShapeType.Box:
212
- velocity.set(0, 0, 1);
213
- if (this.shape.sphericalDirectionAmount > 0) {
214
- this.tempVec3.set(position.x, position.y, position.z).multiply(this.shape.scale).normalize();
215
- velocity.lerp(this.tempVec3, this.shape.sphericalDirectionAmount);
216
- }
217
- break;
218
- case Modules.ParticleSystemShapeType.Cone:
219
- // const maxAngle = 90;
220
- // const fwd = this.shape.angle / maxAngle;
221
- // const side = 1 - fwd;
222
- // const angle = Mathf.toRadians(this.shape.angle);
223
- // const upDir = Math.random();
224
- // const sideDir = 1 - upDir;
225
- // const quat = new THREE.Quaternion().setFromAxisAngle(this.tempVec3.set(side, 0, fwd), angle * Math.random())
226
- const dir = new THREE.Vector3(0, 1, 0);//.applyQuaternion(quat);
227
- velocity.copy(dir);
228
- break;
229
- case Modules.ParticleSystemShapeType.Circle:
230
- this.tempQuat.setFromAxisAngle(this.tempVec3.set(0, 0, 1), Math.random() * Mathf.toRadians(this.shape.arc));
231
- velocity.copy(this.tempVec3.set(1, 0, 0).applyQuaternion(this.tempQuat));
232
- break;
233
- default:
234
- velocity.set(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1);
235
- break;
345
+ initialize(particle: ParticleWithVelocity) {
346
+ const dir = this.shape.getDirection(particle.position);
347
+ const speed = this.startSpeed.evaluate(0, Math.random()) * this.startMultiplier;
348
+ particle.velocity.x = dir.x * speed;
349
+ particle.velocity.y = dir.y * speed;
350
+ particle.velocity.z = dir.z * speed;
351
+ if (!particle.velocity_start)
352
+ particle.velocity_start = {};
353
+ particle.velocity_start.x = particle.velocity.x;
354
+ particle.velocity_start.y = particle.velocity.y;
355
+ particle.velocity_start.z = particle.velocity.z;
356
+
357
+ if (this.gravity) {
358
+ particle.gravity = this.gravity.evaluate(0, Math.random()) * this.gravityModifierMultiplier * 9.81;
236
359
  }
237
- velocity.normalize();
238
-
239
- // set position
240
- switch (this.shape.shapeType) {
241
- case Modules.ParticleSystemShapeType.Circle:
242
- position.add(velocity).multiplyScalar(this.shape.radius);
243
- break;
360
+ else {
361
+ particle.gravity = 0;
244
362
  }
245
363
 
246
- velocity.multiplyScalar(this.main.startSpeedMultiplier);
364
+ // particle.acceleration.y = 1;
365
+ // console.log(particle);
247
366
  }
367
+
248
368
  }