@needle-tools/engine 2.58.4-pre → 2.59.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 +13 -0
- package/dist/needle-engine.js +8820 -8736
- package/dist/needle-engine.umd.cjs +195 -195
- package/lib/engine/debug/debug_overlay.js +11 -0
- package/lib/engine/debug/debug_overlay.js.map +1 -1
- package/lib/engine/engine_addressables.js +8 -5
- package/lib/engine/engine_addressables.js.map +1 -1
- package/lib/engine/engine_element.js +2 -1
- package/lib/engine/engine_element.js.map +1 -1
- package/lib/engine/engine_gameobject.d.ts +3 -1
- package/lib/engine/engine_gameobject.js +31 -2
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_hot_reload.d.ts +2 -0
- package/lib/engine/engine_hot_reload.js +15 -2
- package/lib/engine/engine_hot_reload.js.map +1 -1
- package/lib/engine/engine_input.d.ts +2 -0
- package/lib/engine/engine_input.js +16 -0
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_utils.d.ts +1 -1
- package/lib/engine/engine_utils.js +5 -2
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_gameobject_data.js +6 -4
- package/lib/engine/extensions/NEEDLE_gameobject_data.js.map +1 -1
- package/lib/engine-components/Animator.js +10 -6
- package/lib/engine-components/Animator.js.map +1 -1
- package/lib/engine-components/AnimatorController.d.ts +1 -1
- package/lib/engine-components/AnimatorController.js +19 -12
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/Component.d.ts +1 -0
- package/lib/engine-components/Component.js +4 -1
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/OrbitControls.d.ts +7 -2
- package/lib/engine-components/OrbitControls.js +34 -15
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/ParticleSystem.d.ts +1 -0
- package/lib/engine-components/ParticleSystem.js +15 -2
- package/lib/engine-components/ParticleSystem.js.map +1 -1
- package/lib/engine-components/WebXR.js.map +1 -1
- package/lib/engine-components/timeline/PlayableDirector.js +5 -2
- package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
- package/lib/engine-components/timeline/TimelineTracks.d.ts +1 -0
- package/lib/engine-components/timeline/TimelineTracks.js +14 -3
- package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
- package/lib/engine-components/ui/EventSystem.d.ts +10 -5
- package/lib/engine-components/ui/EventSystem.js +45 -41
- package/lib/engine-components/ui/EventSystem.js.map +1 -1
- package/lib/engine-components/ui/Raycaster.js +2 -2
- package/lib/engine-components/ui/Raycaster.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/engine/debug/debug_overlay.ts +17 -5
- package/src/engine/engine_addressables.ts +8 -5
- package/src/engine/engine_element.ts +2 -1
- package/src/engine/engine_gameobject.ts +34 -3
- package/src/engine/engine_hot_reload.ts +16 -5
- package/src/engine/engine_input.ts +11 -0
- package/src/engine/engine_utils.ts +4 -3
- package/src/engine/extensions/NEEDLE_gameobject_data.ts +11 -6
- package/src/engine-components/Animator.ts +12 -9
- package/src/engine-components/AnimatorController.ts +20 -13
- package/src/engine-components/Component.ts +5 -1
- package/src/engine-components/OrbitControls.ts +44 -19
- package/src/engine-components/ParticleSystem.ts +18 -3
- package/src/engine-components/WebXR.ts +1 -0
- package/src/engine-components/timeline/PlayableDirector.ts +4 -2
- package/src/engine-components/timeline/TimelineTracks.ts +15 -4
- package/src/engine-components/ui/EventSystem.ts +48 -42
- package/src/engine-components/ui/Raycaster.ts +2 -2
|
@@ -345,7 +345,6 @@ class VelocityBehaviour extends ParticleSystemBaseBehaviour {
|
|
|
345
345
|
|
|
346
346
|
initialize(particle: Particle): void {
|
|
347
347
|
const factor = 1 + this.scaleFactorDiff;
|
|
348
|
-
|
|
349
348
|
particle.startSpeed = this.system.main.startSpeed.evaluate(Math.random(), Math.random()) * factor;
|
|
350
349
|
particle.velocity.copy(this.system.shape.getDirection(particle.position)).multiplyScalar(particle.startSpeed);
|
|
351
350
|
if (this.system.inheritVelocity?.enabled) {
|
|
@@ -414,6 +413,10 @@ class VelocityBehaviour extends ParticleSystemBaseBehaviour {
|
|
|
414
413
|
// const factor = this.system.worldScale.x;
|
|
415
414
|
limitVelocityOverLifetime.apply(particle.position, baseVelocity, particle.velocity, particle.size, t01, delta, 1);
|
|
416
415
|
}
|
|
416
|
+
|
|
417
|
+
if (this.system.worldspace) {
|
|
418
|
+
particle.velocity.multiply(this.system.worldScale);
|
|
419
|
+
}
|
|
417
420
|
}
|
|
418
421
|
}
|
|
419
422
|
|
|
@@ -421,14 +424,19 @@ const $colorLerpFactor = Symbol("colorLerpFactor");
|
|
|
421
424
|
class ColorBehaviour extends ParticleSystemBaseBehaviour {
|
|
422
425
|
type: string = "NeedleColor";
|
|
423
426
|
|
|
424
|
-
initialize(
|
|
425
|
-
|
|
427
|
+
initialize(_particle: Particle): void {
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
private _init(particle: Particle) {
|
|
431
|
+
const col = this.system.main.startColor.evaluate(Math.random());
|
|
426
432
|
particle.startColor.set(col.r, col.g, col.b, col.alpha);
|
|
427
433
|
particle.color.copy(particle.startColor);
|
|
428
434
|
particle[$colorLerpFactor] = Math.random();
|
|
429
435
|
}
|
|
430
436
|
|
|
431
437
|
update(particle: Particle, _delta: number): void {
|
|
438
|
+
if (particle.age === 0)
|
|
439
|
+
this._init(particle);
|
|
432
440
|
if (this.system.colorOverLifetime.enabled) {
|
|
433
441
|
const t = particle.age / particle.life;
|
|
434
442
|
const col = this.system.colorOverLifetime.color.evaluate(t, particle[$colorLerpFactor]);
|
|
@@ -767,6 +775,13 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
|
|
|
767
775
|
this.addSubParticleSystems();
|
|
768
776
|
}
|
|
769
777
|
|
|
778
|
+
onDestroy(): void {
|
|
779
|
+
this._container?.removeFromParent();
|
|
780
|
+
this._batchSystem?.removeFromParent();
|
|
781
|
+
this._particleSystem?.emitter.removeFromParent();
|
|
782
|
+
this._particleSystem?.dispose();
|
|
783
|
+
}
|
|
784
|
+
|
|
770
785
|
onEnable() {
|
|
771
786
|
if (this.inheritVelocity)
|
|
772
787
|
this.inheritVelocity.system = this;
|
|
@@ -126,8 +126,9 @@ export class PlayableDirector extends Behaviour {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
onDestroy(): void {
|
|
129
|
-
for (const
|
|
130
|
-
track
|
|
129
|
+
for (const tracks of this._allTracks) {
|
|
130
|
+
for (const track of tracks)
|
|
131
|
+
track.onDestroy?.();
|
|
131
132
|
}
|
|
132
133
|
}
|
|
133
134
|
|
|
@@ -151,6 +152,7 @@ export class PlayableDirector extends Behaviour {
|
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
stop() {
|
|
155
|
+
for(const track of this._audioTracks) track.stop();
|
|
154
156
|
if (this._isPlaying) {
|
|
155
157
|
this._time = 0;
|
|
156
158
|
this._isPlaying = false;
|
|
@@ -182,7 +182,7 @@ export class AnimationTrackHandler extends TrackHandler {
|
|
|
182
182
|
clip.tracks.push(track);
|
|
183
183
|
this.createPositionInterpolant(clip, clipModel, track);
|
|
184
184
|
}
|
|
185
|
-
else if(!foundRotationTrack){
|
|
185
|
+
else if (!foundRotationTrack) {
|
|
186
186
|
const trackName = clip.tracks[0].name.substring(0, indexOfProperty) + ".quaternion";
|
|
187
187
|
if (debug) console.warn("Create quaternion track", objName, targetObj);
|
|
188
188
|
const rot = targetObj.quaternion;
|
|
@@ -442,6 +442,8 @@ export class AnimationTrackHandler extends TrackHandler {
|
|
|
442
442
|
|
|
443
443
|
}
|
|
444
444
|
|
|
445
|
+
const muteAudioTracks = getParam("mutetimeline");
|
|
446
|
+
|
|
445
447
|
export class AudioTrackHandler extends TrackHandler {
|
|
446
448
|
models: Array<Models.ClipModel> = [];
|
|
447
449
|
|
|
@@ -469,7 +471,8 @@ export class AudioTrackHandler extends TrackHandler {
|
|
|
469
471
|
const audio = new THREE.Audio(this.listener);
|
|
470
472
|
audio.setVolume(model.asset.volume);
|
|
471
473
|
const loader = new THREE.AudioLoader();
|
|
472
|
-
|
|
474
|
+
if (debug)
|
|
475
|
+
console.log(path, this.director.sourceId);
|
|
473
476
|
loader.load(path, (buffer) => {
|
|
474
477
|
audio.setBuffer(buffer);
|
|
475
478
|
audio.loop = model.asset.loop;
|
|
@@ -495,18 +498,26 @@ export class AudioTrackHandler extends TrackHandler {
|
|
|
495
498
|
}
|
|
496
499
|
}
|
|
497
500
|
|
|
501
|
+
stop() {
|
|
502
|
+
for (let i = 0; i < this.audio.length; i++) {
|
|
503
|
+
const audio = this.audio[i];
|
|
504
|
+
if (audio?.isPlaying)
|
|
505
|
+
audio.stop();
|
|
506
|
+
}
|
|
507
|
+
}
|
|
498
508
|
evaluate(time: number) {
|
|
509
|
+
if(muteAudioTracks) return;
|
|
499
510
|
if (this.track.muted) return;
|
|
500
511
|
for (let i = 0; i < this.models.length; i++) {
|
|
501
512
|
const model = this.models[i];
|
|
502
513
|
const audio = this.audio[i];
|
|
503
514
|
if (time >= model.start && time <= model.end) {
|
|
504
|
-
if (this.director.
|
|
515
|
+
if (this.director.isPlaying == false) {
|
|
505
516
|
if (audio.isPlaying)
|
|
506
517
|
audio.stop();
|
|
507
518
|
if (this.lastTime === time) continue;
|
|
508
519
|
}
|
|
509
|
-
if (!audio.isPlaying) {
|
|
520
|
+
else if (!audio.isPlaying) {
|
|
510
521
|
audio.offset = model.clipIn + (time - model.start) * model.timeScale;
|
|
511
522
|
audio.play();
|
|
512
523
|
}
|
|
@@ -16,6 +16,11 @@ import { $shadowDomOwner } from "./BaseUIComponent";
|
|
|
16
16
|
|
|
17
17
|
const debug = getParam("debugeventsystem");
|
|
18
18
|
|
|
19
|
+
export enum EventSystemEvents {
|
|
20
|
+
BeforeHandleInput = "BeforeHandleInput",
|
|
21
|
+
AfterHandleInput = "AfterHandleInput",
|
|
22
|
+
}
|
|
23
|
+
|
|
19
24
|
export class EventSystem extends Behaviour {
|
|
20
25
|
|
|
21
26
|
|
|
@@ -45,6 +50,16 @@ export class EventSystem extends Behaviour {
|
|
|
45
50
|
return this._eventSystemMap.get(context)!;
|
|
46
51
|
}
|
|
47
52
|
|
|
53
|
+
static get(ctx: Context): EventSystem | null {
|
|
54
|
+
const systems = this._eventSystemMap.get(ctx);
|
|
55
|
+
if (systems && systems.length > 0) return systems[0];
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static get instance(): EventSystem | null {
|
|
60
|
+
return this.systems[0];
|
|
61
|
+
}
|
|
62
|
+
|
|
48
63
|
//@ts-ignore
|
|
49
64
|
static ensureUpdateMeshUI(instance, context: Context) {
|
|
50
65
|
MeshUIHelper.update(instance, context);
|
|
@@ -53,12 +68,8 @@ export class EventSystem extends Behaviour {
|
|
|
53
68
|
MeshUIHelper.markDirty();
|
|
54
69
|
}
|
|
55
70
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
private orbitControl: OrbitControls | null = null;
|
|
61
|
-
private orbitControlWasEnabled: boolean = false;
|
|
71
|
+
// private orbitControl: OrbitControls | null = null;
|
|
72
|
+
// private orbitControlWasEnabled: boolean = false;
|
|
62
73
|
private raycaster: Raycaster[] = [];
|
|
63
74
|
|
|
64
75
|
constructor() {
|
|
@@ -66,6 +77,9 @@ export class EventSystem extends Behaviour {
|
|
|
66
77
|
EventSystem.systems.push(this);
|
|
67
78
|
}
|
|
68
79
|
|
|
80
|
+
get hasActiveUI() { return this.currentActiveMeshUIComponents.length > 0; }
|
|
81
|
+
get isHoveringObjects() { return this.objectsHoveredThisFrame.length > 0; }
|
|
82
|
+
|
|
69
83
|
onDestroy(): void {
|
|
70
84
|
EventSystem.systems.splice(EventSystem.systems.indexOf(this), 1);
|
|
71
85
|
}
|
|
@@ -90,7 +104,7 @@ export class EventSystem extends Behaviour {
|
|
|
90
104
|
private _selectStartFn?: any;
|
|
91
105
|
private _selectEndFn?: any;
|
|
92
106
|
private _selectUpdateFn?: any;
|
|
93
|
-
private
|
|
107
|
+
private _handleEventFn?: any;
|
|
94
108
|
|
|
95
109
|
onEnable(): void {
|
|
96
110
|
|
|
@@ -150,9 +164,14 @@ export class EventSystem extends Behaviour {
|
|
|
150
164
|
WebXRController.addEventListener(ControllerEvents.Update, this._selectUpdateFn);
|
|
151
165
|
|
|
152
166
|
// TODO: unregister
|
|
153
|
-
this.
|
|
154
|
-
this.context.pre_update_callbacks.push(this.
|
|
155
|
-
|
|
167
|
+
this._handleEventFn ??= this.onHandleEvents.bind(this);
|
|
168
|
+
this.context.pre_update_callbacks.push(this._handleEventFn);
|
|
169
|
+
// If we subscribe to those events here we get duplicate event handling for e.g. button clicks
|
|
170
|
+
// I think this was done as a workaround for the InputField where we needed to handle the event within the browser event method
|
|
171
|
+
// without it (via pre_update callbacks) we handle the events outside of the browser loop delayed which doesnt work for some cases
|
|
172
|
+
// this.context.input.addEventListener(InputEvents.PointerDown, this._handleEventFn);
|
|
173
|
+
// this.context.input.addEventListener(InputEvents.PointerUp, this._handleEventFn);
|
|
174
|
+
// this.context.input.addEventListener(InputEvents.PointerMove, this._handleEventFn);
|
|
156
175
|
}
|
|
157
176
|
|
|
158
177
|
onDisable(): void {
|
|
@@ -160,8 +179,10 @@ export class EventSystem extends Behaviour {
|
|
|
160
179
|
WebXRController.removeEventListener(ControllerEvents.SelectEnd, this._selectEndFn);
|
|
161
180
|
WebXRController.removeEventListener(ControllerEvents.Update, this._selectUpdateFn);
|
|
162
181
|
|
|
163
|
-
this.context.pre_update_callbacks.splice(this.context.pre_update_callbacks.indexOf(this.
|
|
164
|
-
this.context.input.removeEventListener(InputEvents.PointerDown, this.
|
|
182
|
+
this.context.pre_update_callbacks.splice(this.context.pre_update_callbacks.indexOf(this._handleEventFn), 1);
|
|
183
|
+
// this.context.input.removeEventListener(InputEvents.PointerDown, this._handleEventFn);
|
|
184
|
+
// this.context.input.removeEventListener(InputEvents.PointerUp, this._handleEventFn);
|
|
185
|
+
// this.context.input.removeEventListener(InputEvents.PointerMove, this._handleEventFn);
|
|
165
186
|
}
|
|
166
187
|
|
|
167
188
|
|
|
@@ -180,7 +201,8 @@ export class EventSystem extends Behaviour {
|
|
|
180
201
|
|
|
181
202
|
private _didMove: boolean = false;
|
|
182
203
|
|
|
183
|
-
|
|
204
|
+
|
|
205
|
+
onHandleEvents() {
|
|
184
206
|
this.objectsHoveredThisFrame.length = 0;
|
|
185
207
|
this.resetMeshUIStates();
|
|
186
208
|
|
|
@@ -196,7 +218,6 @@ export class EventSystem extends Behaviour {
|
|
|
196
218
|
this._didMove = true;
|
|
197
219
|
}
|
|
198
220
|
|
|
199
|
-
const hits = this.performRaycast(null);
|
|
200
221
|
let pointerId = 0;
|
|
201
222
|
for (const i of this.context.input.foreachPointerId()) {
|
|
202
223
|
const isDown = this.context.input.getPointerDown(i);
|
|
@@ -206,6 +227,7 @@ export class EventSystem extends Behaviour {
|
|
|
206
227
|
break;
|
|
207
228
|
}
|
|
208
229
|
}
|
|
230
|
+
|
|
209
231
|
const ptr = this.context.input.getPointerEvent(pointerId);
|
|
210
232
|
// console.log(ptr);
|
|
211
233
|
const args: PointerEventData = new PointerEventData(ptr);
|
|
@@ -215,42 +237,25 @@ export class EventSystem extends Behaviour {
|
|
|
215
237
|
args.isDown = this.context.input.getPointerDown(pointerId);
|
|
216
238
|
args.isUp = this.context.input.getPointerUp(pointerId);
|
|
217
239
|
args.isPressed = this.context.input.getPointerPressed(pointerId);
|
|
218
|
-
|
|
219
|
-
|
|
240
|
+
if (debug && args.isClicked) console.log("CLICK", pointerId);
|
|
241
|
+
|
|
242
|
+
const hits = this.performRaycast(null);
|
|
220
243
|
if (!hits) return;
|
|
244
|
+
this.lastPointerEvent = args;
|
|
221
245
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (this.context.input.mouseDown && this.currentActiveMeshUIComponents.length > 0 && this.context.mainCameraComponent) {
|
|
227
|
-
orbitControlComponent = GameObject.getComponent(this.context.mainCameraComponent.gameObject, OrbitControls) ?? null;
|
|
228
|
-
if (orbitControlComponent) {
|
|
229
|
-
previousOrbitControlState = orbitControlComponent.enabled;
|
|
230
|
-
orbitControlComponent.enabled = false;
|
|
231
|
-
}
|
|
246
|
+
const evt = {
|
|
247
|
+
sender: this,
|
|
248
|
+
args: args,
|
|
249
|
+
hasActiveUI: this.currentActiveMeshUIComponents.length > 0,
|
|
232
250
|
}
|
|
233
|
-
|
|
234
|
-
// if (args.isClicked)
|
|
235
|
-
// console.log(this.guid, ...hits);
|
|
251
|
+
this.dispatchEvent(new CustomEvent(EventSystemEvents.BeforeHandleInput, { detail: evt }))
|
|
236
252
|
this.handleIntersections(hits, args);
|
|
237
|
-
|
|
238
|
-
if (orbitControlComponent) {
|
|
239
|
-
this.orbitControl = orbitControlComponent;
|
|
240
|
-
if (this.orbitControl?.enabled) {
|
|
241
|
-
this.orbitControlWasEnabled = this.orbitControl.enabled;
|
|
242
|
-
this.orbitControl.enabled = false;
|
|
243
|
-
}
|
|
244
|
-
else if (this.orbitControl && !this.context.input.mousePressed) {
|
|
245
|
-
this.orbitControl.enabled = this.orbitControlWasEnabled;
|
|
246
|
-
this.orbitControl = null;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
253
|
+
this.dispatchEvent(new CustomEvent(EventSystemEvents.AfterHandleInput, { detail: evt }))
|
|
250
254
|
}
|
|
251
255
|
|
|
252
256
|
private _tempComponentsArray: Behaviour[] = [];
|
|
253
257
|
onBeforeRender() {
|
|
258
|
+
|
|
254
259
|
if (this.lastPointerEvent)
|
|
255
260
|
this.lastPointerEvent.used = false;
|
|
256
261
|
else return;
|
|
@@ -374,6 +379,7 @@ export class EventSystem extends Behaviour {
|
|
|
374
379
|
const actualGo = parent[$shadowDomOwner].gameObject;
|
|
375
380
|
if (actualGo) {
|
|
376
381
|
const res = UIRaycastUtils.isInteractable(actualGo, this.out);
|
|
382
|
+
// console.log(actualGo, res);
|
|
377
383
|
if (!res) return this.out.canvasGroup?.interactable ?? false;
|
|
378
384
|
canvasGroup = this.out.canvasGroup ?? null;
|
|
379
385
|
|
|
@@ -9,11 +9,11 @@ export class Raycaster extends Behaviour {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
onEnable(): void {
|
|
12
|
-
EventSystem.
|
|
12
|
+
EventSystem.get(this.context)?.register(this);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
onDisable(): void {
|
|
16
|
-
EventSystem.
|
|
16
|
+
EventSystem.get(this.context)?.unregister(this);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
performRaycast(_opts: RaycastOptions | null = null): THREE.Intersection[] | null {
|