@oyna360/lobby-sdk 0.1.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.
Files changed (211) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +123 -0
  3. package/dist/avatar-accessories.d.ts +16 -0
  4. package/dist/avatar-accessories.d.ts.map +1 -0
  5. package/dist/avatar-accessories.js +214 -0
  6. package/dist/avatar-accessories.js.map +1 -0
  7. package/dist/avatar-asset-manager.d.ts +54 -0
  8. package/dist/avatar-asset-manager.d.ts.map +1 -0
  9. package/dist/avatar-asset-manager.js +215 -0
  10. package/dist/avatar-asset-manager.js.map +1 -0
  11. package/dist/avatar-clips.d.ts +17 -0
  12. package/dist/avatar-clips.d.ts.map +1 -0
  13. package/dist/avatar-clips.js +47 -0
  14. package/dist/avatar-clips.js.map +1 -0
  15. package/dist/avatar-config.d.ts +4 -0
  16. package/dist/avatar-config.d.ts.map +1 -0
  17. package/dist/avatar-config.js +9 -0
  18. package/dist/avatar-config.js.map +1 -0
  19. package/dist/avatar-factory.d.ts +64 -0
  20. package/dist/avatar-factory.d.ts.map +1 -0
  21. package/dist/avatar-factory.js +464 -0
  22. package/dist/avatar-factory.js.map +1 -0
  23. package/dist/avatar-instance.d.ts +31 -0
  24. package/dist/avatar-instance.d.ts.map +1 -0
  25. package/dist/avatar-instance.js +56 -0
  26. package/dist/avatar-instance.js.map +1 -0
  27. package/dist/avatar-material-pipeline.d.ts +34 -0
  28. package/dist/avatar-material-pipeline.d.ts.map +1 -0
  29. package/dist/avatar-material-pipeline.js +580 -0
  30. package/dist/avatar-material-pipeline.js.map +1 -0
  31. package/dist/avatar-rig-builder.d.ts +74 -0
  32. package/dist/avatar-rig-builder.d.ts.map +1 -0
  33. package/dist/avatar-rig-builder.js +347 -0
  34. package/dist/avatar-rig-builder.js.map +1 -0
  35. package/dist/draco.d.ts +7 -0
  36. package/dist/draco.d.ts.map +1 -0
  37. package/dist/draco.js +82 -0
  38. package/dist/draco.js.map +1 -0
  39. package/dist/humanoid-animator.d.ts +35 -0
  40. package/dist/humanoid-animator.d.ts.map +1 -0
  41. package/dist/humanoid-animator.js +191 -0
  42. package/dist/humanoid-animator.js.map +1 -0
  43. package/dist/humanoid-bone-names.d.ts +35 -0
  44. package/dist/humanoid-bone-names.d.ts.map +1 -0
  45. package/dist/humanoid-bone-names.js +126 -0
  46. package/dist/humanoid-bone-names.js.map +1 -0
  47. package/dist/humanoid-locomotion.d.ts +101 -0
  48. package/dist/humanoid-locomotion.d.ts.map +1 -0
  49. package/dist/humanoid-locomotion.js +300 -0
  50. package/dist/humanoid-locomotion.js.map +1 -0
  51. package/dist/humanoid-rig.d.ts +51 -0
  52. package/dist/humanoid-rig.d.ts.map +1 -0
  53. package/dist/humanoid-rig.js +304 -0
  54. package/dist/humanoid-rig.js.map +1 -0
  55. package/dist/index.d.ts +60 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +42 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/lobby-chat-ui.d.ts +3 -0
  60. package/dist/lobby-chat-ui.d.ts.map +1 -0
  61. package/dist/lobby-chat-ui.js +258 -0
  62. package/dist/lobby-chat-ui.js.map +1 -0
  63. package/dist/lobby-colliders.d.ts +10 -0
  64. package/dist/lobby-colliders.d.ts.map +1 -0
  65. package/dist/lobby-colliders.js +225 -0
  66. package/dist/lobby-colliders.js.map +1 -0
  67. package/dist/lobby-connection-ui.d.ts +8 -0
  68. package/dist/lobby-connection-ui.d.ts.map +1 -0
  69. package/dist/lobby-connection-ui.js +68 -0
  70. package/dist/lobby-connection-ui.js.map +1 -0
  71. package/dist/lobby-debug.d.ts +50 -0
  72. package/dist/lobby-debug.d.ts.map +1 -0
  73. package/dist/lobby-debug.js +132 -0
  74. package/dist/lobby-debug.js.map +1 -0
  75. package/dist/lobby-font.d.ts +5 -0
  76. package/dist/lobby-font.d.ts.map +1 -0
  77. package/dist/lobby-font.js +35 -0
  78. package/dist/lobby-font.js.map +1 -0
  79. package/dist/lobby-music.d.ts +40 -0
  80. package/dist/lobby-music.d.ts.map +1 -0
  81. package/dist/lobby-music.js +250 -0
  82. package/dist/lobby-music.js.map +1 -0
  83. package/dist/lobby-orientation-ui.d.ts +10 -0
  84. package/dist/lobby-orientation-ui.d.ts.map +1 -0
  85. package/dist/lobby-orientation-ui.js +64 -0
  86. package/dist/lobby-orientation-ui.js.map +1 -0
  87. package/dist/lobby-perf-diag.d.ts +254 -0
  88. package/dist/lobby-perf-diag.d.ts.map +1 -0
  89. package/dist/lobby-perf-diag.js +775 -0
  90. package/dist/lobby-perf-diag.js.map +1 -0
  91. package/dist/lobby-plaza-diag.d.ts +103 -0
  92. package/dist/lobby-plaza-diag.d.ts.map +1 -0
  93. package/dist/lobby-plaza-diag.js +534 -0
  94. package/dist/lobby-plaza-diag.js.map +1 -0
  95. package/dist/lobby-presence-ui.d.ts +4 -0
  96. package/dist/lobby-presence-ui.d.ts.map +1 -0
  97. package/dist/lobby-presence-ui.js +89 -0
  98. package/dist/lobby-presence-ui.js.map +1 -0
  99. package/dist/lobby-real-device-diag.d.ts +119 -0
  100. package/dist/lobby-real-device-diag.d.ts.map +1 -0
  101. package/dist/lobby-real-device-diag.js +468 -0
  102. package/dist/lobby-real-device-diag.js.map +1 -0
  103. package/dist/lobby-spawn.d.ts +15 -0
  104. package/dist/lobby-spawn.d.ts.map +1 -0
  105. package/dist/lobby-spawn.js +18 -0
  106. package/dist/lobby-spawn.js.map +1 -0
  107. package/dist/lobby-ui-i18n.d.ts +11 -0
  108. package/dist/lobby-ui-i18n.d.ts.map +1 -0
  109. package/dist/lobby-ui-i18n.js +21 -0
  110. package/dist/lobby-ui-i18n.js.map +1 -0
  111. package/dist/lobby-voice-ui.d.ts +3 -0
  112. package/dist/lobby-voice-ui.d.ts.map +1 -0
  113. package/dist/lobby-voice-ui.js +105 -0
  114. package/dist/lobby-voice-ui.js.map +1 -0
  115. package/dist/local-player-controller.d.ts +80 -0
  116. package/dist/local-player-controller.d.ts.map +1 -0
  117. package/dist/local-player-controller.js +422 -0
  118. package/dist/local-player-controller.js.map +1 -0
  119. package/dist/name-tag.d.ts +3 -0
  120. package/dist/name-tag.d.ts.map +1 -0
  121. package/dist/name-tag.js +59 -0
  122. package/dist/name-tag.js.map +1 -0
  123. package/dist/network-client.d.ts +87 -0
  124. package/dist/network-client.d.ts.map +1 -0
  125. package/dist/network-client.js +182 -0
  126. package/dist/network-client.js.map +1 -0
  127. package/dist/platform-bridge.d.ts +17 -0
  128. package/dist/platform-bridge.d.ts.map +1 -0
  129. package/dist/platform-bridge.js +90 -0
  130. package/dist/platform-bridge.js.map +1 -0
  131. package/dist/platform-lobby.d.ts +176 -0
  132. package/dist/platform-lobby.d.ts.map +1 -0
  133. package/dist/platform-lobby.js +679 -0
  134. package/dist/platform-lobby.js.map +1 -0
  135. package/dist/platform-types.d.ts +56 -0
  136. package/dist/platform-types.d.ts.map +1 -0
  137. package/dist/platform-types.js +3 -0
  138. package/dist/platform-types.js.map +1 -0
  139. package/dist/player-label.d.ts +9 -0
  140. package/dist/player-label.d.ts.map +1 -0
  141. package/dist/player-label.js +14 -0
  142. package/dist/player-label.js.map +1 -0
  143. package/dist/playground/playground-layout.d.ts +14 -0
  144. package/dist/playground/playground-layout.d.ts.map +1 -0
  145. package/dist/playground/playground-layout.js +320 -0
  146. package/dist/playground/playground-layout.js.map +1 -0
  147. package/dist/playground/playground-system.d.ts +30 -0
  148. package/dist/playground/playground-system.d.ts.map +1 -0
  149. package/dist/playground/playground-system.js +202 -0
  150. package/dist/playground/playground-system.js.map +1 -0
  151. package/dist/plaza-layout.d.ts +30 -0
  152. package/dist/plaza-layout.d.ts.map +1 -0
  153. package/dist/plaza-layout.js +527 -0
  154. package/dist/plaza-layout.js.map +1 -0
  155. package/dist/plugins.d.ts +5 -0
  156. package/dist/plugins.d.ts.map +1 -0
  157. package/dist/plugins.js +26 -0
  158. package/dist/plugins.js.map +1 -0
  159. package/dist/protocol.d.ts +276 -0
  160. package/dist/protocol.d.ts.map +1 -0
  161. package/dist/protocol.js +107 -0
  162. package/dist/protocol.js.map +1 -0
  163. package/dist/quality.d.ts +39 -0
  164. package/dist/quality.d.ts.map +1 -0
  165. package/dist/quality.js +95 -0
  166. package/dist/quality.js.map +1 -0
  167. package/dist/remote-player-manager.d.ts +48 -0
  168. package/dist/remote-player-manager.d.ts.map +1 -0
  169. package/dist/remote-player-manager.js +339 -0
  170. package/dist/remote-player-manager.js.map +1 -0
  171. package/dist/scene-manager.d.ts +26 -0
  172. package/dist/scene-manager.d.ts.map +1 -0
  173. package/dist/scene-manager.js +169 -0
  174. package/dist/scene-manager.js.map +1 -0
  175. package/dist/spawn-utils.d.ts +8 -0
  176. package/dist/spawn-utils.d.ts.map +1 -0
  177. package/dist/spawn-utils.js +29 -0
  178. package/dist/spawn-utils.js.map +1 -0
  179. package/dist/starter-layout.d.ts +17 -0
  180. package/dist/starter-layout.d.ts.map +1 -0
  181. package/dist/starter-layout.js +102 -0
  182. package/dist/starter-layout.js.map +1 -0
  183. package/dist/third-person-camera.d.ts +35 -0
  184. package/dist/third-person-camera.d.ts.map +1 -0
  185. package/dist/third-person-camera.js +181 -0
  186. package/dist/third-person-camera.js.map +1 -0
  187. package/dist/types.d.ts +164 -0
  188. package/dist/types.d.ts.map +1 -0
  189. package/dist/types.js +2 -0
  190. package/dist/types.js.map +1 -0
  191. package/dist/voice-chat.d.ts +78 -0
  192. package/dist/voice-chat.d.ts.map +1 -0
  193. package/dist/voice-chat.js +321 -0
  194. package/dist/voice-chat.js.map +1 -0
  195. package/dist/yield-to-render.d.ts +3 -0
  196. package/dist/yield-to-render.d.ts.map +1 -0
  197. package/dist/yield-to-render.js +11 -0
  198. package/dist/yield-to-render.js.map +1 -0
  199. package/dist/zones.d.ts +36 -0
  200. package/dist/zones.d.ts.map +1 -0
  201. package/dist/zones.js +68 -0
  202. package/dist/zones.js.map +1 -0
  203. package/docs/00-overview.md +47 -0
  204. package/docs/01-connect.md +85 -0
  205. package/docs/02-github.md +43 -0
  206. package/docs/03-modes.md +70 -0
  207. package/docs/04-api.md +106 -0
  208. package/docs/05-features.md +55 -0
  209. package/docs/06-controls.md +34 -0
  210. package/docs/07-troubleshooting.md +39 -0
  211. package/package.json +65 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatar-asset-manager.js","sourceRoot":"","sources":["../src/avatar-asset-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { LobbyAnimationState } from './protocol';
