@needle-tools/engine 3.37.3-alpha → 3.37.5-alpha
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 +10 -0
- package/README.md +5 -3
- package/dist/needle-engine.js +325 -248
- package/dist/needle-engine.light.js +1614 -1537
- package/dist/needle-engine.light.min.js +111 -98
- package/dist/needle-engine.light.umd.cjs +146 -133
- package/dist/needle-engine.min.js +43 -30
- package/dist/needle-engine.umd.cjs +64 -51
- package/lib/engine/engine_physics.d.ts +2 -2
- package/lib/engine/engine_physics.js +4 -4
- package/lib/engine/engine_physics.js.map +1 -1
- package/lib/engine/engine_physics_rapier.d.ts +24 -4
- package/lib/engine/engine_physics_rapier.js +33 -12
- package/lib/engine/engine_physics_rapier.js.map +1 -1
- package/lib/engine/engine_types.d.ts +27 -4
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_lighting_settings.d.ts +0 -1
- package/lib/engine/extensions/NEEDLE_lighting_settings.js +0 -6
- package/lib/engine/extensions/NEEDLE_lighting_settings.js.map +1 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js +14 -1
- package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
- package/lib/engine-components/Collider.d.ts +25 -0
- package/lib/engine-components/Collider.js +25 -0
- package/lib/engine-components/Collider.js.map +1 -1
- package/lib/engine-components/OrbitControls.d.ts +16 -3
- package/lib/engine-components/OrbitControls.js +25 -9
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/ParticleSystem.d.ts +31 -1
- package/lib/engine-components/ParticleSystem.js +42 -1
- package/lib/engine-components/ParticleSystem.js.map +1 -1
- package/lib/engine-components/RigidBody.d.ts +3 -0
- package/lib/engine-components/RigidBody.js +5 -2
- package/lib/engine-components/RigidBody.js.map +1 -1
- package/lib/engine-components/SceneSwitcher.d.ts +22 -2
- package/lib/engine-components/SceneSwitcher.js +29 -3
- package/lib/engine-components/SceneSwitcher.js.map +1 -1
- package/lib/engine-components/SyncedTransform.js +3 -15
- package/lib/engine-components/SyncedTransform.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/codegen/register_types.ts +2 -2
- package/src/engine/engine_physics.ts +4 -4
- package/src/engine/engine_physics_rapier.ts +48 -14
- package/src/engine/engine_types.ts +29 -6
- package/src/engine/extensions/NEEDLE_lighting_settings.ts +0 -5
- package/src/engine/webcomponents/needle menu/needle-menu.ts +14 -1
- package/src/engine-components/Collider.ts +27 -4
- package/src/engine-components/OrbitControls.ts +29 -11
- package/src/engine-components/ParticleSystem.ts +44 -4
- package/src/engine-components/RigidBody.ts +5 -2
- package/src/engine-components/SceneSwitcher.ts +45 -5
- package/src/engine-components/SyncedTransform.ts +4 -17
|
@@ -35,6 +35,7 @@ export enum SubEmitterType {
|
|
|
35
35
|
Manual = 4,
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/** @internal */
|
|
38
39
|
export class ParticleSystemRenderer extends Behaviour {
|
|
39
40
|
|
|
40
41
|
@serializable()
|
|
@@ -88,7 +89,7 @@ export class ParticleSystemRenderer extends Behaviour {
|
|
|
88
89
|
// don't modify the assigned material
|
|
89
90
|
material = material.clone();
|
|
90
91
|
material.side = BackSide;
|
|
91
|
-
if(trailEnabled) this.trailMaterial = material;
|
|
92
|
+
if (trailEnabled) this.trailMaterial = material;
|
|
92
93
|
else this.particleMaterial = material;
|
|
93
94
|
}
|
|
94
95
|
}
|
|
@@ -642,6 +643,11 @@ class ParticlesEmissionState implements EmissionState {
|
|
|
642
643
|
waitEmiting: number = 0;
|
|
643
644
|
}
|
|
644
645
|
|
|
646
|
+
/**
|
|
647
|
+
* The ParticleSystem component efficiently handles the rendering of particles.
|
|
648
|
+
*
|
|
649
|
+
* You can add custom behaviours to the particle system to fully customize the behaviour of the particles. See {@link ParticleSystemBaseBehaviour} and {@link ParticleSystem.addBehaviour} for more information.
|
|
650
|
+
*/
|
|
645
651
|
export class ParticleSystem extends Behaviour implements IParticleSystem {
|
|
646
652
|
|
|
647
653
|
play(includeChildren: boolean = false) {
|
|
@@ -838,8 +844,23 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
|
|
|
838
844
|
return this._isUsedAsSubsystem;
|
|
839
845
|
}
|
|
840
846
|
|
|
841
|
-
/** Add a custom quarks behaviour to the particle system.
|
|
842
|
-
* @link
|
|
847
|
+
/** Add a custom quarks behaviour to the particle system.
|
|
848
|
+
* You can add a quarks.Behaviour type or derive from {@link ParticleSystemBaseBehaviour}
|
|
849
|
+
* @link https://github.com/Alchemist0823/three.quarks
|
|
850
|
+
* @example
|
|
851
|
+
* ```typescript
|
|
852
|
+
* class MyBehaviour extends ParticleSystemBaseBehaviour {
|
|
853
|
+
* initialize(particle: Particle) {
|
|
854
|
+
* // initialize the particle
|
|
855
|
+
* }
|
|
856
|
+
* update(particle: Particle, delta: number) {
|
|
857
|
+
* // do something with the particle
|
|
858
|
+
* }
|
|
859
|
+
* }
|
|
860
|
+
*
|
|
861
|
+
* const system = gameObject.getComponent(ParticleSystem);
|
|
862
|
+
* system.addBehaviour(new MyBehaviour());
|
|
863
|
+
* ```
|
|
843
864
|
*/
|
|
844
865
|
addBehaviour(particleSystemBehaviour: Behavior | ParticleSystemBaseBehaviour): boolean {
|
|
845
866
|
if (!this._particleSystem) {
|
|
@@ -852,6 +873,19 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
|
|
|
852
873
|
this._particleSystem.addBehavior(particleSystemBehaviour);
|
|
853
874
|
return true;
|
|
854
875
|
}
|
|
876
|
+
/** Remove a custom quarks behaviour from the particle system. **/
|
|
877
|
+
removeBehaviour(particleSystemBehaviour: Behavior | ParticleSystemBaseBehaviour): boolean {
|
|
878
|
+
if (!this._particleSystem) {
|
|
879
|
+
return false;
|
|
880
|
+
}
|
|
881
|
+
const behaviours = this._particleSystem.behaviors;
|
|
882
|
+
const index = behaviours.indexOf(particleSystemBehaviour);
|
|
883
|
+
if (index !== -1) {
|
|
884
|
+
behaviours.splice(index, 1);
|
|
885
|
+
return true;
|
|
886
|
+
}
|
|
887
|
+
return true;
|
|
888
|
+
}
|
|
855
889
|
/** Removes all behaviours from the particle system
|
|
856
890
|
* **Note:** this will also remove the default behaviours like SizeBehaviour, ColorBehaviour etc.
|
|
857
891
|
*/
|
|
@@ -919,6 +953,7 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
|
|
|
919
953
|
}
|
|
920
954
|
private _subEmitterSystems?: SubEmitterSystem[];
|
|
921
955
|
|
|
956
|
+
/** @internal */
|
|
922
957
|
onAfterDeserialize(_) {
|
|
923
958
|
// doing this here to get a chance to resolve the subemitter guid
|
|
924
959
|
if (this._subEmitterSystems && Array.isArray(this._subEmitterSystems)) {
|
|
@@ -928,6 +963,7 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
|
|
|
928
963
|
}
|
|
929
964
|
}
|
|
930
965
|
|
|
966
|
+
/** @internal */
|
|
931
967
|
awake(): void {
|
|
932
968
|
this._worldPositionFrame = -1;
|
|
933
969
|
|
|
@@ -976,11 +1012,13 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
|
|
|
976
1012
|
}
|
|
977
1013
|
}
|
|
978
1014
|
|
|
1015
|
+
/** @internal */
|
|
979
1016
|
start() {
|
|
980
1017
|
this.addSubParticleSystems();
|
|
981
1018
|
this.updateLayers();
|
|
982
1019
|
}
|
|
983
1020
|
|
|
1021
|
+
/** @internal */
|
|
984
1022
|
onDestroy(): void {
|
|
985
1023
|
this._container?.removeFromParent();
|
|
986
1024
|
this._batchSystem?.removeFromParent();
|
|
@@ -988,6 +1026,7 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
|
|
|
988
1026
|
this._particleSystem?.dispose();
|
|
989
1027
|
}
|
|
990
1028
|
|
|
1029
|
+
/** @internal */
|
|
991
1030
|
onEnable() {
|
|
992
1031
|
if (!this.main) return;
|
|
993
1032
|
if (this.inheritVelocity)
|
|
@@ -1004,6 +1043,7 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
|
|
|
1004
1043
|
this._batchSystem.visible = false;
|
|
1005
1044
|
}
|
|
1006
1045
|
|
|
1046
|
+
/** @internal */
|
|
1007
1047
|
onBeforeRender() {
|
|
1008
1048
|
if (!this.main) return;
|
|
1009
1049
|
if (this._didPreWarm === false && this.main?.prewarm === true) {
|
|
@@ -1143,7 +1183,7 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
|
|
|
1143
1183
|
}
|
|
1144
1184
|
|
|
1145
1185
|
|
|
1146
|
-
|
|
1186
|
+
/** @internal */
|
|
1147
1187
|
export class SubEmitterSystem {
|
|
1148
1188
|
|
|
1149
1189
|
particleSystem?: ParticleSystem;
|
|
@@ -167,8 +167,11 @@ export class Rigidbody extends Behaviour implements IRigidbody {
|
|
|
167
167
|
@serializable()
|
|
168
168
|
useGravity: boolean = true;
|
|
169
169
|
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
/**
|
|
171
|
+
* The center of mass is the point around which the mass of the rigid-body is evenly distributed. It is used to compute the torque applied to the rigid-body when forces are applied to it.
|
|
172
|
+
*/
|
|
173
|
+
@serializable(Vector3)
|
|
174
|
+
centerOfMass: Vector3 = new Vector3(0, 0, 0);
|
|
172
175
|
|
|
173
176
|
/**
|
|
174
177
|
* Constraints are used to lock the position or rotation of an object in a specific axis.
|
|
@@ -43,7 +43,23 @@ export type LoadSceneEvent = {
|
|
|
43
43
|
index: number;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* The ISceneEventListener is called by the {@link SceneSwitcher} when a scene is loaded or unloaded.
|
|
48
|
+
* It must be added to the root object of your scene (that is being loaded) or on the same object as the SceneSwitcher
|
|
49
|
+
* It can be used to e.g. smooth the transition between scenes or to load additional content when a scene is loaded.
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { ISceneEventListener } from "@needle-tools/engine";
|
|
53
|
+
*
|
|
54
|
+
* // Add this component to the root object of a scene loaded by a SceneSwitcher or to the same object as the SceneSwitcher
|
|
55
|
+
* export class MySceneListener implements ISceneEventListener {
|
|
56
|
+
* async sceneOpened(sceneSwitcher: SceneSwitcher) {
|
|
57
|
+
* console.log("Scene opened", sceneSwitcher.currentlyLoadedScene?.uri);
|
|
58
|
+
* }
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
**/
|
|
47
63
|
export interface ISceneEventListener {
|
|
48
64
|
/** Called when the scene is loaded and added */
|
|
49
65
|
sceneOpened?(sceneSwitcher: SceneSwitcher): Promise<void>
|
|
@@ -60,6 +76,9 @@ export interface ISceneEventListener {
|
|
|
60
76
|
* - [Needle Website](https://needle.tools)
|
|
61
77
|
* - [Songs Of Cultures](https://app.songsofcultures.com)
|
|
62
78
|
*
|
|
79
|
+
* ### Interfaces
|
|
80
|
+
* Use the {@link ISceneEventListener} interface to listen to scene open and closing events with the ability to modify transitions and stall the scene loading process.
|
|
81
|
+
*
|
|
63
82
|
* ### Events
|
|
64
83
|
* - `loadscene-start`: Called when a scene starts loading
|
|
65
84
|
* - `loadscene-finished`: Called when a scene finished loading
|
|
@@ -438,7 +457,8 @@ export class SceneSwitcher extends Behaviour {
|
|
|
438
457
|
}
|
|
439
458
|
|
|
440
459
|
private _currentlyLoadingScene?: AssetReference;
|
|
441
|
-
|
|
460
|
+
/** @internal */
|
|
461
|
+
private async __internalSwitchScene(scene: AssetReference): Promise<boolean> {
|
|
442
462
|
|
|
443
463
|
if (this._currentScene) {
|
|
444
464
|
if (debug) console.log("UNLOAD", scene.uri)
|
|
@@ -591,15 +611,25 @@ export class SceneSwitcher extends Behaviour {
|
|
|
591
611
|
await this._loadingScenePromise;
|
|
592
612
|
if (this._isCurrentlyLoading && this.loadingScene?.asset) {
|
|
593
613
|
if (debug) console.log("Add loading scene", this.loadingScene.uri, this.loadingScene.asset)
|
|
594
|
-
const
|
|
595
|
-
GameObject.add(
|
|
596
|
-
const sceneListener = this.tryGetSceneEventListener(
|
|
614
|
+
const loadingScene = this.loadingScene.asset as any as Object3D;
|
|
615
|
+
GameObject.add(loadingScene, this.gameObject);
|
|
616
|
+
const sceneListener = this.tryGetSceneEventListener(loadingScene);
|
|
597
617
|
if (sceneListener?.sceneOpened) {
|
|
598
618
|
const res = sceneListener.sceneOpened(this);
|
|
599
619
|
if (res instanceof Promise) await res;
|
|
600
620
|
}
|
|
601
621
|
}
|
|
602
622
|
}
|
|
623
|
+
// Invoke the event on a loading listener on the same object as the scene switcher
|
|
624
|
+
if (this._isCurrentlyLoading) {
|
|
625
|
+
const listener = this.tryGetSceneEventListener(this.gameObject);
|
|
626
|
+
if (listener) {
|
|
627
|
+
if (listener.sceneOpened) {
|
|
628
|
+
const res = listener.sceneOpened(this);
|
|
629
|
+
if (res instanceof Promise) await res;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
603
633
|
}
|
|
604
634
|
private async onEndLoading() {
|
|
605
635
|
this._isCurrentlyLoading = false;
|
|
@@ -614,6 +644,16 @@ export class SceneSwitcher extends Behaviour {
|
|
|
614
644
|
}
|
|
615
645
|
GameObject.remove(obj);
|
|
616
646
|
}
|
|
647
|
+
// Invoke the event on a loading listener on the same object as the scene switcher
|
|
648
|
+
if (!this._isCurrentlyLoading) {
|
|
649
|
+
const listener = this.tryGetSceneEventListener(this.gameObject);
|
|
650
|
+
if (listener) {
|
|
651
|
+
if (listener.sceneClosing) {
|
|
652
|
+
const res = listener.sceneClosing();
|
|
653
|
+
if (res instanceof Promise) await res;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
}
|
|
617
657
|
}
|
|
618
658
|
|
|
619
659
|
private tryGetSceneEventListener(obj: Object3D, level: number = 0): ISceneEventListener | null {
|
|
@@ -282,22 +282,14 @@ export class SyncedTransform extends Behaviour {
|
|
|
282
282
|
this.lastWorldRotation.copy(wr);
|
|
283
283
|
|
|
284
284
|
|
|
285
|
-
// if (this._model.isOwned === false && this.autoOwnership) {
|
|
286
|
-
// this.requestOwnership();
|
|
287
|
-
// }
|
|
288
|
-
|
|
289
285
|
if (!this._model) return;
|
|
290
|
-
|
|
286
|
+
|
|
291
287
|
if (!this._model || this._model.hasOwnership === undefined || !this._model.hasOwnership) {
|
|
292
|
-
if
|
|
293
|
-
this.rb.isKinematic = this._model.isOwned ?? false;
|
|
294
|
-
this.rb.setVelocity(0, 0, 0);
|
|
295
|
-
}
|
|
288
|
+
// if we're not the owner of this synced transform then don't send any data
|
|
296
289
|
return;
|
|
297
290
|
}
|
|
298
291
|
|
|
299
292
|
// local user is owner:
|
|
300
|
-
|
|
301
293
|
if (this.rb) {
|
|
302
294
|
if (this._wasKinematic !== undefined) {
|
|
303
295
|
if (debug)
|
|
@@ -305,13 +297,8 @@ export class SyncedTransform extends Behaviour {
|
|
|
305
297
|
this.rb.isKinematic = this._wasKinematic;
|
|
306
298
|
}
|
|
307
299
|
|
|
308
|
-
//
|
|
309
|
-
|
|
310
|
-
if (debug)
|
|
311
|
-
console.log("RESET", this.name)
|
|
312
|
-
this.gameObject.position.set(0, 1, 0);
|
|
313
|
-
this.rb.setVelocity(0, 0, 0);
|
|
314
|
-
}
|
|
300
|
+
// TODO: if the SyncedTransform has a dynamic rigidbody we should probably synchronize the Rigidbody's properties (velocity etc)
|
|
301
|
+
// Or the Rigidbody should be synchronized separately in which case the SyncedTransform should be passive
|
|
315
302
|
}
|
|
316
303
|
|
|
317
304
|
const updateInterval = 10;
|