@needle-tools/engine 4.4.0-beta.5 → 4.4.0-beta.6

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 (30) hide show
  1. package/CHANGELOG.md +2 -1
  2. package/dist/needle-engine.bundle.js +2568 -2554
  3. package/dist/needle-engine.bundle.light.js +2539 -2525
  4. package/dist/needle-engine.bundle.light.min.js +95 -95
  5. package/dist/needle-engine.bundle.light.umd.cjs +95 -95
  6. package/dist/needle-engine.bundle.min.js +95 -95
  7. package/dist/needle-engine.bundle.umd.cjs +98 -98
  8. package/lib/engine/engine_components.js +1 -1
  9. package/lib/engine/engine_components.js.map +1 -1
  10. package/lib/engine/engine_context.d.ts +10 -1
  11. package/lib/engine/engine_context.js +33 -12
  12. package/lib/engine/engine_context.js.map +1 -1
  13. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +6 -6
  14. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
  15. package/lib/engine/xr/NeedleXRController.js +2 -3
  16. package/lib/engine/xr/NeedleXRController.js.map +1 -1
  17. package/lib/engine/xr/NeedleXRSession.js +12 -12
  18. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  19. package/lib/engine-components/CameraUtils.js +7 -4
  20. package/lib/engine-components/CameraUtils.js.map +1 -1
  21. package/package.json +1 -1
  22. package/plugins/common/license.js +2 -2
  23. package/plugins/types/userconfig.d.ts +3 -0
  24. package/plugins/vite/build-pipeline.js +1 -1
  25. package/src/engine/engine_components.ts +1 -1
  26. package/src/engine/engine_context.ts +36 -12
  27. package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +6 -6
  28. package/src/engine/xr/NeedleXRController.ts +2 -3
  29. package/src/engine/xr/NeedleXRSession.ts +12 -12
  30. package/src/engine-components/CameraUtils.ts +7 -4
