@mml-io/3d-web-experience-client 0.15.0 → 0.17.0
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/LICENSE +19 -0
- package/build/Networked3dWebExperienceClient.d.ts +29 -5
- package/build/index.js +88 -41
- package/build/index.js.map +2 -2
- package/package.json +8 -6
package/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2023 Improbable MV Limited
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
@@ -1,11 +1,33 @@
|
|
1
|
-
import { AnimationConfig } from "@mml-io/3d-web-client-core";
|
1
|
+
import { AnimationConfig, EnvironmentConfiguration } from "@mml-io/3d-web-client-core";
|
2
|
+
type MMLDocumentConfiguration = {
|
3
|
+
url: string;
|
4
|
+
position?: {
|
5
|
+
x: number;
|
6
|
+
y: number;
|
7
|
+
z: number;
|
8
|
+
};
|
9
|
+
rotation?: {
|
10
|
+
x: number;
|
11
|
+
y: number;
|
12
|
+
z: number;
|
13
|
+
};
|
14
|
+
scale?: {
|
15
|
+
x: number;
|
16
|
+
y: number;
|
17
|
+
z: number;
|
18
|
+
};
|
19
|
+
};
|
2
20
|
export type Networked3dWebExperienceClientConfig = {
|
3
21
|
sessionToken: string;
|
4
|
-
chatNetworkAddress
|
22
|
+
chatNetworkAddress?: string;
|
23
|
+
voiceChatAddress?: string;
|
5
24
|
userNetworkAddress: string;
|
6
|
-
|
25
|
+
mmlDocuments?: Array<MMLDocumentConfiguration>;
|
7
26
|
animationConfig: AnimationConfig;
|
8
|
-
|
27
|
+
environmentConfiguration?: EnvironmentConfiguration;
|
28
|
+
skyboxHdrJpgUrl: string;
|
29
|
+
enableTweakPane?: boolean;
|
30
|
+
updateURLLocation?: boolean;
|
9
31
|
};
|
10
32
|
export declare class Networked3dWebExperienceClient {
|
11
33
|
private holderElement;
|
@@ -13,7 +35,7 @@ export declare class Networked3dWebExperienceClient {
|
|
13
35
|
private element;
|
14
36
|
private scene;
|
15
37
|
private composer;
|
16
|
-
private tweakPane
|
38
|
+
private tweakPane?;
|
17
39
|
private audioListener;
|
18
40
|
private cameraManager;
|
19
41
|
private collisionsManager;
|
@@ -31,6 +53,7 @@ export declare class Networked3dWebExperienceClient {
|
|
31
53
|
private textChatUI;
|
32
54
|
private voiceChatManager;
|
33
55
|
private readonly latestCharacterObject;
|
56
|
+
private characterControllerPaneSet;
|
34
57
|
private initialLoadCompleted;
|
35
58
|
private loadingProgressManager;
|
36
59
|
private loadingScreen;
|
@@ -45,3 +68,4 @@ export declare class Networked3dWebExperienceClient {
|
|
45
68
|
private spawnCharacter;
|
46
69
|
private setupMMLScene;
|
47
70
|
}
|
71
|
+
export {};
|
package/build/index.js
CHANGED
@@ -7,12 +7,12 @@ import {
|
|
7
7
|
Composer,
|
8
8
|
decodeCharacterAndCamera,
|
9
9
|
getSpawnPositionInsideCircle,
|
10
|
+
GroundPlane,
|
10
11
|
KeyInputManager,
|
12
|
+
LoadingScreen,
|
11
13
|
MMLCompositionScene,
|
12
14
|
TimeManager,
|
13
15
|
TweakPane,
|
14
|
-
GroundPlane,
|
15
|
-
LoadingScreen,
|
16
16
|
VirtualJoystick
|
17
17
|
} from "@mml-io/3d-web-client-core";
|
18
18
|
import { ChatNetworkingClient, TextChatUI } from "@mml-io/3d-web-text-chat";
|
@@ -46,8 +46,10 @@ var Networked3dWebExperienceClient = class {
|
|
46
46
|
this.latestCharacterObject = {
|
47
47
|
characterState: null
|
48
48
|
};
|
49
|
+
this.characterControllerPaneSet = false;
|
49
50
|
this.initialLoadCompleted = false;
|
50
51
|
this.loadingProgressManager = new LoadingProgressManager();
|
52
|
+
var _a;
|
51
53
|
this.element = document.createElement("div");
|
52
54
|
this.element.style.position = "absolute";
|
53
55
|
this.element.style.width = "100%";
|
@@ -67,16 +69,24 @@ var Networked3dWebExperienceClient = class {
|
|
67
69
|
y: 0,
|
68
70
|
mouse_support: false
|
69
71
|
});
|
70
|
-
this.composer = new Composer(
|
71
|
-
|
72
|
+
this.composer = new Composer({
|
73
|
+
scene: this.scene,
|
74
|
+
camera: this.cameraManager.camera,
|
75
|
+
spawnSun: true,
|
76
|
+
environmentConfiguration: this.config.environmentConfiguration
|
77
|
+
});
|
78
|
+
this.composer.useHDRJPG(this.config.skyboxHdrJpgUrl);
|
72
79
|
this.element.appendChild(this.composer.renderer.domElement);
|
73
|
-
this.
|
74
|
-
this.
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
+
if (this.config.enableTweakPane !== false) {
|
81
|
+
this.tweakPane = new TweakPane(
|
82
|
+
this.element,
|
83
|
+
this.composer.renderer,
|
84
|
+
this.scene,
|
85
|
+
this.composer.effectComposer
|
86
|
+
);
|
87
|
+
this.cameraManager.setupTweakPane(this.tweakPane);
|
88
|
+
this.composer.setupTweakPane(this.tweakPane);
|
89
|
+
}
|
80
90
|
const resizeObserver = new ResizeObserver(() => {
|
81
91
|
this.composer.fitContainer();
|
82
92
|
});
|
@@ -133,12 +143,15 @@ var Networked3dWebExperienceClient = class {
|
|
133
143
|
animationConfig: this.config.animationConfig,
|
134
144
|
characterResolve: (characterId) => {
|
135
145
|
return this.resolveCharacterData(characterId);
|
136
|
-
}
|
146
|
+
},
|
147
|
+
updateURLLocation: this.config.updateURLLocation !== false
|
137
148
|
});
|
138
149
|
this.scene.add(this.characterManager.group);
|
139
|
-
|
140
|
-
|
141
|
-
|
150
|
+
if (((_a = this.config.environmentConfiguration) == null ? void 0 : _a.groundPlane) !== false) {
|
151
|
+
const groundPlane = new GroundPlane();
|
152
|
+
this.collisionsManager.addMeshesGroup(groundPlane);
|
153
|
+
this.scene.add(groundPlane);
|
154
|
+
}
|
142
155
|
this.setupMMLScene();
|
143
156
|
this.loadingScreen = new LoadingScreen(this.loadingProgressManager);
|
144
157
|
document.body.append(this.loadingScreen.element);
|
@@ -188,32 +201,34 @@ var Networked3dWebExperienceClient = class {
|
|
188
201
|
connectToVoiceChat() {
|
189
202
|
if (this.clientId === null)
|
190
203
|
return;
|
191
|
-
if (this.voiceChatManager === null) {
|
192
|
-
this.voiceChatManager = new VoiceChatManager(
|
193
|
-
this.
|
194
|
-
this.
|
195
|
-
this.
|
196
|
-
this.
|
197
|
-
|
204
|
+
if (this.voiceChatManager === null && this.config.voiceChatAddress) {
|
205
|
+
this.voiceChatManager = new VoiceChatManager({
|
206
|
+
url: this.config.voiceChatAddress,
|
207
|
+
holderElement: this.element,
|
208
|
+
userId: this.clientId,
|
209
|
+
remoteUserStates: this.remoteUserStates,
|
210
|
+
latestCharacterObj: this.latestCharacterObject,
|
211
|
+
autoJoin: false
|
212
|
+
});
|
198
213
|
}
|
199
214
|
}
|
200
215
|
connectToTextChat() {
|
201
216
|
if (this.clientId === null) {
|
202
217
|
return;
|
203
218
|
}
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
this.textChatUI
|
210
|
-
this.
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
219
|
+
if (this.networkChat === null && this.config.chatNetworkAddress) {
|
220
|
+
const user = this.userProfiles.get(this.clientId);
|
221
|
+
if (!user) {
|
222
|
+
throw new Error("User not found");
|
223
|
+
}
|
224
|
+
if (this.textChatUI === null) {
|
225
|
+
this.textChatUI = new TextChatUI(
|
226
|
+
this.element,
|
227
|
+
user.username,
|
228
|
+
this.sendChatMessageToServer.bind(this)
|
229
|
+
);
|
230
|
+
this.textChatUI.init();
|
231
|
+
}
|
217
232
|
this.networkChat = new ChatNetworkingClient({
|
218
233
|
url: this.config.chatNetworkAddress,
|
219
234
|
sessionToken: this.config.sessionToken,
|
@@ -233,7 +248,7 @@ var Networked3dWebExperienceClient = class {
|
|
233
248
|
}
|
234
249
|
}
|
235
250
|
update() {
|
236
|
-
var _a, _b, _c;
|
251
|
+
var _a, _b, _c, _d;
|
237
252
|
this.timeManager.update();
|
238
253
|
this.characterManager.update();
|
239
254
|
(_a = this.voiceChatManager) == null ? void 0 : _a.speakingParticipants.forEach((value, id) => {
|
@@ -242,8 +257,17 @@ var Networked3dWebExperienceClient = class {
|
|
242
257
|
this.cameraManager.update();
|
243
258
|
(_c = this.composer.sun) == null ? void 0 : _c.updateCharacterPosition((_b = this.characterManager.localCharacter) == null ? void 0 : _b.position);
|
244
259
|
this.composer.render(this.timeManager);
|
245
|
-
if (this.tweakPane.guiVisible) {
|
260
|
+
if ((_d = this.tweakPane) == null ? void 0 : _d.guiVisible) {
|
246
261
|
this.tweakPane.updateStats(this.timeManager);
|
262
|
+
this.tweakPane.updateCameraData(this.cameraManager);
|
263
|
+
if (this.characterManager.localCharacter && this.characterManager.localController) {
|
264
|
+
if (!this.characterControllerPaneSet) {
|
265
|
+
this.characterControllerPaneSet = true;
|
266
|
+
this.characterManager.setupTweakPane(this.tweakPane);
|
267
|
+
} else {
|
268
|
+
this.tweakPane.updateCharacterData(this.characterManager.localController);
|
269
|
+
}
|
270
|
+
}
|
247
271
|
}
|
248
272
|
requestAnimationFrame(() => {
|
249
273
|
this.update();
|
@@ -296,10 +320,33 @@ var Networked3dWebExperienceClient = class {
|
|
296
320
|
});
|
297
321
|
this.scene.add(this.mmlCompositionScene.group);
|
298
322
|
setGlobalMMLScene(this.mmlCompositionScene.mmlScene);
|
299
|
-
|
300
|
-
const
|
301
|
-
|
302
|
-
|
323
|
+
if (this.config.mmlDocuments) {
|
324
|
+
for (const mmlDocument of this.config.mmlDocuments) {
|
325
|
+
const frameElement = document.createElement("m-frame");
|
326
|
+
frameElement.setAttribute("src", mmlDocument.url);
|
327
|
+
if (mmlDocument.position) {
|
328
|
+
frameElement.setAttribute("x", mmlDocument.position.x.toString());
|
329
|
+
frameElement.setAttribute("y", mmlDocument.position.y.toString());
|
330
|
+
frameElement.setAttribute("z", mmlDocument.position.z.toString());
|
331
|
+
}
|
332
|
+
if (mmlDocument.rotation) {
|
333
|
+
frameElement.setAttribute("rx", mmlDocument.rotation.x.toString());
|
334
|
+
frameElement.setAttribute("ry", mmlDocument.rotation.y.toString());
|
335
|
+
frameElement.setAttribute("rz", mmlDocument.rotation.z.toString());
|
336
|
+
}
|
337
|
+
if (mmlDocument.scale) {
|
338
|
+
if (mmlDocument.scale.x !== void 0) {
|
339
|
+
frameElement.setAttribute("sx", mmlDocument.scale.x.toString());
|
340
|
+
}
|
341
|
+
if (mmlDocument.scale.y !== void 0) {
|
342
|
+
frameElement.setAttribute("sy", mmlDocument.scale.y.toString());
|
343
|
+
}
|
344
|
+
if (mmlDocument.scale.z !== void 0) {
|
345
|
+
frameElement.setAttribute("sz", mmlDocument.scale.z.toString());
|
346
|
+
}
|
347
|
+
}
|
348
|
+
document.body.appendChild(frameElement);
|
349
|
+
}
|
303
350
|
}
|
304
351
|
const mmlProgressManager = this.mmlCompositionScene.mmlScene.getLoadingProgressManager();
|
305
352
|
this.loadingProgressManager.addLoadingDocument(mmlProgressManager, "mml", mmlProgressManager);
|
package/build/index.js.map
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"version": 3,
|
3
3
|
"sources": ["../src/Networked3dWebExperienceClient.ts"],
|
4
|
-
"sourcesContent": ["import {\n AnimationConfig,\n CameraManager,\n CharacterDescription,\n CharacterManager,\n CharacterModelLoader,\n CharacterState,\n CollisionsManager,\n Composer,\n decodeCharacterAndCamera,\n getSpawnPositionInsideCircle,\n KeyInputManager,\n MMLCompositionScene,\n TimeManager,\n TweakPane,\n GroundPlane,\n LoadingScreen,\n VirtualJoystick,\n} from \"@mml-io/3d-web-client-core\";\nimport { ChatNetworkingClient, FromClientChatMessage, TextChatUI } from \"@mml-io/3d-web-text-chat\";\nimport {\n UserData,\n UserNetworkingClient,\n UserNetworkingClientUpdate,\n WebsocketStatus,\n} from \"@mml-io/3d-web-user-networking\";\nimport { VoiceChatManager } from \"@mml-io/3d-web-voice-chat\";\nimport {\n IMMLScene,\n LoadingProgressManager,\n registerCustomElementsToWindow,\n setGlobalMMLScene,\n} from \"mml-web\";\nimport { AudioListener, Euler, Scene, Vector3 } from \"three\";\n\nexport type Networked3dWebExperienceClientConfig = {\n sessionToken: string;\n chatNetworkAddress: string;\n userNetworkAddress: string;\n mmlDocumentAddresses: string[];\n animationConfig: AnimationConfig;\n hdrJpgUrl: string;\n};\n\nexport class Networked3dWebExperienceClient {\n private element: HTMLDivElement;\n\n private scene = new Scene();\n private composer: Composer;\n private tweakPane: TweakPane;\n private audioListener = new AudioListener();\n\n private cameraManager: CameraManager;\n\n private collisionsManager = new CollisionsManager(this.scene);\n\n private characterModelLoader = new CharacterModelLoader();\n private characterManager: CharacterManager;\n\n private timeManager = new TimeManager();\n\n private keyInputManager = new KeyInputManager();\n private virtualJoystick: VirtualJoystick;\n\n private mmlCompositionScene: MMLCompositionScene;\n\n private clientId: number | null = null;\n private networkClient: UserNetworkingClient;\n private remoteUserStates = new Map<number, CharacterState>();\n private userProfiles = new Map<number, UserData>();\n\n private networkChat: ChatNetworkingClient | null = null;\n private textChatUI: TextChatUI | null = null;\n\n private voiceChatManager: VoiceChatManager | null = null;\n private readonly latestCharacterObject = {\n characterState: null as null | CharacterState,\n };\n\n private initialLoadCompleted = false;\n private loadingProgressManager = new LoadingProgressManager();\n private loadingScreen: LoadingScreen;\n\n constructor(\n private holderElement: HTMLElement,\n private config: Networked3dWebExperienceClientConfig,\n ) {\n this.element = document.createElement(\"div\");\n this.element.style.position = \"absolute\";\n this.element.style.width = \"100%\";\n this.element.style.height = \"100%\";\n this.holderElement.appendChild(this.element);\n\n document.addEventListener(\"mousedown\", () => {\n if (this.audioListener.context.state === \"suspended\") {\n this.audioListener.context.resume();\n }\n });\n\n this.cameraManager = new CameraManager(this.element, this.collisionsManager);\n this.cameraManager.camera.add(this.audioListener);\n\n this.virtualJoystick = new VirtualJoystick(this.element, {\n radius: 70,\n inner_radius: 20,\n x: 70,\n y: 0,\n mouse_support: false,\n });\n\n this.composer = new Composer(this.scene, this.cameraManager.camera, true);\n this.composer.useHDRJPG(this.config.hdrJpgUrl);\n this.element.appendChild(this.composer.renderer.domElement);\n\n this.tweakPane = new TweakPane(\n this.element,\n this.composer.renderer,\n this.scene,\n this.composer.effectComposer,\n );\n this.composer.setupTweakPane(this.tweakPane);\n\n const resizeObserver = new ResizeObserver(() => {\n this.composer.fitContainer();\n });\n resizeObserver.observe(this.element);\n\n const initialNetworkLoadRef = {};\n this.loadingProgressManager.addLoadingAsset(initialNetworkLoadRef, \"network\", \"network\");\n this.networkClient = new UserNetworkingClient({\n url: this.config.userNetworkAddress,\n sessionToken: this.config.sessionToken,\n websocketFactory: (url: string) => new WebSocket(url),\n statusUpdateCallback: (status: WebsocketStatus) => {\n if (status === WebsocketStatus.Disconnected || status === WebsocketStatus.Reconnecting) {\n // The connection was lost after being established - the connection may be re-established with a different client ID\n this.characterManager.clear();\n this.remoteUserStates.clear();\n this.clientId = null;\n }\n },\n assignedIdentity: (clientId: number) => {\n console.log(`Assigned ID: ${clientId}`);\n this.clientId = clientId;\n if (this.initialLoadCompleted) {\n // Already loaded - respawn the character\n this.spawnCharacter();\n } else {\n this.loadingProgressManager.completedLoadingAsset(initialNetworkLoadRef);\n }\n },\n clientUpdate: (\n remoteClientId: number,\n userNetworkingClientUpdate: null | UserNetworkingClientUpdate,\n ) => {\n if (userNetworkingClientUpdate === null) {\n this.remoteUserStates.delete(remoteClientId);\n } else {\n this.remoteUserStates.set(remoteClientId, userNetworkingClientUpdate);\n }\n },\n clientProfileUpdated: (\n clientId: number,\n username: string,\n characterDescription: CharacterDescription,\n ): void => {\n this.updateUserProfile(clientId, {\n username,\n characterDescription,\n });\n },\n });\n\n this.characterManager = new CharacterManager({\n composer: this.composer,\n characterModelLoader: this.characterModelLoader,\n collisionsManager: this.collisionsManager,\n cameraManager: this.cameraManager,\n timeManager: this.timeManager,\n keyInputManager: this.keyInputManager,\n virtualJoystick: this.virtualJoystick,\n remoteUserStates: this.remoteUserStates,\n sendUpdate: (characterState: CharacterState) => {\n this.latestCharacterObject.characterState = characterState;\n this.networkClient.sendUpdate(characterState);\n },\n animationConfig: this.config.animationConfig,\n characterResolve: (characterId: number) => {\n return this.resolveCharacterData(characterId);\n },\n });\n this.scene.add(this.characterManager.group);\n\n const groundPlane = new GroundPlane();\n this.collisionsManager.addMeshesGroup(groundPlane);\n this.scene.add(groundPlane);\n\n this.setupMMLScene();\n\n this.loadingScreen = new LoadingScreen(this.loadingProgressManager);\n document.body.append(this.loadingScreen.element);\n\n this.loadingProgressManager.addProgressCallback(() => {\n const [, completed] = this.loadingProgressManager.toRatio();\n if (completed && !this.initialLoadCompleted) {\n this.initialLoadCompleted = true;\n /*\n When all content (in particular MML) has loaded, spawn the character (this is to avoid the character falling\n through as-yet-unloaded geometry)\n */\n this.connectToVoiceChat();\n this.connectToTextChat();\n this.spawnCharacter();\n }\n });\n this.loadingProgressManager.setInitialLoad(true);\n }\n\n static createFullscreenHolder(): HTMLDivElement {\n document.body.style.margin = \"0\";\n document.body.style.overflow = \"hidden\";\n\n const holder = document.createElement(\"div\");\n holder.style.position = \"absolute\";\n holder.style.width = \"100%\";\n holder.style.height = \"100%\";\n holder.style.overflow = \"hidden\";\n document.body.appendChild(holder);\n return holder;\n }\n\n private resolveCharacterData(clientId: number): {\n username: string;\n characterDescription: CharacterDescription;\n } {\n const user = this.userProfiles.get(clientId)!;\n if (!user) {\n throw new Error(`Failed to resolve user for clientId ${clientId}`);\n }\n\n return {\n username: user.username,\n characterDescription: user.characterDescription,\n };\n }\n\n private updateUserProfile(id: number, userData: UserData) {\n console.log(`Update user_profile for id=${id} (username=${userData.username})`);\n\n this.userProfiles.set(id, userData);\n\n this.characterManager.respawnIfPresent(id);\n }\n\n private sendChatMessageToServer(message: string): void {\n this.mmlCompositionScene.onChatMessage(message);\n if (this.clientId === null || this.networkChat === null) return;\n this.networkChat.sendChatMessage(message);\n }\n\n private connectToVoiceChat() {\n if (this.clientId === null) return;\n\n if (this.voiceChatManager === null) {\n this.voiceChatManager = new VoiceChatManager(\n this.element,\n this.clientId,\n this.remoteUserStates,\n this.latestCharacterObject,\n );\n }\n }\n\n private connectToTextChat() {\n if (this.clientId === null) {\n return;\n }\n const user = this.userProfiles.get(this.clientId);\n if (!user) {\n throw new Error(\"User not found\");\n }\n\n if (this.textChatUI === null) {\n this.textChatUI = new TextChatUI(\n this.element,\n user.username,\n this.sendChatMessageToServer.bind(this),\n );\n this.textChatUI.init();\n }\n\n if (this.networkChat === null) {\n this.networkChat = new ChatNetworkingClient({\n url: this.config.chatNetworkAddress,\n sessionToken: this.config.sessionToken,\n websocketFactory: (url: string) => new WebSocket(`${url}?id=${this.clientId}`),\n statusUpdateCallback: (status: WebsocketStatus) => {\n if (status === WebsocketStatus.Disconnected || status === WebsocketStatus.Reconnecting) {\n // The connection was lost after being established - the connection may be re-established with a different client ID\n }\n },\n clientChatUpdate: (\n clientId: number,\n chatNetworkingUpdate: null | FromClientChatMessage,\n ) => {\n if (chatNetworkingUpdate !== null && this.textChatUI !== null) {\n const username = this.userProfiles.get(clientId)?.username || \"Unknown\";\n this.textChatUI.addTextMessage(username, chatNetworkingUpdate.text);\n }\n },\n });\n }\n }\n\n public update(): void {\n this.timeManager.update();\n this.characterManager.update();\n this.voiceChatManager?.speakingParticipants.forEach((value: boolean, id: number) => {\n this.characterManager.setSpeakingCharacter(id, value);\n });\n this.cameraManager.update();\n this.composer.sun?.updateCharacterPosition(this.characterManager.localCharacter?.position);\n this.composer.render(this.timeManager);\n if (this.tweakPane.guiVisible) {\n this.tweakPane.updateStats(this.timeManager);\n }\n requestAnimationFrame(() => {\n this.update();\n });\n }\n\n private spawnCharacter() {\n if (this.clientId === null) {\n throw new Error(\"Client ID not set\");\n }\n const spawnPosition = getSpawnPositionInsideCircle(3, 30, this.clientId!, 0.4);\n const spawnRotation = new Euler(0, 0, 0);\n let cameraPosition: Vector3 | null = null;\n if (window.location.hash && window.location.hash.length > 1) {\n const urlParams = decodeCharacterAndCamera(window.location.hash.substring(1));\n spawnPosition.copy(urlParams.character.position);\n spawnRotation.setFromQuaternion(urlParams.character.quaternion);\n cameraPosition = urlParams.camera.position;\n }\n const ownIdentity = this.userProfiles.get(this.clientId);\n if (!ownIdentity) {\n throw new Error(\"Own identity not found\");\n }\n\n this.characterManager.spawnLocalCharacter(\n this.clientId!,\n ownIdentity.username,\n ownIdentity.characterDescription,\n spawnPosition,\n spawnRotation,\n );\n if (cameraPosition !== null) {\n this.cameraManager.camera.position.copy(cameraPosition);\n this.cameraManager.setTarget(\n new Vector3().add(spawnPosition).add(this.characterManager.headTargetOffset),\n );\n this.cameraManager.reverseUpdateFromPositions();\n }\n }\n\n private setupMMLScene() {\n registerCustomElementsToWindow(window);\n this.mmlCompositionScene = new MMLCompositionScene({\n targetElement: this.element,\n renderer: this.composer.renderer,\n scene: this.scene,\n camera: this.cameraManager.camera,\n audioListener: this.audioListener,\n collisionsManager: this.collisionsManager,\n getUserPositionAndRotation: () => {\n return this.characterManager.getLocalCharacterPositionAndRotation();\n },\n });\n this.scene.add(this.mmlCompositionScene.group);\n setGlobalMMLScene(this.mmlCompositionScene.mmlScene as IMMLScene);\n\n for (const address of this.config.mmlDocumentAddresses) {\n const frameElement = document.createElement(\"m-frame\");\n frameElement.setAttribute(\"src\", address);\n document.body.appendChild(frameElement);\n }\n\n const mmlProgressManager = this.mmlCompositionScene.mmlScene.getLoadingProgressManager!()!;\n this.loadingProgressManager.addLoadingDocument(mmlProgressManager, \"mml\", mmlProgressManager);\n mmlProgressManager.addProgressCallback(() => {\n this.loadingProgressManager.updateDocumentProgress(mmlProgressManager);\n });\n mmlProgressManager.setInitialLoad(true);\n }\n}\n"],
|
5
|
-
"mappings": ";AAAA;AAAA,EAEE;AAAA,EAEA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,
|
4
|
+
"sourcesContent": ["import {\n AnimationConfig,\n CameraManager,\n CharacterDescription,\n CharacterManager,\n CharacterModelLoader,\n CharacterState,\n CollisionsManager,\n Composer,\n decodeCharacterAndCamera,\n EnvironmentConfiguration,\n getSpawnPositionInsideCircle,\n GroundPlane,\n KeyInputManager,\n LoadingScreen,\n MMLCompositionScene,\n TimeManager,\n TweakPane,\n VirtualJoystick,\n} from \"@mml-io/3d-web-client-core\";\nimport { ChatNetworkingClient, FromClientChatMessage, TextChatUI } from \"@mml-io/3d-web-text-chat\";\nimport {\n UserData,\n UserNetworkingClient,\n UserNetworkingClientUpdate,\n WebsocketStatus,\n} from \"@mml-io/3d-web-user-networking\";\nimport { VoiceChatManager } from \"@mml-io/3d-web-voice-chat\";\nimport {\n IMMLScene,\n LoadingProgressManager,\n registerCustomElementsToWindow,\n setGlobalMMLScene,\n} from \"mml-web\";\nimport { AudioListener, Euler, Scene, Vector3 } from \"three\";\n\ntype MMLDocumentConfiguration = {\n url: string;\n position?: {\n x: number;\n y: number;\n z: number;\n };\n rotation?: {\n x: number;\n y: number;\n z: number;\n };\n scale?: {\n x: number;\n y: number;\n z: number;\n };\n};\n\nexport type Networked3dWebExperienceClientConfig = {\n sessionToken: string;\n chatNetworkAddress?: string;\n voiceChatAddress?: string;\n userNetworkAddress: string;\n mmlDocuments?: Array<MMLDocumentConfiguration>;\n animationConfig: AnimationConfig;\n environmentConfiguration?: EnvironmentConfiguration;\n skyboxHdrJpgUrl: string;\n enableTweakPane?: boolean;\n updateURLLocation?: boolean;\n};\n\nexport class Networked3dWebExperienceClient {\n private element: HTMLDivElement;\n\n private scene = new Scene();\n private composer: Composer;\n private tweakPane?: TweakPane;\n private audioListener = new AudioListener();\n\n private cameraManager: CameraManager;\n\n private collisionsManager = new CollisionsManager(this.scene);\n\n private characterModelLoader = new CharacterModelLoader();\n private characterManager: CharacterManager;\n\n private timeManager = new TimeManager();\n\n private keyInputManager = new KeyInputManager();\n private virtualJoystick: VirtualJoystick;\n\n private mmlCompositionScene: MMLCompositionScene;\n\n private clientId: number | null = null;\n private networkClient: UserNetworkingClient;\n private remoteUserStates = new Map<number, CharacterState>();\n private userProfiles = new Map<number, UserData>();\n\n private networkChat: ChatNetworkingClient | null = null;\n private textChatUI: TextChatUI | null = null;\n\n private voiceChatManager: VoiceChatManager | null = null;\n private readonly latestCharacterObject = {\n characterState: null as null | CharacterState,\n };\n private characterControllerPaneSet: boolean = false;\n\n private initialLoadCompleted = false;\n private loadingProgressManager = new LoadingProgressManager();\n private loadingScreen: LoadingScreen;\n\n constructor(\n private holderElement: HTMLElement,\n private config: Networked3dWebExperienceClientConfig,\n ) {\n this.element = document.createElement(\"div\");\n this.element.style.position = \"absolute\";\n this.element.style.width = \"100%\";\n this.element.style.height = \"100%\";\n this.holderElement.appendChild(this.element);\n\n document.addEventListener(\"mousedown\", () => {\n if (this.audioListener.context.state === \"suspended\") {\n this.audioListener.context.resume();\n }\n });\n\n this.cameraManager = new CameraManager(this.element, this.collisionsManager);\n this.cameraManager.camera.add(this.audioListener);\n\n this.virtualJoystick = new VirtualJoystick(this.element, {\n radius: 70,\n inner_radius: 20,\n x: 70,\n y: 0,\n mouse_support: false,\n });\n\n this.composer = new Composer({\n scene: this.scene,\n camera: this.cameraManager.camera,\n spawnSun: true,\n environmentConfiguration: this.config.environmentConfiguration,\n });\n\n this.composer.useHDRJPG(this.config.skyboxHdrJpgUrl);\n this.element.appendChild(this.composer.renderer.domElement);\n\n if (this.config.enableTweakPane !== false) {\n this.tweakPane = new TweakPane(\n this.element,\n this.composer.renderer,\n this.scene,\n this.composer.effectComposer,\n );\n this.cameraManager.setupTweakPane(this.tweakPane);\n this.composer.setupTweakPane(this.tweakPane);\n }\n\n const resizeObserver = new ResizeObserver(() => {\n this.composer.fitContainer();\n });\n resizeObserver.observe(this.element);\n\n const initialNetworkLoadRef = {};\n this.loadingProgressManager.addLoadingAsset(initialNetworkLoadRef, \"network\", \"network\");\n this.networkClient = new UserNetworkingClient({\n url: this.config.userNetworkAddress,\n sessionToken: this.config.sessionToken,\n websocketFactory: (url: string) => new WebSocket(url),\n statusUpdateCallback: (status: WebsocketStatus) => {\n if (status === WebsocketStatus.Disconnected || status === WebsocketStatus.Reconnecting) {\n // The connection was lost after being established - the connection may be re-established with a different client ID\n this.characterManager.clear();\n this.remoteUserStates.clear();\n this.clientId = null;\n }\n },\n assignedIdentity: (clientId: number) => {\n console.log(`Assigned ID: ${clientId}`);\n this.clientId = clientId;\n if (this.initialLoadCompleted) {\n // Already loaded - respawn the character\n this.spawnCharacter();\n } else {\n this.loadingProgressManager.completedLoadingAsset(initialNetworkLoadRef);\n }\n },\n clientUpdate: (\n remoteClientId: number,\n userNetworkingClientUpdate: null | UserNetworkingClientUpdate,\n ) => {\n if (userNetworkingClientUpdate === null) {\n this.remoteUserStates.delete(remoteClientId);\n } else {\n this.remoteUserStates.set(remoteClientId, userNetworkingClientUpdate);\n }\n },\n clientProfileUpdated: (\n clientId: number,\n username: string,\n characterDescription: CharacterDescription,\n ): void => {\n this.updateUserProfile(clientId, {\n username,\n characterDescription,\n });\n },\n });\n\n this.characterManager = new CharacterManager({\n composer: this.composer,\n characterModelLoader: this.characterModelLoader,\n collisionsManager: this.collisionsManager,\n cameraManager: this.cameraManager,\n timeManager: this.timeManager,\n keyInputManager: this.keyInputManager,\n virtualJoystick: this.virtualJoystick,\n remoteUserStates: this.remoteUserStates,\n sendUpdate: (characterState: CharacterState) => {\n this.latestCharacterObject.characterState = characterState;\n this.networkClient.sendUpdate(characterState);\n },\n animationConfig: this.config.animationConfig,\n characterResolve: (characterId: number) => {\n return this.resolveCharacterData(characterId);\n },\n updateURLLocation: this.config.updateURLLocation !== false,\n });\n this.scene.add(this.characterManager.group);\n\n if (this.config.environmentConfiguration?.groundPlane !== false) {\n const groundPlane = new GroundPlane();\n this.collisionsManager.addMeshesGroup(groundPlane);\n this.scene.add(groundPlane);\n }\n\n this.setupMMLScene();\n\n this.loadingScreen = new LoadingScreen(this.loadingProgressManager);\n document.body.append(this.loadingScreen.element);\n\n this.loadingProgressManager.addProgressCallback(() => {\n const [, completed] = this.loadingProgressManager.toRatio();\n if (completed && !this.initialLoadCompleted) {\n this.initialLoadCompleted = true;\n /*\n When all content (in particular MML) has loaded, spawn the character (this is to avoid the character falling\n through as-yet-unloaded geometry)\n */\n this.connectToVoiceChat();\n this.connectToTextChat();\n this.spawnCharacter();\n }\n });\n this.loadingProgressManager.setInitialLoad(true);\n }\n\n static createFullscreenHolder(): HTMLDivElement {\n document.body.style.margin = \"0\";\n document.body.style.overflow = \"hidden\";\n\n const holder = document.createElement(\"div\");\n holder.style.position = \"absolute\";\n holder.style.width = \"100%\";\n holder.style.height = \"100%\";\n holder.style.overflow = \"hidden\";\n document.body.appendChild(holder);\n return holder;\n }\n\n private resolveCharacterData(clientId: number): {\n username: string;\n characterDescription: CharacterDescription;\n } {\n const user = this.userProfiles.get(clientId)!;\n if (!user) {\n throw new Error(`Failed to resolve user for clientId ${clientId}`);\n }\n\n return {\n username: user.username,\n characterDescription: user.characterDescription,\n };\n }\n\n private updateUserProfile(id: number, userData: UserData) {\n console.log(`Update user_profile for id=${id} (username=${userData.username})`);\n\n this.userProfiles.set(id, userData);\n\n this.characterManager.respawnIfPresent(id);\n }\n\n private sendChatMessageToServer(message: string): void {\n this.mmlCompositionScene.onChatMessage(message);\n if (this.clientId === null || this.networkChat === null) return;\n this.networkChat.sendChatMessage(message);\n }\n\n private connectToVoiceChat() {\n if (this.clientId === null) return;\n\n if (this.voiceChatManager === null && this.config.voiceChatAddress) {\n this.voiceChatManager = new VoiceChatManager({\n url: this.config.voiceChatAddress,\n holderElement: this.element,\n userId: this.clientId,\n remoteUserStates: this.remoteUserStates,\n latestCharacterObj: this.latestCharacterObject,\n autoJoin: false,\n });\n }\n }\n\n private connectToTextChat() {\n if (this.clientId === null) {\n return;\n }\n if (this.networkChat === null && this.config.chatNetworkAddress) {\n const user = this.userProfiles.get(this.clientId);\n if (!user) {\n throw new Error(\"User not found\");\n }\n\n if (this.textChatUI === null) {\n this.textChatUI = new TextChatUI(\n this.element,\n user.username,\n this.sendChatMessageToServer.bind(this),\n );\n this.textChatUI.init();\n }\n\n this.networkChat = new ChatNetworkingClient({\n url: this.config.chatNetworkAddress,\n sessionToken: this.config.sessionToken,\n websocketFactory: (url: string) => new WebSocket(`${url}?id=${this.clientId}`),\n statusUpdateCallback: (status: WebsocketStatus) => {\n if (status === WebsocketStatus.Disconnected || status === WebsocketStatus.Reconnecting) {\n // The connection was lost after being established - the connection may be re-established with a different client ID\n }\n },\n clientChatUpdate: (\n clientId: number,\n chatNetworkingUpdate: null | FromClientChatMessage,\n ) => {\n if (chatNetworkingUpdate !== null && this.textChatUI !== null) {\n const username = this.userProfiles.get(clientId)?.username || \"Unknown\";\n this.textChatUI.addTextMessage(username, chatNetworkingUpdate.text);\n }\n },\n });\n }\n }\n\n public update(): void {\n this.timeManager.update();\n this.characterManager.update();\n this.voiceChatManager?.speakingParticipants.forEach((value: boolean, id: number) => {\n this.characterManager.setSpeakingCharacter(id, value);\n });\n this.cameraManager.update();\n this.composer.sun?.updateCharacterPosition(this.characterManager.localCharacter?.position);\n this.composer.render(this.timeManager);\n if (this.tweakPane?.guiVisible) {\n this.tweakPane.updateStats(this.timeManager);\n this.tweakPane.updateCameraData(this.cameraManager);\n if (this.characterManager.localCharacter && this.characterManager.localController) {\n if (!this.characterControllerPaneSet) {\n this.characterControllerPaneSet = true;\n this.characterManager.setupTweakPane(this.tweakPane);\n } else {\n this.tweakPane.updateCharacterData(this.characterManager.localController);\n }\n }\n }\n requestAnimationFrame(() => {\n this.update();\n });\n }\n\n private spawnCharacter() {\n if (this.clientId === null) {\n throw new Error(\"Client ID not set\");\n }\n const spawnPosition = getSpawnPositionInsideCircle(3, 30, this.clientId!, 0.4);\n const spawnRotation = new Euler(0, 0, 0);\n let cameraPosition: Vector3 | null = null;\n if (window.location.hash && window.location.hash.length > 1) {\n const urlParams = decodeCharacterAndCamera(window.location.hash.substring(1));\n spawnPosition.copy(urlParams.character.position);\n spawnRotation.setFromQuaternion(urlParams.character.quaternion);\n cameraPosition = urlParams.camera.position;\n }\n const ownIdentity = this.userProfiles.get(this.clientId);\n if (!ownIdentity) {\n throw new Error(\"Own identity not found\");\n }\n\n this.characterManager.spawnLocalCharacter(\n this.clientId!,\n ownIdentity.username,\n ownIdentity.characterDescription,\n spawnPosition,\n spawnRotation,\n );\n if (cameraPosition !== null) {\n this.cameraManager.camera.position.copy(cameraPosition);\n this.cameraManager.setTarget(\n new Vector3().add(spawnPosition).add(this.characterManager.headTargetOffset),\n );\n this.cameraManager.reverseUpdateFromPositions();\n }\n }\n\n private setupMMLScene() {\n registerCustomElementsToWindow(window);\n this.mmlCompositionScene = new MMLCompositionScene({\n targetElement: this.element,\n renderer: this.composer.renderer,\n scene: this.scene,\n camera: this.cameraManager.camera,\n audioListener: this.audioListener,\n collisionsManager: this.collisionsManager,\n getUserPositionAndRotation: () => {\n return this.characterManager.getLocalCharacterPositionAndRotation();\n },\n });\n this.scene.add(this.mmlCompositionScene.group);\n setGlobalMMLScene(this.mmlCompositionScene.mmlScene as IMMLScene);\n\n if (this.config.mmlDocuments) {\n for (const mmlDocument of this.config.mmlDocuments) {\n const frameElement = document.createElement(\"m-frame\");\n frameElement.setAttribute(\"src\", mmlDocument.url);\n if (mmlDocument.position) {\n frameElement.setAttribute(\"x\", mmlDocument.position.x.toString());\n frameElement.setAttribute(\"y\", mmlDocument.position.y.toString());\n frameElement.setAttribute(\"z\", mmlDocument.position.z.toString());\n }\n if (mmlDocument.rotation) {\n frameElement.setAttribute(\"rx\", mmlDocument.rotation.x.toString());\n frameElement.setAttribute(\"ry\", mmlDocument.rotation.y.toString());\n frameElement.setAttribute(\"rz\", mmlDocument.rotation.z.toString());\n }\n if (mmlDocument.scale) {\n if (mmlDocument.scale.x !== undefined) {\n frameElement.setAttribute(\"sx\", mmlDocument.scale.x.toString());\n }\n if (mmlDocument.scale.y !== undefined) {\n frameElement.setAttribute(\"sy\", mmlDocument.scale.y.toString());\n }\n if (mmlDocument.scale.z !== undefined) {\n frameElement.setAttribute(\"sz\", mmlDocument.scale.z.toString());\n }\n }\n document.body.appendChild(frameElement);\n }\n }\n\n const mmlProgressManager = this.mmlCompositionScene.mmlScene.getLoadingProgressManager!()!;\n this.loadingProgressManager.addLoadingDocument(mmlProgressManager, \"mml\", mmlProgressManager);\n mmlProgressManager.addProgressCallback(() => {\n this.loadingProgressManager.updateDocumentProgress(mmlProgressManager);\n });\n mmlProgressManager.setInitialLoad(true);\n }\n}\n"],
|
5
|
+
"mappings": "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",
|
6
6
|
"names": []
|
7
7
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@mml-io/3d-web-experience-client",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.17.0",
|
4
4
|
"publishConfig": {
|
5
5
|
"access": "public"
|
6
6
|
},
|
@@ -18,14 +18,16 @@
|
|
18
18
|
"lint-fix": "eslint \"./{src,test}/**/*.{js,jsx,ts,tsx}\" --fix"
|
19
19
|
},
|
20
20
|
"dependencies": {
|
21
|
-
"@mml-io/3d-web-client-core": "^0.
|
22
|
-
"@mml-io/3d-web-text-chat": "^0.
|
23
|
-
"@mml-io/3d-web-user-networking": "^0.
|
24
|
-
"@mml-io/3d-web-voice-chat": "^0.
|
21
|
+
"@mml-io/3d-web-client-core": "^0.17.0",
|
22
|
+
"@mml-io/3d-web-text-chat": "^0.17.0",
|
23
|
+
"@mml-io/3d-web-user-networking": "^0.17.0",
|
24
|
+
"@mml-io/3d-web-voice-chat": "^0.17.0",
|
25
|
+
"mml-web": "^0.15.0",
|
25
26
|
"three": "0.163.0"
|
26
27
|
},
|
27
28
|
"devDependencies": {
|
28
29
|
"@types/node": "^20.12.7",
|
29
30
|
"@types/three": "0.163.0"
|
30
|
-
}
|
31
|
+
},
|
32
|
+
"gitHead": "bc97b49ea69d920e0824a6885f7e8fca440e2e12"
|
31
33
|
}
|