@needle-tools/engine 2.65.0-pre.1 → 2.65.2-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 (29) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/dist/needle-engine.js +9956 -9881
  3. package/dist/needle-engine.umd.cjs +211 -207
  4. package/lib/engine/engine_license.js +9 -5
  5. package/lib/engine/engine_license.js.map +1 -1
  6. package/lib/engine/extensions/NEEDLE_techniques_webgl.js +5 -2
  7. package/lib/engine/extensions/NEEDLE_techniques_webgl.js.map +1 -1
  8. package/lib/engine-components/Animator.d.ts +25 -1
  9. package/lib/engine-components/Animator.js +64 -37
  10. package/lib/engine-components/Animator.js.map +1 -1
  11. package/lib/engine-components/AnimatorController.d.ts +14 -12
  12. package/lib/engine-components/AnimatorController.js +15 -13
  13. package/lib/engine-components/AnimatorController.js.map +1 -1
  14. package/lib/engine-components/ParticleSystem.d.ts +12 -8
  15. package/lib/engine-components/ParticleSystem.js +59 -30
  16. package/lib/engine-components/ParticleSystem.js.map +1 -1
  17. package/lib/engine-components/ParticleSystemModules.d.ts +1 -0
  18. package/lib/engine-components/ParticleSystemModules.js +12 -5
  19. package/lib/engine-components/ParticleSystemModules.js.map +1 -1
  20. package/lib/engine-components/Skybox.js +18 -5
  21. package/lib/engine-components/Skybox.js.map +1 -1
  22. package/package.json +1 -1
  23. package/src/engine/engine_license.ts +9 -5
  24. package/src/engine/extensions/NEEDLE_techniques_webgl.ts +5 -2
  25. package/src/engine-components/Animator.ts +54 -27
  26. package/src/engine-components/AnimatorController.ts +15 -13
  27. package/src/engine-components/ParticleSystem.ts +68 -37
  28. package/src/engine-components/ParticleSystemModules.ts +12 -6
  29. package/src/engine-components/Skybox.ts +15 -5
@@ -11,6 +11,8 @@ import { EXRLoader } from "three/examples/jsm/loaders/EXRLoader";
11
11
  import { EquirectangularRefractionMapping, sRGBEncoding, TextureLoader } from "three";
12
12
  import { syncField } from "../engine/engine_networking_auto";
13
13
  import { Camera } from "./Camera";
