@@ -153,12 +153,23 @@
|
|
153
153
|
|
154
154
|
private _loading?: PromiseLike<any>;
|
155
155
|
|
156
|
-
|
157
|
-
|
156
|
+
/** The url of the loaded asset (or the asset to be loaded)
|
157
|
+
* @deprecated use url */
|
158
158
|
get uri(): string {
|
159
159
|
return this._url;
|
160
160
|
}
|
161
|
+
/** The url of the loaded asset (or the asset to be loaded) */
|
162
|
+
get url(): string {
|
163
|
+
return this._url;
|
164
|
+
}
|
161
165
|
|
166
|
+
/**
|
167
|
+
* @returns true if the uri is a valid URL (http, https, blob)
|
168
|
+
*/
|
169
|
+
get hasUrl() {
|
170
|
+
return this._url !== undefined && (this._url.startsWith("http") || this._url.startsWith("blob:"));
|
171
|
+
}
|
172
|
+
|
162
173
|
/**
|
163
174
|
* This is the loaded asset root object. If the asset is a glb/gltf file this will be the {@link three#Scene} object.
|
164
175
|
*/
|
@@ -185,7 +185,13 @@
|
|
185
185
|
/** @internal */
|
186
186
|
awake(): void {
|
187
187
|
if (this.scenes === undefined) this.scenes = [];
|
188
|
-
|
188
|
+
// remove all scenes from the url that are in the scenes array at startup
|
189
|
+
for (const scene of this.scenes) {
|
190
|
+
if (scene && !scene.hasUrl && scene.asset instanceof Object3D) {
|
191
|
+
scene.asset.removeFromParent();
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
189
195
|
if (debug) console.log("SceneSwitcher", this);
|
190
196
|
}
|
191
197
|
|
@@ -467,7 +473,14 @@
|
|
467
473
|
const res = sceneListener.sceneClosing();
|
468
474
|
if (res instanceof Promise) await res;
|
469
475
|
}
|
470
|
-
|
476
|
+
// if the current scene has a URL (so it can be reloaded)
|
477
|
+
// then we unload it
|
478
|
+
if (this._currentScene.hasUrl)
|
479
|
+
this._currentScene.unload();
|
480
|
+
// otherwise if it's a regular Object3D we just remove it from the scene
|
481
|
+
else if (this._currentScene.asset instanceof Object3D) {
|
482
|
+
this._currentScene.asset.removeFromParent();
|
483
|
+
}
|
471
484
|
}
|
472
485
|
|
473
486
|
this._currentScene = undefined;
|
@@ -501,7 +514,7 @@
|
|
501
514
|
return false;
|
502
515
|
}
|
503
516
|
if (this._currentIndex === index) {
|
504
|
-
if (debug) console.log("ADD", scene.uri)
|
517
|
+
if (debug) console.log("ADD", scene.uri);
|
505
518
|
this._currentScene = scene;
|
506
519
|
GameObject.add(scene.asset, this.gameObject);
|
507
520
|
if (this.useSceneLighting)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
|
2
2
|
import { serializable } from "../../../engine/engine_serialization_decorator.js";
|
3
|
+
import { getTempVector } from "../../../engine/engine_three_utils.js";
|
3
4
|
import type { NeedleXREventArgs } from "../../../engine/engine_xr.js";
|
4
5
|
import { Behaviour } from "../../Component.js";
|
5
6
|
|
@@ -57,10 +58,12 @@
|
|
57
58
|
if (this.useGripSpace || ctrl.targetRayMode === "transient-pointer") {
|
58
59
|
this.gameObject.worldPosition = ctrl.gripWorldPosition;
|
59
60
|
this.gameObject.worldQuaternion = ctrl.gripWorldQuaternion;
|
61
|
+
this.gameObject.worldScale = getTempVector(ctrl.xr.rigScale, ctrl.xr.rigScale, ctrl.xr.rigScale);
|
60
62
|
}
|
61
63
|
else {
|
62
64
|
this.gameObject.worldPosition = ctrl.rayWorldPosition;
|
63
65
|
this.gameObject.worldQuaternion = ctrl.rayWorldQuaternion;
|
66
|
+
this.gameObject.worldScale = getTempVector(ctrl.xr.rigScale, ctrl.xr.rigScale, ctrl.xr.rigScale);
|
64
67
|
}
|
65
68
|
}
|
66
69
|
|
@@ -26,9 +26,17 @@
|
|
26
26
|
*/
|
27
27
|
export class XRControllerModel extends Behaviour {
|
28
28
|
|
29
|
+
/**
|
30
|
+
* If true, the controller model will be created when a controller is added/connected
|
31
|
+
* @default true
|
32
|
+
*/
|
29
33
|
@serializable()
|
30
34
|
createControllerModel: boolean = true;
|
31
35
|
|
36
|
+
/**
|
37
|
+
* If true, the hand model will be created when a hand is "added"/tracked
|
38
|
+
* @default true
|
39
|
+
*/
|
32
40
|
@serializable()
|
33
41
|
createHandModel: boolean = true;
|
34
42
|
|
@@ -22,36 +22,49 @@
|
|
22
22
|
*/
|
23
23
|
export class XRControllerMovement extends Behaviour implements XRMovementBehaviour {
|
24
24
|
|
25
|
-
/** Movement speed in meters per second
|
25
|
+
/** Movement speed in meters per second
|
26
|
+
* @default 1
|
27
|
+
*/
|
26
28
|
@serializable()
|
27
29
|
movementSpeed = 1;
|
28
30
|
|
29
|
-
/** How many degrees to rotate the XR rig when using the rotation trigger
|
31
|
+
/** How many degrees to rotate the XR rig when using the rotation trigger
|
32
|
+
* @default 60
|
33
|
+
*/
|
30
34
|
@serializable()
|
31
35
|
rotationStep = 60;
|
32
36
|
|
33
|
-
/** When enabled you can teleport using the right XR controller's thumbstick by pressing forward
|
37
|
+
/** When enabled you can teleport using the right XR controller's thumbstick by pressing forward
|
38
|
+
* @default true
|
39
|
+
*/
|
34
40
|
@serializable()
|
35
41
|
useTeleport: boolean = true;
|
36
42
|
|
37
|
-
/** Enable to only allow teleporting on objects with a teleport target component
|
43
|
+
/** Enable to only allow teleporting on objects with a teleport target component
|
44
|
+
* @default false
|
45
|
+
*/
|
38
46
|
@serializable()
|
39
47
|
useTeleportTarget = false;
|
40
48
|
|
41
|
-
/** Enable to fade out the scene when teleporting
|
49
|
+
/** Enable to fade out the scene when teleporting
|
50
|
+
* @default false
|
51
|
+
*/
|
42
52
|
@serializable()
|
43
53
|
useTeleportFade = false;
|
44
54
|
|
45
|
-
/** enable to visualize controller rays in the 3D scene
|
55
|
+
/** enable to visualize controller rays in the 3D scene
|
56
|
+
* @default true
|
57
|
+
*/
|
46
58
|
@serializable()
|
47
59
|
showRays: boolean = true;
|
48
60
|
|
49
|
-
/** enable to visualize pointer targets in the 3D scene
|
61
|
+
/** enable to visualize pointer targets in the 3D scene
|
62
|
+
* @default false
|
63
|
+
*/
|
50
64
|
@serializable()
|
51
|
-
showHits: boolean =
|
65
|
+
showHits: boolean = false;
|
52
66
|
|
53
67
|
readonly isXRMovementHandler: true = true;
|
54
|
-
|
55
68
|
readonly xrSessionMode = "immersive-vr";
|
56
69
|
|
57
70
|
private _didApplyRotation = false;
|