@needle-tools/engine 2.35.5-pre → 2.36.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.
- package/CHANGELOG.md +19 -0
- package/dist/needle-engine.d.ts +160 -110
- package/dist/needle-engine.js +370 -365
- package/dist/needle-engine.js.map +4 -4
- package/dist/needle-engine.min.js +61 -56
- package/dist/needle-engine.min.js.map +4 -4
- package/lib/engine/debug/debug_overlay.js +12 -1
- package/lib/engine/debug/debug_overlay.js.map +1 -1
- package/lib/engine/engine_element_loading.js +1 -1
- package/lib/engine/engine_element_loading.js.map +1 -1
- package/lib/engine/engine_gameobject.d.ts +1 -0
- package/lib/engine/engine_gameobject.js +13 -1
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_gltf_builtin_components.js +4 -0
- package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
- package/lib/engine/engine_mainloop_utils.d.ts +1 -1
- package/lib/engine/engine_mainloop_utils.js +7 -3
- package/lib/engine/engine_mainloop_utils.js.map +1 -1
- package/lib/engine/engine_physics.d.ts +29 -28
- package/lib/engine/engine_physics.js +85 -86
- package/lib/engine/engine_physics.js.map +1 -1
- package/lib/engine/engine_serialization_core.js +14 -6
- package/lib/engine/engine_serialization_core.js.map +1 -1
- package/lib/engine/engine_setup.js +1 -1
- package/lib/engine/engine_setup.js.map +1 -1
- package/lib/engine/engine_time.d.ts +1 -0
- package/lib/engine/engine_time.js +1 -0
- package/lib/engine/engine_time.js.map +1 -1
- package/lib/engine/engine_types.d.ts +1 -0
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/engine_typestore.d.ts +1 -0
- package/lib/engine/engine_typestore.js +1 -0
- package/lib/engine/engine_typestore.js.map +1 -1
- package/lib/engine/engine_utils.js +1 -1
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_animator_controller_model.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_techniques_webgl.js +5 -0
- package/lib/engine/extensions/NEEDLE_techniques_webgl.js.map +1 -1
- package/lib/engine-components/Animation.d.ts +5 -1
- package/lib/engine-components/Animation.js +21 -0
- package/lib/engine-components/Animation.js.map +1 -1
- package/lib/engine-components/AnimatorController.d.ts +1 -0
- package/lib/engine-components/AnimatorController.js +14 -7
- package/lib/engine-components/AnimatorController.js.map +1 -1
- package/lib/engine-components/BoxHelperComponent.d.ts +2 -2
- package/lib/engine-components/BoxHelperComponent.js +27 -9
- package/lib/engine-components/BoxHelperComponent.js.map +1 -1
- package/lib/engine-components/Component.d.ts +2 -1
- package/lib/engine-components/Component.js +11 -5
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/GroundProjection.d.ts +2 -0
- package/lib/engine-components/GroundProjection.js +18 -6
- package/lib/engine-components/GroundProjection.js.map +1 -1
- package/lib/engine-components/ReflectionProbe.d.ts +22 -0
- package/lib/engine-components/ReflectionProbe.js +134 -0
- package/lib/engine-components/ReflectionProbe.js.map +1 -0
- package/lib/engine-components/Renderer.d.ts +13 -2
- package/lib/engine-components/Renderer.js +96 -45
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/WebARSessionRoot.d.ts +7 -7
- package/lib/engine-components/WebARSessionRoot.js +7 -7
- package/lib/engine-components/WebARSessionRoot.js.map +1 -1
- package/lib/engine-components/WebXR.d.ts +9 -8
- package/lib/engine-components/WebXR.js +40 -24
- package/lib/engine-components/WebXR.js.map +1 -1
- package/lib/engine-components/WebXRAvatar.d.ts +4 -5
- package/lib/engine-components/WebXRAvatar.js +9 -8
- package/lib/engine-components/WebXRAvatar.js.map +1 -1
- package/lib/engine-components/WebXRController.d.ts +21 -21
- package/lib/engine-components/WebXRController.js +79 -63
- package/lib/engine-components/WebXRController.js.map +1 -1
- package/lib/engine-components/WebXRGrabRendering.d.ts +3 -3
- package/lib/engine-components/WebXRGrabRendering.js +2 -2
- package/lib/engine-components/WebXRGrabRendering.js.map +1 -1
- package/lib/engine-components/WebXRSync.d.ts +8 -8
- package/lib/engine-components/WebXRSync.js +15 -15
- package/lib/engine-components/WebXRSync.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +1 -0
- package/lib/engine-components/codegen/components.js +1 -0
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/ui/EventSystem.d.ts +1 -0
- package/lib/engine-components/ui/EventSystem.js +21 -1
- package/lib/engine-components/ui/EventSystem.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/codegen/register_types.js +293 -0
- package/src/engine/debug/debug_overlay.ts +9 -2
- package/src/engine/engine_element_loading.ts +1 -1
- package/src/engine/engine_gameobject.ts +17 -4
- package/src/engine/engine_gltf_builtin_components.ts +5 -1
- package/src/engine/engine_mainloop_utils.ts +7 -3
- package/src/engine/engine_physics.ts +130 -130
- package/src/engine/engine_serialization_core.ts +14 -7
- package/src/engine/engine_setup.ts +1 -1
- package/src/engine/engine_time.ts +2 -0
- package/src/engine/engine_types.ts +1 -0
- package/src/engine/engine_typestore.ts +2 -0
- package/src/engine/engine_utils.ts +3 -2
- package/src/engine/extensions/EXT_texture_exr.js +1 -1
- package/src/engine/extensions/NEEDLE_animator_controller_model.ts +2 -1
- package/src/engine/extensions/NEEDLE_techniques_webgl.ts +7 -0
- package/src/engine-components/Animation.ts +16 -1
- package/src/engine-components/AnimatorController.ts +19 -9
- package/src/engine-components/BoxHelperComponent.ts +29 -9
- package/src/engine-components/Component.ts +11 -5
- package/src/engine-components/GroundProjection.ts +22 -7
- package/src/engine-components/ReflectionProbe.ts +141 -0
- package/src/engine-components/Renderer.ts +796 -737
- package/src/engine-components/WebARSessionRoot.ts +16 -16
- package/src/engine-components/WebXR.ts +53 -48
- package/src/engine-components/WebXRAvatar.ts +16 -16
- package/src/engine-components/WebXRController.ts +129 -107
- package/src/engine-components/WebXRGrabRendering.ts +6 -6
- package/src/engine-components/WebXRSync.ts +20 -20
- package/src/engine-components/codegen/components.ts +1 -0
- package/src/engine-components/ui/EventSystem.ts +26 -3
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { WebXR } from "./WebXR";
|
|
3
|
-
import * as THREE from "three";
|
|
4
|
-
import { SyncedTransform } from "./SyncedTransform";
|
|
5
|
-
import { Physics, RaycastOptions } from "../engine/engine_physics";
|
|
6
|
-
import { XRControllerModel, XRControllerModelFactory } from 'three/examples/jsm/webxr/XRControllerModelFactory.js';
|
|
1
|
+
import { BoxHelper, BufferGeometry, Color, Euler, Group, Intersection, Layers, Line, LineBasicMaterial, Material, Mesh, MeshBasicMaterial, Object3D, PerspectiveCamera, Quaternion, Ray, SphereGeometry, Vector2, Vector3, XRInputSource, XRSession } from "three";
|
|
7
2
|
import { OculusHandModel } from 'three/examples/jsm/webxr/OculusHandModel.js';
|
|
8
3
|
import { OculusHandPointerModel } from 'three/examples/jsm/webxr/OculusHandPointerModel.js';
|
|
9
|
-
import {
|
|
10
|
-
|
|
4
|
+
import { XRControllerModel, XRControllerModelFactory } from 'three/examples/jsm/webxr/XRControllerModelFactory.js';
|
|
5
|
+
|
|
6
|
+
import { InstancingUtil } from "../engine/engine_instancing";
|
|
11
7
|
import { Mathf } from "../engine/engine_math";
|
|
12
|
-
import
|
|
8
|
+
import { RaycastOptions } from "../engine/engine_physics";
|
|
9
|
+
import { getWorldPosition, getWorldQuaternion, setWorldPosition, setWorldQuaternion } from "../engine/engine_three_utils";
|
|
10
|
+
import { getParam, getPath } from "../engine/engine_utils";
|
|
11
|
+
|
|
12
|
+
import { Avatar_POI } from "./avatar/Avatar_Brain_LookAt";
|
|
13
|
+
import { Behaviour, GameObject } from "./Component";
|
|
13
14
|
import { Interactable, UsageMarker } from "./Interactable";
|
|
14
|
-
import { InstancingUtil } from "../engine/engine_instancing";
|
|
15
15
|
import { Rigidbody } from "./RigidBody";
|
|
16
|
-
import {
|
|
16
|
+
import { SyncedTransform } from "./SyncedTransform";
|
|
17
17
|
import { UIRaycastUtils } from "./ui/RaycastUtils";
|
|
18
|
-
import {
|
|
18
|
+
import { WebXR } from "./WebXR";
|
|
19
19
|
|
|
20
20
|
const debug = getParam("debugwebxrcontroller");
|
|
21
21
|
|
|
@@ -38,28 +38,28 @@ export class WebXRController extends Behaviour {
|
|
|
38
38
|
|
|
39
39
|
public static Factory: XRControllerModelFactory = new XRControllerModelFactory();
|
|
40
40
|
|
|
41
|
-
private static raycastColor:
|
|
42
|
-
private static raycastNoHitColor:
|
|
43
|
-
private static geometry = new
|
|
41
|
+
private static raycastColor: Color = new Color(.9, .3, .3);
|
|
42
|
+
private static raycastNoHitColor: Color = new Color(.6, .6, .6);
|
|
43
|
+
private static geometry = new BufferGeometry().setFromPoints([new Vector3(0, 0, 0), new Vector3(0, 0, -1)]);
|
|
44
44
|
private static handModels: { [index: number]: OculusHandPointerModel } = {};
|
|
45
45
|
|
|
46
|
-
private static CreateRaycastLine():
|
|
47
|
-
const line = new
|
|
48
|
-
const mat = line.material as
|
|
46
|
+
private static CreateRaycastLine(): Line {
|
|
47
|
+
const line = new Line(this.geometry);
|
|
48
|
+
const mat = line.material as LineBasicMaterial;
|
|
49
49
|
mat.color = this.raycastColor;
|
|
50
50
|
// mat.linewidth = 10;
|
|
51
|
-
line.layers.set(
|
|
51
|
+
line.layers.set(2);
|
|
52
52
|
line.name = 'line';
|
|
53
53
|
line.scale.z = 1;
|
|
54
54
|
return line;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
private static CreateRaycastHitPoint():
|
|
58
|
-
const geometry = new
|
|
59
|
-
const material = new
|
|
60
|
-
const sphere = new
|
|
57
|
+
private static CreateRaycastHitPoint(): Mesh {
|
|
58
|
+
const geometry = new SphereGeometry(.5, 22, 22);
|
|
59
|
+
const material = new MeshBasicMaterial({ color: this.raycastColor });
|
|
60
|
+
const sphere = new Mesh(geometry, material);
|
|
61
61
|
sphere.visible = false;
|
|
62
|
-
sphere.layers.set(
|
|
62
|
+
sphere.layers.set(2);
|
|
63
63
|
return sphere;
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -71,7 +71,7 @@ export class WebXRController extends Behaviour {
|
|
|
71
71
|
ctrl.type = type;
|
|
72
72
|
|
|
73
73
|
const context = owner.context;
|
|
74
|
-
// from https://github.com/mrdoob/
|
|
74
|
+
// from https://github.com/mrdoob/js/blob/master/examples/webxr_vr_dragging.html
|
|
75
75
|
// controllers
|
|
76
76
|
ctrl.controller = context.renderer.xr.getController(index);
|
|
77
77
|
ctrl.controllerGrip = context.renderer.xr.getControllerGrip(index);
|
|
@@ -80,24 +80,28 @@ export class WebXRController extends Behaviour {
|
|
|
80
80
|
|
|
81
81
|
ctrl.hand = context.renderer.xr.getHand(index);
|
|
82
82
|
const hand = new OculusHandModel(ctrl.hand);
|
|
83
|
-
|
|
83
|
+
if (ctrl.webXR.handModelPath && ctrl.webXR.handModelPath !== "")
|
|
84
|
+
hand["path"] = "/" + getPath(owner.sourceId, ctrl.webXR.handModelPath);
|
|
84
85
|
ctrl.hand.add(hand);
|
|
85
86
|
ctrl.hand.traverse(x => x.layers.set(2));
|
|
86
87
|
|
|
87
88
|
ctrl.handPointerModel = new OculusHandPointerModel(ctrl.hand, ctrl.controller);
|
|
88
89
|
|
|
89
90
|
|
|
90
|
-
// TODO remove all these once https://github.com/mrdoob/
|
|
91
|
+
// TODO remove all these once https://github.com/mrdoob/js/pull/23279 lands
|
|
91
92
|
ctrl.controller.addEventListener('connected', (_) => {
|
|
92
93
|
ctrl.setControllerLayers(ctrl.controllerModel, 2);
|
|
93
94
|
ctrl.setControllerLayers(ctrl.controllerGrip, 2);
|
|
95
|
+
ctrl.setControllerLayers(ctrl.hand, 2);
|
|
94
96
|
setTimeout(() => {
|
|
97
|
+
ctrl.setControllerLayers(ctrl.controllerModel, 2);
|
|
95
98
|
ctrl.setControllerLayers(ctrl.controllerGrip, 2);
|
|
99
|
+
ctrl.setControllerLayers(ctrl.hand, 2);
|
|
96
100
|
}, 1000);
|
|
97
101
|
});
|
|
98
102
|
|
|
99
103
|
// TODO: unsubscribe! this should be moved into onenable and ondisable!
|
|
100
|
-
// TODO remove all these once https://github.com/mrdoob/
|
|
104
|
+
// TODO remove all these once https://github.com/mrdoob/js/pull/23279 lands
|
|
101
105
|
ctrl.hand.addEventListener('connected', (event) => {
|
|
102
106
|
const xrInputSource = event.data;
|
|
103
107
|
if (xrInputSource.hand) {
|
|
@@ -144,12 +148,12 @@ export class WebXRController extends Behaviour {
|
|
|
144
148
|
public webXR!: WebXR;
|
|
145
149
|
public index: number = -1;
|
|
146
150
|
public controllerModel!: XRControllerModel;
|
|
147
|
-
public controller!:
|
|
148
|
-
public controllerGrip!:
|
|
149
|
-
public hand!:
|
|
151
|
+
public controller!: Group;
|
|
152
|
+
public controllerGrip!: Group;
|
|
153
|
+
public hand!: Group;
|
|
150
154
|
public handPointerModel!: OculusHandPointerModel;
|
|
151
155
|
public grabbed: AttachedObject | null = null;
|
|
152
|
-
public input:
|
|
156
|
+
public input: XRInputSource | null = null;
|
|
153
157
|
public type: ControllerType = ControllerType.PhysicalDevice;
|
|
154
158
|
|
|
155
159
|
get isUsingHands(): boolean {
|
|
@@ -157,35 +161,35 @@ export class WebXRController extends Behaviour {
|
|
|
157
161
|
return r !== null && r !== undefined;
|
|
158
162
|
}
|
|
159
163
|
|
|
160
|
-
get wrist():
|
|
164
|
+
get wrist(): Object3D | null {
|
|
161
165
|
if (!this.hand) return null;
|
|
162
166
|
const jnts = this.hand["joints"];
|
|
163
167
|
if (!jnts) return null;
|
|
164
168
|
return jnts["wrist"];
|
|
165
169
|
}
|
|
166
170
|
|
|
167
|
-
private _wristQuaternion:
|
|
168
|
-
getWristQuaternion():
|
|
171
|
+
private _wristQuaternion: Quaternion | null = null;
|
|
172
|
+
getWristQuaternion(): Quaternion | null {
|
|
169
173
|
const wrist = this.wrist;
|
|
170
174
|
if (!wrist) return null;
|
|
171
|
-
if (!this._wristQuaternion) this._wristQuaternion = new
|
|
172
|
-
const wr =
|
|
175
|
+
if (!this._wristQuaternion) this._wristQuaternion = new Quaternion();
|
|
176
|
+
const wr = getWorldQuaternion(wrist).multiply(this._wristQuaternion.setFromEuler(new Euler(-Math.PI / 4, 0, 0)));
|
|
173
177
|
return wr;
|
|
174
178
|
}
|
|
175
179
|
|
|
176
|
-
private movementVector:
|
|
177
|
-
private worldRot:
|
|
178
|
-
private joystick:
|
|
180
|
+
private movementVector: Vector3 = new Vector3();
|
|
181
|
+
private worldRot: Quaternion = new Quaternion();
|
|
182
|
+
private joystick: Vector2 = new Vector2();
|
|
179
183
|
private didRotate: boolean = false;
|
|
180
184
|
private didTeleport: boolean = false;
|
|
181
185
|
private didChangeScale: boolean = false;
|
|
182
186
|
private static PreviousCameraFarDistance: number | undefined = undefined;
|
|
183
187
|
private static MovementSpeedFactor: number = 1;
|
|
184
188
|
|
|
185
|
-
private lastHit:
|
|
189
|
+
private lastHit: Intersection | null = null;
|
|
186
190
|
|
|
187
|
-
private raycastLine:
|
|
188
|
-
private _raycastHitPoint:
|
|
191
|
+
private raycastLine: Line | null = null;
|
|
192
|
+
private _raycastHitPoint: Object3D | null = null;
|
|
189
193
|
private _connnectedCallback: any | null = null;
|
|
190
194
|
private _disconnectedCallback: any | null = null;
|
|
191
195
|
private _selectStartEvt: any | null = null;
|
|
@@ -195,7 +199,7 @@ export class WebXRController extends Behaviour {
|
|
|
195
199
|
public get selectionUp(): boolean { return !this._selectionPressed && this._selectionPressedLastFrame; }
|
|
196
200
|
public get selectionPressed(): boolean { return this._selectionPressed; }
|
|
197
201
|
public get selectionClick(): boolean { return this._selectionEndTime - this._selectionStartTime < 0.3; }
|
|
198
|
-
public get raycastHitPoint():
|
|
202
|
+
public get raycastHitPoint(): Object3D | null { return this._raycastHitPoint; }
|
|
199
203
|
|
|
200
204
|
private _selectionPressed: boolean = false;
|
|
201
205
|
private _selectionPressedLastFrame: boolean = false;
|
|
@@ -336,7 +340,7 @@ export class WebXRController extends Behaviour {
|
|
|
336
340
|
}
|
|
337
341
|
}
|
|
338
342
|
|
|
339
|
-
rayRotation:
|
|
343
|
+
rayRotation: Quaternion = new Quaternion();
|
|
340
344
|
|
|
341
345
|
update(): void {
|
|
342
346
|
|
|
@@ -357,8 +361,13 @@ export class WebXRController extends Behaviour {
|
|
|
357
361
|
let t = 1;
|
|
358
362
|
if (this.type === ControllerType.PhysicalDevice) t = this.context.time.deltaTime / .1;
|
|
359
363
|
else if (this.isUsingHands && this.handPointerModel.pinched) t = this.context.time.deltaTime / .3;
|
|
360
|
-
this.rayRotation.slerp(
|
|
361
|
-
const wp =
|
|
364
|
+
this.rayRotation.slerp(getWorldQuaternion(this.controller), this.useSmoothing ? t : 1.0);
|
|
365
|
+
const wp = getWorldPosition(this.controller);
|
|
366
|
+
|
|
367
|
+
// hide hand pointer model, it's giant and doesn't really help
|
|
368
|
+
if (this.isUsingHands && this.handPointerModel.cursorObject) {
|
|
369
|
+
this.handPointerModel.cursorObject.visible = false;
|
|
370
|
+
}
|
|
362
371
|
|
|
363
372
|
if (this.raycastLine) {
|
|
364
373
|
if (this.type === ControllerType.Touch) {
|
|
@@ -366,7 +375,7 @@ export class WebXRController extends Behaviour {
|
|
|
366
375
|
}
|
|
367
376
|
else if (this.isUsingHands) {
|
|
368
377
|
this.raycastLine.visible = !this.grabbed;
|
|
369
|
-
|
|
378
|
+
setWorldPosition(this.raycastLine, wp);
|
|
370
379
|
const jnts = this.hand!['joints'];
|
|
371
380
|
if (jnts) {
|
|
372
381
|
const wrist = jnts['wrist'];
|
|
@@ -377,12 +386,12 @@ export class WebXRController extends Behaviour {
|
|
|
377
386
|
// this.rayRotation.slerp(wr, this.useSmoothing ? t * 2 : 1);
|
|
378
387
|
}
|
|
379
388
|
}
|
|
380
|
-
|
|
389
|
+
setWorldQuaternion(this.raycastLine, this.rayRotation);
|
|
381
390
|
}
|
|
382
391
|
else {
|
|
383
392
|
this.raycastLine.visible = true;
|
|
384
|
-
|
|
385
|
-
|
|
393
|
+
setWorldQuaternion(this.raycastLine, this.rayRotation);
|
|
394
|
+
setWorldPosition(this.raycastLine, wp);
|
|
386
395
|
}
|
|
387
396
|
}
|
|
388
397
|
|
|
@@ -480,8 +489,8 @@ export class WebXRController extends Behaviour {
|
|
|
480
489
|
if (pinched && this._pinchStartTime && this.context.time.time - this._pinchStartTime > .8) {
|
|
481
490
|
// hacky approach for basic hand teleportation -
|
|
482
491
|
// we teleport if we pinch and the back of the hand points down (open hand gesture)
|
|
483
|
-
// const v1 = new
|
|
484
|
-
// const worldQuaternion = new
|
|
492
|
+
// const v1 = new Vector3();
|
|
493
|
+
// const worldQuaternion = new Quaternion();
|
|
485
494
|
// this.controller.getWorldQuaternion(worldQuaternion);
|
|
486
495
|
// v1.copy(this.controller.up).applyQuaternion(worldQuaternion);
|
|
487
496
|
// const dotPr = -v1.dot(this.controller.up);
|
|
@@ -510,7 +519,7 @@ export class WebXRController extends Behaviour {
|
|
|
510
519
|
doTeleport = true;
|
|
511
520
|
newRigScale = .1;
|
|
512
521
|
WebXRController.MovementSpeedFactor = newRigScale * 2;
|
|
513
|
-
const cam = this.context.mainCamera as
|
|
522
|
+
const cam = this.context.mainCamera as PerspectiveCamera;
|
|
514
523
|
WebXRController.PreviousCameraFarDistance = cam.far;
|
|
515
524
|
cam.far /= newRigScale;
|
|
516
525
|
}
|
|
@@ -519,7 +528,7 @@ export class WebXRController extends Behaviour {
|
|
|
519
528
|
rig.scale.set(1, 1, 1);
|
|
520
529
|
newRigScale = 1;
|
|
521
530
|
WebXRController.MovementSpeedFactor = 1;
|
|
522
|
-
const cam = this.context.mainCamera as
|
|
531
|
+
const cam = this.context.mainCamera as PerspectiveCamera;
|
|
523
532
|
if (WebXRController.PreviousCameraFarDistance)
|
|
524
533
|
cam.far = WebXRController.PreviousCameraFarDistance;
|
|
525
534
|
}
|
|
@@ -539,7 +548,7 @@ export class WebXRController extends Behaviour {
|
|
|
539
548
|
const hit = rc[0];
|
|
540
549
|
if (isInMiniatureMode || this.isValidTeleportTarget(hit.object)) {
|
|
541
550
|
const point = hit.point;
|
|
542
|
-
|
|
551
|
+
setWorldPosition(rig, point);
|
|
543
552
|
}
|
|
544
553
|
}
|
|
545
554
|
}
|
|
@@ -554,17 +563,17 @@ export class WebXRController extends Behaviour {
|
|
|
554
563
|
}
|
|
555
564
|
}
|
|
556
565
|
|
|
557
|
-
private isValidTeleportTarget(obj:
|
|
566
|
+
private isValidTeleportTarget(obj: Object3D): boolean {
|
|
558
567
|
return GameObject.getComponentInParent(obj, TeleportTarget) != null;
|
|
559
568
|
}
|
|
560
569
|
|
|
561
|
-
private updateStick(inputSource:
|
|
570
|
+
private updateStick(inputSource: XRInputSource) {
|
|
562
571
|
if (!inputSource || !inputSource.gamepad || inputSource.gamepad.axes?.length < 4) return;
|
|
563
572
|
this.joystick.x = inputSource.gamepad.axes[2];
|
|
564
573
|
this.joystick.y = inputSource.gamepad.axes[3];
|
|
565
574
|
}
|
|
566
575
|
|
|
567
|
-
private updateLastHit():
|
|
576
|
+
private updateLastHit(): Intersection | null {
|
|
568
577
|
const rc = this.raycast();
|
|
569
578
|
const hit = rc ? rc[0] : null;
|
|
570
579
|
this.lastHit = hit;
|
|
@@ -576,7 +585,7 @@ export class WebXRController extends Behaviour {
|
|
|
576
585
|
|
|
577
586
|
if (this.raycastLine) {
|
|
578
587
|
this.raycastLine.scale.z = factor * (this.lastHit?.distance ?? 9999);
|
|
579
|
-
const mat = this.raycastLine.material as
|
|
588
|
+
const mat = this.raycastLine.material as LineBasicMaterial;
|
|
580
589
|
if (hit != null) mat.color = WebXRController.raycastColor;
|
|
581
590
|
else mat.color = WebXRController.raycastNoHitColor;
|
|
582
591
|
}
|
|
@@ -603,7 +612,7 @@ export class WebXRController extends Behaviour {
|
|
|
603
612
|
}
|
|
604
613
|
|
|
605
614
|
private selectStartCallback: Function | null = null;
|
|
606
|
-
private lastSelectStartObject:
|
|
615
|
+
private lastSelectStartObject: Object3D | null = null;;
|
|
607
616
|
|
|
608
617
|
private onHandleSelectStart() {
|
|
609
618
|
this.selectStartCallback = null;
|
|
@@ -613,7 +622,7 @@ export class WebXRController extends Behaviour {
|
|
|
613
622
|
// console.log("DOWN", this.index, WebXRController.eventSubs);
|
|
614
623
|
|
|
615
624
|
// let maxDistance = this.isUsingHands ? .1 : undefined;
|
|
616
|
-
let intersections:
|
|
625
|
+
let intersections: Intersection[] | null = null;
|
|
617
626
|
let closeGrab: boolean = false;
|
|
618
627
|
if (this.isUsingHands) {
|
|
619
628
|
intersections = this.overlap();
|
|
@@ -627,14 +636,12 @@ export class WebXRController extends Behaviour {
|
|
|
627
636
|
}
|
|
628
637
|
else intersections = this.raycast();
|
|
629
638
|
|
|
639
|
+
if (debug)
|
|
640
|
+
console.log("onHandleSelectStart", "close grab? " + closeGrab, "intersections", intersections);
|
|
641
|
+
|
|
630
642
|
if (intersections && intersections.length > 0) {
|
|
631
643
|
for (const intersection of intersections) {
|
|
632
644
|
const object = intersection.object;
|
|
633
|
-
// if (!this.testIsVisible(object)) {
|
|
634
|
-
// if (debug)
|
|
635
|
-
// console.log("not visible");
|
|
636
|
-
// continue;
|
|
637
|
-
// }
|
|
638
645
|
this.lastSelectStartObject = object;
|
|
639
646
|
const args = { selected: object, grab: object };
|
|
640
647
|
const subs = WebXRController.eventSubs[ControllerEvents.SelectStart];
|
|
@@ -691,7 +698,7 @@ export class WebXRController extends Behaviour {
|
|
|
691
698
|
}
|
|
692
699
|
}
|
|
693
700
|
|
|
694
|
-
private testIsVisible(obj:
|
|
701
|
+
private testIsVisible(obj: Object3D | null): boolean {
|
|
695
702
|
if (!obj) return false;
|
|
696
703
|
if (GameObject.isActiveInHierarchy(obj) === false) return false;
|
|
697
704
|
if (UIRaycastUtils.isInteractable(obj) === false) {
|
|
@@ -702,7 +709,7 @@ export class WebXRController extends Behaviour {
|
|
|
702
709
|
// return this.testIsVisible(obj.parent);
|
|
703
710
|
}
|
|
704
711
|
|
|
705
|
-
private setControllerLayers(obj:
|
|
712
|
+
private setControllerLayers(obj: Object3D, layer: number) {
|
|
706
713
|
if (!obj) return;
|
|
707
714
|
obj.layers.set(layer);
|
|
708
715
|
if (obj.children) {
|
|
@@ -715,28 +722,43 @@ export class WebXRController extends Behaviour {
|
|
|
715
722
|
}
|
|
716
723
|
}
|
|
717
724
|
|
|
718
|
-
public getRay():
|
|
719
|
-
const ray = new
|
|
725
|
+
public getRay(): Ray {
|
|
726
|
+
const ray = new Ray();
|
|
720
727
|
// this.tempMatrix.identity().extractRotation(this.controller.matrixWorld);
|
|
721
728
|
// ray.origin.setFromMatrixPosition(this.controller.matrixWorld);
|
|
722
|
-
ray.origin.copy(
|
|
729
|
+
ray.origin.copy(getWorldPosition(this.controller));
|
|
723
730
|
ray.direction.set(0, 0, -1).applyQuaternion(this.rayRotation);
|
|
724
731
|
return ray;
|
|
725
732
|
}
|
|
726
733
|
|
|
727
|
-
|
|
734
|
+
private closeGrabBoundingBoxHelper?: BoxHelper;
|
|
735
|
+
|
|
736
|
+
public overlap(): Intersection[] {
|
|
728
737
|
const overlapCenter = (this.isUsingHands && this.handPointerModel) ? this.handPointerModel.pointerObject : this.controllerGrip;
|
|
738
|
+
|
|
739
|
+
if (debug) {
|
|
740
|
+
if (!this.closeGrabBoundingBoxHelper && overlapCenter) {
|
|
741
|
+
this.closeGrabBoundingBoxHelper = new BoxHelper( overlapCenter, 0xffff00 );
|
|
742
|
+
this.scene.add(this.closeGrabBoundingBoxHelper);
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
if (this.closeGrabBoundingBoxHelper && overlapCenter) {
|
|
746
|
+
this.closeGrabBoundingBoxHelper.setFromObject(overlapCenter);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
729
750
|
if (!overlapCenter)
|
|
730
|
-
return new Array<
|
|
751
|
+
return new Array<Intersection>();
|
|
731
752
|
|
|
732
|
-
const wp =
|
|
753
|
+
const wp = getWorldPosition(overlapCenter).clone();
|
|
733
754
|
return this.context.physics.sphereOverlap(wp, .02);
|
|
734
755
|
}
|
|
735
756
|
|
|
736
|
-
public raycast():
|
|
757
|
+
public raycast(): Intersection[] {
|
|
737
758
|
const opts = new RaycastOptions();
|
|
738
|
-
opts.layerMask = new
|
|
759
|
+
opts.layerMask = new Layers();
|
|
739
760
|
opts.layerMask.set(0);
|
|
761
|
+
opts.layerMask.disable(2);
|
|
740
762
|
opts.ray = this.getRay();
|
|
741
763
|
const hits = this.context.physics.raycast(opts);
|
|
742
764
|
for (let i = 0; i < hits.length; i++) {
|
|
@@ -795,7 +817,7 @@ export class AttachedObject {
|
|
|
795
817
|
}
|
|
796
818
|
}
|
|
797
819
|
|
|
798
|
-
public static TryTake(controller: WebXRController, candidate:
|
|
820
|
+
public static TryTake(controller: WebXRController, candidate: Object3D, intersection: Intersection, closeGrab: boolean): AttachedObject | null {
|
|
799
821
|
const interactable = GameObject.getComponentInParent(candidate, Interactable);
|
|
800
822
|
if (!interactable) {
|
|
801
823
|
if (debug)
|
|
@@ -828,24 +850,24 @@ export class AttachedObject {
|
|
|
828
850
|
|
|
829
851
|
|
|
830
852
|
public sync: SyncedTransform | null = null;
|
|
831
|
-
public selected:
|
|
832
|
-
public selectedParent:
|
|
833
|
-
public selectedMesh:
|
|
853
|
+
public selected: Object3D | null = null;
|
|
854
|
+
public selectedParent: Object3D | null = null;
|
|
855
|
+
public selectedMesh: Mesh | null = null;
|
|
834
856
|
public controller: WebXRController | null = null;
|
|
835
857
|
public grabTime: number = 0;
|
|
836
858
|
public grabUUID: string = "";
|
|
837
859
|
public isCloseGrab: boolean = false; // when taken via sphere cast with hands
|
|
838
860
|
|
|
839
|
-
private originalMaterial:
|
|
861
|
+
private originalMaterial: Material | Material[] | null = null;
|
|
840
862
|
private usageMarker: UsageMarker | null = null;
|
|
841
863
|
private rigidbodies: Rigidbody[] | null = null;
|
|
842
864
|
private didReparent: boolean = false;
|
|
843
865
|
private grabDistance: number = 0;
|
|
844
866
|
private interactable: Interactable | null = null;
|
|
845
|
-
private positionSource:
|
|
867
|
+
private positionSource: Object3D | null = null;
|
|
846
868
|
|
|
847
|
-
private Take(controller: WebXRController, take:
|
|
848
|
-
intersection:
|
|
869
|
+
private Take(controller: WebXRController, take: Object3D, hit: Object3D, sync: SyncedTransform | null, _interactable: Interactable,
|
|
870
|
+
intersection: Intersection, closeGrab: boolean)
|
|
849
871
|
: AttachedObject {
|
|
850
872
|
console.assert(take !== null, "Expected object to be taken but was", take);
|
|
851
873
|
|
|
@@ -864,11 +886,11 @@ export class AttachedObject {
|
|
|
864
886
|
AttachedObject.Events.WillTake?.forEach(x => x(this, args));
|
|
865
887
|
|
|
866
888
|
|
|
867
|
-
const mesh = hit as
|
|
889
|
+
const mesh = hit as Mesh;
|
|
868
890
|
if (mesh?.material) {
|
|
869
891
|
this.originalMaterial = mesh.material;
|
|
870
892
|
if (!Array.isArray(mesh.material)) {
|
|
871
|
-
mesh.material = (mesh.material as
|
|
893
|
+
mesh.material = (mesh.material as Material).clone();
|
|
872
894
|
if (mesh.material && mesh.material["emissive"])
|
|
873
895
|
mesh.material["emissive"].b = .2;
|
|
874
896
|
}
|
|
@@ -895,7 +917,7 @@ export class AttachedObject {
|
|
|
895
917
|
this.grabUUID = Date.now().toString();
|
|
896
918
|
this.usageMarker = GameObject.addNewComponent(this.selected, UsageMarker);
|
|
897
919
|
this.rigidbodies = GameObject.getComponentsInChildren(this.selected, Rigidbody);
|
|
898
|
-
|
|
920
|
+
getWorldPosition(this.positionSource, this.lastControllerWorldPos);
|
|
899
921
|
const getGrabPoint = () => closeGrab ? this.lastControllerWorldPos.clone() : intersection.point.clone();
|
|
900
922
|
this.grabDistance = getGrabPoint().distanceTo(this.lastControllerWorldPos);
|
|
901
923
|
this.totalChangeAlongDirection = 0.0;
|
|
@@ -904,11 +926,11 @@ export class AttachedObject {
|
|
|
904
926
|
// we're storing rotation relative to the ray
|
|
905
927
|
this.localPositionOffsetToGrab = this.selected.worldToLocal(getGrabPoint());
|
|
906
928
|
const rot = controller.isUsingHands && closeGrab ? this.controller.getWristQuaternion()!.clone() : controller.rayRotation.clone();
|
|
907
|
-
|
|
929
|
+
getWorldQuaternion(this.selected, this.localQuaternionToGrab).premultiply(rot.invert());
|
|
908
930
|
|
|
909
931
|
const rig = this.controller.webXR.Rig;
|
|
910
932
|
if (rig)
|
|
911
|
-
this.rigPositionLastFrame.copy(
|
|
933
|
+
this.rigPositionLastFrame.copy(getWorldPosition(rig))
|
|
912
934
|
|
|
913
935
|
Avatar_POI.Add(controller.context, this.selected);
|
|
914
936
|
AttachedObject.Register(this);
|
|
@@ -975,20 +997,20 @@ export class AttachedObject {
|
|
|
975
997
|
AttachedObject.Events.DidFree?.forEach(x => x(this, args));
|
|
976
998
|
}
|
|
977
999
|
|
|
978
|
-
public grabPoint:
|
|
1000
|
+
public grabPoint: Vector3 = new Vector3();
|
|
979
1001
|
|
|
980
|
-
private localPositionOffsetToGrab:
|
|
981
|
-
private localPositionOffsetToGrab_worldSpace:
|
|
982
|
-
private localQuaternionToGrab:
|
|
983
|
-
private targetDir:
|
|
984
|
-
private quaternionLerp:
|
|
1002
|
+
private localPositionOffsetToGrab: Vector3 | null = null;
|
|
1003
|
+
private localPositionOffsetToGrab_worldSpace: Vector3 = new Vector3();
|
|
1004
|
+
private localQuaternionToGrab: Quaternion = new Quaternion(0, 0, 0, 1);
|
|
1005
|
+
private targetDir: Vector3 | null = null;
|
|
1006
|
+
private quaternionLerp: Quaternion | null = null;
|
|
985
1007
|
|
|
986
|
-
private controllerDir = new
|
|
987
|
-
private controllerWorldPos = new
|
|
988
|
-
private lastControllerWorldPos = new
|
|
989
|
-
private controllerPosDelta = new
|
|
1008
|
+
private controllerDir = new Vector3();
|
|
1009
|
+
private controllerWorldPos = new Vector3();
|
|
1010
|
+
private lastControllerWorldPos = new Vector3();
|
|
1011
|
+
private controllerPosDelta = new Vector3();
|
|
990
1012
|
private totalChangeAlongDirection = 0.0;
|
|
991
|
-
private rigPositionLastFrame = new
|
|
1013
|
+
private rigPositionLastFrame = new Vector3();
|
|
992
1014
|
|
|
993
1015
|
private controllerMovementSinceLastFrame() {
|
|
994
1016
|
if (!this.positionSource || !this.controller) return 0.0;
|
|
@@ -998,13 +1020,13 @@ export class AttachedObject {
|
|
|
998
1020
|
this.controllerDir.applyQuaternion(this.controller.rayRotation);
|
|
999
1021
|
|
|
1000
1022
|
// controller delta
|
|
1001
|
-
|
|
1023
|
+
getWorldPosition(this.positionSource, this.controllerWorldPos);
|
|
1002
1024
|
this.controllerPosDelta.copy(this.controllerWorldPos);
|
|
1003
1025
|
this.controllerPosDelta.sub(this.lastControllerWorldPos);
|
|
1004
1026
|
this.lastControllerWorldPos.copy(this.controllerWorldPos);
|
|
1005
1027
|
const rig = this.controller.webXR.Rig;
|
|
1006
1028
|
if (rig) {
|
|
1007
|
-
const rigPos =
|
|
1029
|
+
const rigPos = getWorldPosition(rig);
|
|
1008
1030
|
const rigDelta = this.rigPositionLastFrame.sub(rigPos);
|
|
1009
1031
|
this.controllerPosDelta.add(rigDelta);
|
|
1010
1032
|
this.rigPositionLastFrame.copy(rigPos);
|
|
@@ -1052,7 +1074,7 @@ export class AttachedObject {
|
|
|
1052
1074
|
if (this.grabDistance / rigScale < 0.8) currentDist = 1.0; // don't accelerate if this is a close grab, want full control
|
|
1053
1075
|
|
|
1054
1076
|
if (!this.targetDir) {
|
|
1055
|
-
this.targetDir = new
|
|
1077
|
+
this.targetDir = new Vector3();
|
|
1056
1078
|
}
|
|
1057
1079
|
this.targetDir.set(0, 0, -this.grabDistance * currentDist);
|
|
1058
1080
|
const target = this.targetDir.applyQuaternion(this.controller.rayRotation).add(this.controllerWorldPos);
|
|
@@ -1063,7 +1085,7 @@ export class AttachedObject {
|
|
|
1063
1085
|
this.quaternionLerp = targetQuat.clone();
|
|
1064
1086
|
}
|
|
1065
1087
|
this.quaternionLerp.slerp(targetQuat, this.controller.useSmoothing ? this.controller.context.time.deltaTime / .03 : 1.0);
|
|
1066
|
-
|
|
1088
|
+
setWorldQuaternion(this.selected, this.quaternionLerp);
|
|
1067
1089
|
this.selected.updateWorldMatrix(false, false); // necessary so that rotation is correct for the following position update
|
|
1068
1090
|
|
|
1069
1091
|
// apply position
|
|
@@ -1071,10 +1093,10 @@ export class AttachedObject {
|
|
|
1071
1093
|
// apply local grab offset
|
|
1072
1094
|
if (this.localPositionOffsetToGrab) {
|
|
1073
1095
|
this.localPositionOffsetToGrab_worldSpace.copy(this.localPositionOffsetToGrab);
|
|
1074
|
-
this.selected.localToWorld(this.localPositionOffsetToGrab_worldSpace).sub(
|
|
1096
|
+
this.selected.localToWorld(this.localPositionOffsetToGrab_worldSpace).sub(getWorldPosition(this.selected));
|
|
1075
1097
|
target.sub(this.localPositionOffsetToGrab_worldSpace);
|
|
1076
1098
|
}
|
|
1077
|
-
|
|
1099
|
+
setWorldPosition(this.selected, target);
|
|
1078
1100
|
}
|
|
1079
1101
|
|
|
1080
1102
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getWorldPosition, setWorldPosition, setWorldPositionXYZ } from "../engine/engine_three_utils";
|
|
2
2
|
import { Behaviour, GameObject } from "./Component";
|
|
3
3
|
import { AttachedObject, AttachedObjectEvents } from "./WebXRController";
|
|
4
|
-
import
|
|
4
|
+
import { Object3D, Vector3 } from "three";
|
|
5
5
|
import { PlayerColor } from "./PlayerColor";
|
|
6
6
|
import { Context } from "../engine/engine_setup";
|
|
7
7
|
import { IModel, SendQueue } from "../engine/engine_networking_types";
|
|
@@ -20,7 +20,7 @@ export class XRGrabModel implements IModel {
|
|
|
20
20
|
source: { x: number, y: number, z: number } = { x: 0, y: 0, z: 0 };
|
|
21
21
|
target: string | undefined;
|
|
22
22
|
|
|
23
|
-
update(context : Context, point:
|
|
23
|
+
update(context : Context, point: Vector3, source: Vector3, target: string | undefined = undefined) {
|
|
24
24
|
this.userId = context.connection.connectionId;
|
|
25
25
|
this.point.x = point.x;
|
|
26
26
|
this.point.y = point.y;
|
|
@@ -34,14 +34,14 @@ export class XRGrabModel implements IModel {
|
|
|
34
34
|
|
|
35
35
|
// sends grab info to other users and creates rendering instances
|
|
36
36
|
export class XRGrabRendering extends Behaviour {
|
|
37
|
-
prefab:
|
|
37
|
+
prefab: Object3D | null = null;
|
|
38
38
|
|
|
39
39
|
private _grabModels: Array<XRGrabModel> = [];
|
|
40
40
|
private _grabModelsUpdateTime: Array<number> = [];
|
|
41
41
|
private _addOrUpdateSub: Function | null = null;
|
|
42
42
|
private _endSub: Function | null = null;
|
|
43
43
|
private _freeSub: Function | null = null;
|
|
44
|
-
private _instances: { [key: string]: {instance:
|
|
44
|
+
private _instances: { [key: string]: {instance:Object3D, model:XRGrabModel} } = {};
|
|
45
45
|
|
|
46
46
|
awake(): void {
|
|
47
47
|
if(this.prefab) this.prefab.visible = false;
|
|
@@ -72,7 +72,7 @@ export class XRGrabRendering extends Behaviour {
|
|
|
72
72
|
const inst = this._instances[data.guid];
|
|
73
73
|
if(!inst)
|
|
74
74
|
{
|
|
75
|
-
const instance = GameObject.instantiate(this.prefab) as
|
|
75
|
+
const instance = GameObject.instantiate(this.prefab) as Object3D;
|
|
76
76
|
instance.visible = true;
|
|
77
77
|
this._instances[data.guid] = {instance, model:data};
|
|
78
78
|
if(data.userId){
|
|
@@ -135,7 +135,7 @@ export class XRGrabRendering extends Behaviour {
|
|
|
135
135
|
model.update(this.context, att.grabPoint, att.controller.worldPosition, targetObject);
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
private temp :
|
|
138
|
+
private temp : Vector3 = new Vector3();
|
|
139
139
|
private updateRendering() {
|
|
140
140
|
const step = this.context.time.deltaTime / .5;
|
|
141
141
|
for(const key in this._instances){
|