Needle Engine

Changes between version 3.6.12 and 3.6.13
Files changed (4) hide show
  1. src/engine/codegen/register_types.js +2 -2
  2. src/engine/engine_context.ts +24 -3
  3. src/engine/engine_util_decorator.ts +11 -2
  4. src/engine-components/export/usdz/USDZExporter.ts +14 -5
src/engine/codegen/register_types.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { TypeStore } from "./../engine_typestore"
2
-
2
+
3
3
  // Import types
4
4
  import { __Ignore } from "../../engine-components/codegen/components";
5
5
  import { ActionBuilder } from "../../engine-components/export/usdz/extensions/behavior/BehavioursBuilder";
@@ -216,7 +216,7 @@
216
216
  import { XRGrabRendering } from "../../engine-components/webxr/WebXRGrabRendering";
217
217
  import { XRRig } from "../../engine-components/webxr/WebXRRig";
218
218
  import { XRState } from "../../engine-components/XRFlag";
219
-
219
+
220
220
  // Register types
221
221
  TypeStore.add("__Ignore", __Ignore);
222
222
  TypeStore.add("ActionBuilder", ActionBuilder);
src/engine/engine_context.ts CHANGED
@@ -33,7 +33,7 @@
33
33
  import { isDevEnvironment, LogType, showBalloonMessage } from './debug';
34
34
 
35
35
 
36
- const debug = utils.getParam("debugSetup");
36
+ const debug = utils.getParam("debugcontext");
37
37
  const stats = utils.getParam("stats");
38
38
  const debugActive = utils.getParam("debugactive");
39
39
  const debugframerate = utils.getParam("debugframerate");
@@ -94,6 +94,16 @@
94
94
 
95
95
  export class Context implements IContext {
96
96
 
97
+ private static _defaultTargetFramerate: { value?: number } = { value: 60 }
98
+ /** When a new context is created this is the framerate that will be used by default */
99
+ static get DefaultTargetFrameRate(): number | undefined {
100
+ return Context._defaultTargetFramerate.value;
101
+ }
102
+ /** When a new context is created this is the framerate that will be used by default */
103
+ static set DefaultTargetFrameRate(val: number | undefined) {
104
+ Context._defaultTargetFramerate.value = val;
105
+ }
106
+
97
107
  /** the needle engine version */
98
108
  get version() {
99
109
  return VERSION;
@@ -122,7 +132,7 @@
122
132
  * Set to the target framerate you want your application to run in (you can use ?stats to check the fps)
123
133
  * Set to undefined if you want to run at the maximum framerate
124
134
  */
125
- targetFrameRate?: number = 60;
135
+ targetFrameRate?: number | { value?: number };
126
136
 
127
137
  /** used to append to loaded assets */
128
138
  hash?: string;
@@ -713,6 +723,14 @@
713
723
  if (debug)
714
724
  logHierarchy(this.scene, true);
715
725
 
726
+ // If no target framerate was set we use the default
727
+ if (this.targetFrameRate === undefined) {
728
+ if (debug) console.warn("No target framerate set, using default", Context.DefaultTargetFrameRate);
729
+ // the _defaultTargetFramerate is intentionally an object so it can be changed at any time if not explictly set by the user
730
+ this.targetFrameRate = Context._defaultTargetFramerate;
731
+ }
732
+ else if(debug) console.log("Target framerate set to", this.targetFrameRate);
733
+
716
734
  this._isCreating = false;
717
735
  this.restartRenderLoop();
718
736
  this._dispatchReadyAfterFrame = true;
@@ -766,7 +784,10 @@
766
784
 
767
785
  if (this.isInXR === false && this.targetFrameRate !== undefined) {
768
786
  this._accumulatedTime += this._framerateClock.getDelta();
769
- if (this._accumulatedTime < (1 / (this.targetFrameRate + 1))) {
787
+ let targetFrameRate = this.targetFrameRate as any;
788
+ if (typeof targetFrameRate === "object") targetFrameRate = targetFrameRate.value;
789
+ // if(debug) console.log(targetFrameRate)
790
+ if (this._accumulatedTime < (1 / (targetFrameRate + 1))) {
770
791
  return;
771
792
  }
772
793
  this._accumulatedTime = 0;
src/engine/engine_util_decorator.ts CHANGED
@@ -86,9 +86,18 @@
86
86
  const originalValue = originalProp.value;
87
87
  const prefix = target[propertyKey];
88
88
  Object.defineProperty(targetType, propertyKey, {
89
- value: function(...args){
89
+ value: function (...args) {
90
90
  const res = prefix?.call(this, ...args);
91
- if(res === false) return;
91
+ // If the prefix method is async we need to check if the user returned false
92
+ // In which case we don't want to call the original method
93
+ if (res instanceof Promise) {
94
+ res.then((r) => {
95
+ if (r === false) return;
96
+ return originalValue.call(this, ...args);
97
+ });
98
+ return;
99
+ }
100
+ if (res === false) return;
92
101
  return originalValue.call(this, ...args);
93
102
  },
94
103
  });
src/engine-components/export/usdz/USDZExporter.ts CHANGED
@@ -62,6 +62,9 @@
62
62
 
63
63
  extensions: IUSDExporterExtension[] = [];
64
64
 
65
+ @serializable()
66
+ allowCreateQuicklookButton: boolean = true;
67
+
65
68
  private link!: HTMLAnchorElement;
66
69
  private webxr?: WebXR;
67
70
  private webARSessionRoot: WebARSessionRoot | undefined;
@@ -83,10 +86,6 @@
83
86
  }, 2000)
84
87
  }
85
88
  }
86
- document.getElementById("open-in-ar")?.addEventListener("click", (evt) => {
87
- evt.preventDefault();
88
- this.exportAsync();
89
- });
90
89
 
91
90
  // fall back to this object or to the scene if it's empty and doesn't have a mesh
92
91
  if (!this.objectToExport)
@@ -105,7 +104,8 @@
105
104
  const ios = isiOS()
106
105
  const safari = isSafari();
107
106
  if (debug || (ios && safari)) {
108
- this.addQuicklookButton();
107
+ if (debug || this.allowCreateQuicklookButton)
108
+ this.addQuicklookButton();
109
109
  this.webARSessionRoot = GameObject.findObjectOfType(WebARSessionRoot) ?? undefined;
110
110
  this.lastCallback = this.quicklookCallback.bind(this);
111
111
  this.link = ensureQuicklookLinkIsCreated(this.context);
@@ -113,6 +113,8 @@
113
113
  }
114
114
  if (debug)
115
115
  showBalloonMessage("USDZ Exporter enabled: " + this.name);
116
+
117
+ document.getElementById("open-in-ar")?.addEventListener("click", this.onClickedOpenInARElement);
116
118
  }
117
119
 
118
120
  onDisable() {
@@ -124,8 +126,15 @@
124
126
  }
125
127
  if (debug)
126
128
  showBalloonMessage("USDZ Exporter disabled: " + this.name);
129
+
130
+ document.getElementById("open-in-ar")?.removeEventListener("click", this.onClickedOpenInARElement);
127
131
  }
128
132
 
133
+ private onClickedOpenInARElement = (evt) => {
134
+ evt.preventDefault();
135
+ this.exportAsync();
136
+ }
137
+
129
138
  async exportAsync() {
130
139
 
131
140
  let name = this.exportFileName ?? this.objectToExport?.name ?? this.name;