@needle-tools/engine 2.26.1-pre → 2.28.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 (37) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/needle-engine.d.ts +5 -1
  3. package/dist/needle-engine.js +4 -4
  4. package/dist/needle-engine.js.map +3 -3
  5. package/dist/needle-engine.min.js +4 -4
  6. package/dist/needle-engine.min.js.map +3 -3
  7. package/lib/engine/engine_networking_utils.js +1 -2
  8. package/lib/engine/engine_networking_utils.js.map +1 -1
  9. package/lib/engine/engine_serialization_builtin_serializer.js +15 -4
  10. package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
  11. package/lib/engine/engine_setup.d.ts +5 -1
  12. package/lib/engine/engine_setup.js +21 -3
  13. package/lib/engine/engine_setup.js.map +1 -1
  14. package/lib/engine/extensions/NEEDLE_techniques_webgl.js +2 -2
  15. package/lib/engine/extensions/NEEDLE_techniques_webgl.js.map +1 -1
  16. package/lib/engine/extensions/extension_utils.js +6 -6
  17. package/lib/engine/extensions/extension_utils.js.map +1 -1
  18. package/lib/engine-components/AvatarLoader.js +1 -1
  19. package/lib/engine-components/AvatarLoader.js.map +1 -1
  20. package/lib/engine-components/ui/BaseUIComponent.js +8 -5
  21. package/lib/engine-components/ui/BaseUIComponent.js.map +1 -1
  22. package/lib/engine-components/ui/Image.js +4 -0
  23. package/lib/engine-components/ui/Image.js.map +1 -1
  24. package/lib/engine-components/ui/InputField.js +2 -2
  25. package/lib/engine-components/ui/RectTransform.js +1 -1
  26. package/lib/engine-components/ui/RectTransform.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/engine/engine_networking_utils.ts +1 -2
  29. package/src/engine/engine_serialization_builtin_serializer.ts +15 -3
  30. package/src/engine/engine_setup.ts +19 -3
  31. package/src/engine/extensions/NEEDLE_techniques_webgl.ts +2 -2
  32. package/src/engine/extensions/extension_utils.ts +6 -6
  33. package/src/engine-components/AvatarLoader.ts +1 -1
  34. package/src/engine-components/ui/BaseUIComponent.ts +12 -5
  35. package/src/engine-components/ui/Image.ts +4 -0
  36. package/src/engine-components/ui/InputField.ts +2 -2
  37. package/src/engine-components/ui/RectTransform.ts +1 -1
@@ -146,11 +146,23 @@ class ComponentSerializer extends TypeSerializer {
146
146
  }
147
147
 
148
148
  findObjectForGuid(guid: string, root: THREE.Object3D): any {
149
- return GameObject.foreachComponent(root, (c) => {
150
- if (guid === c.gameObject.guid) return c.gameObject;
149
+ // recursively search root
150
+ // need to check the root object too
151
+ if (root["guid"] === guid) return root;
152
+
153
+ const res = GameObject.foreachComponent(root, (c) => {
151
154
  if (c.guid === guid) return c;
152
155
  return undefined;
153
- });
156
+ }, false);
157
+ if (res !== undefined)
158
+ return res;
159
+
160
+ // if not found, search in children
161
+ for (let i = 0; i < root.children.length; i++) {
162
+ const child = root.children[i];
163
+ const res = this.findObjectForGuid(guid, child);
164
+ if (res) return res;
165
+ }
154
166
  }
155
167
  }
156
168
  export const componentSerializer = new ComponentSerializer();
