@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.
- package/CHANGELOG.md +7 -0
- package/dist/needle-engine.d.ts +269 -123
- package/dist/needle-engine.js +389 -389
- package/dist/needle-engine.js.map +4 -4
- package/dist/needle-engine.min.js +41 -41
- package/dist/needle-engine.min.js.map +4 -4
- package/lib/engine/engine_gizmos.d.ts +1 -0
- package/lib/engine/engine_gizmos.js +16 -4
- package/lib/engine/engine_gizmos.js.map +1 -1
- package/lib/engine/engine_math.d.ts +9 -6
- package/lib/engine/engine_math.js +9 -0
- package/lib/engine/engine_math.js.map +1 -1
- package/lib/engine/engine_physics.js +14 -6
- package/lib/engine/engine_physics.js.map +1 -1
- package/lib/engine/engine_serialization_core.js +2 -0
- package/lib/engine/engine_serialization_core.js.map +1 -1
- package/lib/engine/engine_utils.d.ts +1 -0
- package/lib/engine/engine_utils.js +3 -0
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine-components/AnimationCurve.js +20 -5
- package/lib/engine-components/AnimationCurve.js.map +1 -1
- package/lib/engine-components/Light.d.ts +2 -0
- package/lib/engine-components/Light.js +33 -9
- package/lib/engine-components/Light.js.map +1 -1
- package/lib/engine-components/ParticleSystem.d.ts +15 -26
- package/lib/engine-components/ParticleSystem.js +251 -184
- package/lib/engine-components/ParticleSystem.js.map +1 -1
- package/lib/engine-components/ParticleSystemModules.d.ts +208 -63
- package/lib/engine-components/ParticleSystemModules.js +640 -153
- package/lib/engine-components/ParticleSystemModules.js.map +1 -1
- package/lib/engine-components/WebXR.js +8 -3
- package/lib/engine-components/WebXR.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/package.json +3 -1
- package/src/engine/codegen/register_types.js +24 -0
- package/src/engine/engine_gizmos.ts +19 -4
- package/src/engine/engine_math.ts +19 -6
- package/src/engine/engine_physics.ts +17 -7
- package/src/engine/engine_serialization_core.ts +1 -0
- package/src/engine/engine_utils.ts +5 -0
- package/src/engine-components/AnimationCurve.ts +25 -11
- package/src/engine-components/Light.ts +39 -8
- package/src/engine-components/ParticleSystem.ts +314 -194
- package/src/engine-components/ParticleSystemModules.ts +537 -154
- package/src/engine-components/WebXR.ts +11 -8
- package/src/engine-components/codegen/components.ts +6 -0
- package/src/engine/dist/engine_physics.js +0 -739
- package/src/engine/dist/engine_setup.js +0 -777
- package/src/engine-components/dist/CharacterController.js +0 -123
- 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
|
|
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
|
-
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
141
|
+
onEnable() {
|
|
142
|
+
this._emitter.emit();
|
|
143
|
+
this._system.addEmitter(this._emitter);
|
|
144
|
+
this._system.emit({ onStart: () => { }, onUpdate: () => { }, onEnd: () => { }, });
|
|
30
145
|
}
|
|
31
146
|
|
|
32
|
-
|
|
33
|
-
|
|
147
|
+
onDisable() {
|
|
148
|
+
this._system.removeEmitter(this._emitter);
|
|
149
|
+
}
|
|
34
150
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
|
|
50
|
-
private material!: THREE.PointsMaterial;
|
|
51
|
-
private particlesMesh!: THREE.Points;
|
|
171
|
+
class MinMaxCurveSpan {
|
|
52
172
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
private activeCount: number = 0;
|
|
173
|
+
readonly time: Time;
|
|
174
|
+
readonly curve: MinMaxCurve;
|
|
175
|
+
multiplier: number = 1;
|
|
57
176
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
76
|
-
|
|
197
|
+
readonly startCurve: MinMaxCurve;
|
|
198
|
+
startMultiplier: number = 1;
|
|
77
199
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
209
|
+
class SizeBehaviour extends MinMaxCurveBehaviour {
|
|
83
210
|
|
|
84
|
-
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
-
|
|
112
|
-
|
|
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
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
-
|
|
160
|
-
|
|
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
|
|
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
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
-
|
|
189
|
-
|
|
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
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
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
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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
|
-
|
|
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
|
-
|
|
364
|
+
// particle.acceleration.y = 1;
|
|
365
|
+
// console.log(particle);
|
|
247
366
|
}
|
|
367
|
+
|
|
248
368
|
}
|