@needle-tools/engine 2.28.0-pre → 2.30.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 +232 -139
- package/dist/needle-engine.js +349 -345
- package/dist/needle-engine.js.map +4 -4
- package/dist/needle-engine.min.js +24 -20
- package/dist/needle-engine.min.js.map +4 -4
- package/lib/engine/engine.d.ts +1 -0
- package/lib/engine/engine_input.d.ts +13 -1
- package/lib/engine/engine_input.js +47 -16
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_physics.d.ts +1 -0
- package/lib/engine/engine_physics.js +2 -1
- package/lib/engine/engine_physics.js.map +1 -1
- package/lib/engine/engine_playerview.d.ts +26 -0
- package/lib/engine/engine_playerview.js +65 -0
- package/lib/engine/engine_playerview.js.map +1 -0
- package/lib/engine/engine_serialization.d.ts +1 -0
- package/lib/engine/engine_serialization.js +1 -0
- package/lib/engine/engine_serialization.js.map +1 -1
- package/lib/engine/engine_serialization_core.js +5 -0
- package/lib/engine/engine_serialization_core.js.map +1 -1
- package/lib/engine/engine_setup.d.ts +8 -0
- package/lib/engine/engine_setup.js +23 -0
- package/lib/engine/engine_setup.js.map +1 -1
- package/lib/engine/engine_utils.d.ts +1 -1
- package/lib/engine/engine_utils.js +25 -8
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_deferred_texture.d.ts +1 -1
- package/lib/engine/extensions/NEEDLE_deferred_texture.js +26 -14
- package/lib/engine/extensions/NEEDLE_deferred_texture.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_lighting_settings.js +6 -2
- package/lib/engine/extensions/NEEDLE_lighting_settings.js.map +1 -1
- package/lib/engine/extensions/extension_utils.js +24 -13
- package/lib/engine/extensions/extension_utils.js.map +1 -1
- package/lib/engine/extensions/extensions.js +3 -1
- package/lib/engine/extensions/extensions.js.map +1 -1
- package/lib/engine-components/Camera.js +7 -0
- package/lib/engine-components/Camera.js.map +1 -1
- package/lib/engine-components/Component.d.ts +1 -1
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/Light.js +1 -0
- package/lib/engine-components/Light.js.map +1 -1
- package/lib/engine-components/OrbitControls.js +3 -3
- package/lib/engine-components/OrbitControls.js.map +1 -1
- package/lib/engine-components/ParticleSystem.d.ts +0 -1
- package/lib/engine-components/ParticleSystem.js +24 -27
- package/lib/engine-components/ParticleSystem.js.map +1 -1
- package/lib/engine-components/PlayerColor.js +1 -2
- package/lib/engine-components/PlayerColor.js.map +1 -1
- package/lib/engine-components/Renderer.d.ts +1 -0
- package/lib/engine-components/Renderer.js +10 -3
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/ScreenCapture.d.ts +1 -0
- package/lib/engine-components/ScreenCapture.js +265 -1
- package/lib/engine-components/ScreenCapture.js.map +1 -1
- package/lib/engine-components/SpectatorCamera.d.ts +24 -17
- package/lib/engine-components/SpectatorCamera.js +435 -182
- package/lib/engine-components/SpectatorCamera.js.map +1 -1
- package/lib/engine-components/SyncedCamera.d.ts +8 -4
- package/lib/engine-components/SyncedCamera.js +15 -18
- package/lib/engine-components/SyncedCamera.js.map +1 -1
- package/lib/engine-components/SyncedRoom.js +2 -0
- package/lib/engine-components/SyncedRoom.js.map +1 -1
- package/lib/engine-components/VideoPlayer.d.ts +10 -1
- package/lib/engine-components/VideoPlayer.js +64 -15
- package/lib/engine-components/VideoPlayer.js.map +1 -1
- package/lib/engine-components/Volume.d.ts +4 -0
- package/lib/engine-components/Volume.js +44 -3
- package/lib/engine-components/Volume.js.map +1 -1
- package/lib/engine-components/WebARSessionRoot.d.ts +9 -2
- package/lib/engine-components/WebARSessionRoot.js +69 -24
- package/lib/engine-components/WebARSessionRoot.js.map +1 -1
- package/lib/engine-components/WebXR.d.ts +6 -3
- package/lib/engine-components/WebXR.js +43 -7
- package/lib/engine-components/WebXR.js.map +1 -1
- package/lib/engine-components/WebXRAvatar.d.ts +3 -0
- package/lib/engine-components/WebXRAvatar.js +20 -0
- package/lib/engine-components/WebXRAvatar.js.map +1 -1
- package/lib/engine-components/WebXRController.js +14 -8
- package/lib/engine-components/WebXRController.js.map +1 -1
- package/lib/engine-components/WebXRSync.js +3 -3
- package/lib/engine-components/WebXRSync.js.map +1 -1
- package/lib/engine-components/XRFlag.d.ts +2 -1
- package/lib/engine-components/XRFlag.js +1 -0
- package/lib/engine-components/XRFlag.js.map +1 -1
- package/lib/engine-components/ui/CanvasGroup.d.ts +1 -0
- package/lib/engine-components/ui/CanvasGroup.js +1 -0
- package/lib/engine-components/ui/CanvasGroup.js.map +1 -1
- package/lib/engine-components/ui/EventSystem.js +13 -4
- package/lib/engine-components/ui/EventSystem.js.map +1 -1
- package/lib/engine-components/ui/Graphic.d.ts +1 -0
- package/lib/engine-components/ui/Graphic.js +2 -0
- package/lib/engine-components/ui/Graphic.js.map +1 -1
- package/lib/engine-components/ui/Interfaces.d.ts +2 -0
- package/package.json +2 -2
- package/src/engine/engine_components.js +16 -0
- package/src/engine/engine_input.ts +62 -20
- package/src/engine/engine_physics.ts +2 -1
- package/src/engine/engine_playerview.ts +80 -0
- package/src/engine/engine_serialization.ts +3 -1
- package/src/engine/engine_serialization_core.ts +8 -0
- package/src/engine/engine_setup.ts +24 -0
- package/src/engine/engine_utils.ts +34 -8
- package/src/engine/extensions/NEEDLE_deferred_texture.ts +25 -19
- package/src/engine/extensions/NEEDLE_lighting_settings.ts +4 -2
- package/src/engine/extensions/extension_utils.ts +24 -12
- package/src/engine/extensions/extensions.ts +3 -2
- package/src/engine-components/Camera.ts +9 -1
- package/src/engine-components/Component.ts +1 -1
- package/src/engine-components/Light.ts +3 -0
- package/src/engine-components/OrbitControls.ts +3 -3
- package/src/engine-components/ParticleSystem.ts +25 -26
- package/src/engine-components/PlayerColor.ts +1 -1
- package/src/engine-components/Renderer.ts +11 -3
- package/src/engine-components/ScreenCapture.ts +312 -2
- package/src/engine-components/SpectatorCamera.ts +490 -195
- package/src/engine-components/SyncedCamera.ts +23 -22
- package/src/engine-components/SyncedRoom.ts +1 -0
- package/src/engine-components/VideoPlayer.ts +97 -21
- package/src/engine-components/Volume.ts +47 -4
- package/src/engine-components/WebARSessionRoot.ts +78 -28
- package/src/engine-components/WebXR.ts +51 -15
- package/src/engine-components/WebXRAvatar.ts +27 -2
- package/src/engine-components/WebXRController.ts +21 -15
- package/src/engine-components/WebXRSync.ts +3 -3
- package/src/engine-components/XRFlag.ts +1 -0
- package/src/engine-components/ui/CanvasGroup.ts +2 -0
- package/src/engine-components/ui/EventSystem.ts +21 -15
- package/src/engine-components/ui/Graphic.ts +3 -0
- package/src/engine-components/ui/Interfaces.ts +2 -0
|
@@ -12,6 +12,7 @@ import { serializeable } from "../engine/engine_serialization_decorator";
|
|
|
12
12
|
import { Object3D } from "three";
|
|
13
13
|
import { AvatarMarker } from "./WebXRAvatar";
|
|
14
14
|
import { AssetReference } from "../engine/engine_addressables";
|
|
15
|
+
import { ViewDevice } from "../engine/engine_playerview";
|
|
15
16
|
|
|
16
17
|
const SyncedCameraModelIdentifier = "SCAM";
|
|
17
18
|
registerType(SyncedCameraModelIdentifier, SyncedCameraModel.getRootAsSyncedCameraModel);
|
|
@@ -33,8 +34,7 @@ class CameraModel {
|
|
|
33
34
|
this.userId = connectionId;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
send(
|
|
37
|
-
const cam = sync.cam?.cam;
|
|
37
|
+
send(cam: THREE.Camera | null | undefined, con: NetworkConnection) {
|
|
38
38
|
if (cam) {
|
|
39
39
|
builder.clear();
|
|
40
40
|
const guid = builder.createString(this.guid);
|
|
@@ -53,23 +53,22 @@ class CameraModel {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
declare type UserCamInfo =
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
};
|
|
56
|
+
declare type UserCamInfo = {
|
|
57
|
+
obj: THREE.Object3D,
|
|
58
|
+
lastUpdate: number;
|
|
59
|
+
userId: string;
|
|
60
|
+
};
|
|
62
61
|
|
|
63
62
|
export class SyncedCamera extends Behaviour {
|
|
64
63
|
|
|
65
|
-
|
|
64
|
+
static instances: UserCamInfo[] = [];
|
|
65
|
+
|
|
66
|
+
getCameraObject(userId: string): THREE.Object3D | null {
|
|
66
67
|
const guid = this.userToCamMap[userId];
|
|
67
68
|
if (!guid) return null;
|
|
68
69
|
return this.remoteCams[guid].obj;
|
|
69
70
|
}
|
|
70
71
|
|
|
71
|
-
@serializeable(Camera)
|
|
72
|
-
public cam: Camera | null = null;
|
|
73
72
|
@serializeable([Object3D, AssetReference])
|
|
74
73
|
public cameraPrefab: THREE.Object3D | null | AssetReference = null;
|
|
75
74
|
|
|
@@ -97,15 +96,8 @@ export class SyncedCamera extends Behaviour {
|
|
|
97
96
|
if (this.cameraPrefab && "isObject3D" in this.cameraPrefab) {
|
|
98
97
|
this.cameraPrefab.visible = false;
|
|
99
98
|
}
|
|
100
|
-
|
|
101
99
|
}
|
|
102
|
-
}
|
|
103
100
|
|
|
104
|
-
start() {
|
|
105
|
-
if (!this.cam) {
|
|
106
|
-
console.warn("Missing camera, fallback to main camera", this);
|
|
107
|
-
this.cam = this.context.mainCameraComponent as Camera ?? null;
|
|
108
|
-
}
|
|
109
101
|
}
|
|
110
102
|
|
|
111
103
|
onEnable(): void {
|
|
@@ -129,13 +121,17 @@ export class SyncedCamera extends Behaviour {
|
|
|
129
121
|
delete this.remoteCams[guid];
|
|
130
122
|
if (cam)
|
|
131
123
|
delete this.userToCamMap[cam.userId];
|
|
124
|
+
|
|
125
|
+
SyncedCamera.instances.push(cam);
|
|
126
|
+
this.context.players.removePlayerView(cam.userId, ViewDevice.Browser);
|
|
132
127
|
continue;
|
|
133
128
|
}
|
|
134
129
|
}
|
|
135
130
|
|
|
136
131
|
if (WebXR.IsInWebXR) return;
|
|
137
132
|
|
|
138
|
-
|
|
133
|
+
const cam = this.context.mainCamera
|
|
134
|
+
if (cam === null) {
|
|
139
135
|
this.enabled = false;
|
|
140
136
|
return;
|
|
141
137
|
}
|
|
@@ -146,8 +142,8 @@ export class SyncedCamera extends Behaviour {
|
|
|
146
142
|
this._model = new CameraModel(this.context.connection.connectionId, this.context.connection.connectionId + "_camera");
|
|
147
143
|
}
|
|
148
144
|
|
|
149
|
-
const wp = utils.getWorldPosition(
|
|
150
|
-
const wq = utils.getWorldQuaternion(
|
|
145
|
+
const wp = utils.getWorldPosition(cam);
|
|
146
|
+
const wq = utils.getWorldQuaternion(cam);
|
|
151
147
|
if (wp.distanceTo(this._lastWorldPosition) > 0.001 || wq.angleTo(this._lastWorldQuaternion) > 0.01) {
|
|
152
148
|
this._needsUpdate = true;
|
|
153
149
|
}
|
|
@@ -163,7 +159,9 @@ export class SyncedCamera extends Behaviour {
|
|
|
163
159
|
|
|
164
160
|
this._lastUpdateTime = this.context.time.realtimeSinceStartup;
|
|
165
161
|
this._needsUpdate = false;
|
|
166
|
-
this._model.send(
|
|
162
|
+
this._model.send(cam, this.context.connection);
|
|
163
|
+
if (!this.context.isInXR)
|
|
164
|
+
this.context.players.setPlayerView(this.context.connection.connectionId, cam, ViewDevice.Browser);
|
|
167
165
|
}
|
|
168
166
|
|
|
169
167
|
private onReceivedRemoteCameraInfoBin(model: SyncedCameraModel) {
|
|
@@ -183,10 +181,12 @@ export class SyncedCamera extends Behaviour {
|
|
|
183
181
|
rc.obj.visible = true;
|
|
184
182
|
this.gameObject.add(instance);
|
|
185
183
|
this.userToCamMap[userId] = guid;
|
|
184
|
+
SyncedCamera.instances.push(rc);
|
|
186
185
|
|
|
187
186
|
const marker = GameObject.getOrAddComponent(instance, AvatarMarker);
|
|
188
187
|
marker.connectionId = userId;
|
|
189
188
|
marker.avatar = instance;
|
|
189
|
+
|
|
190
190
|
}
|
|
191
191
|
else {
|
|
192
192
|
return;
|
|
@@ -194,6 +194,7 @@ export class SyncedCamera extends Behaviour {
|
|
|
194
194
|
// console.log(this.remoteCams);
|
|
195
195
|
}
|
|
196
196
|
const obj = rc.obj;
|
|
197
|
+
this.context.players.setPlayerView(userId, obj, ViewDevice.Browser);
|
|
197
198
|
rc.lastUpdate = this.context.time.realtimeSinceStartup;
|
|
198
199
|
InstancingUtil.markDirty(obj);
|
|
199
200
|
const pos = model.pos();
|
|
@@ -2,9 +2,10 @@ import { Behaviour } from "./Component";
|
|
|
2
2
|
import * as THREE from "three";
|
|
3
3
|
import { Material } from "material/Material";
|
|
4
4
|
import { serializeable } from "../engine/engine_serialization_decorator";
|
|
5
|
-
import { Object3D } from "three";
|
|
5
|
+
import { LinearFilter, Object3D, Texture } from "three";
|
|
6
6
|
import { awaitInput } from "../engine/engine_input_utils";
|
|
7
7
|
import { getParam } from "../engine/engine_utils";
|
|
8
|
+
import { Renderer } from "./Renderer";
|
|
8
9
|
|
|
9
10
|
const debug = getParam("debugvideo");
|
|
10
11
|
|
|
@@ -20,22 +21,17 @@ export enum VideoSource {
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export enum VideoAudioOutputMode {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Direct,
|
|
35
|
-
/// <summary>
|
|
36
|
-
/// <para>Send the embedded audio to the associated AudioSampleProvider.</para>
|
|
37
|
-
/// </summary>
|
|
38
|
-
APIOnly,
|
|
24
|
+
None = 0,
|
|
25
|
+
AudioSource = 1,
|
|
26
|
+
Direct = 2,
|
|
27
|
+
APIOnly = 3,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export enum VideoRenderMode {
|
|
31
|
+
CameraFarPlane = 0,
|
|
32
|
+
CameraNearPlane = 1,
|
|
33
|
+
RenderTexture = 2,
|
|
34
|
+
MaterialOverride = 3,
|
|
39
35
|
}
|
|
40
36
|
|
|
41
37
|
export class VideoPlayer extends Behaviour {
|
|
@@ -48,7 +44,16 @@ export class VideoPlayer extends Behaviour {
|
|
|
48
44
|
playOnEnable?: boolean;
|
|
49
45
|
|
|
50
46
|
@serializeable()
|
|
51
|
-
|
|
47
|
+
private renderMode?: VideoRenderMode;
|
|
48
|
+
|
|
49
|
+
@serializeable()
|
|
50
|
+
private targetMaterialProperty?: string;
|
|
51
|
+
|
|
52
|
+
@serializeable(Renderer)
|
|
53
|
+
private targetMaterialRenderer?: Renderer;
|
|
54
|
+
|
|
55
|
+
@serializeable(Texture)
|
|
56
|
+
private targetTexture?: Texture;
|
|
52
57
|
|
|
53
58
|
@serializeable()
|
|
54
59
|
private time: number = 0;
|
|
@@ -250,11 +255,26 @@ export class VideoPlayer extends Behaviour {
|
|
|
250
255
|
if (!this.enabled) return;
|
|
251
256
|
if (!this.videoElement) return;
|
|
252
257
|
|
|
253
|
-
|
|
258
|
+
let target: Object3D | undefined = this.gameObject;
|
|
259
|
+
|
|
260
|
+
switch (this.renderMode) {
|
|
261
|
+
case VideoRenderMode.MaterialOverride:
|
|
262
|
+
target = this.targetMaterialRenderer?.gameObject;
|
|
263
|
+
break;
|
|
264
|
+
case VideoRenderMode.RenderTexture:
|
|
265
|
+
console.error("VideoPlayer renderTexture not implemented yet. Please use material override instead");
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (!target) {
|
|
270
|
+
console.error("Missing target for video material renderer", this);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const mat = target["material"];
|
|
254
274
|
if (mat) {
|
|
255
275
|
if (mat !== this.videoMaterial) {
|
|
256
276
|
this.videoMaterial = mat.clone();
|
|
257
|
-
|
|
277
|
+
target["material"] = this.videoMaterial;
|
|
258
278
|
}
|
|
259
279
|
|
|
260
280
|
if (!this.targetMaterialProperty) {
|
|
@@ -305,4 +325,60 @@ export class VideoPlayer extends Behaviour {
|
|
|
305
325
|
this.videoElement.style.visibility = "hidden";
|
|
306
326
|
this.videoElement.style.display = "none";
|
|
307
327
|
}
|
|
308
|
-
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
// class VideoTexture extends Texture {
|
|
334
|
+
|
|
335
|
+
// get isVideoTexture() { return true; }
|
|
336
|
+
|
|
337
|
+
// constructor( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
|
|
338
|
+
|
|
339
|
+
// super( video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy );
|
|
340
|
+
|
|
341
|
+
// this.minFilter = minFilter !== undefined ? minFilter : LinearFilter;
|
|
342
|
+
// this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
|
|
343
|
+
|
|
344
|
+
// this.generateMipmaps = false;
|
|
345
|
+
|
|
346
|
+
// const scope = this;
|
|
347
|
+
|
|
348
|
+
// function updateVideo() {
|
|
349
|
+
|
|
350
|
+
// scope.needsUpdate = true;
|
|
351
|
+
// video.requestVideoFrameCallback( updateVideo );
|
|
352
|
+
|
|
353
|
+
// }
|
|
354
|
+
|
|
355
|
+
// if ( 'requestVideoFrameCallback' in video ) {
|
|
356
|
+
|
|
357
|
+
// video.requestVideoFrameCallback( updateVideo );
|
|
358
|
+
|
|
359
|
+
// }
|
|
360
|
+
|
|
361
|
+
// }
|
|
362
|
+
|
|
363
|
+
// // clone() {
|
|
364
|
+
|
|
365
|
+
// // return new this.constructor( this.image ).copy( this );
|
|
366
|
+
|
|
367
|
+
// // }
|
|
368
|
+
|
|
369
|
+
// update() {
|
|
370
|
+
|
|
371
|
+
// const video = this.image;
|
|
372
|
+
// const hasVideoFrameCallback = 'requestVideoFrameCallback' in video;
|
|
373
|
+
|
|
374
|
+
// if ( hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA ) {
|
|
375
|
+
|
|
376
|
+
// this.needsUpdate = true;
|
|
377
|
+
|
|
378
|
+
// }
|
|
379
|
+
|
|
380
|
+
// }
|
|
381
|
+
|
|
382
|
+
// }
|
|
383
|
+
|
|
384
|
+
// export { VideoTexture };
|
|
@@ -2,6 +2,9 @@ import { Behaviour } from "./Component";
|
|
|
2
2
|
import { NoToneMapping, LinearToneMapping, ACESFilmicToneMapping, ReinhardToneMapping } from "three";
|
|
3
3
|
import { serializeable } from "../engine/engine_serialization_decorator";
|
|
4
4
|
import { Context } from "../engine/engine_setup";
|
|
5
|
+
import { getParam } from "../engine/engine_utils";
|
|
6
|
+
|
|
7
|
+
const debug = getParam("debugvolume");
|
|
5
8
|
|
|
6
9
|
export enum TonemappingMode {
|
|
7
10
|
None = 0,
|
|
@@ -35,21 +38,41 @@ function resolveComponentType(data) {
|
|
|
35
38
|
return VolumeComponent;
|
|
36
39
|
}
|
|
37
40
|
|
|
41
|
+
const volumeKey = Symbol("volumeprofile");
|
|
42
|
+
|
|
38
43
|
export class VolumeProfile {
|
|
39
44
|
@serializeable([d => resolveComponentType(d), VolumeComponent])
|
|
40
45
|
components?: VolumeComponent[];
|
|
41
46
|
|
|
42
|
-
|
|
43
47
|
apply(context: Context) {
|
|
48
|
+
this.onUpdate(context, false);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
unapply(context: Context) {
|
|
52
|
+
this.onUpdate(context, true);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private onUpdate(context: Context, remove: boolean) {
|
|
44
56
|
if (!this.components) return;
|
|
57
|
+
const renderer = context.renderer;
|
|
58
|
+
const currentProfile = renderer[volumeKey];
|
|
59
|
+
const isActive = currentProfile !== undefined;
|
|
60
|
+
if (remove) {
|
|
61
|
+
// can not remove volume profile that is not active
|
|
62
|
+
if (!isActive) return;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
renderer[volumeKey] = this;
|
|
66
|
+
}
|
|
45
67
|
for (const component of this.components) {
|
|
46
68
|
|
|
47
69
|
if (component instanceof ToneMapping) {
|
|
48
70
|
const tonemapping = component as ToneMapping;
|
|
49
|
-
if (!component.active) {
|
|
71
|
+
if (!component.active || remove) {
|
|
50
72
|
context.renderer.toneMapping = LinearToneMapping;
|
|
51
73
|
continue;
|
|
52
74
|
}
|
|
75
|
+
if (debug) console.log("VOLUME:", TonemappingMode[tonemapping.mode?.value ?? 0]);
|
|
53
76
|
switch (tonemapping.mode?.value ?? 0) {
|
|
54
77
|
case TonemappingMode.None:
|
|
55
78
|
context.renderer.toneMapping = LinearToneMapping;
|
|
@@ -66,9 +89,11 @@ export class VolumeProfile {
|
|
|
66
89
|
const colorAdjustments = component as ColorAdjustments;
|
|
67
90
|
// unity range goes from -15..15
|
|
68
91
|
// three.js range goes from 0..inf
|
|
69
|
-
|
|
92
|
+
if (debug)
|
|
93
|
+
console.log(colorAdjustments.postExposure);
|
|
70
94
|
const exposure = Math.pow(2, colorAdjustments.postExposure?.value ?? 0);
|
|
71
|
-
|
|
95
|
+
const useExposure = colorAdjustments.postExposure?.overrideState && !remove;
|
|
96
|
+
context.renderer.toneMappingExposure = useExposure ? exposure : 1;
|
|
72
97
|
}
|
|
73
98
|
}
|
|
74
99
|
}
|
|
@@ -80,7 +105,25 @@ export class Volume extends Behaviour {
|
|
|
80
105
|
@serializeable(VolumeProfile)
|
|
81
106
|
sharedProfile?: VolumeProfile;
|
|
82
107
|
|
|
108
|
+
awake() {
|
|
109
|
+
if (debug) {
|
|
110
|
+
console.log(this);
|
|
111
|
+
console.log("Press P to toggle post processing");
|
|
112
|
+
window.addEventListener("keydown", (e) => {
|
|
113
|
+
if (e.key === "p") {
|
|
114
|
+
console.log("Toggle volume: " + this.name, !this.enabled);
|
|
115
|
+
this.enabled = !this.enabled;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
83
121
|
onEnable() {
|
|
122
|
+
if (debug) console.log("APPLY VOLUME", this)
|
|
84
123
|
this.sharedProfile?.apply(this.context);
|
|
85
124
|
}
|
|
125
|
+
|
|
126
|
+
onDisable() {
|
|
127
|
+
this.sharedProfile?.unapply(this.context);
|
|
128
|
+
}
|
|
86
129
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Behaviour } from "./Component";
|
|
1
|
+
import { Behaviour, GameObject } from "./Component";
|
|
2
2
|
import * as THREE from 'three'
|
|
3
|
-
import { Object3D, XRPose } from "three";
|
|
4
|
-
import { WebAR } from "./WebXR";
|
|
3
|
+
import { Matrix4, Object3D, XRPose } from "three";
|
|
4
|
+
import { WebAR, WebXR } from "./WebXR";
|
|
5
5
|
import { InstancingUtil } from "./Renderer";
|
|
6
6
|
import { serializeable } from "../engine/engine_serialization_decorator";
|
|
7
7
|
|
|
@@ -11,6 +11,10 @@ export class WebARSessionRoot extends Behaviour {
|
|
|
11
11
|
|
|
12
12
|
webAR: WebAR | null = null;
|
|
13
13
|
|
|
14
|
+
get rig(): THREE.Object3D | undefined {
|
|
15
|
+
return this.webAR?.webxr.Rig;
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
@serializeable()
|
|
15
19
|
invertForward: boolean = false;
|
|
16
20
|
|
|
@@ -24,46 +28,57 @@ export class WebARSessionRoot extends Behaviour {
|
|
|
24
28
|
this.setScale(val);
|
|
25
29
|
}
|
|
26
30
|
|
|
31
|
+
private readonly _initalMatrix = new THREE.Matrix4();
|
|
32
|
+
private readonly _selectStartFn = this.onSelectStart.bind(this);
|
|
33
|
+
private readonly _selectEndFn = this.onSelectEnd.bind(this);
|
|
34
|
+
|
|
35
|
+
start() {
|
|
36
|
+
const xr = GameObject.findObjectOfType(WebXR);
|
|
37
|
+
if (xr) {
|
|
38
|
+
xr.Rig.updateMatrix();
|
|
39
|
+
this._initalMatrix.copy(xr.Rig.matrix);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
27
43
|
private _arScale: number = 5;
|
|
28
44
|
private _rig: THREE.Object3D | null = null;
|
|
29
45
|
private _startPose: THREE.Matrix4 | null = null;
|
|
30
46
|
private _placementPose: THREE.Matrix4 | null = null;
|
|
31
47
|
private _isTouching: boolean = false;
|
|
48
|
+
private _rigStartPose: THREE.Matrix4 | undefined | null = null;
|
|
32
49
|
|
|
33
50
|
onBegin(session: THREE.XRSession) {
|
|
34
51
|
this._placementPose = null;
|
|
35
52
|
this.gameObject.visible = false;
|
|
36
53
|
this.gameObject.matrixAutoUpdate = false;
|
|
37
54
|
this._startPose = this.gameObject.matrix.clone();
|
|
38
|
-
|
|
39
|
-
session.addEventListener('
|
|
40
|
-
|
|
55
|
+
this._rigStartPose = this.rig?.matrix.clone();
|
|
56
|
+
session.addEventListener('selectstart', this._selectStartFn);
|
|
57
|
+
session.addEventListener('selectend', this._selectEndFn);
|
|
58
|
+
// setTimeout(() => this.gameObject.visible = false, 1000); // TODO test on phone AR and Hololens if this was still needed
|
|
59
|
+
|
|
60
|
+
// console.log(this.rig?.position, this.rig?.quaternion, this.rig?.scale);
|
|
61
|
+
this.gameObject.visible = false;
|
|
62
|
+
|
|
63
|
+
if (this.rig) {
|
|
64
|
+
// reset rig to initial pose, this is helping the mix of immersive AR and immersive VR that we now have on quest
|
|
65
|
+
// where the rig can be moved and scaled by the user in VR mode and we use the rig position when entering
|
|
66
|
+
// immersive Ar right now to place the user/offset the session
|
|
67
|
+
this.rig.matrixAutoUpdate = true;
|
|
68
|
+
this._initalMatrix.decompose(this.rig.position, this.rig.quaternion, this.rig.scale);
|
|
69
|
+
}
|
|
41
70
|
}
|
|
42
71
|
|
|
43
|
-
onUpdate(rig: THREE.Object3D | null, _session: THREE.XRSession, pose: XRPose | null | undefined) {
|
|
72
|
+
onUpdate(rig: THREE.Object3D | null, _session: THREE.XRSession, pose: XRPose | null | undefined): boolean {
|
|
44
73
|
|
|
45
74
|
if (pose && !this._placementPose) {
|
|
46
75
|
if (this._isTouching) {
|
|
47
76
|
if (this.webAR) this.webAR.setReticleActive(false);
|
|
48
|
-
this.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (this.invertForward) {
|
|
52
|
-
const rot = new THREE.Matrix4().makeRotationY(Math.PI);
|
|
53
|
-
this._placementPose.premultiply(rot);
|
|
54
|
-
}
|
|
55
|
-
this._rig = rig;
|
|
56
|
-
|
|
57
|
-
this.setScale(this.arScale);
|
|
58
|
-
}
|
|
59
|
-
else this._rig = null;
|
|
60
|
-
// this.gameObject.matrix.copy(this._placementPose);
|
|
61
|
-
// if (rig) {
|
|
62
|
-
// this.gameObject.matrix.premultiply(rig.matrixWorld)
|
|
63
|
-
// }
|
|
64
|
-
this.gameObject.visible = true;
|
|
77
|
+
this.placeAt(rig, new THREE.Matrix4().fromArray(pose.transform.matrix).invert());
|
|
78
|
+
return true;
|
|
65
79
|
}
|
|
66
80
|
}
|
|
81
|
+
return false;
|
|
67
82
|
|
|
68
83
|
// if (this._placementPose) {
|
|
69
84
|
// this.gameObject.matrixAutoUpdate = false;
|
|
@@ -75,16 +90,47 @@ export class WebARSessionRoot extends Behaviour {
|
|
|
75
90
|
// }
|
|
76
91
|
}
|
|
77
92
|
|
|
93
|
+
placeAt(rig: THREE.Object3D | null, mat: Matrix4) {
|
|
94
|
+
if (!this._placementPose) this._placementPose = new THREE.Matrix4();
|
|
95
|
+
this._placementPose.copy(mat);
|
|
96
|
+
if (rig) {
|
|
97
|
+
|
|
98
|
+
if (this.invertForward) {
|
|
99
|
+
const rot = new THREE.Matrix4().makeRotationY(Math.PI);
|
|
100
|
+
this._placementPose.premultiply(rot);
|
|
101
|
+
}
|
|
102
|
+
this._rig = rig;
|
|
103
|
+
|
|
104
|
+
this.setScale(this.arScale);
|
|
105
|
+
}
|
|
106
|
+
else this._rig = null;
|
|
107
|
+
// this.gameObject.matrix.copy(this._placementPose);
|
|
108
|
+
// if (rig) {
|
|
109
|
+
// this.gameObject.matrix.premultiply(rig.matrixWorld)
|
|
110
|
+
// }
|
|
111
|
+
this.gameObject.visible = true;
|
|
112
|
+
}
|
|
113
|
+
|
|
78
114
|
onEnd(rig: THREE.Object3D | null, _session: THREE.XRSession) {
|
|
79
115
|
this._placementPose = null;
|
|
80
116
|
this.gameObject.visible = false;
|
|
81
|
-
|
|
117
|
+
this.gameObject.matrixAutoUpdate = false;
|
|
118
|
+
if (this._startPose) {
|
|
82
119
|
this.gameObject.matrix.copy(this._startPose);
|
|
83
|
-
|
|
84
|
-
if (rig)
|
|
120
|
+
}
|
|
121
|
+
if (rig) {
|
|
122
|
+
rig.matrixAutoUpdate = true;
|
|
123
|
+
if (this._rigStartPose) {
|
|
124
|
+
this._rigStartPose.decompose(rig.position, rig.quaternion, rig.scale);
|
|
125
|
+
// console.log(rig.position, rig.quaternion, rig.scale);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
85
128
|
InstancingUtil.markDirty(this.gameObject, true);
|
|
86
129
|
// HACK to fix physics being not in correct place after exiting AR
|
|
87
|
-
setTimeout(() =>
|
|
130
|
+
setTimeout(() => {
|
|
131
|
+
this.gameObject.matrixAutoUpdate = true;
|
|
132
|
+
this.gameObject.visible = true;
|
|
133
|
+
}, 100);
|
|
88
134
|
}
|
|
89
135
|
|
|
90
136
|
|
|
@@ -101,9 +147,13 @@ export class WebARSessionRoot extends Behaviour {
|
|
|
101
147
|
if (!rig || !this._placementPose) {
|
|
102
148
|
return;
|
|
103
149
|
}
|
|
150
|
+
if (!this._rigStartPose) {
|
|
151
|
+
this._rigStartPose = rig.matrix.clone();
|
|
152
|
+
}
|
|
104
153
|
rig.matrixAutoUpdate = false;
|
|
105
154
|
rig.matrix.multiplyMatrices(new THREE.Matrix4().makeScale(scale, scale, scale), this._placementPose);
|
|
106
155
|
rig.matrix.decompose(rig.position, rig.quaternion, rig.scale);
|
|
107
156
|
rig.updateMatrixWorld();
|
|
157
|
+
console.log("Place", rig.position);
|
|
108
158
|
}
|
|
109
159
|
}
|