@needle-tools/engine 3.34.3-alpha.1 → 3.34.4-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 +4 -0
- package/README.md +9 -10
- package/dist/needle-engine.js +1679 -1682
- package/dist/needle-engine.light.js +1741 -1744
- package/dist/needle-engine.light.min.js +151 -151
- package/dist/needle-engine.light.umd.cjs +155 -155
- package/dist/needle-engine.min.js +150 -150
- package/dist/needle-engine.umd.cjs +155 -155
- package/lib/engine-components/Camera.js +1 -1
- package/lib/engine-components/Camera.js.map +1 -1
- package/lib/engine-components/OrbitControls.d.ts +2 -0
- package/lib/engine-components/OrbitControls.js +41 -40
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/webxr/WebXR.js +0 -6
- package/lib/engine-components/webxr/WebXR.js.map +1 -1
- package/lib/engine-components/webxr/WebXRButtons.js +6 -0
- package/lib/engine-components/webxr/WebXRButtons.js.map +1 -1
- package/package.json +1 -1
- package/src/engine-components/Camera.ts +1 -1
- package/src/engine-components/OrbitControls.ts +40 -38
- package/src/engine-components/webxr/WebXR.ts +0 -5
- package/src/engine-components/webxr/WebXRButtons.ts +6 -1
|
@@ -155,46 +155,18 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
155
155
|
private _camera: Camera | null = null;
|
|
156
156
|
private _syncedTransform?: SyncedTransform;
|
|
157
157
|
private _didStart = false;
|
|
158
|
+
private _didSetTarget = false;
|
|
158
159
|
|
|
159
160
|
targetElement: HTMLElement | null = null;
|
|
160
161
|
|
|
161
162
|
awake(): void {
|
|
162
163
|
this._didStart = false;
|
|
164
|
+
this._didSetTarget = false;
|
|
163
165
|
this._startedListeningToKeyEvents = false;
|
|
164
166
|
}
|
|
165
167
|
|
|
166
168
|
start() {
|
|
167
169
|
this._didStart = true;
|
|
168
|
-
if (this.autoTarget) {
|
|
169
|
-
if (this._controls) {
|
|
170
|
-
const camGo = GameObject.getComponent(this.gameObject, Camera);
|
|
171
|
-
if (camGo && !this.setLookTargetFromConstraint()) {
|
|
172
|
-
if (this.debugLog)
|
|
173
|
-
console.log("NO TARGET");
|
|
174
|
-
const worldPosition = getWorldPosition(camGo.cam);
|
|
175
|
-
const distanceToCenter = worldPosition.length();
|
|
176
|
-
const forward = new Vector3(0, 0, -distanceToCenter).applyMatrix4(camGo.cam.matrixWorld);
|
|
177
|
-
this.setLookTargetPosition(forward, true);
|
|
178
|
-
}
|
|
179
|
-
// we need to wait one frame for the scene be fully populated. E.g. when we added progressive meshes and a heavy scene this was necessary
|
|
180
|
-
delayForFrames(0).then(() => {
|
|
181
|
-
if (this.autoTarget && !this.autoFit && !this.setLookTargetFromConstraint()) {
|
|
182
|
-
const opts = new RaycastOptions();
|
|
183
|
-
// center of the screen:
|
|
184
|
-
opts.screenPoint = new Vector2(0, 0);
|
|
185
|
-
opts.lineThreshold = 0.1;
|
|
186
|
-
const hits = this.context.physics.raycast(opts);
|
|
187
|
-
if (hits.length > 0) {
|
|
188
|
-
this.setLookTargetPosition(hits[0].point, true);
|
|
189
|
-
}
|
|
190
|
-
if (debugCameraFit)
|
|
191
|
-
console.log("OrbitControls hits", ...hits);
|
|
192
|
-
}
|
|
193
|
-
if (this.autoFit) this.fitCamera()
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
170
|
this._eventSystem = EventSystem.get(this.context) ?? undefined;
|
|
199
171
|
if (this._eventSystem) {
|
|
200
172
|
this._afterHandleInputFn = this.afterHandleInput.bind(this);
|
|
@@ -211,15 +183,13 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
211
183
|
this._enableTime = this.context.time.time;
|
|
212
184
|
const cameraComponent = GameObject.getComponent(this.gameObject, Camera);
|
|
213
185
|
this._camera = cameraComponent;
|
|
214
|
-
|
|
186
|
+
let cam = cameraComponent?.cam;
|
|
187
|
+
if (!cam && this.gameObject instanceof PerspectiveCamera) {
|
|
188
|
+
cam = this.gameObject;
|
|
189
|
+
}
|
|
215
190
|
if (cam) setCameraController(cam, this, true);
|
|
216
|
-
if (!this._controls) {
|
|
217
|
-
|
|
218
|
-
console.warn("OrbitControls: Requires a Camera component on the same object as this component.");
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
if (cam)
|
|
222
|
-
this._cameraObject = cam;
|
|
191
|
+
if (!this._controls && cam instanceof PerspectiveCamera) {
|
|
192
|
+
this._cameraObject = cam;
|
|
223
193
|
// Using the parent if possible to make it possible to disable input on the canvas
|
|
224
194
|
// for having HTML content behind it and still receive input
|
|
225
195
|
const element = this.targetElement ?? this.context.renderer.domElement;
|
|
@@ -306,6 +276,8 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
306
276
|
onBeforeRender() {
|
|
307
277
|
if (!this._controls) return;
|
|
308
278
|
if (this._cameraObject !== this.context.mainCamera) return;
|
|
279
|
+
|
|
280
|
+
this.__handleSetTargetWhenBecomingActiveTheFirstTime();
|
|
309
281
|
|
|
310
282
|
if (this.context.input.getPointerDown(1) || this.context.input.getPointerDown(2) || this.context.input.mouseWheelChanged || (this.context.input.getPointerPressed(0) && this.context.input.getPointerPositionDelta(0)?.length() || 0 > .1)) {
|
|
311
283
|
this._inputs += 1;
|
|
@@ -406,6 +378,36 @@ export class OrbitControls extends Behaviour implements ICameraController {
|
|
|
406
378
|
|
|
407
379
|
}
|
|
408
380
|
|
|
381
|
+
private __handleSetTargetWhenBecomingActiveTheFirstTime() {
|
|
382
|
+
if (this._didSetTarget) return;
|
|
383
|
+
this._didSetTarget = true;
|
|
384
|
+
if (this.autoTarget) {
|
|
385
|
+
|
|
386
|
+
const camGo = GameObject.getComponent(this.gameObject, Camera);
|
|
387
|
+
if (camGo && !this.setLookTargetFromConstraint()) {
|
|
388
|
+
if (this.debugLog)
|
|
389
|
+
console.log("NO TARGET");
|
|
390
|
+
const worldPosition = getWorldPosition(camGo.cam);
|
|
391
|
+
const distanceToCenter = worldPosition.length();
|
|
392
|
+
const forward = new Vector3(0, 0, -distanceToCenter).applyMatrix4(camGo.cam.matrixWorld);
|
|
393
|
+
this.setLookTargetPosition(forward, true);
|
|
394
|
+
}
|
|
395
|
+
if (!this.autoFit && !this.setLookTargetFromConstraint()) {
|
|
396
|
+
const opts = new RaycastOptions();
|
|
397
|
+
// center of the screen:
|
|
398
|
+
opts.screenPoint = new Vector2(0, 0);
|
|
399
|
+
opts.lineThreshold = 0.1;
|
|
400
|
+
const hits = this.context.physics.raycast(opts);
|
|
401
|
+
if (hits.length > 0) {
|
|
402
|
+
this.setLookTargetPosition(hits[0].point, true);
|
|
403
|
+
}
|
|
404
|
+
if (debugCameraFit)
|
|
405
|
+
console.log("OrbitControls hits", ...hits);
|
|
406
|
+
}
|
|
407
|
+
if (this.autoFit) this.fitCamera()
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
409
411
|
|
|
410
412
|
/**
|
|
411
413
|
* Sets camera target position and look direction. Does perform a raycast in the forward direction of the passed in object to find an orbit point
|
|
@@ -279,19 +279,16 @@ export class WebXR extends Behaviour {
|
|
|
279
279
|
if ((isiOS() && isSafari()) || debugQuicklook) {
|
|
280
280
|
if (this.useQuicklookExport) {
|
|
281
281
|
const button = this.getButtonsFactory().createQuicklookButton();
|
|
282
|
-
button.prepend(getIconElement("view_in_ar"));
|
|
283
282
|
this.addButton(button, xrButtonsPriority);
|
|
284
283
|
}
|
|
285
284
|
}
|
|
286
285
|
// WebXR
|
|
287
286
|
if (this.createARButton) {
|
|
288
287
|
const arbutton = this.getButtonsFactory().createARButton();
|
|
289
|
-
arbutton.prepend(getIconElement("view_in_ar"))
|
|
290
288
|
this.addButton(arbutton, xrButtonsPriority);
|
|
291
289
|
}
|
|
292
290
|
if (this.createVRButton) {
|
|
293
291
|
const vrbutton = this.getButtonsFactory().createVRButton();
|
|
294
|
-
vrbutton.prepend(getIconElement("panorama_photosphere"));
|
|
295
292
|
this.addButton(vrbutton, xrButtonsPriority);
|
|
296
293
|
}
|
|
297
294
|
}
|
|
@@ -300,7 +297,6 @@ export class WebXR extends Behaviour {
|
|
|
300
297
|
NeedleXRSession.isVRSupported().then(supported => {
|
|
301
298
|
if (!supported) {
|
|
302
299
|
const button = this.getButtonsFactory().createSendToQuestButton();
|
|
303
|
-
button.prepend(getIconElement("share_windows"));
|
|
304
300
|
this.addButton(button, xrButtonsPriority);
|
|
305
301
|
}
|
|
306
302
|
});
|
|
@@ -310,7 +306,6 @@ export class WebXR extends Behaviour {
|
|
|
310
306
|
NeedleXRSession.isXRSupported().then(supported => {
|
|
311
307
|
if (isDesktop() || !supported) {
|
|
312
308
|
const qrCode = this.getButtonsFactory().createQRCode();
|
|
313
|
-
qrCode.prepend(getIconElement("qr_code"));
|
|
314
309
|
this.addButton(qrCode, xrButtonsPriority);
|
|
315
310
|
}
|
|
316
311
|
});
|
|
@@ -2,6 +2,7 @@ import { isDevEnvironment } from "../../engine/debug/index.js";
|
|
|
2
2
|
import { generateQRCode } from "../../engine/engine_utils.js";
|
|
3
3
|
import { isMozillaXR } from "../../engine/engine_utils.js";
|
|
4
4
|
import { NeedleXRSession } from "../../engine/engine_xr.js";
|
|
5
|
+
import { getIconElement } from "../../engine/webcomponents/icons.js";
|
|
5
6
|
import { GameObject } from "../Component.js";
|
|
6
7
|
import { USDZExporter } from "../export/usdz/USDZExporter.js";
|
|
7
8
|
|
|
@@ -49,9 +50,9 @@ export class WebXRButtonFactory {
|
|
|
49
50
|
|
|
50
51
|
const button = document.createElement("button");
|
|
51
52
|
this._quicklookButton = button;
|
|
52
|
-
|
|
53
53
|
button.dataset["needle"] = "quicklook-button";
|
|
54
54
|
button.innerText = "Open in Quicklook";
|
|
55
|
+
button.prepend(getIconElement("view_in_ar"));
|
|
55
56
|
button.addEventListener("click", () => {
|
|
56
57
|
const usdzExporter = GameObject.findObjectOfType(USDZExporter);
|
|
57
58
|
if (usdzExporter) {
|
|
@@ -87,6 +88,7 @@ export class WebXRButtonFactory {
|
|
|
87
88
|
button.classList.add("webxr-button");
|
|
88
89
|
button.dataset["needle"] = "webxr-ar-button";
|
|
89
90
|
button.innerText = "Enter AR";
|
|
91
|
+
button.prepend(getIconElement("view_in_ar"))
|
|
90
92
|
button.title = "Click to start an AR session";
|
|
91
93
|
button.addEventListener("click", () => NeedleXRSession.start(mode, init));
|
|
92
94
|
this.updateSessionSupported(button, mode);
|
|
@@ -120,6 +122,7 @@ export class WebXRButtonFactory {
|
|
|
120
122
|
button.classList.add("webxr-button");
|
|
121
123
|
button.dataset["needle"] = "webxr-vr-button";
|
|
122
124
|
button.innerText = "Enter VR";
|
|
125
|
+
button.prepend(getIconElement("panorama_photosphere"));
|
|
123
126
|
button.title = "Click to start a VR session";
|
|
124
127
|
button.addEventListener("click", () => NeedleXRSession.start(mode, init));
|
|
125
128
|
this.updateSessionSupported(button, mode);
|
|
@@ -148,6 +151,7 @@ export class WebXRButtonFactory {
|
|
|
148
151
|
this._sendToQuestButton = button;
|
|
149
152
|
button.dataset["needle"] = "webxr-sendtoquest-button";
|
|
150
153
|
button.innerText = "Open on Quest";
|
|
154
|
+
button.prepend(getIconElement("share_windows"));
|
|
151
155
|
button.title = "Click to send this page to the Oculus Browser on your Quest";
|
|
152
156
|
button.addEventListener("click", () => {
|
|
153
157
|
const urlParameter = encodeURIComponent(window.location.href);
|
|
@@ -175,6 +179,7 @@ export class WebXRButtonFactory {
|
|
|
175
179
|
const qrCodeButton = document.createElement("button");
|
|
176
180
|
this._qrButton = qrCodeButton;
|
|
177
181
|
qrCodeButton.innerText = "QR Code";
|
|
182
|
+
qrCodeButton.prepend(getIconElement("qr_code"));
|
|
178
183
|
qrCodeButton.title = "Scan this QR code with your phone to open this page";
|
|
179
184
|
this.hideElementDuringXRSession(qrCodeButton);
|
|
180
185
|
|