14
+ import { getParam, getPath } from "../engine/engine_utils";
15
+ const debug = getParam("debugskybox");
14
16
  export class RemoteSkybox extends Behaviour {
15
17
  url;
16
18
  allowDrop = true;
@@ -37,9 +39,16 @@ export class RemoteSkybox extends Behaviour {
37
39
  async setSkybox(url) {
38
40
  if (!url)
39
41
  return;
40
- if (!url?.endsWith(".hdr") && !url.endsWith(".exr")) {
42
+ if (!url?.endsWith(".hdr") && !url.endsWith(".exr") && !url.endsWith(".jpg") && !url.endsWith(".png") && !url.endsWith(".jpeg")) {
41
43
  console.warn("Potentially invalid skybox url", this.url, "on", this.name);
42
44
  }
45
+ if (debug)
46
+ console.log("Remote skybox url?: " + url);
47
+ if (!url.startsWith("http") && !url.startsWith("www.") && !url.startsWith("data:")) {
48
+ url = getPath(this.sourceId, url);
49
+ if (debug)
50
+ console.log("Remote skybox resolved to " + url);
51
+ }
43
52
  if (this._prevUrl === url && this._prevLoadedEnvironment) {
44
53
  this.applySkybox();
45
54
  return;
@@ -63,7 +72,8 @@ export class RemoteSkybox extends Behaviour {
63
72
  if (!(this._loader instanceof TextureLoader))
64
73
  this._loader = new TextureLoader();
65
74
  }
66
- console.log("Loading skybox: " + url);
75
+ if (debug)
76
+ console.log("Loading skybox: " + url);
67
77
  const envMap = await this._loader.loadAsync(url);
68
78
  if (!envMap)
69
79
  return;
@@ -91,7 +101,8 @@ export class RemoteSkybox extends Behaviour {
91
101
  this._prevBackground = this.context.scene.background;
92
102
  if (this.context.scene.environment !== envMap)
93
103
  this._prevEnvironment = this.context.scene.environment;
94
- console.log("Set remote skybox", this.url);
104
+ if (debug)
105
+ console.log("Set remote skybox", this.url);
95
106
  if (this.environment)
96
107
  this.context.scene.environment = envMap;
97
108
  if (this.background && !Camera.backgroundShouldBeTransparent(this.context))
@@ -128,12 +139,14 @@ export class RemoteSkybox extends Behaviour {
128
139
  for (const type of e.dataTransfer.types) {
129
140
  if (type === "text/uri-list") {
130
141
  const url = e.dataTransfer.getData(type);
131
- console.log(type, url);
142
+ if (debug)
143
+ console.log(type, url);
132
144
  let name = new RegExp(/polyhaven.com\/asset_img\/.+?\/(?<name>.+)\.png/).exec(url)?.groups?.name;
133
145
  if (!name) {
134
146
  name = new RegExp(/polyhaven\.com\/a\/(?<name>.+)/).exec(url)?.groups?.name;
135
147
  }
136
- console.log(name);
148
+ if (debug)
149
+ console.log(name);
137
150
  if (name) {
138
151
  const envurl = "https://dl.polyhaven.org/file/ph-assets/HDRIs/exr/1k/" + name + "_1k.exr";
139
152
  this.setSkybox(envurl);
@@ -1 +1 @@
1
- {"version":3,"file":"Skybox.js","sourceRoot":"","sources":["../../../src/engine-components/Skybox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Skybox.js","sourceRoot":"","sources":["../../../src/engine-components/Skybox.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@needle-tools/engine",
3
- "version": "2.65.0-pre.1",
3
+ "version": "2.65.2-pre",
4
4
  "description": "Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development, and can be deployed anywhere. It is flexible, extensible, and collaboration and XR come naturally.",
5
5
  "main": "dist/needle-engine.umd.cjs",
6
6
  "module": "lib/needle-engine.js",
@@ -86,14 +86,18 @@ function insertNonCommercialUseHint(ctx: IContext) {
86
86
  async function logNonCommercialUse(_logo?: string) {
87
87
  const logo = "data:image/webp;base64,UklGRrABAABXRUJQVlA4WAoAAAAQAAAAHwAAHwAAQUxQSKEAAAARN6CmbSM4WR7vdARON11EBDq3fLiNbVtVzpMCPlKAEzsx0Y/x+Ovuv4dn0EFE/ydAvz6YggXzgh5sVgXM/zOC/4sii7qgGvB5N7hmuQYwkvazWAu1JPW41FXSHq6pnaQWvqYH18Fc0j1hO/BFTtIeSBlJi5w6qIIO7IOrwhFsB2Yxukif0FTRLpXswHR8MxbslKe9VZsn/Ub5C7YFOpqSTABWUDgg6AAAAFAGAJ0BKiAAIAA+7VyoTqmkpCI3+qgBMB2JbACdMt69DwMIQBLhkTO6XwY00UEDK6cNIDnuNibPf0EgAP7Y1myuiQHLDsF/0h5unrGh6WAbv7aegg2ZMd3uRKfT/3SJztcaujYfTvMXspfCTmYcoO6a+vhC3ss4M8uM58t4siiu59I4aOl59e9Sr6xoxYlHf2v+NnBNpJYeJf8jABQAId/PXuBkLEFkiCucgSGEcfhvajql/j3reCGl0M5/9gQWy7ayNPs+wlvIxFnNfSlfuND4CZOCyxOHhRqOmHN4ULHo3tCSrUNvgAA=";
88
88
  const style = `
89
- font-size:18px;
90
- background-size: contain;
91
- background-position: left center;
89
+ font-size: 18px;
90
+ background-size: 20px;
91
+ background-position: left top;
92
92
  background-repeat:no-repeat;
93
- background-image:url('${logo}')
93
+ background-image:url('${logo}');
94
+ background-max-size: 40px;
95
+ padding-left: 30px;
96
+ margin-bottom: 2px;
97
+ margin-bottom: 5px;
94
98
  `;
95
99
  let licenseText = "Needle Engine — non commercial version";
96
- console.log("%c " + licenseText, style)
100
+ console.log("%c" + licenseText, style)
97
101
  }
98
102
 
99
103
  function createLicenseElement() {
@@ -9,7 +9,7 @@ import { SourceIdentifier } from "../engine_types";
9
9
  import { ILight } from "../engine_types";
10
10
  import { getWorldPosition } from "../engine_three_utils";
11
11
 
12
- const debug = getParam("debugshaders");
12
+ const debug = getParam("debugcustomshader");
13
13
 
14
14
  export const NEEDLE_TECHNIQUES_WEBGL_NAME = "NEEDLE_techniques_webgl";
15
15
 
@@ -524,8 +524,11 @@ export class NEEDLE_techniques_webgl implements GLTFLoaderPlugin {
524
524
  console.warn("Missing/unassigned texture, fallback to white: " + uniformName)
525
525
  break;
526
526
  default:
527
+ if (uniformName === "unity_OrthoParams") {
527
528
 
528
- console.warn("TODO: EXPECTED UNIFORM / fallback NOT SET: " + uniformName, techniqueUniforms[u]);
529
+ }
530
+ else
531
+ console.warn("TODO: EXPECTED UNIFORM / fallback NOT SET: " + uniformName, techniqueUniforms[u]);
529
532
  break;
530
533
  }
531
534
  }
@@ -50,55 +50,82 @@ export class Animator extends Behaviour {
50
50
  return this._animatorController;
51
51
  }
52
52
 
53
- Play(name: string | number, layer: number = -1, normalizedTime: number = Number.NEGATIVE_INFINITY, transitionDurationInSec: number = 0) {
54
- this.runtimeAnimatorController?.Play(name, layer, normalizedTime, transitionDurationInSec);
55
- }
53
+ // NOTE: the uppercase events have been deprecated because UnityEvent methods are all exported with lowercase first letter
56
54
 
57
- Reset() {
58
- this._animatorController?.Reset();
55
+ /**@deprecated use play */
56
+ Play(name: string | number, layer: number = -1, normalizedTime: number = Number.NEGATIVE_INFINITY, transitionDurationInSec: number = 0) { this.play(name, layer, normalizedTime, transitionDurationInSec); }
57
+ play(name: string | number, layer: number = -1, normalizedTime: number = Number.NEGATIVE_INFINITY, transitionDurationInSec: number = 0) {
58
+ this.runtimeAnimatorController?.play(name, layer, normalizedTime, transitionDurationInSec);
59
59
  }
60
60
 
61
- SetBool(name: string | number, value: boolean) {
62
- this.runtimeAnimatorController?.SetBool(name, value);
61
+ /**@deprecated use reset */
62
+ Reset() { this.reset(); }
63
+ reset() {
64
+ this._animatorController?.reset();
63
65
  }
64
66
 
65
- GetBool(name: string | number): boolean {
66
- return this.runtimeAnimatorController?.GetBool(name) ?? false;
67
+ /**@deprecated use setBool */
68
+ SetBool(name: string | number, val: boolean) { this.setBool(name, val); }
69
+ setBool(name: string | number, value: boolean) {
70
+ this.runtimeAnimatorController?.setBool(name, value);
67
71
  }
68
72
 
69
- SetFloat(name: string | number, val: number) {
70
- this.runtimeAnimatorController?.SetFloat(name, val);
73
+ /**@deprecated use getBool */
74
+ GetBool(name: string | number) { return this.getBool(name); }
75
+ getBool(name: string | number): boolean {
76
+ console.log("name", name);
77
+ return this.runtimeAnimatorController?.getBool(name) ?? false;
71
78
  }
72
79
 
73
- GetFloat(name: string | number): number {
74
- return this.runtimeAnimatorController?.GetFloat(name) ?? -1;
80
+ /**@deprecated use setFloat */
81
+ SetFloat(name: string | number, val: number) { this.setFloat(name, val); }
82
+ setFloat(name: string | number, val: number) {
83
+ this.runtimeAnimatorController?.setFloat(name, val);
75
84
  }
76
85
 
77
- SetInteger(name: string | number, val: number) {
78
- this.runtimeAnimatorController?.SetInteger(name, val);
86
+ /**@deprecated use getFloat */
87
+ GetFloat(name: string | number) { return this.getFloat(name); }
88
+ getFloat(name: string | number): number {
89
+ return this.runtimeAnimatorController?.getFloat(name) ?? -1;
79
90
  }
80
91
 
81
- GetInteger(name: string | number): number {
82
- return this.runtimeAnimatorController?.GetInteger(name) ?? -1;
92
+ /**@deprecated use setInteger */
93
+ SetInteger(name: string | number, val: number) { this.setInteger(name, val); }
94
+ setInteger(name: string | number, val: number) {
95
+ this.runtimeAnimatorController?.setInteger(name, val);
83
96
  }
84
97
 
85
- SetTrigger(name: string | number) {
86
- this.runtimeAnimatorController?.SetTrigger(name);
98
+ /**@deprecated use getInteger */
99
+ GetInteger(name: string | number) { return this.getInteger(name); }
100
+ getInteger(name: string | number): number {
101
+ return this.runtimeAnimatorController?.getInteger(name) ?? -1;
87
102
  }
88
103
 
89
- ResetTrigger(name: string | number) {
90
- this.runtimeAnimatorController?.ResetTrigger(name);
104
+ /**@deprecated use setTrigger */
105
+ SetTrigger(name: string | number) { this.setTrigger(name); }
106
+ setTrigger(name: string | number) {
107
+ console.log("name", name);
108
+ this.runtimeAnimatorController?.setTrigger(name);
91
109
  }
92
110
 
93
- IsInTransition(): boolean {
94
- return this.runtimeAnimatorController?.IsInTransition() ?? false;
111
+ /**@deprecated use resetTrigger */
112
+ ResetTrigger(name: string | number) { this.resetTrigger(name); }
113
+ resetTrigger(name: string | number) {
114
+ this.runtimeAnimatorController?.resetTrigger(name);
95
115
  }
96
116
 
117
+ /**@deprecated use isInTransition */
118
+ IsInTransition() { return this.isInTransition(); }
119
+ isInTransition(): boolean {
120
+ return this.runtimeAnimatorController?.isInTransition() ?? false;
121
+ }
97
122
 
98
- SetSpeed(speed: number) {
123
+ /**@deprecated use setSpeed */
124
+ SetSpeed(speed: number) { return this.setSpeed(speed); }
125
+ setSpeed(speed: number) {
99
126
  if (speed === this.speed) return;
100
127
  this.speed = speed;
101
- this._animatorController?.SetSpeed(speed);
128
+ this._animatorController?.setSpeed(speed);
102
129
  }
103
130
 
104
131
  set minMaxSpeed(minMax: { x: number, y: number }) {
@@ -130,7 +157,7 @@ export class Animator extends Behaviour {
130
157
  this.runtimeAnimatorController = clone;
131
158
  console.assert(this.runtimeAnimatorController === clone);
132
159
  this.runtimeAnimatorController.bind(this);
133
- this.runtimeAnimatorController.SetSpeed(this.speed);
160
+ this.runtimeAnimatorController.setSpeed(this.speed);
134
161
  this.runtimeAnimatorController.normalizedStartOffset = this.normalizedStartOffset;
135
162
  }
136
163
  else console.warn("Could not clone animator controller", this.runtimeAnimatorController);
@@ -139,7 +166,7 @@ export class Animator extends Behaviour {
139
166
 
140
167
  onDisable() {
141
168
  if (!this.keepAnimatorControllerStateOnDisable)
142
- this._animatorController?.Reset();
169
+ this._animatorController?.reset();
143
170
  }
144
171
 
145
172
  onBeforeRender() {
@@ -14,7 +14,7 @@ const debugRootMotion = getParam("debugrootmotion");
14
14
 
15
15
  export class AnimatorController {
16
16
 
17
- Play(name: string | number, layerIndex: number = -1, normalizedTime: number = Number.NEGATIVE_INFINITY, durationInSec: number = 0) {
17
+ play(name: string | number, layerIndex: number = -1, normalizedTime: number = Number.NEGATIVE_INFINITY, durationInSec: number = 0) {
18
18
  if (layerIndex < 0) layerIndex = 0;
19
19
  else if (layerIndex >= this.model.layers.length) {
20
20
  console.warn("invalid layer");
@@ -33,61 +33,63 @@ export class AnimatorController {
33
33
  console.warn("Could not find " + name + " to play");
34
34
  }
35
35
 
36
- Reset() {
36
+ reset() {
37
37
  this.setStartTransition();
38
38
  }
39
39
 
40
- SetBool(name: string | number, value: boolean) {
40
+ setBool(name: string | number, value: boolean) {
41
41
  const key = typeof name === "string" ? "name" : "hash";
42
42
  return this.model?.parameters?.filter(p => p[key] === name).forEach(p => p.value = value);
43
43
  }
44
44
 
45
- GetBool(name: string | number): boolean {
45
+ getBool(name: string | number): boolean {
46
46
  const key = typeof name === "string" ? "name" : "hash";
47
47
  return this.model?.parameters?.find(p => p[key] === name)?.value as boolean ?? false;
48
48
  }
49
49
 
50
- SetFloat(name: string | number, val: number) {
50
+ setFloat(name: string | number, val: number) {
51
51
  const key = typeof name === "string" ? "name" : "hash";
52
52
  return this.model?.parameters?.filter(p => p[key] === name).forEach(p => p.value = val);
53
53
  }
54
54
 
55
- GetFloat(name: string | number): number {
55
+ getFloat(name: string | number): number {
56
56
  const key = typeof name === "string" ? "name" : "hash";
57
57
  return this.model?.parameters?.find(p => p[key] === name)?.value as number ?? 0;
58
58
  }
59
59
 
60
- SetInteger(name: string | number, val: number) {
60
+ setInteger(name: string | number, val: number) {
61
61
  const key = typeof name === "string" ? "name" : "hash";
62
62
  return this.model?.parameters?.filter(p => p[key] === name).forEach(p => p.value = val);
63
63
  }
64
64
 
65
- GetInteger(name: string | number): number {
65
+ getInteger(name: string | number): number {
66
66
  const key = typeof name === "string" ? "name" : "hash";
67
67
  return this.model?.parameters?.find(p => p[key] === name)?.value as number ?? 0;
68
68
  }
69
69
 
70
- SetTrigger(name: string | number) {
70
+ setTrigger(name: string | number) {
71
71
  if (debug)
72
72
  console.log("SET TRIGGER", name);
73
73
  const key = typeof name === "string" ? "name" : "hash";
74
74
  return this.model?.parameters?.filter(p => p[key] === name).forEach(p => p.value = true);
75
75
  }
76
76
 
77
- ResetTrigger(name: string | number) {
77
+ resetTrigger(name: string | number) {
78
78
  const key = typeof name === "string" ? "name" : "hash";
79
79
  return this.model?.parameters?.filter(p => p[key] === name).forEach(p => p.value = false);
80
80
  }
81
81
 
82
- IsInTransition(): boolean {
82
+ isInTransition(): boolean {
83
83
  return this._activeStates.length > 1;
84
84
  }
85
85
 
86
- SetSpeed(speed: number) {
86
+ setSpeed(speed: number) {
87
87
  this._speed = speed;
88
88
  }
89
89
 
90
- FindState(name: string | undefined | null): State | null {
90
+ /**@deprecated use findState */
91
+ FindState(name: string | undefined | null): State | null { return this.findState(name); }
92
+ findState(name: string | undefined | null): State | null {
91
93
  if (!name) return null;
92
94
  if (Array.isArray(this.model.layers)) {
93
95
  for (const layer of this.model.layers) {
@@ -9,7 +9,7 @@ import { getParam } from "../engine/engine_utils";
9
9
  import { serializable } from "../engine/engine_serialization";
10
10
  import { RGBAColor } from "./js-extensions/RGBAColor";
11
11
  import { AxesHelper, BufferGeometry, Color, Material, Matrix4, Mesh, MeshStandardMaterial, Object3D, OneMinusDstAlphaFactor, PlaneGeometry, Quaternion, Sprite, SpriteMaterial, Vector3, Vector4 } from "three";
12
- import { getWorldPosition, getWorldQuaternion, getWorldScale } from "../engine/engine_three_utils";
12
+ import { getWorldPosition, getWorldQuaternion, getWorldScale, setWorldScale } from "../engine/engine_three_utils";
13
13
  import { assign } from "../engine/engine_serialization_core";
14
14
  import { BatchedParticleRenderer, Behavior, BillBoardSettings, BurstParameters, ColorGenerator, ConstantColor, ConstantValue, EmissionState, EmitSubParticleSystem, EmitterShape, FunctionColorGenerator, FunctionJSON, FunctionValueGenerator, IntervalValue, MeshSettings, Particle, ParticleEmitter, ParticleSystem as _ParticleSystem, ParticleSystemParameters, PointEmitter, RecordState, RenderMode, RotationGenerator, SizeOverLife, TrailBatch, TrailParticle, TrailSettings, ValueGenerator } from "three.quarks";
15
15
  import { createFlatTexture } from "../engine/engine_shaders";
@@ -17,6 +17,7 @@ import { Mathf } from "../engine/engine_math";
17
17
  import { Context } from "../engine/engine_setup";
18
18
  import { ParticleSubEmitter } from "./ParticleSystemSubEmitter";
19
19
  import { NEEDLE_progressive } from "../engine/extensions/NEEDLE_progressive";
20
+ import { Gizmos, isDevEnvironment } from "../engine/api";
20
21
 
21
22
  const debug = getParam("debugparticles");
22
23
  const suppressProgressiveLoading = getParam("noprogressive");
@@ -30,24 +31,6 @@ export enum SubEmitterType {
30
31
  Manual = 4,
31
32
  }
32
33
 
33
- export class SubEmitterSystem {
34
-
35
- particleSystem?: ParticleSystem;
36
-
37
- emitProbability: number = 1;
38
- properties?: number;
39
- type?: SubEmitterType;
40
-
41
- _deserialize(context: Context) {
42
- const ps = this.particleSystem;
43
- if (ps && !(ps instanceof ParticleSystem) && typeof ps["guid"] === "string") {
44
- if (debug) console.log("DESERIALIZE SUBEMITTER", ps);
45
- this.particleSystem = undefined;
46
- this.particleSystem = GameObject.findByGuid(ps["guid"], context.scene) as ParticleSystem;
47
- }
48
- }
49
- }
50
-
51
34
  export class ParticleSystemRenderer extends Behaviour {
52
35
 
53
36
  @serializable()
@@ -62,6 +45,22 @@ export class ParticleSystemRenderer extends Behaviour {
62
45
  // @serializable(Mesh)
63
46
  particleMesh?: Mesh | string;
64
47
 
48
+ @serializable()
49
+ maxParticleSize!: number;
50
+
51
+ @serializable()
52
+ minParticleSize!: number;
53
+
54
+ start() {
55
+ if (this.maxParticleSize !== .5 && this.minParticleSize !== 0) {
56
+ if (isDevEnvironment()) {
57
+ const msg = `ParticleSystem \"${this.name}\" has non-default min/max particle size. This may not render correctly. Please set min size to 0 and the max size to 0.5 and use the \"StartSize\" setting instead`;
58
+ console.warn(msg);
59
+ // showBalloonWarning(msg);
60
+ }
61
+ }
62
+ }
63
+
65
64
  get transparent(): boolean {
66
65
  const res = this.particleMaterial?.transparent ?? false;
67
66
  // console.log(res, this.particleMaterial);
@@ -305,8 +304,13 @@ class SizeBehaviour extends ParticleSystemBaseBehaviour {
305
304
 
306
305
  type: string = "NeedleSize";
307
306
 
307
+ private _minSize = 0;
308
+ private _maxSize = 1;
309
+
308
310
  initialize(particle: Particle) {
309
311
  particle[$sizeLerpFactor] = Math.random();
312
+ this._minSize = this.system.renderer.minParticleSize;
313
+ this._maxSize = this.system.renderer.maxParticleSize;
310
314
  }
311
315
 
312
316
  update(particle: Particle, _delta: number): void {
@@ -320,7 +324,8 @@ class SizeBehaviour extends ParticleSystemBaseBehaviour {
320
324
  size *= this.system.sizeOverLifetime.evaluate(age01, undefined, particle[$sizeLerpFactor]).x;
321
325
  const scaleFactor = this.system.worldScale.x / this.system.cameraScale;
322
326
  particle.size = particle.startSize * size * scaleFactor;
323
-
327
+ // in Unity this is viewport size
328
+ particle.size = Mathf.clamp(particle.size, this._minSize, this._maxSize);
324
329
  }
325
330
  }
326
331
  }
@@ -383,7 +388,9 @@ class VelocityBehaviour extends ParticleSystemBaseBehaviour {
383
388
  private _gravityDirection = new Vector3();
384
389
 
385
390
  initialize(particle: Particle): void {
386
- const factor = 1 + this.scaleFactorDiff;
391
+ const simulationSpeed = this.system.main.simulationSpeed;
392
+
393
+ const factor = 1 + this.scaleFactorDiff * simulationSpeed;
387
394
  particle.startSpeed = this.system.main.startSpeed.evaluate(Math.random(), Math.random()) * factor;
388
395
  particle.velocity.copy(this.system.shape.getDirection(particle.position)).multiplyScalar(particle.startSpeed);
389
396
  if (this.system.inheritVelocity?.enabled) {
@@ -393,7 +400,7 @@ class VelocityBehaviour extends ParticleSystemBaseBehaviour {
393
400
  else particle[$startVelocity].copy(particle.velocity);
394
401
 
395
402
  const gravityFactor = this.system.main.gravityModifier.evaluate(Math.random(), Math.random()) / (9.81 * 2);
396
- particle[$gravityFactor] = gravityFactor;
403
+ particle[$gravityFactor] = gravityFactor * simulationSpeed;
397
404
 
398
405
  particle[$velocityLerpFactor] = Math.random();
399
406
 
@@ -411,18 +418,18 @@ class VelocityBehaviour extends ParticleSystemBaseBehaviour {
411
418
  if (gravityFactor !== 0) {
412
419
  // gravityFactor *= -1;
413
420
  temp3.copy(this._gravityDirection).multiplyScalar(gravityFactor);
414
- // Gizmos.DrawDirection(particle.position, temp3, 0xff0000, 0, false, 10);
421
+ if(debug) Gizmos.DrawDirection(particle.position, temp3, 0x0000ff, 0, false, 10);
415
422
  baseVelocity.add(temp3);
416
423
  }
417
424
  particle.velocity.copy(baseVelocity);
418
425
 
426
+
419
427
  const t01 = particle.age / particle.life;
420
428
 
421
429
  if (this.system.inheritVelocity?.enabled) {
422
430
  this.system.inheritVelocity.applyCurrent(particle.velocity, t01, particle[$velocityLerpFactor]);
423
431
  }
424
432
 
425
-
426
433
  const noise = this.system.noise;
427
434
  if (noise.enabled) {
428
435
  noise.apply(0, particle.position, particle.velocity, delta, particle.age, particle.life);
@@ -772,22 +779,25 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
772
779
  }
773
780
  private _subEmitterSystems?: SubEmitterSystem[];
774
781
 
775
- awake(): void {
776
-
782
+ onAfterDeserialize(_){
777
783
  if (this._subEmitterSystems && Array.isArray(this._subEmitterSystems)) {
778
784
  for (const sub of this._subEmitterSystems) {
779
- sub._deserialize(this.context);
785
+ sub._deserialize(this.context, this.gameObject);
780
786
  }
781
787
  }
788
+ }
789
+
790
+ awake(): void {
782
791
 
783
792
  this._renderer = this.gameObject.getComponent(ParticleSystemRenderer) as ParticleSystemRenderer;
784
793
 
785
794
  this._container = new Object3D();
786
795
  this._container.matrixAutoUpdate = false;
787
- if (this.main.simulationSpace == ParticleSystemSimulationSpace.Local) {
788
- this.gameObject.add(this._container);
789
- }
790
- else {
796
+ // if (this.main.simulationSpace == ParticleSystemSimulationSpace.Local) {
797
+ // this.gameObject.add(this._container);
798
+ // }
799
+ // else
800
+ {
791
801
  this.context.scene.add(this._container);
792
802
  }
793
803
  // else this._container = this.context.scene;
@@ -875,21 +885,27 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
875
885
  this._cameraScale = scale.x;
876
886
  }
877
887
 
878
- let source = this._container;
879
- if (this.worldspace)
880
- source = this.gameObject;
888
+ const isLocalSpace = !this.worldspace;
889
+
890
+ const source = this.gameObject;
881
891
  getWorldQuaternion(source, this.__worldQuaternion)
882
892
  this._worldQuaternionInverted.copy(this.__worldQuaternion).invert();
883
893
  getWorldScale(this.gameObject, this._worldScale);
884
894
 
885
- if (!this.worldspace && this._container && this.gameObject?.parent) {
895
+ // Handle LOCALSPACE
896
+ if (isLocalSpace && this._container && this.gameObject?.parent) {
897
+ // TODO: there's probably a more efficient way to do this
886
898
  const scale = getWorldScale(this.gameObject.parent);
887
899
  scale.x = 1 / scale.x;
888
900
  scale.y = 1 / scale.y;
889
901
  scale.z = 1 / scale.z;
890
- this._container.matrix.identity();
891
- this._container.matrix.scale(scale);
902
+ this._container.matrix.makeScale(scale.x, scale.y, scale.z);
903
+ this._container.matrix.makeRotationFromQuaternion(this.__worldQuaternion);
904
+ this._container.matrix.setPosition(this.worldPos);
905
+ this._container.matrix.scale(this.gameObject.scale);
892
906
  }
907
+
908
+
893
909
  this.emission.system = this;
894
910
  this._interface.update();
895
911
  this.shape.update(this, this.context, this.main.simulationSpace, this.gameObject);
@@ -918,3 +934,18 @@ export class ParticleSystem extends Behaviour implements IParticleSystem {
918
934
  }
919
935
 
920
936
 
937
+
938
+ export class SubEmitterSystem {
939
+
940
+ particleSystem?: ParticleSystem;
941
+ emitProbability: number = 1;
942
+ properties?: number;
943
+ type?: SubEmitterType;
944
+
945
+ _deserialize(context: Context, _gameObject: GameObject) {
946
+ const ps = this.particleSystem;
947
+ if (ps && !(ps instanceof ParticleSystem) && typeof ps["guid"] === "string") {
948
+ this.particleSystem = GameObject.findByGuid(ps["guid"], context.scene) as ParticleSystem;
949
+ }
950
+ }
951
+ }
@@ -522,10 +522,10 @@ export class ShapeModule implements EmitterShape {
522
522
  private readonly _worldSpaceMatrix: Matrix4 = new Matrix4();
523
523
  private readonly _worldSpaceMatrixInverse: Matrix4 = new Matrix4();
524
524
 
525
-
526
- // constructor() {
527
- // console.log(this);
528
- // }
525
+ constructor() {
526
+ if (debug)
527
+ console.log(this);
528
+ }
529
529
 
530
530
  update(system: IParticleSystem, _context: Context, simulationSpace: ParticleSystemSimulationSpace, obj: Object3D) {
531
531
  this.system = system;
@@ -571,6 +571,7 @@ export class ShapeModule implements EmitterShape {
571
571
  if (this.enabled) {
572
572
  switch (this.shapeType) {
573
573
  case ParticleSystemShapeType.Box:
574
+ if(debug) Gizmos.DrawBox(this.position, this.scale, 0xdddddd, 1);
574
575
  this._vector.x = Math.random() * this.scale.x - this.scale.x / 2;
575
576
  this._vector.y = Math.random() * this.scale.y - this.scale.y / 2;
576
577
  this._vector.z = Math.random() * this.scale.z - this.scale.z / 2;
@@ -605,6 +606,10 @@ export class ShapeModule implements EmitterShape {
605
606
  this._vector.applyQuaternion(this.system.worldQuaternion);
606
607
  this._vector.add(this.system.worldPos);
607
608
  }
609
+
610
+ if (debug) {
611
+ Gizmos.DrawSphere(this._vector, .03, 0xff0000, .5, true);
612
+ }
608
613
  }
609
614
 
610
615
 
@@ -631,14 +636,15 @@ export class ShapeModule implements EmitterShape {
631
636
  const ry = pos.y;
632
637
  const rz = pos.z;
633
638
  this._dir.set(rx, ry, rz)
634
- this._dir.sub(this.position)
639
+ if (this.system?.worldspace)
640
+ this._dir.sub(this.system.worldPos)
635
641
  break;
636
642
  default:
637
643
  this._dir.set(0, 0, 1);
638
644
  break;
639
645
  }
640
646
  if (this._space === ParticleSystemSimulationSpace.World) {
641
- this._dir.applyMatrix4(this._worldSpaceMatrixInverse);
647
+ this._dir.applyQuaternion(this.system.worldQuaternion);
642
648
  }
643
649
  if (this.updateRotation())
644
650
  this._dir.applyEuler(this._rotation);