@@ -90,13 +90,26 @@ export class Context {
90
90
  isManagedExternally: boolean = false;
91
91
 
92
92
  domElement: HTMLElement;
93
+ get resolutionScaleFactor() { return this._resolutionScaleFactor; }
94
+ /** use to scale the resolution up or down of the renderer. default is 1 */
95
+ set resolutionScaleFactor(val: number) {
96
+ if(val === this._resolutionScaleFactor) return;
97
+ if(typeof val !== "number") return;
98
+ if(val <= 0) {
99
+ console.error("Invalid resolution scale factor", val);
100
+ return;
101
+ }
102
+ this._resolutionScaleFactor = val;
103
+ this.updateSize();
104
+ }
105
+ private _resolutionScaleFactor: number = 1;
93
106
  get domWidth(): number { return this.domElement.clientWidth; }
94
107
  get domHeight(): number { return this.domElement.clientHeight; }
95
108
  get domX(): number { return this.domElement.offsetLeft; }
96
109
  get domY(): number { return this.domElement.offsetTop; }
97
110
  get isInXR() { return this.renderer.xr?.isPresenting || false; }
98
111
  get xrSession() { return this.renderer.xr?.getSession(); }
99
- get AROverlayElement(): HTMLElement {
112
+ get arOverlayElement(): HTMLElement {
100
113
  const el = this.domElement as any;
101
114
  if (typeof el.getAROverlayContainer === "function")
102
115
  return el.getAROverlayContainer();
@@ -208,12 +221,15 @@ export class Context {
208
221
  private updateSize() {
209
222
  if (!this.isManagedExternally && !this.renderer.xr.isPresenting) {
210
223
  this._sizeChanged = false;
211
- const width = this.domWidth;
212
- const height = this.domHeight;
224
+ const scaleFactor = this.resolutionScaleFactor;
225
+ const width = this.domWidth * scaleFactor;
226
+ const height = this.domHeight * scaleFactor;
213
227
  const camera = this.mainCamera as PerspectiveCamera;
214
228
  this.updateAspect(camera);
215
229
  this.renderer.setSize(width, height);
216
230
  this.renderer.setPixelRatio(window.devicePixelRatio);
231
+ this.renderer.domElement.style.width = this.domWidth + "px";
232
+ this.renderer.domElement.style.height = this.domHeight + "px";
217
233
  if (this.composer) {
218
234
  this.composer.setSize(width, height);
219
235
  this.composer.setPixelRatio(window.devicePixelRatio);
@@ -392,8 +392,8 @@ export class NEEDLE_techniques_webgl implements GLTFLoaderPlugin {
392
392
  for (const key in materialExtension.values) {
393
393
  const val = materialExtension.values[key];
394
394
  if (typeof val === "string") {
395
- if (val.startsWith("textures/")) {
396
- const indexString = val.substring(9);
395
+ if (val.startsWith("/textures/")) {
396
+ const indexString = val.substring("/textures/".length);
397
397
  const texIndex = Number.parseInt(indexString);
398
398
  if (texIndex >= 0) {
399
399
  const tex = await this.parser.getDependency("texture", texIndex);
@@ -10,12 +10,13 @@ declare type DependencyInfo = {
10
10
  dependencyName: string,
11
11
  }
12
12
 
13
+ const rootExtensionPrefix = "/extensions/";
13
14
  const defaultDependencies = [
14
- { prefix: "nodes/", dependencyName: "node" },
15
- { prefix: "meshes/", dependencyName: "mesh" },
16
- { prefix: "materials/", dependencyName: "material" },
17
- { prefix: "textures/", dependencyName: "texture" },
18
- { prefix: "animations/", dependencyName: "animation" }
15
+ { prefix: "/nodes/", dependencyName: "node" },
16
+ { prefix: "/meshes/", dependencyName: "mesh" },
17
+ { prefix: "/materials/", dependencyName: "material" },
18
+ { prefix: "/textures/", dependencyName: "texture" },
19
+ { prefix: "/animations/", dependencyName: "animation" }
19
20
  ]
20
21
 
21
22
  export async function resolveReferences(parser: GLTFParser, obj) {
@@ -93,7 +94,6 @@ function internalResolve(paths: DependencyInfo[], parser: GLTFParser, obj, promi
93
94
  }
94
95
 
95
96
 
96
- const rootExtensionPrefix = "extensions/";
97
97
  function resolveExtension(parser: GLTFParser, str): Promise<void> | null {
98
98
  if (parser && parser.plugins && typeof str === "string" && str.startsWith(rootExtensionPrefix)) {
99
99
  let name = str.substring(rootExtensionPrefix.length);
@@ -35,7 +35,7 @@ export class AvatarModel {
35
35
 
36
36
  export class AvatarLoader {
37
37
 
38
- private readonly avatarRegistryUrl: string | null = null;// = "https://needle-storage-castle-demo.glitch.me";//"https://smol-worlds.glitch.me/files/";
38
+ private readonly avatarRegistryUrl: string | null = null;
39
39
  // private loader: GLTFLoader | null;
40
40
  // private avatarModelCache: Map<string, AvatarModel | null> = new Map<string, AvatarModel | null>();
41
41
 
@@ -67,19 +67,26 @@ export class BaseUIComponent extends Behaviour {
67
67
  return;
68
68
  }
69
69
 
70
- // console.trace(container);
71
70
  container.name = this.name + " (" + (this.constructor.name ?? "UI") + ")";
72
71
  container.autoLayout = this._parentComponent.controlsChildLayout;
73
72
  container.shadowComponentOwner = this;
74
- const raycastTarget = (this as unknown as IGraphic).raycastTarget;
73
+
74
+ // TODO: raycastTarget doesnt work anymore -> i think we need to set the gameObject layer and then check in the raycaster if the shadowComponentOwner is on the correct layer?!
75
+ // const raycastTarget = (this as unknown as IGraphic).raycastTarget;
76
+ // this.gameObject.layers.set(2)
77
+
78
+
75
79
  // TODO: only traverse our own hierarchy, we can stop if we find another owner
76
80
  container.traverse(c => {
77
- if (c.shadowComponentOwner === undefined)
81
+ if (c.shadowComponentOwner === undefined) {
78
82
  c.shadowComponentOwner = this;
79
- if (raycastTarget === false) {
80
- c.layers.set(2);
81
83
  }
84
+ // // this makes text not render anymore when enabled again
85
+ // if (raycastTarget === false) {
86
+ // c.layers.set(2);
87
+ // }
82
88
  })
89
+
83
90
  if (this.Root?.gameObject === this.gameObject) {
84
91
  this.gameObject.add(container);
85
92
  }
@@ -22,6 +22,10 @@ export class Image extends MaskableGraphic {
22
22
  case "Background":
23
23
  return true;
24
24
  }
25
+ // this is a hack/workaround for production builds where the name of the sprite is missing
26
+ // need to remove this!!!!
27
+ if(this.sprite?.texture?.image?.width === 32 && this.sprite?.texture?.image?.height === 32)
28
+ return true;
25
29
  return false;
26
30
  }
27
31
 
@@ -91,7 +91,7 @@ export class InputField extends Behaviour implements IPointerEventHandler {
91
91
 
92
92
  private onSelected() {
93
93
  if (InputField.active === this) return;
94
- if (debug) console.log("Select", this.name, this, InputField.htmlField, this.context.isInXR, this.context.AROverlayElement, this.textComponent?.text, InputField.htmlField?.value);
94
+ if (debug) console.log("Select", this.name, this, InputField.htmlField, this.context.isInXR, this.context.arOverlayElement, this.textComponent?.text, InputField.htmlField?.value);
95
95
 
96
96
  InputField.active?.onDeselected();
97
97
  InputField.active = this;
@@ -106,7 +106,7 @@ export class InputField extends Behaviour implements IPointerEventHandler {
106
106
  console.log("set input field value", InputField.htmlField.value);
107
107
 
108
108
  if (this.context.isInXR) {
109
- const overlay = this.context.AROverlayElement;
109
+ const overlay = this.context.arOverlayElement;
110
110
  if (overlay) {
111
111
  InputField.htmlField.style.width = "0px";
112
112
  InputField.htmlField.style.height = "0px";
@@ -66,7 +66,7 @@ export class RectTransform extends BaseUIComponent {
66
66
  onEnable() {
67
67
  super.onEnable();
68
68
  this.addShadowComponent(this.rectBlock);
69
- this.applyTransform();
69
+ this._transformNeedsUpdate = true;
70
70
  }
71
71
 
72
72
  onDisable() {