@@ -408,7 +408,7 @@ export class Context implements IContext {
408
408
 
409
409
  get isCreated() { return this._isCreated; }
410
410
 
411
- private _sizeChanged: boolean = false;
411
+ private _needsUpdateSize: boolean = false;
412
412
  private _isCreated: boolean = false;
413
413
  private _isCreating: boolean = false;
414
414
  private _isVisible: boolean = false;
@@ -446,11 +446,11 @@ export class Context implements IContext {
446
446
  this.animations = new AnimationsRegistry(this);
447
447
 
448
448
 
449
- const resizeCallback = () => this._sizeChanged = true;
449
+ const resizeCallback = () => this._needsUpdateSize = true;
450
450
  window.addEventListener('resize', resizeCallback);
451
451
  this._disposeCallbacks.push(() => window.removeEventListener('resize', resizeCallback));
452
452
 
453
- const resizeObserver = new ResizeObserver(_ => this._sizeChanged = true);
453
+ const resizeObserver = new ResizeObserver(_ => this._needsUpdateSize = true);
454
454
  resizeObserver.observe(this.domElement);
455
455
  this._disposeCallbacks.push(() => resizeObserver.disconnect());
456
456
 
@@ -519,15 +519,30 @@ export class Context implements IContext {
519
519
 
520
520
 
521
521
  /** will request a renderer size update the next render call (will call updateSize the next update) */
522
- requestSizeUpdate() { this._sizeChanged = true; }
522
+ requestSizeUpdate() { this._needsUpdateSize = true; }
523
523
 
524
524
  /** Clamps the renderer max resolution. If undefined the max resolution is not clamped. Default is undefined */
525
525
  maxRenderResolution?: Vec2;
526
526
 
527
+ /** Control the renderer devicePixelRatio.
528
+ * **Options**
529
+ * - `auto` - Needle Engine automatically sets the pixel ratio to the current window.devicePixelRatio.
530
+ * - `manual` - Needle Engine will not change the renderer pixel ratio. You can set it manually.
531
+ * - `number` - Needle Engine will set the pixel ratio to the given number. The change will be applied to the renderer and the composer (if used) at the end of the current frame.
532
+ */
533
+ get devicePixelRatio() { return this._devicePixelRatio; }
534
+ set devicePixelRatio(val: "auto" | "manual" | number) {
535
+ if (val !== this._devicePixelRatio) {
536
+ this._devicePixelRatio = val;
537
+ this._needsUpdateSize = true;
538
+ }
539
+ }
540
+ private _devicePixelRatio: "auto" | "manual" | number = "auto";
541
+
527
542
  /** update the renderer and canvas size */
528
543
  updateSize(force: boolean = false) {
529
544
  if (force || (!this.isManagedExternally && this.renderer.xr?.isPresenting === false)) {
530
- this._sizeChanged = false;
545
+ this._needsUpdateSize = false;
531
546
  const scaleFactor = this.resolutionScaleFactor;
532
547
  let width = this.domWidth * scaleFactor;
533
548
  let height = this.domHeight * scaleFactor;
@@ -540,15 +555,24 @@ export class Context implements IContext {
540
555
  const camera = this.mainCamera as PerspectiveCamera;
541
556
  this.updateAspect(camera);
542
557
  this.renderer.setSize(width, height, true);
543
- this.renderer.setPixelRatio(window.devicePixelRatio);
544
558
  // avoid setting pixel values here since this can cause pingpong updates
545
559
  // e.g. when system scale is set to 125%
546
560
  // https://github.com/needle-tools/needle-engine-support/issues/69
547
561
  this.renderer.domElement.style.width = "100%";
548
562
  this.renderer.domElement.style.height = "100%";
563
+
564
+ const devicePixelRatio = typeof this.devicePixelRatio === "number"
565
+ ? this.devicePixelRatio
566
+ : this.devicePixelRatio === "auto"
567
+ ? window.devicePixelRatio
568
+ : undefined;
569
+ if (devicePixelRatio !== undefined) {
570
+ this.renderer.setPixelRatio(devicePixelRatio);
571
+ }
572
+
549
573
  if (this.composer) {
550
574
  this.composer.setSize?.call(this.composer, width, height);
551
- if ("setPixelRatio" in this.composer && typeof this.composer.setPixelRatio === "function")
575
+ if (devicePixelRatio !== undefined && "setPixelRatio" in this.composer && typeof this.composer.setPixelRatio === "function")
552
576
  this.composer.setPixelRatio?.call(this.composer, window.devicePixelRatio);
553
577
  }
554
578
  }
@@ -1016,7 +1040,7 @@ export class Context implements IContext {
1016
1040
  // this.composer.setSize(this.domWidth, this.domHeight);
1017
1041
  }
1018
1042
 
1019
- this._sizeChanged = true;
1043
+ this._needsUpdateSize = true;
1020
1044
 
1021
1045
  if (this._stats) {
1022
1046
  this._stats.showPanel(0);
@@ -1186,11 +1210,11 @@ export class Context implements IContext {
1186
1210
  if (frame === undefined) frame = null;
1187
1211
  if (isDevEnvironment() || debug || looputils.hasNewScripts()) {
1188
1212
  try {
1189
- performance.mark('update.start');
1213
+ //performance.mark('update.start');
1190
1214
  this.internalStep(timestamp, frame);
1191
1215
  this._renderlooperrors = 0;
1192
- performance.mark('update.end');
1193
- performance.measure('NE Frame', 'update.start', 'update.end');
1216
+ //performance.mark('update.end');
1217
+ //performance.measure('NE Frame', 'update.start', 'update.end');
1194
1218
  }
1195
1219
  catch (err) {
1196
1220
  this._renderlooperrors += 1;
@@ -1361,7 +1385,7 @@ export class Context implements IContext {
1361
1385
  this.executeCoroutines(FrameEvent.OnBeforeRender);
1362
1386
  invokeLifecycleFunctions(this, FrameEvent.OnBeforeRender);
1363
1387
 
1364
- if (this._sizeChanged)
1388
+ if (this._needsUpdateSize)
1365
1389
  this.updateSize();
1366
1390
 
1367
1391
  if (this.pre_render_callbacks) {
@@ -155,7 +155,7 @@ export class NeedleSpatialMenu {
155
155
  private readonly positionFilter = new OneEuroFilterXYZ(90, .5);
156
156
 
157
157
  private updateMenu() {
158
- performance.mark('NeedleSpatialMenu updateMenu start');
158
+ //performance.mark('NeedleSpatialMenu updateMenu start');
159
159
  const menu = this.getMenu();
160
160
  this.handleNeedleWatermark();
161
161
  this._context.scene.add(menu as any);
@@ -200,14 +200,14 @@ export class NeedleSpatialMenu {
200
200
  }
201
201
 
202
202
  if (this.uiisDirty) {
203
- performance.mark('SpatialMenu.update.uiisDirty.start');
203
+ //performance.mark('SpatialMenu.update.uiisDirty.start');
204
204
  this.uiisDirty = false;
205
205
  ThreeMeshUI.update();
206
- performance.mark('SpatialMenu.update.uiisDirty.end');
207
- performance.measure('SpatialMenu.update.uiisDirty', 'SpatialMenu.update.uiisDirty.start', 'SpatialMenu.update.uiisDirty.end');
206
+ //performance.mark('SpatialMenu.update.uiisDirty.end');
207
+ //performance.measure('SpatialMenu.update.uiisDirty', 'SpatialMenu.update.uiisDirty.start', 'SpatialMenu.update.uiisDirty.end');
208
208
  }
209
- performance.mark('NeedleSpatialMenu updateMenu end');
210
- performance.measure('SpatialMenu.update', 'NeedleSpatialMenu updateMenu start', 'NeedleSpatialMenu updateMenu end');
209
+ //performance.mark('NeedleSpatialMenu updateMenu end');
210
+ //performance.measure('SpatialMenu.update', 'NeedleSpatialMenu updateMenu start', 'NeedleSpatialMenu updateMenu end');
211
211
  }
212
212
 
213
213
  private ensureRenderOnTop(obj: Object3D, level: number = 0) {
@@ -381,12 +381,11 @@ export class NeedleXRController implements IPointerHitEventReceiver {
381
381
  }
382
382
 
383
383
  onUpdate(frame: XRFrame) {
384
- performance.mark('NeedleXRController onUpdate start');
385
384
  this.onUpdateFrame(frame);
386
385
  this.updateInputEvents();
387
386
  this.onUpdateMove();
388
- performance.mark('NeedleXRController onUpdate end');
389
- performance.measure('NeedleXRController onUpdate', 'NeedleXRController onUpdate start', 'NeedleXRController onUpdate end');
387
+ //performance.mark('NeedleXRController onUpdate end');
388
+ //performance.measure('NeedleXRController onUpdate', 'NeedleXRController onUpdate start', 'NeedleXRController onUpdate end');
390
389
  }
391
390
 
392
391
  onRenderDebug() {
@@ -444,7 +444,7 @@ export class NeedleXRSession implements INeedleXRSession {
444
444
  if (!context) context = ContextRegistry.All[0] as Context;
445
445
  if (!context) throw new Error("No Needle Engine Context found");
446
446
 
447
- performance.mark('NeedleXRSession start');
447
+ //performance.mark('NeedleXRSession start');
448
448
 
449
449
  // setup session init args, make sure we have default values
450
450
  if (!init) init = {};
@@ -534,8 +534,8 @@ export class NeedleXRSession implements INeedleXRSession {
534
534
  return null;
535
535
  }
536
536
  const session = this.setSession(mode, newSession, init, context);
537
- performance.mark('NeedleXRSession end');
538
- performance.measure('NeedleXRSession Startup', 'NeedleXRSession start', 'NeedleXRSession end');
537
+ //performance.mark('NeedleXRSession end');
538
+ //performance.measure('NeedleXRSession Startup', 'NeedleXRSession start', 'NeedleXRSession end');
539
539
  return session;
540
540
  }
541
541
 
@@ -884,7 +884,7 @@ export class NeedleXRSession implements INeedleXRSession {
884
884
  /** the initialization arguments */
885
885
  init: XRSessionInit,
886
886
  }) {
887
- performance.mark(measure_SessionStartedMarker);
887
+ //performance.mark(measure_SessionStartedMarker);
888
888
 
889
889
  saveSessionInfo(mode, extra.init);
890
890
  this.session = session;
@@ -1128,8 +1128,8 @@ export class NeedleXRSession implements INeedleXRSession {
1128
1128
 
1129
1129
  enableSpatialConsole(false);
1130
1130
 
1131
- performance.mark(measure_SessionEndedMarker);
1132
- performance.measure('NeedleXRSession', measure_SessionStartedMarker, measure_SessionEndedMarker);
1131
+ //performance.mark(measure_SessionEndedMarker);
1132
+ //performance.measure('NeedleXRSession', measure_SessionStartedMarker, measure_SessionEndedMarker);
1133
1133
  };
1134
1134
 
1135
1135
  private _didStart: boolean = false;
@@ -1139,7 +1139,7 @@ export class NeedleXRSession implements INeedleXRSession {
1139
1139
  const frame = context.xrFrame;
1140
1140
  if (!frame) return;
1141
1141
 
1142
- performance.mark('NeedleXRSession onBefore start');
1142
+ //performance.mark('NeedleXRSession onBefore start');
1143
1143
 
1144
1144
  // ensure that XR is always set to a running session
1145
1145
  this.context.xr = this;
@@ -1291,7 +1291,7 @@ export class NeedleXRSession implements INeedleXRSession {
1291
1291
  console.error("XRControllers are not added but inputSources are present");
1292
1292
  }
1293
1293
 
1294
- performance.mark('NeedleXRSession update scripts start');
1294
+ //performance.mark('NeedleXRSession update scripts start');
1295
1295
  // invoke update on all scripts
1296
1296
  for (const script of this._xr_update_scripts) {
1297
1297
  if (script.destroyed === true) {
@@ -1304,8 +1304,8 @@ export class NeedleXRSession implements INeedleXRSession {
1304
1304
  }
1305
1305
  if (script.onUpdateXR) script.onUpdateXR(args);
1306
1306
  }
1307
- performance.mark('NeedleXRSession update scripts end');
1308
- performance.measure('NeedleXRSession update scripts', 'NeedleXRSession update scripts start', 'NeedleXRSession update scripts end');
1307
+ //performance.mark('NeedleXRSession update scripts end');
1308
+ //performance.measure('NeedleXRSession update scripts', 'NeedleXRSession update scripts start', 'NeedleXRSession update scripts end');
1309
1309
 
1310
1310
  // handle inactive scripts
1311
1311
  this.handleInactiveScripts();
@@ -1326,8 +1326,8 @@ export class NeedleXRSession implements INeedleXRSession {
1326
1326
  this.sync?.onUpdate(this);
1327
1327
 
1328
1328
  this.onRenderDebug();
1329
- performance.mark('NeedleXRSession onBefore end');
1330
- performance.measure('NE XR frame', 'NeedleXRSession onBefore start', 'NeedleXRSession onBefore end');
1329
+ //performance.mark('NeedleXRSession onBefore end');
1330
+ //performance.measure('NE XR frame', 'NeedleXRSession onBefore start', 'NeedleXRSession onBefore end');
1331
1331
  }
1332
1332
 
1333
1333
  private onRenderDebug() {
@@ -46,11 +46,14 @@ ContextRegistry.registerCallback(ContextEvent.MissingCamera, (evt) => {
46
46
  else {
47
47
  camInstance.clearFlags = ClearFlags.SolidColor;
48
48
 
49
- let backgroundColor = "#efefef";
50
- if (typeof window !== undefined && (window.matchMedia('(prefers-color-scheme: dark)').matches)) {
51
- backgroundColor = "#1f1f1f";
49
+ // Don't set the background color if the user set a background color in the <needle-engine> element
50
+ if (!evt.context.domElement.getAttribute("background-color")) {
51
+ let backgroundColor = "#efefef";
52
+ if (typeof window !== undefined && (window.matchMedia('(prefers-color-scheme: dark)').matches)) {
53
+ backgroundColor = "#1f1f1f";
54
+ }
55
+ scene.background = new Color(backgroundColor); // dont set it on the camera because this might be controlled from "background-color" attribute which is set on the scene directly. If the camera has a background color, it will override the scene's background color
52
56
  }
53
- scene.background = new Color(backgroundColor); // dont set it on the camera because this might be controlled from "background-color" attribute which is set on the scene directly. If the camera has a background color, it will override the scene's background color
54
57
 
55
58
  // Generate a default environment map if none is set
56
59
  if (!scene.environment) {