2
+ /** Alias lists used to map lobby locomotion → clip names in a GLB. */
3
+ export declare const AVATAR_CLIP_ALIASES: Record<LobbyAnimationState, string[]>;
4
+ export type NamedClip = {
5
+ name: string;
6
+ };
7
+ /**
8
+ * Pick the best animation clip for a locomotion state.
9
+ *
10
+ * Important: never fall back idle → walk (Meshy often ships only Walking;
11
+ * playing it while standing looks like the avatar always walks).
12
+ * Returns null when no suitable clip exists — caller should freeze bind pose.
13
+ */
14
+ export declare function pickAvatarClip<T extends NamedClip>(clips: readonly T[], state: LobbyAnimationState): T | null;
15
+ /** Drop duplicate clip names (Meshy often emits the same anim twice). Keep first. */
16
+ export declare function dedupeClipsByName<T extends NamedClip>(clips: readonly T[]): T[];
17
+ //# sourceMappingURL=avatar-clips.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatar-clips.d.ts","sourceRoot":"","sources":["../src/avatar-clips.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,sEAAsE;AACtE,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,EAAE,MAAM,EAAE,CAMrE,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAMzC;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,SAAS,EAChD,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,KAAK,EAAE,mBAAmB,GACzB,CAAC,GAAG,IAAI,CAgBV;AAED,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,EAAE,CAU/E"}
@@ -0,0 +1,47 @@
1
+ /** Alias lists used to map lobby locomotion → clip names in a GLB. */
2
+ export const AVATAR_CLIP_ALIASES = {
3
+ idle: ['idle', 'Idle', 'stand', 'Standing', 'TPose', 'APose'],
4
+ walk: ['walk', 'Walk', 'walking', 'Walking', 'locomotion'],
5
+ run: ['run', 'Run', 'running', 'Running', 'sprint', 'Sprint'],
6
+ jump: ['jump', 'Jump'],
7
+ fall: ['fall', 'Fall', 'falling', 'Falling'],
8
+ };
9
+ function matchAlias(clips, aliases) {
10
+ return clips.find((c) => aliases.some((a) => c.name.toLowerCase().includes(a.toLowerCase()))) ?? null;
11
+ }
12
+ /**
13
+ * Pick the best animation clip for a locomotion state.
14
+ *
15
+ * Important: never fall back idle → walk (Meshy often ships only Walking;
16
+ * playing it while standing looks like the avatar always walks).
17
+ * Returns null when no suitable clip exists — caller should freeze bind pose.
18
+ */
19
+ export function pickAvatarClip(clips, state) {
20
+ if (!clips.length)
21
+ return null;
22
+ const direct = matchAlias(clips, AVATAR_CLIP_ALIASES[state]);
23
+ if (direct)
24
+ return direct;
25
+ if (state === 'run') {
26
+ return matchAlias(clips, AVATAR_CLIP_ALIASES.walk);
27
+ }
28
+ if (state === 'jump' || state === 'fall') {
29
+ return matchAlias(clips, AVATAR_CLIP_ALIASES.idle);
30
+ }
31
+ // idle / walk with no matching clip → null (bind pose), never invent a clip
32
+ return null;
33
+ }
34
+ /** Drop duplicate clip names (Meshy often emits the same anim twice). Keep first. */
35
+ export function dedupeClipsByName(clips) {
36
+ const seen = new Set();
37
+ const out = [];
38
+ for (const clip of clips) {
39
+ const key = clip.name.trim().toLowerCase() || `__anon_${out.length}`;
40
+ if (seen.has(key))
41
+ continue;
42
+ seen.add(key);
43
+ out.push(clip);
44
+ }
45
+ return out;
46
+ }
47
+ //# sourceMappingURL=avatar-clips.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatar-clips.js","sourceRoot":"","sources":["../src/avatar-clips.ts"],"names":[],"mappings":"AAEA,sEAAsE;AACtE,MAAM,CAAC,MAAM,mBAAmB,GAA0C;IACxE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC;IAC7D,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,CAAC;IAC1D,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC;IAC7D,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC;CAC7C,CAAC;AAIF,SAAS,UAAU,CAAsB,KAAmB,EAAE,OAAiB;IAC7E,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACxG,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAmB,EACnB,KAA0B;IAE1B,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAE/B,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,EAAE,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7D,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QACpB,OAAO,UAAU,CAAC,KAAK,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACzC,OAAO,UAAU,CAAC,KAAK,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,4EAA4E;IAC5E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,iBAAiB,CAAsB,KAAmB;IACxE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAQ,EAAE,CAAC;IACpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,UAAU,GAAG,CAAC,MAAM,EAAE,CAAC;QACrE,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { SdkLobbyAvatar } from './platform-types';
2
+ /** Resolve absolute/relative glbUrl from SdkLobbyAvatar (phase A config). */
3
+ export declare function resolveGlbUrl(avatar: SdkLobbyAvatar): string | null;
4
+ //# sourceMappingURL=avatar-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatar-config.d.ts","sourceRoot":"","sources":["../src/avatar-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAKnE"}
@@ -0,0 +1,9 @@
1
+ /** Resolve absolute/relative glbUrl from SdkLobbyAvatar (phase A config). */
2
+ export function resolveGlbUrl(avatar) {
3
+ if (avatar.presetKind !== 'glb')
4
+ return null;
5
+ const config = (avatar.customConfig ?? {});
6
+ const url = config.glbUrl;
7
+ return typeof url === 'string' && url.trim() ? url.trim() : null;
8
+ }
9
+ //# sourceMappingURL=avatar-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatar-config.js","sourceRoot":"","sources":["../src/avatar-config.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,MAAM,UAAU,aAAa,CAAC,MAAsB;IAClD,IAAI,MAAM,CAAC,UAAU,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAC7C,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAA4B,CAAC;IACtE,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1B,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACnE,CAAC"}
@@ -0,0 +1,64 @@
1
+ import { Scene, TransformNode } from '@babylonjs/core';
2
+ import type { AnimationGroup } from '@babylonjs/core';
3
+ import '@babylonjs/loaders/glTF';
4
+ /** Register Draco decoder so compressed avatar GLBs (KHR_draco_mesh_compression) load. */
5
+ import '@babylonjs/core/Meshes/Compression/dracoCompression';
6
+ import type { SdkLobbyAvatar } from './platform-types';
7
+ import { AvatarInstance } from './avatar-instance';
8
+ import { applyAvatarBaseAlbedo, applyAvatarTint, hardenAvatarMaterials, readBaseAlbedoUrlFromConfig } from './avatar-material-pipeline';
9
+ import { type AvatarRig } from './avatar-rig-builder';
10
+ export type { AvatarRig } from './avatar-rig-builder';
11
+ export { AvatarRigBuilder } from './avatar-rig-builder';
12
+ export { applyAvatarTint, applyAvatarBaseAlbedo, readBaseAlbedoUrlFromConfig, hardenAvatarMaterials, };
13
+ /** Resolve absolute/relative glbUrl from SdkLobbyAvatar (phase A config). */
14
+ export { resolveGlbUrl } from './avatar-config';
15
+ export declare class AvatarFactory {
16
+ static create(scene: Scene, avatar: SdkLobbyAvatar, name?: string, displayName?: string, username?: string, options?: {
17
+ collider?: boolean | 'player' | 'body';
18
+ skipNameTag?: boolean;
19
+ }): TransformNode;
20
+ /** Procedural sync create, or GLB load when presetKind is glb + glbUrl. */
21
+ static createAsync(scene: Scene, avatar: SdkLobbyAvatar, name?: string, displayName?: string, username?: string, options?: {
22
+ collider?: boolean | 'player' | 'body';
23
+ skipAccessories?: boolean;
24
+ skipNameTag?: boolean;
25
+ }): Promise<TransformNode>;
26
+ static markLobbyAvatar(root: TransformNode, scene: Scene): void;
27
+ /**
28
+ * Recount avatars and drop extra PBR maps / bloom once the room fills up.
29
+ * Safe to call after spawn or dispose.
30
+ */
31
+ static syncCrowdBudget(scene: Scene): void;
32
+ /** Re-tint materials without reloading the GLB (legacy / procedural). */
33
+ static setTint(root: TransformNode, hex: string | undefined | null): void;
34
+ /** Swap base albedo without reloading the GLB (clothing texture variants). */
35
+ static setBaseAlbedo(root: TransformNode, textureUrl: string | undefined | null): void;
36
+ private static createFromGlb;
37
+ static getRig(root: TransformNode): AvatarRig | null;
38
+ static getAnimationGroups(root: TransformNode): AnimationGroup[] | undefined;
39
+ static setPosition(root: TransformNode, position: {
40
+ x: number;
41
+ y: number;
42
+ z: number;
43
+ }): void;
44
+ static setRotationY(root: TransformNode, rotationY: number): void;
45
+ /** Phase-1: wrap a factory-built root as AvatarInstance (no rebuild). */
46
+ static wrap(root: TransformNode): AvatarInstance;
47
+ /**
48
+ * Phase-1 high-level spawn API for remotes/controllers.
49
+ * Builds a procedural stand-in without exposing GLB/material details to callers.
50
+ */
51
+ static createPlaceholderInstance(scene: Scene, avatar: SdkLobbyAvatar, name: string, displayName?: string, username?: string, options?: {
52
+ collider?: boolean | 'player' | 'body';
53
+ skipNameTag?: boolean;
54
+ }): AvatarInstance;
55
+ /**
56
+ * Phase-1 high-level spawn API — same pipeline as createAsync, returns AvatarInstance.
57
+ */
58
+ static createInstanceAsync(scene: Scene, avatar: SdkLobbyAvatar, name?: string, displayName?: string, username?: string, options?: {
59
+ collider?: boolean | 'player' | 'body';
60
+ skipAccessories?: boolean;
61
+ skipNameTag?: boolean;
62
+ }): Promise<AvatarInstance>;
63
+ }
64
+ //# sourceMappingURL=avatar-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avatar-factory.d.ts","sourceRoot":"","sources":["../src/avatar-factory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,464 @@
1
+ import { Color3, Mesh, MeshBuilder, StandardMaterial, TransformNode, Vector3 as BVector3, VertexBuffer, } from '@babylonjs/core';
2
+ import '@babylonjs/loaders/glTF';
3
+ /** Register Draco decoder so compressed avatar GLBs (KHR_draco_mesh_compression) load. */
4
+ import '@babylonjs/core/Meshes/Compression/dracoCompression';
5
+ import { dedupeClipsByName } from './avatar-clips';
6
+ import { resolveGlbUrl } from './avatar-config';
7
+ import { attachNameTag } from './name-tag';
8
+ import { isTouchDevice, shouldTrimAvatarDetailMaps } from './quality';
9
+ import { isLobbyPerfDiagEnabled, lobbyPerfMark, lobbyPerfTimeAsync } from './lobby-perf-diag';
10
+ import { AvatarInstance } from './avatar-instance';
11
+ import { AvatarAssetManager } from './avatar-asset-manager';
12
+ import { AvatarMaterialPipeline, applyAvatarBaseAlbedo, applyAvatarTint, hardenAvatarMaterials, lobbyQualityOf, readBaseAlbedoUrlFromConfig, readTintFromConfig, trimDetailMapsOnMaterials, } from './avatar-material-pipeline';
13
+ import { AvatarRigBuilder } from './avatar-rig-builder';
14
+ import { yieldToRenderLoop } from './yield-to-render';
15
+ export { AvatarRigBuilder } from './avatar-rig-builder';
16
+ export { applyAvatarTint, applyAvatarBaseAlbedo, readBaseAlbedoUrlFromConfig, hardenAvatarMaterials, };
17
+ const PRESET_LOOKS = {
18
+ 'default-1': { bodyColor: '#6366f1', accentColor: '#fbbf24', pantsColor: '#1e3a5f', hairColor: '#312e81' },
19
+ 'default-2': { bodyColor: '#22c55e', accentColor: '#fde68a', pantsColor: '#14532d', hairColor: '#166534' },
20
+ 'default-3': { bodyColor: '#f97316', accentColor: '#fecaca', pantsColor: '#7c2d12', hairColor: '#9a3412' },
21
+ 'default-4': { bodyColor: '#64748b', accentColor: '#e2e8f0', pantsColor: '#0f172a', hairColor: '#334155' },
22
+ };
23
+ function colorFromConfig(value, fallback) {
24
+ try {
25
+ return Color3.FromHexString(typeof value === 'string' ? value : fallback);
26
+ }
27
+ catch {
28
+ return Color3.FromHexString(fallback);
29
+ }
30
+ }
31
+ function solid(scene, id, hex) {
32
+ const m = new StandardMaterial(id, scene);
33
+ m.diffuseColor = hex;
34
+ m.specularColor = new Color3(0.08, 0.08, 0.08);
35
+ return m;
36
+ }
37
+ function box(scene, name, size, material, parent, local) {
38
+ const mesh = MeshBuilder.CreateBox(name, size, scene);
39
+ mesh.material = material;
40
+ mesh.parent = parent;
41
+ mesh.position.set(local.x, local.y, local.z);
42
+ mesh.isPickable = false;
43
+ mesh.checkCollisions = false;
44
+ return mesh;
45
+ }
46
+ /** Resolve absolute/relative glbUrl from SdkLobbyAvatar (phase A config). */
47
+ export { resolveGlbUrl } from './avatar-config';
48
+ function fitGlbToHumanHeight(model, meshes, targetHeight = 1.85) {
49
+ if (!meshes.length)
50
+ return;
51
+ model.computeWorldMatrix(true);
52
+ for (const m of meshes) {
53
+ m.computeWorldMatrix(true);
54
+ try {
55
+ m.refreshBoundingInfo?.(true, true);
56
+ }
57
+ catch {
58
+ // ignore
59
+ }
60
+ }
61
+ let { min, max } = model.getHierarchyBoundingVectors(true);
62
+ let height = max.y - min.y;
63
+ // Skinned / broken bounds can be astronomical — fall back to local vertex AABB.
64
+ if (!(height > 0.01) || height > 20) {
65
+ let minY = Infinity;
66
+ let maxY = -Infinity;
67
+ let minX = Infinity;
68
+ let maxX = -Infinity;
69
+ let minZ = Infinity;
70
+ let maxZ = -Infinity;
71
+ for (const m of meshes) {
72
+ if (!(m instanceof Mesh))
73
+ continue;
74
+ const pos = m.getVerticesData(VertexBuffer.PositionKind);
75
+ if (!pos)
76
+ continue;
77
+ for (let i = 0; i < pos.length; i += 3) {
78
+ minX = Math.min(minX, pos[i]);
79
+ maxX = Math.max(maxX, pos[i]);
80
+ minY = Math.min(minY, pos[i + 1]);
81
+ maxY = Math.max(maxY, pos[i + 1]);
82
+ minZ = Math.min(minZ, pos[i + 2]);
83
+ maxZ = Math.max(maxZ, pos[i + 2]);
84
+ }
85
+ }
86
+ height = maxY - minY;
87
+ if (!(height > 0.01))
88
+ return;
89
+ const scale = targetHeight / height;
90
+ model.scaling.setAll(scale);
91
+ model.position.y = -minY * scale;
92
+ return;
93
+ }
94
+ const scale = targetHeight / height;
95
+ model.scaling.setAll(scale);
96
+ model.computeWorldMatrix(true);
97
+ for (const m of meshes)
98
+ m.computeWorldMatrix(true);
99
+ const fitted = model.getHierarchyBoundingVectors(true);
100
+ model.position.y -= fitted.min.y;
101
+ }
102
+ function stripCloneSuffix(name) {
103
+ return (name ?? '').replace(/__a\d+$/, '');
104
+ }
105
+ function isImportRootName(name) {
106
+ const base = stripCloneSuffix(name).toLowerCase();
107
+ return base === '__root__' || base === 'world';
108
+ }
109
+ export class AvatarFactory {
110
+ static create(scene, avatar, name = 'avatar', displayName, username, options = {}) {
111
+ const fromPreset = PRESET_LOOKS[avatar.presetKey] ?? PRESET_LOOKS['default-1'];
112
+ const config = {
113
+ ...fromPreset,
114
+ ...avatar.customConfig,
115
+ };
116
+ const shirt = colorFromConfig(config.bodyColor, '#4f46e5');
117
+ const skin = colorFromConfig(config.accentColor, '#fbbf24');
118
+ const pants = colorFromConfig(config.pantsColor, '#1e3a5f');
119
+ const shirtMat = solid(scene, `${name}-shirt-mat`, shirt);
120
+ const skinMat = solid(scene, `${name}-skin-mat`, skin);
121
+ const pantsMat = solid(scene, `${name}-pants-mat`, pants);
122
+ const visual = new TransformNode(`${name}-visual`, scene);
123
+ const tintMeshes = [];
124
+ const torso = new TransformNode(`${name}-torso`, scene);
125
+ torso.parent = visual;
126
+ torso.position.y = 1.18;
127
+ tintMeshes.push(box(scene, `${name}-body`, { width: 0.78, height: 0.82, depth: 0.42 }, shirtMat, torso, { x: 0, y: 0, z: 0 }));
128
+ tintMeshes.push(box(scene, `${name}-hip`, { width: 0.62, height: 0.22, depth: 0.36 }, pantsMat, torso, { x: 0, y: -0.48, z: 0 }));
129
+ const head = new TransformNode(`${name}-head-pivot`, scene);
130
+ head.parent = visual;
131
+ head.position.y = 1.78;
132
+ tintMeshes.push(box(scene, `${name}-head`, { width: 0.5, height: 0.5, depth: 0.5 }, skinMat, head, { x: 0, y: 0, z: 0 }));
133
+ tintMeshes.push(box(scene, `${name}-hair`, { width: 0.54, height: 0.16, depth: 0.54 }, solid(scene, `${name}-hair-mat`, colorFromConfig(config.hairColor, '#1f2937')), head, {
134
+ x: 0,
135
+ y: 0.28,
136
+ z: 0,
137
+ }));
138
+ const armL = new TransformNode(`${name}-arm-l`, scene);
139
+ armL.parent = visual;
140
+ armL.position.set(-0.52, 1.48, 0);
141
+ tintMeshes.push(box(scene, `${name}-arm--1`, { width: 0.22, height: 0.78, depth: 0.22 }, shirtMat, armL, { x: 0, y: -0.4, z: 0 }));
142
+ tintMeshes.push(box(scene, `${name}-hand--1`, { width: 0.2, height: 0.2, depth: 0.2 }, skinMat, armL, { x: 0, y: -0.82, z: 0 }));
143
+ const armR = new TransformNode(`${name}-arm-r`, scene);
144
+ armR.parent = visual;
145
+ armR.position.set(0.52, 1.48, 0);
146
+ tintMeshes.push(box(scene, `${name}-arm-1`, { width: 0.22, height: 0.78, depth: 0.22 }, shirtMat, armR, { x: 0, y: -0.4, z: 0 }));
147
+ tintMeshes.push(box(scene, `${name}-hand-1`, { width: 0.2, height: 0.2, depth: 0.2 }, skinMat, armR, { x: 0, y: -0.82, z: 0 }));
148
+ const legL = new TransformNode(`${name}-leg-l`, scene);
149
+ legL.parent = visual;
150
+ legL.position.set(-0.18, 0.9, 0);
151
+ tintMeshes.push(box(scene, `${name}-leg--1`, { width: 0.26, height: 0.88, depth: 0.28 }, pantsMat, legL, { x: 0, y: -0.44, z: 0 }));
152
+ const legR = new TransformNode(`${name}-leg-r`, scene);
153
+ legR.parent = visual;
154
+ legR.position.set(0.18, 0.9, 0);
155
+ tintMeshes.push(box(scene, `${name}-leg-1`, { width: 0.26, height: 0.88, depth: 0.28 }, pantsMat, legR, { x: 0, y: -0.44, z: 0 }));
156
+ if (!options.skipNameTag) {
157
+ attachNameTag(scene, visual, displayName ?? '', username ?? '', name);
158
+ }
159
+ let collider = null;
160
+ let root = visual;
161
+ if (options.collider === true || options.collider === 'player') {
162
+ collider = MeshBuilder.CreateBox(`${name}-collider`, { width: 0.12, height: 0.12, depth: 0.12 }, scene);
163
+ collider.isVisible = false;
164
+ collider.isPickable = false;
165
+ collider.checkCollisions = true;
166
+ collider.ellipsoid = new BVector3(0.42, 1.05, 0.42);
167
+ collider.ellipsoidOffset = new BVector3(0, 1.05, 0);
168
+ visual.parent = collider;
169
+ visual.position.set(0, 0, 0);
170
+ root = collider;
171
+ }
172
+ else if (options.collider === 'body') {
173
+ collider = MeshBuilder.CreateBox(`${name}-bodycol`, { width: 0.12, height: 0.12, depth: 0.12 }, scene);
174
+ collider.isVisible = false;
175
+ collider.isPickable = false;
176
+ collider.checkCollisions = false;
177
+ visual.parent = collider;
178
+ visual.position.set(0, 0, 0);
179
+ root = collider;
180
+ }
181
+ root.name = name;
182
+ const rig = { root, visual, collider, torso, head, armL, armR, legL, legR };
183
+ root.metadata = { ...(root.metadata ?? {}), rig, tintMeshes, isLobbyAvatarRoot: true };
184
+ return root;
185
+ }
186
+ /** Procedural sync create, or GLB load when presetKind is glb + glbUrl. */
187
+ static async createAsync(scene, avatar, name = 'avatar', displayName, username, options = {}) {
188
+ const run = async () => {
189
+ const glbUrl = resolveGlbUrl(avatar);
190
+ const cfg = avatar.customConfig;
191
+ console.info('[lobby-sdk] avatar createAsync', {
192
+ presetKey: avatar.presetKey,
193
+ presetKind: avatar.presetKind,
194
+ glbUrl,
195
+ colorVariantKey: cfg?.colorVariantKey ?? null,
196
+ baseAlbedo: readBaseAlbedoUrlFromConfig(cfg),
197
+ });
198
+ let root;
199
+ if (!glbUrl) {
200
+ root = AvatarFactory.create(scene, avatar, name, displayName, username, options);
201
+ }
202
+ else {
203
+ const candidates = [glbUrl];
204
+ try {
205
+ const absolute = new URL(glbUrl, typeof window !== 'undefined' ? window.location.href : 'http://localhost');
206
+ if (absolute.pathname && absolute.pathname !== glbUrl) {
207
+ candidates.push(absolute.pathname);
208
+ }
209
+ }
210
+ catch {
211
+ // ignore
212
+ }
213
+ let lastError;
214
+ let loaded = null;
215
+ for (const url of candidates) {
216
+ try {
217
+ loaded = await AvatarFactory.createFromGlb(scene, url, name, displayName, username, options);
218
+ break;
219
+ }
220
+ catch (err) {
221
+ lastError = err;
222
+ console.warn('[lobby-sdk] GLB avatar load failed, trying next URL', url, err);
223
+ }
224
+ }
225
+ if (!loaded) {
226
+ console.warn('[lobby-sdk] GLB avatar failed, falling back to procedural', glbUrl, lastError);
227
+ root = AvatarFactory.create(scene, avatar, name, displayName, username, options);
228
+ }
229
+ else {
230
+ root = loaded;
231
+ }
232
+ }
233
+ if (!options.skipAccessories) {
234
+ try {
235
+ const tAcc = performance.now();
236
+ const { attachAccessoriesFromAvatarConfig } = await import('./avatar-accessories');
237
+ await attachAccessoriesFromAvatarConfig(scene, root, avatar.customConfig);
238
+ if (isLobbyPerfDiagEnabled()) {
239
+ lobbyPerfMark('accessories', performance.now() - tAcc);
240
+ }
241
+ }
242
+ catch (err) {
243
+ console.warn('[lobby-sdk] accessories skipped', err);
244
+ }
245
+ }
246
+ // Appearance (baked clothing albedo) always applies — independent of mesh accessories.
247
+ const baseAlbedo = readBaseAlbedoUrlFromConfig(avatar.customConfig);
248
+ const tAppear = performance.now();
249
+ try {
250
+ applyAvatarBaseAlbedo(root, baseAlbedo);
251
+ }
252
+ catch (err) {
253
+ console.warn('[lobby-sdk] base albedo skipped', err);
254
+ }
255
+ // Whole-avatar tint is legacy (procedural). Never multiply over clothing texture variants.
256
+ if (!baseAlbedo) {
257
+ applyAvatarTint(root, readTintFromConfig(avatar.customConfig));
258
+ }
259
+ else {
260
+ applyAvatarTint(root, null);
261
+ }
262
+ if (isLobbyPerfDiagEnabled()) {
263
+ lobbyPerfMark('albedo_tint', performance.now() - tAppear);
264
+ }
265
+ AvatarFactory.markLobbyAvatar(root, scene);
266
+ return root;
267
+ };
268
+ if (!isLobbyPerfDiagEnabled())
269
+ return run();
270
+ return lobbyPerfTimeAsync('createAsync_total', run, name);
271
+ }
272
+ static markLobbyAvatar(root, scene) {
273
+ root.metadata = { ...(root.metadata ?? {}), isLobbyAvatarRoot: true };
274
+ root.onDisposeObservable.addOnce(() => {
275
+ queueMicrotask(() => {
276
+ if (scene.isDisposed)
277
+ return;
278
+ AvatarFactory.syncCrowdBudget(scene);
279
+ });
280
+ });
281
+ AvatarFactory.syncCrowdBudget(scene);
282
+ }
283
+ /**
284
+ * Recount avatars and drop extra PBR maps / bloom once the room fills up.
285
+ * Safe to call after spawn or dispose.
286
+ */
287
+ static syncCrowdBudget(scene) {
288
+ let count = 0;
289
+ for (const node of scene.transformNodes) {
290
+ if (!node.isDisposed() && node.metadata?.isLobbyAvatarRoot)
291
+ count++;
292
+ }
293
+ for (const mesh of scene.meshes) {
294
+ if (!mesh.isDisposed() && mesh.metadata?.isLobbyAvatarRoot)
295
+ count++;
296
+ }
297
+ scene.metadata?.applyLobbyCrowdLoad?.(count);
298
+ if (!shouldTrimAvatarDetailMaps({
299
+ quality: lobbyQualityOf(scene),
300
+ touch: isTouchDevice(),
301
+ avatarCount: count,
302
+ })) {
303
+ return;
304
+ }
305
+ trimDetailMapsOnMaterials(scene.meshes.filter((mesh) => mesh.metadata?.isLobbyAvatar));
306
+ }
307
+ /** Re-tint materials without reloading the GLB (legacy / procedural). */
308
+ static setTint(root, hex) {
309
+ AvatarMaterialPipeline.applyTint(root, hex);
310
+ }
311
+ /** Swap base albedo without reloading the GLB (clothing texture variants). */
312
+ static setBaseAlbedo(root, textureUrl) {
313
+ AvatarMaterialPipeline.applyBaseAlbedo(root, textureUrl);
314
+ }
315
+ static async createFromGlb(scene, glbUrl, name, displayName, username, options) {
316
+ const visual = new TransformNode(`${name}-visual`, scene);
317
+ // Separate model node so HumanoidAnimator can freely set visual.position.y
318
+ // without undoing the "feet on ground" offset.
319
+ const model = new TransformNode(`${name}-model`, scene);
320
+ model.parent = visual;
321
+ const result = await AvatarAssetManager.instantiateAvatarGlb(scene, glbUrl);
322
+ // Spread post-clone preparation across frames so remote different-base joins
323
+ // do not freeze the lobby on one long sync resume.
324
+ await yieldToRenderLoop();
325
+ const transformNodes = result.transformNodes;
326
+ const skeletons = result.skeletons;
327
+ const animationGroups = dedupeClipsByName(result.animationGroups);
328
+ const importRoot = result.meshes.find((m) => isImportRootName(m.name)) ??
329
+ transformNodes.find((t) => isImportRootName(t.name)) ??
330
+ result.meshes[0];
331
+ // Preserve glTF right-handed flip if present on import root.
332
+ const rootScaleZ = importRoot?.scaling?.z ?? 1;
333
+ const prepared = AvatarRigBuilder.prepareGlbSkeleton({
334
+ scene,
335
+ name,
336
+ glbUrl,
337
+ model,
338
+ importRoot,
339
+ rootScaleZ,
340
+ meshes: result.meshes,
341
+ transformNodes,
342
+ skeletons,
343
+ animationGroups,
344
+ });
345
+ const { clips, displayMeshes, rigidGlb, boneDriven, limbRig, originalAnimationGroups, skeletons: preparedSkeletons, transformNodes: preparedTransformNodes, } = prepared;
346
+ const hasSkeleton = skeletons.length > 0 || result.meshes.some((m) => !!m.skeleton);
347
+ for (const mesh of displayMeshes) {
348
+ mesh.isPickable = false;
349
+ mesh.checkCollisions = false;
350
+ mesh.receiveShadows = false;
351
+ }
352
+ await yieldToRenderLoop();
353
+ fitGlbToHumanHeight(model, displayMeshes);
354
+ {
355
+ const tHarden = performance.now();
356
+ AvatarMaterialPipeline.harden(displayMeshes);
357
+ if (isLobbyPerfDiagEnabled()) {
358
+ lobbyPerfMark('harden_materials', performance.now() - tHarden);
359
+ }
360
+ }
361
+ AvatarRigBuilder.padSkinnedBounds(displayMeshes);
362
+ AvatarMaterialPipeline.trimForLowEnd(scene, displayMeshes);
363
+ await yieldToRenderLoop();
364
+ const humanoid = AvatarRigBuilder.buildHumanoidAfterFit(visual, preparedSkeletons, preparedTransformNodes, boneDriven);
365
+ console.info('[lobby-sdk] GLB loaded', {
366
+ glbUrl,
367
+ hasSkeleton,
368
+ boneDriven,
369
+ humanoid: !!humanoid,
370
+ rigidGlb,
371
+ display: displayMeshes.map((m) => m.name),
372
+ });
373
+ const { torso, head, armL, armR, legL, legR } = AvatarRigBuilder.resolveLimbPivots(scene, name, visual, limbRig);
374
+ if (!options.skipNameTag) {
375
+ attachNameTag(scene, visual, displayName ?? '', username ?? '', name);
376
+ }
377
+ let collider = null;
378
+ let root = visual;
379
+ if (options.collider === true || options.collider === 'player') {
380
+ collider = MeshBuilder.CreateBox(`${name}-collider`, { width: 0.12, height: 0.12, depth: 0.12 }, scene);
381
+ collider.isVisible = false;
382
+ collider.isPickable = false;
383
+ collider.checkCollisions = true;
384
+ collider.ellipsoid = new BVector3(0.42, 1.05, 0.42);
385
+ collider.ellipsoidOffset = new BVector3(0, 1.05, 0);
386
+ visual.parent = collider;
387
+ visual.position.set(0, 0, 0);
388
+ root = collider;
389
+ }
390
+ else if (options.collider === 'body') {
391
+ collider = MeshBuilder.CreateBox(`${name}-bodycol`, { width: 0.12, height: 0.12, depth: 0.12 }, scene);
392
+ collider.isVisible = false;
393
+ collider.isPickable = false;
394
+ collider.checkCollisions = false;
395
+ visual.parent = collider;
396
+ visual.position.set(0, 0, 0);
397
+ root = collider;
398
+ }
399
+ root.name = name;
400
+ const rig = {
401
+ root,
402
+ visual,
403
+ collider,
404
+ torso,
405
+ head,
406
+ armL,
407
+ armR,
408
+ legL,
409
+ legR,
410
+ boneDriven,
411
+ humanoid,
412
+ restRotation: limbRig?.restRotation,
413
+ };
414
+ root.metadata = {
415
+ ...(root.metadata ?? {}),
416
+ rig,
417
+ animationGroups: clips,
418
+ /** Original GLB clips (emotes later); locomotion uses boneDriven procedural. */
419
+ sourceClips: boneDriven ? originalAnimationGroups : clips,
420
+ glbModel: model,
421
+ rigidGlb,
422
+ boneDriven,
423
+ tintMeshes: displayMeshes.filter((m) => !!m?.material && m.isEnabled?.() !== false && !isImportRootName(m.name)),
424
+ isLobbyAvatarRoot: true,
425
+ };
426
+ return root;
427
+ }
428
+ static getRig(root) {
429
+ return root.metadata?.rig ?? null;
430
+ }
431
+ static getAnimationGroups(root) {
432
+ const groups = root.metadata?.animationGroups;
433
+ return groups?.length ? groups : undefined;
434
+ }
435
+ static setPosition(root, position) {
436
+ root.position = new BVector3(position.x, position.y, position.z);
437
+ }
438
+ static setRotationY(root, rotationY) {
439
+ const rig = AvatarFactory.getRig(root);
440
+ const target = rig?.visual ?? root;
441
+ target.rotation.y = rotationY;
442
+ }
443
+ /** Phase-1: wrap a factory-built root as AvatarInstance (no rebuild). */
444
+ static wrap(root) {
445
+ return AvatarInstance.fromRoot(root);
446
+ }
447
+ /**
448
+ * Phase-1 high-level spawn API for remotes/controllers.
449
+ * Builds a procedural stand-in without exposing GLB/material details to callers.
450
+ */
451
+ static createPlaceholderInstance(scene, avatar, name, displayName, username, options = {}) {
452
+ const root = AvatarFactory.create(scene, avatar, name, displayName, username, options);
453
+ AvatarFactory.markLobbyAvatar(root, scene);
454
+ return AvatarInstance.fromRoot(root);
455
+ }
456
+ /**
457
+ * Phase-1 high-level spawn API — same pipeline as createAsync, returns AvatarInstance.
458
+ */
459
+ static async createInstanceAsync(scene, avatar, name = 'avatar', displayName, username, options = {}) {
460
+ const root = await AvatarFactory.createAsync(scene, avatar, name, displayName, username, options);
461
+ return AvatarInstance.fromRoot(root);
462
+ }
463
+ }
464
+ //# sourceMappingURL=avatar-factory.js.map